Pour se familiariser avec GMP, voici un petit code:
C
#include <stdio.h> #include <stdarg.h> #include <gmp.h> int main( void ) { mpz_t p; // Déclare deux variables grands entiers. mpz_t q; mpz_init( p ); // Les initialise (nécessaire) mpz_init_set_str( q, "40094690950920881030683735292761468389214899724061\0", 10); // initialisation à partir d'une chaîne printf("Entrez le premier facteur de la clé privée :\n"); gmp_scanf( "%Zd", p ); // Saisie clavier mpz_t n; // Déclare le résultat du produit mpz_init( n ); // L'initialise // Calcule le produit n = p * q mpz_mul( n, p, q ); // Affiche le résultat. gmp_printf( "Le module de la clé publique vaut:\n%Zd = %Zd * %Zd\n", n, p, q ); // Libère la mémoire mpz_clear( p ); mpz_clear( q ); mpz_clear( n ); return 0 ; }
N'oubliez pas de compiler avec l'option -lgmp
Il faudrait ensuite obtenir quelque chose comme ça :
Bash
Entrez le message à encoder : Bonjour le monde de 2015 ;-) Le module de la clé publique vaut : 2c8d59af47c81ab3725b472be417e3bf7ab85439af726ed3dfdf66489d155dc0b771c7a50ef7c5e58fb Le message clair vaut : a292d3b20353130322065642065646e6f6d20656c2072756f6a6e6f42 Le message encodé vaut : 9ab33d1f07b72ddde545c061ab61ef6a135320764627446ed6d4d2b9e059f672ed5d907f5d0b2ba577 Le message encodé décodé vaut : a292d3b20353130322065642065646e6f6d20656c2072756f6a6e6f42 clair == décodé ( encodé ) => RSΑ OK :-) Message décodé : Bonjour le monde de 2015 ;-)
Par exemple avec ça:
C
#include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <gmp.h> #include <string.h> #include <math.h> // p = 37975227936943673922808872755445627854565536638199 // q = 40094690950920881030683735292761468389214899724061 // e = 65537 int main( void ) { mpz_t p; // clé privée mpz_t q; // clé privée 2 mpz_t e; // exposant public mpz_init_set_str( p, "37975227936943673922808872755445627854565536638199\0", 10 ); // Les initialise mpz_init_set_str( q, "40094690950920881030683735292761468389214899724061\0", 10); mpz_init_set_str( e, "65537\0", 10 ); //printf("Entrez le premier facteur de la clé privée :\n"); //gmp_scanf( "%Zd", p ); / //printf("Entrez le second facteur de la clé privée :\n"); //gmp_scanf( "%Zd", q ); //printf("Entrez l'exposant de la clé publique :\n"); //gmp_scanf( "%Zd", e ); mpz_t n; // module public mpz_init( n ); // L'initialise mpz_t phi; // module privé mpz_init( phi ); mpz_t pm ; // p - 1 mpz_init( pm ) ; mpz_t qm ; // q - 1 mpz_init( qm ); mpz_t d ; // exposant privé mpz_init( d ); // calcule p - 1 mpz_sub_ui ( pm, p, 1 ) ; // calcule q - 1 mpz_sub_ui ( qm, q, 1 ) ; // Calcule le produit phi = pm * qm mpz_mul ( phi, pm, qm ); // Calcule le produit n = p * q mpz_mul ( n, p, q ); // Calcule la puissance de la clé secrète : d = inv(e) mod phi mpz_invert ( d, e, phi ) ; mpz_t m ; mpz_init (m) ; char mes[100] ; // le message printf("Entrez le message à encoder :\n"); fgets( mes, 100, stdin ); int i = strlen(mes) ; while(i >= 0) { mpz_mul_ui(m,m,256); mpz_add_ui(m,m,mes[i--]); } if ( mpz_cmp ( m , n ) > 0 ) { fprintf(stderr, "Message plus long que la clé"); exit(1); } mpz_t mc ; // le message encodé : mc = m ^ e [ n ] mpz_init( mc ) ; mpz_powm_sec ( mc, m, e, n ) ; mpz_t md ; // le message décodé : md = mc ^ d [ n ] mpz_init( md ) ; mpz_powm_sec ( md, mc, d, n ) ; // Affiche les résultats. gmp_printf( "Le module de la clé publique vaut :\n %Zx\n", n ); gmp_printf( "Le message clair vaut : %Zx\n", m ); gmp_printf( "Le message encodé vaut : %Zx\n", mc ); gmp_printf( "Le message encodé décodé vaut : %Zx\n", md ); if ( mpz_cmp ( md, m ) == 0 ) { printf("RSΑ OK :-)\n") ; } else { printf( "RSA KO :-(\n" ) ; } printf("C'est-à-dire :\n"); mpz_t car ; mpz_init( car ) ; unsigned short int cari ; while ( mpz_cmp_ui (md, 0) > 0 ) { mpz_fdiv_qr_ui (md, car , md , 256 ) ; cari = mpz_get_ui(car) ; printf("%c", cari); } // Libère la mémoire mpz_clear( p) ; mpz_clear( q ) ; mpz_clear( n ) ; mpz_clear( m ) ; mpz_clear( mc ) ; mpz_clear( md ) ; mpz_clear( e ) ; mpz_clear( d ) ; mpz_clear( pm ) ; mpz_clear( qm ) ; mpz_clear( phi ) ; return 0 ; }