===== Inverse modulaire =====
Les techniques de chiffrement font usage des calculs avec modulo. Connaissant les nombres entiers $a > 1$ et $p > a$ premier, on a parfois besoin de trouver $u$ vérifiant $a \times u \mod p = 1$.
{{page>nsi:terminales:chiffrement_modulo#Rappel de ce qu'est modulo}}
===== Algorithme d'Euclide étendu =====
On exploite des propriétés arithmétiques importantes. L'une d'elle est le **théorème de Bézout** qui nous dit :
Soient $a, b \in \mathbb{N}$, on peut trouver $u, v \in \mathbb{Z}$ tels que $a\cdot u + b\cdot v = PGCD(a,b)$.
[[https://fr.wikipedia.org/wiki/Algorithme_d%27Euclide_%C3%A9tendu|Wikipedia]] nous donne l'algorithme d'Euclide étendu que je reproduis ici (presque) à l'identique :
ENTRÉES : a, b entiers (naturels)
SORTIES : r entier (naturel) et u, v entiers relatifs tels que r = pgcd(a, b) et r = a*u+b*v
r, u, v, r', u', v' = a, 1, 0, b, 0, 1
TANT QUE r' ≠ 0 FAIRE
q = r÷r'
r, u, v, r', u', v' = r', u', v', r - q *r', u - q*u', v - q*v'
FIN TANT QUE
RENVOYER r, u, v
Le symbole ''÷'' représente une division entière, c'est à dire ''%%//%%'' en Python.
L'algorithme d'Euclide normal est celui qui permet de calculer le PGCD. Cet algorithme est un peu plus complet puisqu'il donne en plus les valeurs de ''u'' et ''v''.
Il y a une infinité de paires ''u,v''. Cet algorithme nous renvoie donc **une de ces paires**. C'est justement celle dont nous avons besoin.
===== Application à notre cas =====
Nous voulons trouver $u$ entier tel que $a\cdot u \mod p = 1$, avec $0 \leqslant u < p$.
$p$ est premier, donc $PGCD(a,p) = 1$ donc nous cherchons $u$ tel que $a\cdot u \mod p = PGCD(a,p)$, ce qui revient à dire $a\cdot u + p\cdot v = PGCD(a,p)$ pour un certain entier $v$.
Cela correspond au théorème de Bézout et à l'algorithme d'Euclide étendu. La valeur de ''u'' renvoyée est justement celle que nous voulons.
===== À faire =====
Vous devez écrire en Python une fonction ''%%inverse_modulaire(a, p)%%'' qui reprend l'algorithme d'Euclide étendu en tenant compte des adaptations :
* Au lieu de ''b'', nous voulons ''p'',
* Au lieu de renvoyer ''%%(r, u, v)%%'', nous ne voulons que ''u''
Pour vérifier :
# 6 * 9 = 54 donc 6 * 9 % 53 = 1
assert inverse_modulaire(6,53) == 9
# dans le même genre...
assert inverse_modulaire(18,53) == 3
assert inverse_modulaire(51,53) == 26
assert inverse_modulaire(52,53) == 52
assert inverse_modulaire(1,53) == 1