Si vous voulez tentez ce TD en C, vous trouverez de l'aide sur cette page.
J'écris cette fiche en me basant sur cette source.
Dans le cadre de RSA, on veut une clé $N = p_1 \times p_2$ avec $p_1$ et $p_2$ premiers. Pour un niveau de sécurité donné, c'est le nombre de bits de $N$ que l'on veut fixer. On demande par exemple $n = 1024$ bits pour $N$.
Cela signifie que $N$ est dans l'intervalle $[2^{n-1}\,;\,2^n[$.
Pour garantir que $N$ sera dans cet intervalle, on choisit $p_1$ et $p_2$ dans $\left[\sqrt{2}\cdot 2^{\frac{n}{2}-1}\,;\,2^{\frac{n}{2}}\right[$
Par exemple, pour $n = 1024$, on cherche $p_1$ et $p_2$ dans $\left[\sqrt{2}\cdot 2^{511}\,;\,2^{512}\right[$ et on sait qu'on peut en trouver jusque $10^{151}$ donc il y a le choix !
Demandons nous maintenant comment on choisit $p_1$ – idem pour $p_2$.
Voici la procédure :
Des détails sur la page Wikipedia.
C'est une approche probabiliste : trouver un très grand $p$ dont on est certain qu'il est premier demande trop de temps de calcul. On se contente d'être raisonnablement certain que $p$ est premier.
Si $p$ réussit un passage de test Rabin - Miller, la probabilité qu'il soit premier est de 75 %. Autrement dit, le risque qu'il ne soit pas premier est $\frac{1}{4}$.
Si $p$ passe $k$ passage de test, alors la probabilité qu'il ne soit pas premier est de $\frac{1}{4^k}$. Dans les applications commerciales, on se contente de diminuer ce risque à $\frac{1}{2^{128}}$. Il suffit donc de réussir $k = 64$ passages de tests.
Je résume ce que je trouve sur Wikipedia, je ne maîtrise pas les détails
Vous pouvez sauter si ça vous paraît trop compliqué/
On note $a \equiv b [c]$ ou $a \overset{c}{\equiv} b$ si $a \mod c = b$.
Soit $p$ un nombre premier. Le petit théorème de Fermat nous dit que pour $2 \leqslant a < p$, on a $a^{p-1} = 1 [p]$.
On sait aussi que si $X^2 \overset{p}{\equiv} 1$ alors $X \overset{p}{\equiv} 1$ ou $X \overset{p}{\equiv} -1 \overset{p}{\equiv} p - 1$.
L'idée est donc de chercher les racines carrés modulo des $p-1$ et de vérifier que le résultat est toujours $1$ ou $-1$.
Pour cela on détermine $d$ et $s$ tels que $p - 1 = d \times 2^s$, avec $d$ impair. Ainsi, pour un nombre $a$ comme précédemment, $a^{d\times 2^{s-1}}$ est la racine de $a^{d \times 2^s} = a^{p-1}$ et donc $a^{d\times 2^{s-1}} \overset{p}{\equiv} 1 \text{ ou } -1$. Et si c'est $1$ alors on peut poursuivre avec la racine suivante, c'est à dire $a^{d\times 2^{s-2}}$. Et ainsi de suite jusque $a^{d}$.
Donc, soit tous les $a^{d\times 2^{s-i}}$ sont égaux à 1 modulo $p$, soit il y en a qui est égal à $-1$ modulo $p$, c'est à dire à $p-1$.
Tout cela nous permet d'énoncer la propriété suivante.
Si $p$ premier, soit $d$ impair et $s$ tels que $p - 1 = d \times 2^s$, alors on a : \[a^d \overset{p}{\equiv} 1 \quad \text{ou} \quad \exists i \text{ tel que } 0 \leqslant i \leqslant s - 1, a^{d\times 2^i} \overset{p}{\equiv} p - 1\]
Si on trouve $a$ qui ne vérifie pas cette propriété, il prouve que $p$ n'est pas premier. On qualifie un tel nombre de témoin de Miller. Il peut aussi arriver que $p$ ne soit pas premier et que l'on choisisse $a$ vérifiant la propriété. Ce $a$ nous fait croire à tort que $p$ est premier. C'est un menteur.
On sait que les menteurs représentent moins de $\frac{1}{4}$ des choix possibles. Si on choisit $a$ au hasard, on a donc une probabilité de $\frac{1}{4}$ d'être trompés. Il suffit de répéter l'opération pour abaisser cette probabilité autant que l'on veut.
Je ne connais pas les mathématiques mises en œuvre. Je vous donne juste le fonctionnement…
Pour $p$ donné, dont on veut savoir s'il est premier,
random.randrange fait l'affaire,pow(a, b, p).
À faire : implémentez une fonction get_prime(n:int) → int qui renvoie un nombre premier à n bits, ou mieux, appartenant à $\left[\sqrt{2}\cdot 2^{n-1}\,;\,2^n\right[$. Il nous suffit que $p$ soit probablement un nombre premier avec une probabilité de $1 - \frac{1}{2^{128}}$, soit 64 passages de Rabin Miller.