RSA
|
Contient les prototypes des fonctions et structures permettant de générer et travailler avec des grands nombres. Plus de détails...
Aller au code source de ce fichier.
Classes | |
struct | GRDNB |
Objet représentant un grand nombre, sa taille et son signe. Plus de détails... | |
Fonctions | |
GRDNB | creerGRDNB (int taille) |
Crée un grand nombre. Plus de détails... | |
GRDNB | diveuclidedeux (GRDNB a, GRDNB b, GRDNB *quotient) |
GRDNB | str2grdnb (char *chaine) |
Convertit un nombre écrit dans une chaine de caractère en GRDNB. Plus de détails... | |
int | divisible (GRDNB e, GRDNB phi_n, int base) |
int | egal (GRDNB a, GRDNB b) |
Permet de savoir si deux GRDNB sont égaux. Plus de détails... | |
void | affectation (GRDNB *a, GRDNB b) |
Permet de faire a = b sans perte de mémoire. Plus de détails... | |
int | tailleBase2 (GRDNB a) |
Permet de connaitre la taille en base 2 d'un GRDNB écrit en base 10. Plus de détails... | |
int | tailleIdentique (GRDNB a, GRDNB b, GRDNB *acopie, GRDNB *bcopie) |
Permet de mettre deux grands nombres à la même taille sans les modifier. Plus de détails... | |
GRDNB | somme (GRDNB a, GRDNB b, int base) |
Permet d'additionner deux GRDNB positifs. Plus de détails... | |
GRDNB | expomodrap (GRDNB message, GRDNB e, GRDNB n, int base) |
Permet de calculer message^e = resultat mod[n] dans une base donnée. Plus de détails... | |
GRDNB | sous (GRDNB a, GRDNB b, int base) |
Permet d'additionner deux GRDNB positifs avec a > b. Plus de détails... | |
GRDNB | soustraction (GRDNB a, GRDNB b, int base) |
Permet de faire a - b, peu importe leur signe et on peut avoir b > a. Plus de détails... | |
void | copie (GRDNB a, GRDNB *acopie) |
GRDNB | b2Tob10 (GRDNB a) |
Permet de convertir un GRDNB de la base 2 à la base 10. Plus de détails... | |
int | sontpremiers (GRDNB a, GRDNB b, int base) |
GRDNB | addition (GRDNB a, GRDNB b, int base) |
Permet de faire a - b, peu importe leur signe et on peut avoir b > a. Plus de détails... | |
void | supprimezero (GRDNB *a) |
Permet de supprimer les zéros superflus au début d'un GRDNB. Plus de détails... | |
int | vraishiftdroite (GRDNB *a) |
Permet de supprimer la dernière case du tableau de a. Plus de détails... | |
GRDNB | mulunique (int a, int b, int base) |
Permet de multiplier deux entiers et de renvoyer le résultat sous forme de GRDNB. Plus de détails... | |
char * | GRDNBtoSTR (GRDNB a) |
Transforme un grand nombre en chaine de caractères. Plus de détails... | |
GRDNB | b10Tob2 (GRDNB a, int taille) |
Permet de convertir un GRDNB de la base 10 à la base 2. Plus de détails... | |
GRDNB | euclideetendu (GRDNB dividende, GRDNB diviseur, int base, GRDNB *u, GRDNB *v) |
Trouve le pgcd de deux entiers a et b et le couple(u,v) tel que au + bv = PGCD(a,b) Plus de détails... | |
GRDNB | mulnaive (GRDNB a, GRDNB b, int base) |
Permet de faire la multiplication entre deux GRDNB dans une base donnée. Plus de détails... | |
GRDNB | div2 (GRDNB a) |
Permet de diviser (entièrement) rapidement un nombre en base 10 par 2. Plus de détails... | |
int | isMulDeux (GRDNB a) |
Permet de savoir si un nombre est divisible par 2. Plus de détails... | |
GRDNB | IntToGRDNB (int a, int base) |
Transforme un int en GRDNB dans une base donnée. Plus de détails... | |
GRDNB | diveuclide (GRDNB a, GRDNB b, int base, GRDNB *quotient) |
Permet d'exprimer a sous la forme a = b * quotient + retour, avec retour < b Plus de détails... | |
int | vraishiftgauche (GRDNB *a) |
Permet d'ajouter une case à 0 à la fin du tableau de a. Plus de détails... | |
GRDNB | sousnombre (GRDNB a, int debut, int fin) |
Recrée un autre nombre à partir d'un autre nombre et d'une position de début (inclue) et de fin (exclue) Plus de détails... | |
int | ismax (GRDNB a, GRDNB b) |
Permet de savoir si a >= b. Plus de détails... | |
GRDNB | PuissanceRapide (GRDNB a, GRDNB puissance, int base) |
Calcule a^puissance dans la base spécifiée. Plus de détails... | |
void | afficher (char *chaine, GRDNB a) |
Affiche dans la console un GRDNB précédé de son signe et d'une chaine de caractère, et suivi d'un retour à la ligne. Plus de détails... | |
int | shiftdroite (GRDNB *a) |
Permet d'ajouter une case valant 0 à gauche d'un GRDNB. Plus de détails... | |
int | shiftgauche (GRDNB *a) |
Permet de supprimer la case la plus à gauche du tableau d'un GRDNB. Plus de détails... | |
void | echanger (int *tableau, int i, int j) |
Echange deux cases dans un tableau d'entiers. Plus de détails... | |
GRDNB | un () |
Crée un grand nombre valant 1. Plus de détails... | |
int | isBase2 (GRDNB a) |
Permet de savoir si le tableau d'un GRDNB ne comprend que des 0 ou des 1. Plus de détails... | |
GRDNB | modulo (GRDNB a, GRDNB b, int base) |
Permet d'exprimer a sous la forme a = b * quotient + retour, avec retour < b Plus de détails... | |
Contient les prototypes des fonctions et structures permettant de générer et travailler avec des grands nombres.
Permet de faire a - b, peu importe leur signe et on peut avoir b > a.
La fonction somme(GRDNB a, GRDNB b, int base) ne peut traiter que deux nombres positifs. Il faut donc faire une fonction qui va adapter les appels selon tous les cas possibles.
Permet de faire a = b sans perte de mémoire.
[in,out] | a | Un pointeur sur le GRDNB qui va recevoir l'affectation. |
[in] | b | Le GRDNB qui va être affecté. |
void afficher | ( | char * | chaine, |
GRDNB | a | ||
) |
On crée un grand nombre ayant une taille identique à a.
On copie case par case de a vers acopie, ainsi que le signe.
GRDNB creerGRDNB | ( | int | taille | ) |
Permet de diviser (entièrement) rapidement un nombre en base 10 par 2.
[in] | a | Le GRDNB a diviser |
On divise le chiffre des unités par 2.
Ensuite pour chaque case en partant de la case à gauche de celle des unités, il faut regarder si le chiffre est pair.
S'il est pair, on divise par 2 directement.
Sinon, on divise par 2 et on ajoute 5 à la case de droite.
Permet d'exprimer a sous la forme a = b * quotient + retour, avec retour < b
[in] | a | Un GRDNB positif |
[in] | b | Un GRDNB positif différent de zéro. |
[in] | base | La base dans laquelle a,b, le quotient et le reste sont exprimés. |
[in] | quotient | L'adresse pointant sur le GRDNB du quotient. |
On regarde si des cas simples se présentent, en effet :
Sinon on determine la taille maximale du quotient (taille de a - taille de b + 1).
On regarde ensuite combien de fois a peut contenir la puissance maximale du quotient dans la base correspondante.
Tant que a > b * puissancemax, on diminue a : a = a - b * puissancemax et on incrémente autant de fois la case du quotient correspondante.
On diminue la valeur de a autant que possible.
On décrémente la taille pour avoir la puissance inférieure et on recommence tant que a >= b.
Il est possible que la première case du quotient soit nulle, on la supprime si c'est le cas.
Le reste, c'est le a restant quand on a a < b.
Exemple : 520 / 3
Le quotient sera au maximum 999 (donc de taille 3). En effet, on peut avoir (au pire), avec des nombres de cette taille, 999 / 1 (le quotient sera 999 donc bien de taille 3).
On a bien 520 = 3 * 173 + 1
void echanger | ( | int * | tableau, |
int | i, | ||
int | j | ||
) |
Echange deux cases dans un tableau d'entiers.
[in,out] | Un | tableau d'entiers qui verra deux de ses cases permutées |
[in] | L'indice | i < taille du tableau |
[in] | l'indice | j < taille du tableau |
Permet de savoir si deux GRDNB sont égaux.
Le programme regarde déjà s'il y a une différence de taille entre a et b, si oui les nombres ne peuvent pas être égaux.
Ensuite, on lit case par case. Si pour un même indice, la case de a est différente de celle de b, alors les nombres ne sont pas égaux.
Si on a parcouru toutes les cases sans trouver de différences, alors les nombres a et b sont égaux.
Nous aurions pu traiter le cas "124" == "00124", en supprimant les zéros devant à chaque fois, mais cela aurait nécessité de faire une copie, et aurait allongé le temps d'exécution.
Trouve le pgcd de deux entiers a et b et le couple(u,v) tel que au + bv = PGCD(a,b)
[in] | a | Un GRDNB |
[in] | b | Un GRDNB tel que b < a |
[in] | base | Un entier précisant la base de a, de b, de u, de v ainsi que du PGCD retourné. |
[out] | u | Un pointeur sur le GRDNB recevant l'un des deux coefficients de Bézout. |
[out] | v | Un pointeur sur le GRDNB recevant l'un des deux coefficients de Bézout. Ce coefficient sera positif. |
On adapte la valeur de v pour que v soit positif en faisant (k = 1):
Permet de calculer message^e = resultat mod[n] dans une base donnée.
[in] | message | Un GRDNB positif qui sera élevé à la puissance e |
[in] | e | Un GRDNB positif qui sera l'exposant de message. |
[in] | n | Le GRDNB positif qui modulera le résultat de message^e |
[in] | base | L'entier correspondant la base de message, e, n et du résultat renvoyé. |
L'exponentiation modulaire rapide repose sur le principe suivant :
a*b mod n = (a mod n) * (b mod n)
Si on écrit l'exposant en binaire, on a message ^ e = produit(k=0, k < nbbits(exposant), (message^2k) ^ exposant.tableau[k]) On a donc resultat = produit(k=0, k < nbbits(exposant), (message^2k) ^ exposant.tableau[k]) mod n On fait donc, pour chaque bit de e, resultat = (resultat * message^((1 + le bit de e en cours)%2)) % n puis message = message * (message)
En pratique :
On pose resultat = 1. Tant que l'exposant n'est pas nul :
char * GRDNBtoSTR | ( | GRDNB | a | ) |
Transforme un grand nombre en chaine de caractères.
[in] | a | Le GRDNB a convertir, base <= 10 |
On sait que '0' s'écrit 48 en ASCII, '1' s'écrit 49...
Il suffit de prendre chaque chiffre et lui ajouter 48 pour obtenir son code ASCII.
On ajoute '\0' à la fin de la chaine nouvellement créée.
GRDNB IntToGRDNB | ( | int | a, |
int | base | ||
) |
Transforme un int en GRDNB dans une base donnée.
[in] | a | Le int à convertir. |
[in] | base | Doit être > 0. |
Pour savoir quelle est la taille du nombre dans une base donnée, il suffit de compter le nombre de divisions entières successives possibles.
On remplit le tableau du nouveau GRDNB à l'envers (des unités vers les bits de poids fort)
Pour récupérer le caractère des unités, il faut récupérer le reste de la division de a par 10.
On divise a par 10 pour faire passer le chiffre des dizaines au chiffre des unités.
On répéte ça pour remplir le tableau de GRDNB.
int isBase2 | ( | GRDNB | a | ) |
Permet de savoir si le tableau d'un GRDNB ne comprend que des 0 ou des 1.
[in] | a | Le GRDNB à tester. |
On parcourt case par case, et dès que l'on trouve un chiffre différent de 0 ou 1, on renvoie 0.
Si on a atteint la fin du nombre, on renvoie 1.
Permet de savoir si a >= b.
int isMulDeux | ( | GRDNB | a | ) |
Permet de savoir si un nombre est divisible par 2.
[in] | a | Le GRDNB à tester. |
Il suffit de regarder le chiffre des unités. Si celui-ci est pair (son reste dans la division par 2 est 0), le nombre est divisible par deux, peu importe la base.
Permet d'exprimer a sous la forme a = b * quotient + retour, avec retour < b
[in] | a | Un GRDNB positif |
[in] | b | Un GRDNB positif différent de zéro. |
[in] | base | La base dans laquelle a, b et le reste sont exprimés. |
On regarde si des cas simples se présentent, en effet :
Sinon on determine la taille maximale du quotient (taille de a - taille de b + 1).
On regarde ensuite combien de fois a peut contenir la puissance maximale du quotient dans la base correspondante.
Tant que a > b * puissancemax, on diminue a : a = a - b * puissancemax
On diminue la valeur de a autant que possible.
On décrémente la taille pour avoir la puissance inférieure et on recommence tant que a >= b.
Le reste, c'est le a restant quand on a a < b.
Exemple : 520 / 3
Le quotient sera au maximum 999 (donc de taille 3). En effet, on peut avoir (au pire), avec des nombres de cette taille, 999 / 1 (le quotient sera 999 donc bien de taille 3).
On a bien 520 = 3 * X + 1
Permet de faire la multiplication entre deux GRDNB dans une base donnée.
Algorithme de multiplication naive.
GRDNB mulunique | ( | int | a, |
int | b, | ||
int | base | ||
) |
Permet de multiplier deux entiers et de renvoyer le résultat sous forme de GRDNB.
[in] | a | Un entier a < base. |
[in] | b | Un entier b < base. |
[in] | base | base > 0. La base dans laquelle sont écrits a et b et sera écrit le résultat |
On fait a*b, si le résultat est supérieur à la base, alors on a besoin de deux cases.
La case 0 comprendra (a*b)/base et la case 1 (a*b)base.
En effet : (a*b) = (a*b)/ base * base^1 + (a*b)base * base^0.
Calcule a^puissance dans la base spécifiée.
[in] | a | Le GRDNB positif que l'on veut multiplier. |
[in] | puissance | L'exposant positif en base 10 ou 2 sous forme de GRDNB. |
[in] | base | La base de a et du résultat (10 ou 2) |
a^n = a * a * a * ... * a (n fois) : n multiplications
Le principe :
Exemple : a^5 = a * (a^4) = a * (a^2)^2 = a * (a*a)^2 = 3 multiplications au lieu de 5.
Le programme regarde si la puissance est égale à 1
Bien que cette fonction soit récursive, une attention particulière a été apportée à la gestion de la mémoire.
int shiftdroite | ( | GRDNB * | a | ) |
Permet d'ajouter une case valant 0 à gauche d'un GRDNB.
[in,out] | a | Un pointeur sur le GRDNB à modifier |
On ajoute une case à la fin du tableau, puis on fait descendre la dernière case à l'indice 0 par échanges successifs.
int shiftgauche | ( | GRDNB * | a | ) |
Permet de supprimer la case la plus à gauche du tableau d'un GRDNB.
[in,out] | a | Un pointeur sur le GRDNB à modifier |
On fait monter la première case tout à la fin du tableau par échanges successifs.
On réalloue le tableau pour supprimer la dernière case.
Permet d'additionner deux GRDNB positifs.
On met les nombres à la même taille, et la retenue à 0.
S'il reste une retenue à la fin du calcul, on ajoute une case au début du retour et met la retenue dedans.
Permet d'additionner deux GRDNB positifs avec a > b.
On met les nombres à la même taille, et la retenue à 0.
Recrée un autre nombre à partir d'un autre nombre et d'une position de début (inclue) et de fin (exclue)
[in] | a | Le GRDNB dont on va extraire le sous-nombre |
[in] | debut | L'indice de début tel que debut < a.indicemax - 2. |
[in] | fin | L'indice de fin tel que debut < fin < a.indicemax |
Exemple : sousnombre("12345",1,3) = "23".
Permet de faire a - b, peu importe leur signe et on peut avoir b > a.
La fonction "sous(GRDNB a, GRDNB b, int base)" ne peut traiter que deux nombres positifs, avec a > b.
Il faut donc faire une fonction qui va adapter les appels selon tous les cas possibles.
GRDNB str2grdnb | ( | char * | chaine | ) |
Convertit un nombre écrit dans une chaine de caractère en GRDNB.
[in] | chaine | Une chaine de caractère ne comprenant éventuellement au début le signe puis que des chiffres. La base doit être inférieure ou égale à 10. |
On lit le premier caractère pour regarder le signe.
Si le signe n'est pas précisé, le nombre est positif.
Dans la table ASCII, '0' s'écrit 48, '1' s'écrit 49 ...
Il suffit de faire carac - 48 pour récupérer la valeur écrite dans le caractère.
void supprimezero | ( | GRDNB * | a | ) |
int tailleBase2 | ( | GRDNB | a | ) |
Permet de mettre deux grands nombres à la même taille sans les modifier.
[in] | a | Un GRDNB. |
[in] | b | Un GRDNB. |
[out] | acopie | Un pointeur sur le GRDNB qui contiendra la copie de a de même taille que bcopie. |
[out] | bcopie | Un pointeur sur le GRDNB qui contiendra la copie de b de même taille que acopie. |
L'agorithme prend le plus grand des deux, et le copie directement case par case dans le pointeur sur le GRDNB correspondant.
Pour le plus petit, il va créer un GRDNB dans le pointeur correspondant avec un tableau de taille du plus grand.
Pour les cases de 0 à |a.indicemax - b.indicemax| exclu, on ne met que des zéros, puis ensuite on copie case par case du petit nombre vers ce tableau.
Si les deux nombres sont de taille identique, il copie (case par case) les deux nombres dans les pointeurs correspondants.
Initialement prévue pour implémenter l'algorithme de Karatsuba pour la multiplication, elle est utilisée dans de nombreuses autres fonctions pour faciliter leur implémentation.
GRDNB un | ( | ) |
Crée un grand nombre valant 1.
int vraishiftdroite | ( | GRDNB * | a | ) |
Permet de supprimer la dernière case du tableau de a.
[in,out] | a | Un pointeur sur le GRDNB à modifier, celui doit avoir une taille de 1 minimum |