Crypto
Travaux Dirig´es Crypto no2
—Formation ISN—
Objectif du TP : programmer RSA.
1 Exponentiation binaire
Question 1 ´
Ecrire un petit programme qui affiche la liste des chiffres en base 2 d’un entier donn´e
(par exemple fourni au clavier, peu importe). On demande de faire en sorte que cette fonction-
nalit´e du programme puisse par la suite resservir, donc il est souhaitable d’´ecrire une fonction
chiffres en base 2, prenant comme argument un entier, et renvoyant une liste python.
Pour r´ealiser cette conversion d’un entier xen base 2, on peut s’y prendre de plusieurs fa¸cons.
Premi`ere m´ethode, r´ecursive :
Si k= 1, retourner la liste [1].
Si k= 2k0+ 1, calculer r´ecursivement l’´ecriture en base 2 de k0, puis en d´eduire celle de k.
Idem dans le cas k= 2k0.
Deuxi`eme m´ethode (la mˆeme sans r´ecursivit´e) :
Pour calculer le d´eveloppement en base 2 de x, on maintient deux entiers yet k, et une liste
t, tels qu’`a chaque instant test de longueur k, et : x=y2k+Pk1
i=0 ti2i.
Initialement, y=x,k= 0, et test la liste vide.
Tant que yest non nul, effectuer l’op´eration suivante :
Si yest impair, ajouter 1 `a la fin de t.
Si yest pair, ajouter 0 `a la fin de t.
Diviser ypar deux. Incr´ementer k.
Question 2 Combien d’op´erations en gros sont n´ecessaires pour effectuer le calcul pr´ec´edent selon
les m´ethodes ci-dessus ? Utilisez votre programme avec des entiers de 10, 20, 40, 80 chiffres (ou plus)
pour tenter de confirmer exp´erimentalement cette hypoth`ese.
Question 3 ´
Ecrire un programme par exponentiation binaire pour calculer akmod n, ´etant donn´e
trois entiers a,k, et n. En prenant pour ndes entiers de tailles croissante, tenter d’obtenir un ordre
de grandeur du nombre d’op´erations en fonction du nombre de chiffres de n.
2 Algorithme d’Euclide
On propose de programmer l’algorithme d’Euclide pour calculer le pgcd de deux entiers, et de
s’en servir dans un second temps pour calculer des inverses modulo un entier n.
On utilise le r´esultat suivant :
Proposition 1 Pour aet bdeux entiers, et b > 0, le pgcd de aet best le mˆeme que le pgcd de b
et de bmod a.
Ainsi, pour calcule pgcd(42,17), on se ram`ene `a
pgcd(42,17) = pgcd(17,8) = pgcd(8,1) = pgcd(1,0) = 1.
Question 4 ´
Ecrire un programme qui calcule le pgcd de deux nombres entiers.
On souhaite maintenant calculer des inverses modulaires. L’explication est un peu longue, mais
normalement le programme est court. Ceci ne sert pas avant la question 7.
1
´
Etant donn´e deux entiers aet M, pour calculer (et d´eterminer s’il existe) un entier berifiant
a×b1 mod M, il faut chercher des entiers tels que
au +Mv = 1.
La solution au probl`eme pos´e est alors l’entier ud’une telle relation. Pour obtenir cette relation,
on consid`ere trois suites d’entiers (u0, u1, . . .), (v0, v1, . . .), et (r0, r1, . . .). Ces suites sont cens´ees
v´erifier, pour chaque valeur de l’indice i0 :
aui+bvi=ri.
Les premi`eres valeurs de ces suites sont :
u0= 1, v0= 0, r0=a,
u1= 0, v1= 1, r1=b.
L’algorithme est le suivant. `
A chaque ´etape, on conserve uniquement les valeurs des suites u,v, et r
correspondant `a deux it´erations, et on s’en sert pour calculer le terme suivant. Ces suites sont donc
des suites r´ecurrentes (avec une r´ecurrence sur deux termes), mais li´ees entre elles. En effet, pour
calculer les termes ui+1, vi+1, ri+1, on proc`ede comme suit :
Soit qle quotient de la division enti`ere de ri1par ri.
La valeur ri1qriest alors le reste de cette division, c’est-`a-dire ri1mod ri.
Les termes d’incice i+ 1 sont obtenus par :
ri+1 =ri1qri,
ui+1 =ui1qui,
vi+1 =vi1qvi,
Lorsqu’on atteint ri+1 = 0, alors le pgcd est ri, et les coefficients uiet vi, dans le cas ri= 1,
donnent ce qu’on cherche.
Question 5 ´
Ecrire un programme qui calcule l’inverse de amodulo nen utilisant l’algorithme
ci-dessus. Est-il n´ecessaire de calculer les vi?
3 RSA
Pour cr´eer un module RSA, on a besoin de cr´eer des nombres premiers. Pour cela, on pourra uti-
liser la fonction randomprime programm´ee dans http://www.loria.fr/~thome/formation-isn/
isprime.py
Question 5 ´
Ecrire un programme qui tire deux nombres premiers au hasard d’un nombre de bits
donn´e (commencez par 100, puis 1000 quand ¸ca marche), calcule l’entier n=pq, et choisit un
exposant eerifiant la contrainte requise, `a savoir epremier avec (p1)(q1).
Question 6 ´
Ecrire un programme qui calcule le chiffr´e d’un message m. Vous pouvez envisager, `a
partir d’une message (c’est-`a-dire une chaˆıne de caract`eres pas trop longue), de fabriquer un entier
en consid´erant l’´ecriture en base 256, par exemple avec une fonction comme :
def string_to_int(s):
somme=0
for i in range(len(s)):
somme=somme*256+ord(s[i])
return somme
R´eciproquement, pour afficher la signature, vous pouvez soit l’afficher sous forme d’entier, soit au
format appel´e base64, `a l’aide du programme suivant :
2
import base64
def int_to_string(x):
s=""
while x>0:
s+=chr(x%256)
x/=256
return s
def int_to_printable_string(x):
return base64.standard_b64encode(int_to_string(x))
Question 7 Compl´eter le programme de g´en´eration de cl´e pour qu’il calcule aussi l’entier dservant
au d´echiffrement. Ajouter une fonction `a votre programme qui, `a l’aide de la cl´e priv´ee, d´echiffre un
message.
3
1 / 3 100%