2 Rsa Correction
2 Rsa Correction
2 Rsa Correction
M1 Reherche IMAO
Comme η est injective on obtient M ed n = [M ]n et donc C d = M ed ≡ M mod n.
4) Soit n ∈ N. Notons expr la fonction exponentitation rapide. Montrons par récurrence sur p ∈ N:
Hp : ”∀a ∈ N, d = expr(a, p, n) vérifie d ≡ ap mod n”
2
exponentiation_rapide(a,p,n):=block([q,b,c],
if p=0 then(
return(1)
)
else(
q:quotient(p,2),
b:exponentiation_rapide(a,q,n),
c:b*b,
if mod(p,2)=0 then(
return(mod(c,n))
)
else(
return(mod(a*c,n))
)
)
)
7) Comme Fp = Z/pZ est un corps, l’anneau Fp [X] est euclidien. Soit P (X) un polynôme de Fp [X] de
degré n > 1. Supposons que P (X) possède une racine α. En effectuant la division euclidienne de P (X)
par (X − α) on obtient Q(X) ∈ Fp [X] et c ∈ Fp tels que P (X) = Q(X) × (X − α) + c. Comme P (α) = 0,
on obtient c = 0 puis que X − α divise P et donc le degré de Q est n − 1. Par une récurrence immédiate
on obtient alors qu’un polynôme de degré n > 0 sur Fp [X] à au plus n racines.
8) Soit n > 3 un nombre impair (si n est pair alors il n’est pas premier car divisible par 2). Posons
n = 1 + 2s × t avec t impair. On dit qu’un entier a ∈ {1, ..., n} est un témoin de Miller pour n si la suite
s
at , a2t , a4t , ..., a2 t
contient que des 1 ou contient n−1 modulo n. On commence par coder une fonction est temoin miller(a,s,t)
qui retourne true si a est un témoin de Miller pour n = 1 + 2s t et false sinon.
est_temoin_miller(a,s,t):=block([k,n,L,U],
n:1+2**s*t,
L:makelist(exponentiation_rapide(a,2**k*t,n),k,0,s),
U:unique(L),
if length(U)=1 and U[1]=1 then(
return(true)
),
return(member(n-1,U))
)
3
La fonction unique(L) retourne une copie sans doublons de L. Ainsi L contient que des 1 si et seulement
si U=[1]. La fonction member(a,L) teste si a apparaı̂t dans la liste L.
Ensuite pour un entier m quelconque il faut savoir déterminer la plus grande puissance de 2 qui
divise m. C’est le role de la fonction valuation diadic:
valuation_diadique(m):=block([k,t],
t:1,
k:0,
while mod(m,t)=0 do(
t:t*2,
k:k+1
),
return(k-1)
)
test_miller_rabin(n):=block([a,k,res,s,t],
if mod(n,2)=0 then(
return(false)
),
s:valuation_diadique(n-1),
t:(n-1)/2**s,
res:true,
k:20,
while k>0 and res=true do(
a:1+random(n-1),
if not gcd(a,n)=1 then(
res:false
)
else(
res:est_temoin_miller(a,s,t)
),
k:k-1
),
return(res)
)
9) Sachant que n est composite il y’a une chance sur quatre pour qu’un entier a soit un temoin de
Miller. Si on teste 20 entiers différents il y’a donc une chance sur 420 pour que le teste de Miller-Rabin
détecte un nombre composite n comme étant pseudo-premier, c’est à dire une chance sur
10) La génération d’une paire de clés pour RSA est essentiellement basée sur la génération de grand
nombre premier. Pour cela on tire au hasard un grand nombre entier, on prend le plus petit impair plus
grand ou égal et on teste le nombre obtenu avec le test de Miller-Rabin. S’il est premier on a fini sinon
on recommence.
4
genere_premier(taille):=block([s,n,trouve],
trouve:false,
s:10**taille,
while not trouve do(
n:s+random(s),
if mod(n,2)=0 then(
n:n+1
),
trouve:test_miller_rabin(n)
),
return(n)
)
On obtient alors le code suivant pour la gnérations d’une paire de clé pour RSA.
genere_cles(taille):=block([p,q,n,phi,d,e,L],
p:genere_premier(taille),
q:genere_premier(taille),
if p=q then(
return(genere_cles(taille))
),
n:p*q,
phi:(p-1)*(q-1),
e:genere_premier(5),
while mod(phi,e)=0 do(
e:genere_premier(6)
),
L:gcdex(e,phi),
d:mod(L[1],phi),
return([[n,e],[n,d]])
)
11) Les focntions de chiffrement et de déchiffrement étant les mêmes on en code une seule.
chiffre(M,cle):=block([n,p],
n:cle[1],
p:cle[2],
return(exponentiation_rapide(M,p,n))
)
demo_rsa(taille):=block([cles,cle_prive,cle_publique,M,C,D],
cles:genere_cles(taille),
cle_publique:cles[1],
cle_prive:cles[2],
n:cle_publique[1],
print("-- Clé publique --"),print("- n : ",n),print("- e : ",cle_publique[2]),
print("-- Clé privé --"),print("- n : ",cle_prive[1]),print("- d : ",cle_prive[2]),
print("-- Chiffrement --"),
M:random(n),
C:chiffre(M,cle_publique),
print("- M : ",M),print("- C : ",C),
print("-- Déchiffrement --"),
D:chiffre(C,cle_prive),
print("- C : ",C),print("- D : ",D),
is(D=M)
)