Accueil > > > CRYPTAGE RC5 32/12/16
CRYPTAGE RC5 32/12/16
Information sur la source
Description
Voici un code source pour le cryptage de chaines de caractères au moyen d'un algorithme RC5 (32 bits, 12 itérations, 16 octets de cle), sous forme d'une DLL créée avec lcc. Je l'ai écrit en adaptant le code présenté dans un document de référence donnée en PJ écrit par Ronald L. Rivest, en utilisant les paramètres 'nominaux': - mots de 32 bits - 12 itérations - 16 octets maxi pour la clé Les deux fonctions exportées 'crypte' et 'decrypte' reçoivent trois pointeurs de caractères : - PText (plain-text) : le texte à crypter - CText (cypher-text): le résultat du cryptage - Cle : la clé de cryptage(maximum 16 octets) Les chaines sont traitées par séquences de caractères représentant chacune deux mots de 32 bits, passés aux fonctions RC5_ENCRYPT et RC5_DECRYPT telles qu'elles figurent dans le document de référence (je me suis contenté de remplacer le type 'WORD' par 'W32', du fait que mon compilateur avait déja une définition pour 'WORD). En entrée du cryptage: les 8 octets sont transférés un à un à l'adresse du tableau de 2 mots, en passant par un casting *int > *char. Ceci pour éviter les problèmes liés aux différences d'implémentation des entiers selon les systèmes. En sortie du cryptage, on a à nouveau deux mots binaires, que l'on transforme en séquence de 10 octets pour obtenir une clé relativement éditable: - chaque octet est ramené à 7 bits pour rester dans le jeu standard ASCII 128 - si le résultat est inférieur à 48 on lui rajoute ce qu'il faut pour éviter d'avoir un code de controle ASCII ou un blanc. - l'information nécessaire pour décoder (2 bits par caractère) est stockée dans un octet de report (un octet de plus à la suite de chaque groupe de 4 octets): -- le bit de poids fort, à restituer -- le bit indiquant si on doit ou non soustraire 48 La chaine cryptée comporte donc 10 octets par groupe de 8 caractères en entrée. Traitement de la cle: L'algorithme est basé sur la construction d'un tableau de codage utilisé pour le cryptage, calculé à partir de la clé et de 2 'magic numbers',par la fonction RC5_SETUP. Lorsqu'une clé est passée, elle est étendue et conservée pour les appels ultérieurs. Lorsque la clé passée est vide ("") on travaille avec la clé enregistrée auparavant, si du moins on en a une (flag FlCle). L'archive en téléchargement comprend: - le document de référence en anglais (Rivest-rc5rev.pdf) - un résumé que j'ai fait en français (Cryptage RC5.doc) - le source C (inforom.c) - la dll (inforom.dll) - un exemple de code VBA pour test des appels depuis Excel (module1.bas)
Source
- #include <windows.h>
- /*----------------------------------------------------------------------*/
- /* RC5REF.C -- Reference implementation of RC5-32/12/16 in C */
- /* Copyright © 1995 RSA Data security. Inc. */
- /*----------------------------------------------------------------------*/
- /* les fonctions crypte et decrypte utilisent les algorithmes de cyptage*/
- /* définis dans ce document de référence. */
- /* RC5_SETUP: extension de la clé passée en argument sous forme de */
- /* chaine de caractères. Si l'appel de crypte ou decrypte ne */
- /* ne comporte pas de cle ("") c'est la cle précdémment */
- /* traitée qui est utilisée */
- /* s'il n' y a pas de texte à crypter la fonction crypte ou */
- /* decrypte se contente de réaliser l'expansion de la clé */
- /* RC5_ENCRYPT: cryptage d'un double mot */
- /* RC5_DECRYPT: decryptage d'un double mot */
- /* dans cette implémentation, on fixe les paramétres de cryptage */
- /* taille du mot: 32 bits */
- /* nombre d'itérations: 12 */
- /* taille (maxi) de clé en octets: 16 */
- /* (paramètres nominaux choisis par Ronald L. Rivest) */
- /* */
- /*----------------------------------------------------------------------*/
- /* crypte et decrypte travaillent sur des textes de longueur variable */
- /* alloués par le module appelant. */
- /* le résultat du cryptage est codé sous la forme d'une chaine de */
- /* caractères sur 7 bits (pour rester dans le jeu standard ASCII) */
- /* et supérieurs à 48 (pour éviter les codes non éditables et blancs) */
- /* la taille à allouer pour la chaine cryptée doit être au moins de */
- /* 5 fois le nombre de groupes de 4 caractères dans le texte à crypter */
-
- /* typedef unsigned long int WORD ; /* should be 32 bits = 4 bytes */
- /* on modifie à cause de win.h qui définit WORD sur 16 bits */
- typedef unsigned int W32;
- # define w 32 /* word size in bits */
- # define r 12 /* number of rounds */
- # define b 16 /* number of bytes in key */
- # define c 4 /* number of words in key */
- /* c =max(1,ceil(8*b/w) */
- # define t 26 /* size of table S =2*(r+1) words */
- W32 S[t] ; /* expanded key table */
- W32 pt[2],ct[2]; /* pour le passage des deux mots */
- W32 P = 0xb7e15163, Q = 0x9e3779b9; /* magic constants */
- int FlCle =0;
-
- /* Rotation operators, x must be unsigned, to get logical right shift */
- # define ROTL(x,y) (((x) << (y & (w-1))) | ((x) >>(w-(y&(w-1)))))
- # define ROTR(x,y) (((x) >> (y & (w-1))) | ((x) <<(w-(y&(w-1)))))
-
- BOOL WINAPI __declspec(dllexport) LibMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
- {
- /* traitement des événements liés au chargement/déchargement */
- /* switch (fdwReason)
- {
- case DLL_PROCESS_ATTACH:
- etc...
- }
- */
- return TRUE;
- }
- /* fonction de cryptage, sur 2 mots binaires en entrée et en sortie */
- void RC5_ENCRYPT( W32 *pt, W32 *ct)
- { W32 i , A= pt[0] + S[0] , B= pt[1] + S[1] ;
- for (i=1 ; i<=r ; i++ )
- { A = ROTL ( A^B,B) + S[2*i] ;
- B = ROTL ( B^A,A) + S[2*i+1] ;
- }
- ct[0]= A ; ct[1]= B ;
- }
- /* fonction de décryptage, sur 2 mots binaires en entrée et en sortie */
- void RC5_DECRYPT( W32 *ct, W32 *pt)
- { W32 i , B= ct[1] , A= ct[0] ;
- for (i=r ; i>0 ; i-- )
- { B = ROTR (B - S[2*i+1], A) ^ A ;
- A = ROTR (A - S[2*i], B) ^ B ;
- }
- pt[1]= B - S[1] ; pt[0]= A - S[0] ;
- }
- /* fonction d'installation de la clé étendue */
- void RC5_SETUP(unsigned char *K)
- { W32 i, j, k, u=w/8, A, B, L[c] ;
- int lc;
- /* initialize L, then S, then mix key into S */
- lc=strlen(K);
- if (lc>b) lc=b;
-
- for (i=b-1, L[c-1]=0 ; i != -1 ; i--) {
- if (i>=lc)
- { L[i/u] = (L[i/u] << 8) + 0 ;}
- else
- { L[i/u] = (L[i/u] << 8) + K[i] ;}
- }
- for (S[0]=P, i=1 ; i<t ; i++ ) S[i] = S[i-1] + Q ;
- for (A=B=i=j=k=0 ; k< 3*t ; k++, i =(i+1)%t, j =(j+1)%c ) /* 3*t > 3*c */
- { A = S[i] = ROTL ( S[i] + (A + B) ,3) ;
- B = L[j] = ROTL ( L[j] + (A + B), (A + B)) ;
- }
- FlCle=1;
- }
- /* fonction exportée pour le cryptage de PText, vers CText, selon Clé... */
- BOOL WINAPI __declspec(dllexport) crypte(char *PText, char *CText, char *Cle)
- {
- /* fontion de cryptage */
- /* le programme passe la chaine à crypter, et une adresse pour le résultat */
- /* si une cle est passée, on fait le SETUP. Sinon on utilise la cle stockée */
- int lt; /* longueur de la chaine en octets */
- int ipt=0; /* indice du caractère courant dans le texte en entrée */
- int ict=0; /* indice du caractère courant dans la chaine en sortie */
- int i;
- unsigned char *sw; /* pointeur de caractères de travail */
- int cx; /* octet de report pour le codage du résultat */
-
- /* Mise en place de la cle si elle est donnée */
- if (strlen(Cle)>0) RC5_SETUP(Cle);
- /* sinon on travaillera avec la cle courante, si elle existe */
- if (FlCle ==0 ) return FALSE;
-
- /* taille du texte à crypter*/
- lt=strlen(PText);
-
- /* on travaille par groupes de 8 octets pour le cryptage */
- while (ipt<lt) {
-
- /* valeur à crypter*/
- /* transfert des octets sur l'adresse du tableau d'entiers pt... */
- sw= (unsigned char *)pt;
- for (i=0;i<8;i++) {
- if (ipt>=lt) sw[i]=0;
- else sw[i]=PText[ipt];
- ipt++;
- }
-
- /* cryptage dans ct */
- RC5_ENCRYPT(pt,ct);
-
- /* report dans la chaine résultat sous forme de caractères éditables */
- /* chaque groupe de 4 octets est complété par un octet de report */
- /* pour chaque caractère on prend les 7 bits de poids faible, */
- /* et on rajoute 48 si nécessaire (pour éviter les codes de controle ASCII) */
- /* on stocke l'info dans les 2 bits correspondants dans l'octet de report */
- sw=(unsigned char *)ct;
- cx=0;
- for (i=0;i<8;i++) {
- /* on prend les 7 bits de droite */
- CText[ict]=sw[i] & 0x7F;
- /* on stocke le bit de gauche dans le bit 1 de l'octet de report */
- cx=cx+((sw[i] & 0x80)>>6);
- /* si le caractère est non imprimable on rajoute 48 et on marque */
- /* le bit 0 de l'octet de report, pus on décale de 2 */
- if (CText[ict]<48) { CText[ict]+=48; cx=cx+1;}
-
- ict++;
-
- if ((i==3) || (i==7)) {
- /* rajout de l'octet de report */
- CText[ict]=cx;
- ict++;cx=0;
- }
- else {
- cx=cx<<2; /* on décale de 2 bits l'octet de report */
- }
- }
- }
- CText[ict]=0;
-
- return TRUE;
- }
- /* fonction exportée pour le décryptage de PText, vers CText, selon Clé... */
- BOOL WINAPI __declspec(dllexport) decrypte(char *CText, char *PText,char *Cle)
- {
- /* fontion de décryptage */
- /* le programme passe la chaine à décrypter, et une adresse pour le résultat */
- /* si une cle est passée, on fait le SETUP. Sinon on utilise la cle stockée */
-
- int lc; /* longueur de la chaine cryptée en octets */
- int ipt=0; /* indice du caractère courant dans le texte en entrée */
- int ict=0; /* indice du caractère courant dans la chaine en sortie */
- int i,j;
- int x=0;
- unsigned char xv; /* octet de report pour le décodage */
- unsigned char *sw; /* pointeur de caractères de travail */
-
- /* Mise en place de la cle si elle est donnée */
- if (strlen(Cle)>0) RC5_SETUP(Cle);
- /* sinon on travaillera avec la cle courante, si elle existe */
- if (FlCle ==0 ) return FALSE;
-
- lc=strlen(CText);
-
- /* on travaille par groupes de 10 octets (2* (4+1) ) */
- /* ict est l'offset du début de groupe dans la chaine */
- while (ict<lc) {
-
- /* valeur à décrypter*/
- /* décodage de la chaine CText vers l'adresse du tableau d'entiers ct... */
- /* chaque groupe de 5 de caractères est traansformé en un entier */
- /* boucle sur le nombre de double-mots (10 octets à chaque fois) */
-
- /* pour remplir les entiers ct[] octet par octet on s'appuie sur un ptr sw */
- sw= (unsigned char *)ct;
-
- /* première phase: on prend tels quels les octets. */
- /* On traitera ensuite les octets de contrôle */
- j=0;
- for (i=0;i<10;i++) {
- if ((i!=4) && (i!=9)) {
- /* on prend l' octet tel quel */
- sw[j]=CText[ict+i];
- /* l'indice j permet d'avancer en sautant les octets de contrôle */
- j++;
- }
- }
-
- /* traitement du premier octet de report */
- xv=CText[ict+4];
- /* les couples de bits sont traités de droite à gauche */
- /* on traite un par un et on décale au fur et à mesure */
- for (i=3;i>=0;i--) {
- /* bit de droite pour enlever 48 */
- x=xv & 1;
- if (x==1) sw[i]=sw[i]-48;
- xv=xv>>1;
- /* nouveau but de droite: reporté en poids fort */
- x=xv & 1;
- if (x==1) sw[i]=sw[i] | 0x80;
- xv=xv>>1;
- }
- /* deuxième octet de controle: même chose */
- xv=CText[ict+9];
- for (i=7;i>=4;i--) {
- /* bit de droite pour enlever 48 */
- x=xv & 1;
- if (x==1) sw[i]=sw[i]-48;
- xv=xv>>1;
- /* nouveau but de droite: reporté en poids fort */
- x=xv & 1;
- if (x==1) sw[i]=sw[i] | 0x80;
- xv=xv>>1;
- }
-
- /* saut vers le prochain groupe de 10 octets */
- ict+=10;
-
- /* decryptage dans pt */
- RC5_DECRYPT(ct,pt);
-
- /* report dans la chaine de départ, octet par octet */
- /* ipt est l'offset courant du groupe de 8 caractères dans la chaine PText */
- sw=(unsigned char *)pt;
- for (i=0;i<8;i++) {
- PText[ipt]=sw[i];
- ipt++;
- }
- }
- PText[ipt]=0;
-
- return TRUE;
- }
- unsigned long WINAPI __declspec(dllexport) teste( int i, int j)
- {
- if (i==0) return pt[j];
- if (i==1) return ct[j];
- return 0;
- }
#include <windows.h>
/*----------------------------------------------------------------------*/
/* RC5REF.C -- Reference implementation of RC5-32/12/16 in C */
/* Copyright © 1995 RSA Data security. Inc. */
/*----------------------------------------------------------------------*/
/* les fonctions crypte et decrypte utilisent les algorithmes de cyptage*/
/* définis dans ce document de référence. */
/* RC5_SETUP: extension de la clé passée en argument sous forme de */
/* chaine de caractères. Si l'appel de crypte ou decrypte ne */
/* ne comporte pas de cle ("") c'est la cle précdémment */
/* traitée qui est utilisée */
/* s'il n' y a pas de texte à crypter la fonction crypte ou */
/* decrypte se contente de réaliser l'expansion de la clé */
/* RC5_ENCRYPT: cryptage d'un double mot */
/* RC5_DECRYPT: decryptage d'un double mot */
/* dans cette implémentation, on fixe les paramétres de cryptage */
/* taille du mot: 32 bits */
/* nombre d'itérations: 12 */
/* taille (maxi) de clé en octets: 16 */
/* (paramètres nominaux choisis par Ronald L. Rivest) */
/* */
/*----------------------------------------------------------------------*/
/* crypte et decrypte travaillent sur des textes de longueur variable */
/* alloués par le module appelant. */
/* le résultat du cryptage est codé sous la forme d'une chaine de */
/* caractères sur 7 bits (pour rester dans le jeu standard ASCII) */
/* et supérieurs à 48 (pour éviter les codes non éditables et blancs) */
/* la taille à allouer pour la chaine cryptée doit être au moins de */
/* 5 fois le nombre de groupes de 4 caractères dans le texte à crypter */
/* typedef unsigned long int WORD ; /* should be 32 bits = 4 bytes */
/* on modifie à cause de win.h qui définit WORD sur 16 bits */
typedef unsigned int W32;
# define w 32 /* word size in bits */
# define r 12 /* number of rounds */
# define b 16 /* number of bytes in key */
# define c 4 /* number of words in key */
/* c =max(1,ceil(8*b/w) */
# define t 26 /* size of table S =2*(r+1) words */
W32 S[t] ; /* expanded key table */
W32 pt[2],ct[2]; /* pour le passage des deux mots */
W32 P = 0xb7e15163, Q = 0x9e3779b9; /* magic constants */
int FlCle =0;
/* Rotation operators, x must be unsigned, to get logical right shift */
# define ROTL(x,y) (((x) << (y & (w-1))) | ((x) >>(w-(y&(w-1)))))
# define ROTR(x,y) (((x) >> (y & (w-1))) | ((x) <<(w-(y&(w-1)))))
BOOL WINAPI __declspec(dllexport) LibMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
{
/* traitement des événements liés au chargement/déchargement */
/* switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
etc...
}
*/
return TRUE;
}
/* fonction de cryptage, sur 2 mots binaires en entrée et en sortie */
void RC5_ENCRYPT( W32 *pt, W32 *ct)
{ W32 i , A= pt[0] + S[0] , B= pt[1] + S[1] ;
for (i=1 ; i<=r ; i++ )
{ A = ROTL ( A^B,B) + S[2*i] ;
B = ROTL ( B^A,A) + S[2*i+1] ;
}
ct[0]= A ; ct[1]= B ;
}
/* fonction de décryptage, sur 2 mots binaires en entrée et en sortie */
void RC5_DECRYPT( W32 *ct, W32 *pt)
{ W32 i , B= ct[1] , A= ct[0] ;
for (i=r ; i>0 ; i-- )
{ B = ROTR (B - S[2*i+1], A) ^ A ;
A = ROTR (A - S[2*i], B) ^ B ;
}
pt[1]= B - S[1] ; pt[0]= A - S[0] ;
}
/* fonction d'installation de la clé étendue */
void RC5_SETUP(unsigned char *K)
{ W32 i, j, k, u=w/8, A, B, L[c] ;
int lc;
/* initialize L, then S, then mix key into S */
lc=strlen(K);
if (lc>b) lc=b;
for (i=b-1, L[c-1]=0 ; i != -1 ; i--) {
if (i>=lc)
{ L[i/u] = (L[i/u] << 8) + 0 ;}
else
{ L[i/u] = (L[i/u] << 8) + K[i] ;}
}
for (S[0]=P, i=1 ; i<t ; i++ ) S[i] = S[i-1] + Q ;
for (A=B=i=j=k=0 ; k< 3*t ; k++, i =(i+1)%t, j =(j+1)%c ) /* 3*t > 3*c */
{ A = S[i] = ROTL ( S[i] + (A + B) ,3) ;
B = L[j] = ROTL ( L[j] + (A + B), (A + B)) ;
}
FlCle=1;
}
/* fonction exportée pour le cryptage de PText, vers CText, selon Clé... */
BOOL WINAPI __declspec(dllexport) crypte(char *PText, char *CText, char *Cle)
{
/* fontion de cryptage */
/* le programme passe la chaine à crypter, et une adresse pour le résultat */
/* si une cle est passée, on fait le SETUP. Sinon on utilise la cle stockée */
int lt; /* longueur de la chaine en octets */
int ipt=0; /* indice du caractère courant dans le texte en entrée */
int ict=0; /* indice du caractère courant dans la chaine en sortie */
int i;
unsigned char *sw; /* pointeur de caractères de travail */
int cx; /* octet de report pour le codage du résultat */
/* Mise en place de la cle si elle est donnée */
if (strlen(Cle)>0) RC5_SETUP(Cle);
/* sinon on travaillera avec la cle courante, si elle existe */
if (FlCle ==0 ) return FALSE;
/* taille du texte à crypter*/
lt=strlen(PText);
/* on travaille par groupes de 8 octets pour le cryptage */
while (ipt<lt) {
/* valeur à crypter*/
/* transfert des octets sur l'adresse du tableau d'entiers pt... */
sw= (unsigned char *)pt;
for (i=0;i<8;i++) {
if (ipt>=lt) sw[i]=0;
else sw[i]=PText[ipt];
ipt++;
}
/* cryptage dans ct */
RC5_ENCRYPT(pt,ct);
/* report dans la chaine résultat sous forme de caractères éditables */
/* chaque groupe de 4 octets est complété par un octet de report */
/* pour chaque caractère on prend les 7 bits de poids faible, */
/* et on rajoute 48 si nécessaire (pour éviter les codes de controle ASCII) */
/* on stocke l'info dans les 2 bits correspondants dans l'octet de report */
sw=(unsigned char *)ct;
cx=0;
for (i=0;i<8;i++) {
/* on prend les 7 bits de droite */
CText[ict]=sw[i] & 0x7F;
/* on stocke le bit de gauche dans le bit 1 de l'octet de report */
cx=cx+((sw[i] & 0x80)>>6);
/* si le caractère est non imprimable on rajoute 48 et on marque */
/* le bit 0 de l'octet de report, pus on décale de 2 */
if (CText[ict]<48) { CText[ict]+=48; cx=cx+1;}
ict++;
if ((i==3) || (i==7)) {
/* rajout de l'octet de report */
CText[ict]=cx;
ict++;cx=0;
}
else {
cx=cx<<2; /* on décale de 2 bits l'octet de report */
}
}
}
CText[ict]=0;
return TRUE;
}
/* fonction exportée pour le décryptage de PText, vers CText, selon Clé... */
BOOL WINAPI __declspec(dllexport) decrypte(char *CText, char *PText,char *Cle)
{
/* fontion de décryptage */
/* le programme passe la chaine à décrypter, et une adresse pour le résultat */
/* si une cle est passée, on fait le SETUP. Sinon on utilise la cle stockée */
int lc; /* longueur de la chaine cryptée en octets */
int ipt=0; /* indice du caractère courant dans le texte en entrée */
int ict=0; /* indice du caractère courant dans la chaine en sortie */
int i,j;
int x=0;
unsigned char xv; /* octet de report pour le décodage */
unsigned char *sw; /* pointeur de caractères de travail */
/* Mise en place de la cle si elle est donnée */
if (strlen(Cle)>0) RC5_SETUP(Cle);
/* sinon on travaillera avec la cle courante, si elle existe */
if (FlCle ==0 ) return FALSE;
lc=strlen(CText);
/* on travaille par groupes de 10 octets (2* (4+1) ) */
/* ict est l'offset du début de groupe dans la chaine */
while (ict<lc) {
/* valeur à décrypter*/
/* décodage de la chaine CText vers l'adresse du tableau d'entiers ct... */
/* chaque groupe de 5 de caractères est traansformé en un entier */
/* boucle sur le nombre de double-mots (10 octets à chaque fois) */
/* pour remplir les entiers ct[] octet par octet on s'appuie sur un ptr sw */
sw= (unsigned char *)ct;
/* première phase: on prend tels quels les octets. */
/* On traitera ensuite les octets de contrôle */
j=0;
for (i=0;i<10;i++) {
if ((i!=4) && (i!=9)) {
/* on prend l' octet tel quel */
sw[j]=CText[ict+i];
/* l'indice j permet d'avancer en sautant les octets de contrôle */
j++;
}
}
/* traitement du premier octet de report */
xv=CText[ict+4];
/* les couples de bits sont traités de droite à gauche */
/* on traite un par un et on décale au fur et à mesure */
for (i=3;i>=0;i--) {
/* bit de droite pour enlever 48 */
x=xv & 1;
if (x==1) sw[i]=sw[i]-48;
xv=xv>>1;
/* nouveau but de droite: reporté en poids fort */
x=xv & 1;
if (x==1) sw[i]=sw[i] | 0x80;
xv=xv>>1;
}
/* deuxième octet de controle: même chose */
xv=CText[ict+9];
for (i=7;i>=4;i--) {
/* bit de droite pour enlever 48 */
x=xv & 1;
if (x==1) sw[i]=sw[i]-48;
xv=xv>>1;
/* nouveau but de droite: reporté en poids fort */
x=xv & 1;
if (x==1) sw[i]=sw[i] | 0x80;
xv=xv>>1;
}
/* saut vers le prochain groupe de 10 octets */
ict+=10;
/* decryptage dans pt */
RC5_DECRYPT(ct,pt);
/* report dans la chaine de départ, octet par octet */
/* ipt est l'offset courant du groupe de 8 caractères dans la chaine PText */
sw=(unsigned char *)pt;
for (i=0;i<8;i++) {
PText[ipt]=sw[i];
ipt++;
}
}
PText[ipt]=0;
return TRUE;
}
unsigned long WINAPI __declspec(dllexport) teste( int i, int j)
{
if (i==0) return pt[j];
if (i==1) return ct[j];
return 0;
}
Conclusion
AVERTISSEMENT: le document de référence que j'utilise a été péché sur le NET, je n'ai PAS VERIFIE LA SOURCE!. Si quelqu'un peut s'en charger ... cependant il existe déja pas mal de documentation sur le sujet, et notamment sur l'auteur.
L'implémentation que j'ai faite n'admet pas de paramètre supplémentaire. Je trouve que c'est largement suffisant pour mes besoins, d'autant plus que ce sont les paramètres que Rivest lui-même a choisis pour les essais officiels. On peut éventuellemtn améliorer le code pour permettre uen extension des paramètres.
Enfin.. j'ai utilisé le C à très forte dose pendant toute la décennie 80, mais aujourd'hui je m'y remets et... j'ai l'impression de repartir à zéro. Par ailleurs je n'ai pas cherché à optimiser le code. Cela pou rm'excuser à l'avance vis à vis de tous ceux qui trouveront à redire...
Sources de la même categorie
Commentaires et avis
|
Derniers Blogs
IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc SHAREPOINT BLOG SITE, PROBLèME D'ARCHIVESSHAREPOINT BLOG SITE, PROBLèME D'ARCHIVES par junarnoalg
Dernièrement, nous avons migré le site
myTIC
vers un nouveau serveur SharePoint 2010. Dans les contenus que nous vouloins récupérer, nous avions un certain nombre de blogs.
Nous avons utilisé les commandes Power...
Cliquez pour lire la suite de l'article par junarnoalg
Forum
MATRICE TEMPLATEMATRICE TEMPLATE par hjr2610
Cliquez pour lire la suite par hjr2610 RE : SAC A DOS RE : SAC A DOS par hadjkaddour
Cliquez pour lire la suite par hadjkaddour
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|