Chapitre 4 : Cryptage à clef publique 

2. Cryptage RSA 

La méthode RSA est due à Rivest, Shamir et Adleman (1977). Chaque personne garde secrets deux grands nombres premiers et ,  ici congrus à 2 modulo 3, et la clef publique est le produit de ces deux nombres :  ..La méthode repose sur le fait qu'il est facile de tester la primalité d'un nombre mais très difficile de le décomposer en facteurs premiers. Ici, pour des raisons de rapidité, on ne prendra que des nombres pas trop grands. La commande ifactor décompose les nombres en facteurs premiers. Avec l'option easy, l'opération s'arrête dès qu'on a deux facteurs. La décomposition complète prend plus de temps : 

> restart: n:=8012940887713968000041:
 

> depart:=time(): ifactor(n,easy); temps_du_calcul:=time()-depart;
 

 

 

> depart:=time(): ifactor(n);      temps_du_calcul:=time()-depart;
 

``(13)*``(457)*``(2847639359)*``(473638939) 

0.78e-1 

3. Transformation d'une suite de caractères en un nombre 

On commence par numériser l'alphabet : 

> restart:Alphabet:=abcdefghijklmnopqrstuvwxyz;
 

abcdefghijklmnopqrstuvwxyz 

> nb_lettres:=length(Alphabet);
 

26 

> for ni to nb_lettres do lettre[ni]:=substring(Alphabet,ni..ni);od:
 

> lettre[0]:=` `:
 

> for ni from 0 to nb_lettres do image_lettre[lettre[ni]]:=ni;od:
 

On transforme  les textes comme si les nombres qui représentent les lettres étaient écrits en base 27, le nombre de lettres plus une unité. Ainsi dans le texte moi, la lettre m étant le 13ème caractère, la lettre o étant le 15ème caractère, et la lettre i étant le 9ème caractère,  moi est traduit en   13*27+ 15*27^2 + 9*27^3 = 188433, autrement dit image_lettre[m]*27 + image_lettre[o]*27^2 + image_lettre[i]*27^3}   = 188433. La procédure transforme  effectue cette opération : 

 

> 13*27+15*27^2+9*27^3;
 

188433 

> transforme := proc(expression)  local ni,resul,element;global nb_lettres;
resul := 0;
 for ni to length(expression) do
 element:=image_lettre[substring(expression,ni..ni)];
resul := resul+element*(nb_lettres+1)^ni;
od; end;
 

