corrections

Université d’Aix-Marseille
Cryptographie
Semestre 2
Exercices et corrections pour le TP 7
2014–2015
Nous recommençons avec les initialisations
pgcde = xgcd ; ppcm = lcm ; exp_mod = power_mod
L’exponentiation modulaire efficace se fait soit avec des entiers, m et c, en utilisant
exp_mod :
n, e = (10200406003,257)
m = 100
c = exp_mod(m,e,n)
soit avec la construction explicite de l’anneau Z/nZ et des éléments m et c dedans :
R = IntegerModRing(n)
m = R(100)
c = m^e
Pour up + vq = 1, rappelons que (pour entiers x1 et x2 )
ι(x1 , x2 ) = x1 + (x2 − x1 )up
= x2 + (x1 − x2 )vq
est l’inverse modulo n de π(x) = (x1 , x2 ) = (x mod p, x mod q).
Chiffrements et signatures RSA
1. Soit p = 100003, q = 102001, et e = 257, et mettre n = pq et t = ppcm(p − 1, q − 1).
On peut prendre le message m = 100 ci-dessous.
a. Trouver u et v tel que 1 = ue + vt, et en déduire d = e−1 mod t. Quel est la
valeur de d ?
b. Trouver d1 et d2 tel que d1 = e−1 mod (p − 1) et d2 = e−1 mod (q − 1) en
utilisant le pgcde, et vérifier que (d1 , d2 ) = (d mod (p − 1), d mod (q − 1)).
c. Trouver c = me mod n et (c1 , c2 ) = (me mod p, me mod q), puis vérifier l’égalité
c = ι(c1 , c2 ).
d. Trouver s = md mod n et (s1 , s2 ) = (md1 mod p, md2 mod q), puis vérifier l’égalité s = ι(s1 , s2 ).
e. Vérifier que s est la signature de m.
f. Quels sont les étapes audessus qui peuvent être fait avec la clé RSA publique
et quels ont besoin de la clé privée ?
Solution.
a. Du code pour déterminer d est :
p, q = (100003,102001)
n, e = (p*q,257)
t = ppcm(p-1,q-1)
r, u, v = pgcde(e,t)
d = u.mod(t)
La valeur de d est 1263449393.
b. On trouver (d1 , d2 ) = (24125, 75395) avec le code suivant :
r1, u1, v1 = pgcde(e,p-1)
d1 = u1.mod(p-1)
r2, u2, v2 = pgcde(e,q-1)
d2 = u2.mod(q-1)
et on vérifie que d1 == d.mod(p-1) et d2 == d.mod(q-1).
c. On trouver c = 1717808841 et (c1 , c2 ) = (57310, 10000) :
m = 100
c = exp_mod(m,e,n)
c1, c2 = (exp_mod(m,e,p), exp_mod(m,e,q))
et on vérifie que c1 == c.mod(p) et c2 == c.mod(q). Une fonction iota se
définit en Sage :
r, u, v = pgcde(p,q)
def iota(c1,c2):
return (c1 + u*p*(c2-c1)).mod(n)
qui permets de vérifie l’égalité c == iota(c1,c2).
On observe aussi que les deux conditions :
c1 == power_mod(m,e.mod(p-1),p),
c2 == power_mod(m,e.mod(q-1),q).
sont satisfaites. Normalement, ce n’est pas le propriétaire de la clé qui chiffre
le texte, donc l’expediteur n’a pas p et q disponible pour fait ce calcule. Par
contre, on lui accord le bénéfice d’un petit exposant e (donc e = e mod (p − 1)
et e = e mod (q − 1)).
d. Trouver s = md mod n et (s1 , s2 ) = (md1 mod p, md2 mod q), puis vérifier l’égalité s = ι(s1 , s2 ).
m = 100
s = exp_mod(m,d,n)
s1, s2 = (exp_mod(m,d1,p), exp_mod(m,d2,q))
e. On vérifie que power_mod(s,e,n) == m.
f. Le propriétaire de la clé peut faire le calcule m 7→ (s1 , s2 ) 7→ s = ι(s1 , s2 ), et
également pour le déchiffrement, il peut faire c 7→ (m1 , m2 ) 7→ m = ι(m1 , m2 ).
Le chiffrement et la vérification d’une signature n’a pas le bénéfice de cette
decomposition, donc normalement on ne peut pas calculer (c1 , c2 ). Par contre
ils peuvent prendre avantage d’un e petit.
2. Écrire une fonction complète pour le déchiffrement RSA en utilisant (d1 , d2 ). Reprendre ces exercices avec p et q aléatoires de 512 bits (cf. random_prime) et
comparer l’efficacité par rapport à c 7→ cd mod n.
Solution. On construit une clé publique :
p = random_prime(2^512)
q = random_prime(2^512)
n, e = (p*q,65537)
ainsi qu’une clé privée :
d = inverse_mod(e,ppcm(p-1,q-1))
d1 = inverse_mod(e,p-1)
d2 = inverse_mod(e,q-1)
puis on écrit une fonction de signature :
r, u, v = pgcde(p,q)
up = (u*p).mod(q)
def iota(s1,s2):
return (s1 + up*(s2-s1)).mod(n)
def signer(m):
s1 = exp_mod(m,d1,p)
s2 = exp_mod(m,d2,q)
return iota(s1,s2)
On a besoin de faire deux fois plus d’exponentiations, mais avec des exposants deux
fois plus petits :
sage: RR(log(d,base=2))
1019.26538473424
sage: RR(log(d1,base=2))
508.147856693156
sage: RR(log(d2,base=2))
507.475318641132
et modulo des entiers deux fois plus petits :
sage: RR(log(n,base=2))
1022.83149535495
sage: RR(log(p,base=2))
511.430630700940
sage: RR(log(q,base=2))
511.400864654009
L’avantage se voit dans le temps de calcule :
sage: timeit("signer(m)")
125 loops, best of 3: 5.68 ms per loop
sage: timeit("exp_mod(m,d,n)")
25 loops, best of 3: 11.6 ms per loop
3. Le chiffrement du même message avec plusiers clés RSA différentes pose un problème de fuite d’information.
a. Si {c1 , c2 , . . . , cr } sont des textes chiffrés de la forme ci = me ni pour (e, ni )
décrire comment construire c = me mod n1 · · · nr .
b. Construire trois clés publiques (e, n1 ), (e, n2 ), (e, n3 ), avec l’exposant commun
e = 3, detérminer ci = me mod ni .
c. Calculer c mod n1 n2 n3 à partir de (c1 , c2 , c3 ) et reconstruire m.
Comment est-ce qu’on peut éviter cette fuite d’information, en gardant des exposants petits ? (Les valeurs 17, 257 ou 65537 sont des choix typiques pour e.)
Solution. La conclusion (dans partie c)) est que c = ι(c1 , c2 , c3 ) et m3 sont plus
petit que n1 n2 n3 , satisfaisant c = m3 mod n1 n2 n3 , on a c = m3 . On peut extrait
une troisième racine (dans R) pour retrouver m.
ElGamal
4. Soit p = 100000000003, a = 2, b = 3, et K = (p, a, b) une clé ElGamal.
a. Trouver la clé privée k (tel que b = ak mod p) associée à K.
b. Calculer un chiffrement c de m = 7 avec (p, a, b).
c. Montrer les étapes pour déchiffrement de votre texte chiffré.
Solution.
a. On trouve k = 1452889085 par :
p = 100000000003
FF = FiniteField(p)
a = FF(2)
b = FF(3)
k = log(b,base=a)
et on peut vérifier power_mod(2,k,p) == 3.
b.
c. Le déchiffrement est (r, s) 7→ m = r−k s mod p, donc les étapes sont les calcules
de r−1 mod p, de la puissance r−k ≡ (r−1 )k mod p, et du produit r−1 s mod p.