Travaux Dirigés Crypto no2 1 Exponentiation binaire 2 Algorithme d

publicité
Crypto
Travaux Dirigés Crypto no 2
—Formation ISN—
Objectif du TP : programmer RSA.
1
Exponentiation binaire
Question 1 Écrire un petit programme qui affiche la liste des chiffres en base 2 d’un entier donné
(par exemple fourni au clavier, peu importe). On demande de faire en sorte que cette fonctionnalité du programme puisse par la suite resservir, donc il est souhaitable d’écrire une fonction
chiffres en base 2, prenant comme argument un entier, et renvoyant une liste python.
Pour réaliser cette conversion d’un entier x en base 2, on peut s’y prendre de plusieurs façons.
– Première méthode, récursive :
– Si k = 1, retourner la liste [1].
– Si k = 2k 0 + 1, calculer récursivement l’écriture en base 2 de k 0 , puis en déduire celle de k.
Idem dans le cas k = 2k 0 .
– Deuxième méthode (la même sans récursivité) :
– Pour calculer le développement en base 2 de x, on maintient deux
y et k, et une liste
P entiers
i.
t
2
t, tels qu’à chaque instant t est de longueur k, et : x = y2k + k−1
i=0 i
– Initialement, y = x, k = 0, et t est la liste vide.
– Tant que y est non nul, effectuer l’opération suivante :
– Si y est impair, ajouter 1 à la fin de t.
– Si y est pair, ajouter 0 à la fin de t.
– Diviser y par deux. Incrémenter k.
Question 2 Combien d’opérations en gros sont nécessaires pour effectuer le calcul précédent selon
les méthodes ci-dessus ? Utilisez votre programme avec des entiers de 10, 20, 40, 80 chiffres (ou plus)
pour tenter de confirmer expérimentalement cette hypothèse.
Question 3 Écrire un programme par exponentiation binaire pour calculer ak mod n, étant donné
trois entiers a, k, et n. En prenant pour n des entiers de tailles croissante, tenter d’obtenir un ordre
de grandeur du nombre d’opérations 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ésultat suivant :
Proposition 1 Pour a et b deux entiers, et b > 0, le pgcd de a et b est le même que le pgcd de b
et de b mod a.
Ainsi, pour calcule pgcd(42, 17), on se ramène à
pgcd(42, 17) = pgcd(17, 8) = pgcd(8, 1) = pgcd(1, 0) = 1.
Question 4 Écrire 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
Étant donné deux entiers a et M , pour calculer (et déterminer s’il existe) un entier b vérifiant
a × b ≡ 1 mod M , il faut chercher des entiers tels que
au + M v = 1.
La solution au problème posé est alors l’entier u d’une telle relation. Pour obtenir cette relation,
on considère trois suites d’entiers (u0 , u1 , . . .), (v0 , v1 , . . .), et (r0 , r1 , . . .). Ces suites sont censées
vérifier, pour chaque valeur de l’indice i ≥ 0 :
aui + bvi = ri .
Les premières valeurs de ces suites sont :
u0 = 1,
v0 = 0,
r0 = a,
u1 = 0,
v1 = 1,
r1 = b.
L’algorithme est le suivant. À chaque étape, on conserve uniquement les valeurs des suites u, v, et r
correspondant à deux itérations, et on s’en sert pour calculer le terme suivant. Ces suites sont donc
des suites récurrentes (avec une récurrence sur deux termes), mais liées entre elles. En effet, pour
calculer les termes ui+1 , vi+1 , ri+1 , on procède comme suit :
– Soit q le quotient de la division entière de ri−1 par ri .
– La valeur ri−1 − qri est alors le reste de cette division, c’est-à-dire ri−1 mod ri .
– Les termes d’incice i + 1 sont obtenus par :
ri+1 = ri−1 − qri ,
ui+1 = ui−1 − qui ,
vi+1 = vi−1 − qvi ,
Lorsqu’on atteint ri+1 = 0, alors le pgcd est ri , et les coefficients ui et vi , dans le cas ri = 1,
donnent ce qu’on cherche.
Question 5 Écrire un programme qui calcule l’inverse de a modulo n en utilisant l’algorithme
ci-dessus. Est-il nécessaire de calculer les vi ?
3
RSA
Pour créer un module RSA, on a besoin de créer des nombres premiers. Pour cela, on pourra utiliser la fonction randomprime programmée dans http://www.loria.fr/~thome/formation-isn/
isprime.py
Question 5 Écrire un programme qui tire deux nombres premiers au hasard d’un nombre de bits
donné (commencez par 100, puis 1000 quand ça marche), calcule l’entier n = pq, et choisit un
exposant e vérifiant la contrainte requise, à savoir e premier avec (p − 1)(q − 1).
Question 6 Écrire un programme qui calcule le chiffré d’un message m. Vous pouvez envisager, à
partir d’une message (c’est-à-dire une chaı̂ne de caractères pas trop longue), de fabriquer un entier
en considérant l’écriture 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éciproquement, pour afficher la signature, vous pouvez soit l’afficher sous forme d’entier, soit au
format appelé base64, à 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éter le programme de génération de clé pour qu’il calcule aussi l’entier d servant
au déchiffrement. Ajouter une fonction à votre programme qui, à l’aide de la clé privée, déchiffre un
message.
3
Téléchargement