proc (expression) local ni, resul, element; global nb_lettres; resul := 0; for ni to length(expression) do element := image_lettre[substring(expression, ni .. ni)]; resul := resul+element*(nb_lettres+...
proc (expression) local ni, resul, element; global nb_lettres; resul := 0; for ni to length(expression) do element := image_lettre[substring(expression, ni .. ni)]; resul := resul+element*(nb_lettres+...
proc (expression) local ni, resul, element; global nb_lettres; resul := 0; for ni to length(expression) do element := image_lettre[substring(expression, ni .. ni)]; resul := resul+element*(nb_lettres+...
proc (expression) local ni, resul, element; global nb_lettres; resul := 0; for ni to length(expression) do element := image_lettre[substring(expression, ni .. ni)]; resul := resul+element*(nb_lettres+...
proc (expression) local ni, resul, element; global nb_lettres; resul := 0; for ni to length(expression) do element := image_lettre[substring(expression, ni .. ni)]; resul := resul+element*(nb_lettres+...
proc (expression) local ni, resul, element; global nb_lettres; resul := 0; for ni to length(expression) do element := image_lettre[substring(expression, ni .. ni)]; resul := resul+element*(nb_lettres+...
proc (expression) local ni, resul, element; global nb_lettres; resul := 0; for ni to length(expression) do element := image_lettre[substring(expression, ni .. ni)]; resul := resul+element*(nb_lettres+...
proc (expression) local ni, resul, element; global nb_lettres; resul := 0; for ni to length(expression) do element := image_lettre[substring(expression, ni .. ni)]; resul := resul+element*(nb_lettres+...
proc (expression) local ni, resul, element; global nb_lettres; resul := 0; for ni to length(expression) do element := image_lettre[substring(expression, ni .. ni)]; resul := resul+element*(nb_lettres+...
 

La procédure detransforme est l'opération inverse : 

> detransforme := proc(nb)  
 local ni,liste,s;global nb_lettres;
 liste := convert(nb,base,nb_lettres+1);  
 s:=seq(lettre[ni],ni = liste);     cat(s);  
end;
 

proc (nb) local ni, liste, s; global nb_lettres; liste := convert(nb, base, nb_lettres+1); s := seq(lettre[ni], ni = liste); cat(s) end proc
proc (nb) local ni, liste, s; global nb_lettres; liste := convert(nb, base, nb_lettres+1); s := seq(lettre[ni], ni = liste); cat(s) end proc
proc (nb) local ni, liste, s; global nb_lettres; liste := convert(nb, base, nb_lettres+1); s := seq(lettre[ni], ni = liste); cat(s) end proc
proc (nb) local ni, liste, s; global nb_lettres; liste := convert(nb, base, nb_lettres+1); s := seq(lettre[ni], ni = liste); cat(s) end proc
proc (nb) local ni, liste, s; global nb_lettres; liste := convert(nb, base, nb_lettres+1); s := seq(lettre[ni], ni = liste); cat(s) end proc
proc (nb) local ni, liste, s; global nb_lettres; liste := convert(nb, base, nb_lettres+1); s := seq(lettre[ni], ni = liste); cat(s) end proc
proc (nb) local ni, liste, s; global nb_lettres; liste := convert(nb, base, nb_lettres+1); s := seq(lettre[ni], ni = liste); cat(s) end proc
 

Application : 

> mm:=transforme(`exportation ou utilisation de moyens ou de prestations cryptologiques`);
 

11161877285996764252040100176836482637247487550761480069332246272579970426611359024268179380332502997
11161877285996764252040100176836482637247487550761480069332246272579970426611359024268179380332502997
11161877285996764252040100176836482637247487550761480069332246272579970426611359024268179380332502997
 

> detransforme(mm);
 

` exportation ou utilisation de moyens ou de prestations cryptologiques` 

4. Codage 

Tout d'abord, il vous faut deux nombres premiers congrus à 2 modulo 3 ; la commande  ithprime(n) retourne le n-ième nombre premier ; vous vérifierez que ithprime(30001)} et ithprime(30002)} sont tous deux convenables et on en fait le produit pour obtenir un nombre appelé : 

> p[alpha]:=ithprime(30001);q[alpha]:=ithprime(30002);
p[alpha] mod 3, q[alpha] mod 3;n[alpha]:=p[alpha]*q[alpha];
 

350381 

350411 

2, 2 

122777356591 

Le codage consiste alors à élever mm au cube modulo : 

> liste_a_coder := convert(mm,base,n[alpha]);
 

[23837826602, 11830203161, 87507179464, 50437414722, 14424963585, 36866185035, 15214119951, 8357253975, 93390448881, 1]
[23837826602, 11830203161, 87507179464, 50437414722, 14424963585, 36866185035, 15214119951, 8357253975, 93390448881, 1]
[23837826602, 11830203161, 87507179464, 50437414722, 14424963585, 36866185035, 15214119951, 8357253975, 93390448881, 1]
 

> code[alpha] := nombre -> nombre^3 mod n[alpha];
 

proc (nombre) options operator, arrow; `mod`(nombre^3, n[alpha]) end proc 

> liste_a_decoder := map(code[alpha],liste_a_coder);
 

[22062983447, 102673864147, 115506797664, 47803007864, 54260357925, 14355759177, 104924343683, 46864859676, 80810335964, 1]
[22062983447, 102673864147, 115506797664, 47803007864, 54260357925, 14355759177, 104924343683, 46864859676, 80810335964, 1]
[22062983447, 102673864147, 115506797664, 47803007864, 54260357925, 14355759177, 104924343683, 46864859676, 80810335964, 1]
 

5. Décodage 

Le décodage consiste à élever mm^3 à la puissance modulo   : 

 

> k[alpha] := (2*(p[alpha]-1)*(q[alpha]-1) + 1)/3;
 

81851103867 

> 55^k[alpha];
 

Error, numeric exception: overflow 

Maple refuse d'élever à une telle puissance ! On peut par contre utiliser la méthode d'exponentiation rapide exposée dans le chapitre précédent : 

> expomodulo:=proc(xx,nn,mm) local x,n,resul;
x:=xx mod mm;
resul:=1; n:=nn;
while n>0 do
  if type(n,odd) then resul:=resul*x mod mm; n:=n-1;  
  else x:=x*x mod mm; n:=n/2 fi;
end do;resul;end;
 

proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
proc (xx, nn, mm) local x, n, resul; x := `mod`(xx, mm); resul := 1; n := nn; while 0 < n do if type(n, odd) then resul := `mod`(resul*x, mm); n := n-1 else x := `mod`(x*x, mm); n := 1/2*n end if end ...
 

> decode[alpha] :=nombre->expomodulo(nombre,k[alpha],n[alpha]);
 

proc (nombre) options operator, arrow; expomodulo(nombre, k[alpha], n[alpha]) end proc 

> liste_decode[alpha] :=map(decode[alpha],liste_a_decoder);
 

[23837826602, 11830203161, 87507179464, 50437414722, 14424963585, 36866185035, 15214119951, 8357253975, 93390448881, 1]
[23837826602, 11830203161, 87507179464, 50437414722, 14424963585, 36866185035, 15214119951, 8357253975, 93390448881, 1]
[23837826602, 11830203161, 87507179464, 50437414722, 14424963585, 36866185035, 15214119951, 8357253975, 93390448881, 1]
 

> Retour:=proc(liste_decode,n_code) local retour,nb_de_termes,i,x;
retour:=0:x:=1;
nb_de_termes := nops(liste_decode);
for i to nb_de_termes do
  retour := retour + liste_decode[i]*x;
  x:=x*n_code;
od:
retour;
end;
 

proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
proc (liste_decode, n_code) local retour, nb_de_termes, i, x; retour := 0; x := 1; nb_de_termes := nops(liste_decode); for i to nb_de_termes do retour := retour+liste_decode[i]*x; x := x*n_code end do...
 

> retour:=Retour(liste_decode[alpha],n[alpha]);
 

11161877285996764252040100176836482637247487550761480069332246272579970426611359024268179380332502997
11161877285996764252040100176836482637247487550761480069332246272579970426611359024268179380332502997
11161877285996764252040100176836482637247487550761480069332246272579970426611359024268179380332502997
 

> detransforme(retour);
 

` exportation ou utilisation de moyens ou de prestations cryptologiques` 

6. Envoi d'un message de α vers ß 

L'émetteur α du message mm vers le destinataire ß chiffrera le message en effectuant .  

 

> p[beta]:=ithprime(30003);q[beta]:=ithprime(30004);
p[beta] mod 3, q[beta] mod 3;n[beta]:=p[beta]*q[beta];
k[beta] := (2*(p[beta]-1)*(q[beta]-1) + 1)/3;
 

350423 

350429 

2, 2 

122798381467 

81865120411 

> code[beta] := nombre -> nombre^3 mod n[beta];
decode[beta] :=nombre->expomodulo(nombre,k[beta],n[beta]);
 

proc (nombre) options operator, arrow; `mod`(nombre^3, n[beta]) end proc 

proc (nombre) options operator, arrow; expomodulo(nombre, k[beta], n[beta]) end proc 

> mmp:=map(code[beta],map(decode[alpha],liste_a_coder));
 

[39580739452, 110993175943, 9161857508, 114434224081, 85422028358, 14974706645, 100394318146, 89160106352, 76973283534, 1]
[39580739452, 110993175943, 9161857508, 114434224081, 85422028358, 14974706645, 100394318146, 89160106352, 76973283534, 1]
[39580739452, 110993175943, 9161857508, 114434224081, 85422028358, 14974706645, 100394318146, 89160106352, 76973283534, 1]
 

7. Réception d'un message de α par ß 

Le destinataire ß décryptera le message venant de α en effectuant : 

 

> mmp1:=map(code[alpha],map(decode[beta],mmp));
 

[23837826602, 11830203161, 87507179464, 50437414722, 14424963585, 36866185035, 15214119951, 8357253975, 93390448881, 1]
[23837826602, 11830203161, 87507179464, 50437414722, 14424963585, 36866185035, 15214119951, 8357253975, 93390448881, 1]
[23837826602, 11830203161, 87507179464, 50437414722, 14424963585, 36866185035, 15214119951, 8357253975, 93390448881, 1]
 

> retour:=Retour(mmp1,n[alpha]);
 

11161877285996764252040100176836482637247487550761480069332246272579970426611359024268179380332502997
11161877285996764252040100176836482637247487550761480069332246272579970426611359024268179380332502997
11161877285996764252040100176836482637247487550761480069332246272579970426611359024268179380332502997
 

> detransforme(retour);
 

` exportation ou utilisation de moyens ou de prestations cryptologiques` 

8. Interception d'un message de α par γ 

Si une troisième personne intercepte le message, il doit être incapable (ne connaissant pas  et mais seulement ) de décrypter ce message : 

> p[gamma]:=ithprime(30008);q[gamma]:=ithprime(30009);
p[gamma] mod 3, q[gamma] mod 3;n[gamma]:=p[gamma]*q[gamma];
k[gamma] := (2*(p[gamma]-1)*(q[gamma]-1) + 1)/3;
 

350447 

350453 

2, 2 

122815202491 

81876334395 

> code[gamma] := nombre -> nombre^3 mod n[gamma];
decode[gamma] :=nombre->expomodulo(nombre,k[gamma],n[gamma]);
 

proc (nombre) options operator, arrow; `mod`(nombre^3, n[gamma]) end proc 

proc (nombre) options operator, arrow; expomodulo(nombre, k[gamma], n[gamma]) end proc 

> mmp1:=map(code[alpha],map(decode[gamma],mmp));
 

[68207171108, 63319802436, 41009426940, 59633204239, 74100285615, 115825234840, 57256617492, 40871138419, 64911725154, 1]
[68207171108, 63319802436, 41009426940, 59633204239, 74100285615, 115825234840, 57256617492, 40871138419, 64911725154, 1]
[68207171108, 63319802436, 41009426940, 59633204239, 74100285615, 115825234840, 57256617492, 40871138419, 64911725154, 1]
 

> retour:=Retour(mmp1,n[alpha]);detransforme(retour);
 

9691371450007710847594449966448933268732861305360979126315894071484107015871462876818244515601860854
9691371450007710847594449966448933268732861305360979126315894071484107015871462876818244515601860854
9691371450007710847594449966448933268732861305360979126315894071484107015871462876818244515601860854
 

`ctqsncgijezdrlpkamb qwz iiolwi mwtzjyg kwgzxvlxa nwalnspqvkundordbflrp` 

On ne trouve qu'un vrai charabia !