Licence 2 INFO/MATHS : TP-3

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 ;
}