La fonction exponentielle croissant très rapidement, on dépasse
facilement les limites de l'arithmétique entière de la machine, et on ne
profite guère de cette accélération. Calculons plutôt
, de
façon à rester dans ces limites. Il suffit de placer un %m
après chaque opération. Voici la version récursive terminale de cette
fonction :
static int expmod_fastrec_aux(int x, int y, int e, int m) {
if (e == 0) {
return y;
} else if (e % 2 == 1) {
return expmod_fastrec_aux(x, x*y % m, e-1, m);
} else {
return expmod_fastrec_aux(x*x % m, y, e/2, m);
}
}
int expmod_fastrec(int x, int e, int m) {
return expmod_fastrec_aux(x, 1, e, m);
}
La version itérative s'obtient facilement par dérécursivation de cette définition récursive terminale :
int expmod_iter(int x, int e, int m) {
int y = 1;
while (e != 0) {
if (e%2 == 1) {
y = (x*y) % m;
e = e-1;
} else {
x = (x*x) % m;
e = e/2;
}
}
return y;
}
L'exponentielle modulaire intervient dans les algorithmes de la cryptographie à clé publique, car l'exponentielle modulaire est considérablement plus facile à calculer que son inverse, le logarithme modulaire (donc chiffrer est plus facile que déchiffrer). Le système de chiffrement à clé publique RSA a été proposé en 1977 par Ron Rivest, Adi Shamir et Leonard Adleman.
Pour construire ses clés, chaque utilisateur de RSA
Quand A veut communiquer un entier m (0<m<n) à B, il calcule
à l'aide de la clé publique de B, qu'il envoie à B ; à la
réception d'un message chiffré c, B calcule
à l'aide de sa
clé privée. Il s'agit bien d'un déchiffrage car
, grâce au théorème d'Euler
si m est premier avec n, et au fait que
.
La sécurité provient de la difficulté à factoriser de grands entiers. En effet, déterminer d à partir de e demande la connaissance de (p-1)(q-1); or la publication de n=pq n'est en aucune façon une aide pour calculer (p-1)(q-1), qui ne peut être obtenu qu'à partir de p et q. D'autre part, on ne sait pas calculer efficacement des racines e-ièmes, ce qui permettrait d'avoir le texte clair m à partir du texte chiffré C(m).