У меня возникли проблемы с компиляцией приведенного ниже кода, и я думаю, что проблема связана с привязкой gmplib к компилятору.

Я не мог понять, как установить библиотеку в Windows или как ее скомпилировать. Вот мой код. Имена переменных и комментарии написаны на французском языке. Простите за это.

// projet(essai final).cpp : Defines the entry point for the console application.
//

//****** la classe rsa_gmp.h ******* 
#include "stdafx.h"
#include<iostream>
#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <gmp.h> 
#include <time.h>
using namespace std;


class Class_one {
private:
    string fichierSource;
    string fichierDest;
    int tailleBloc ;
public:  
    Class_one();
    void PGCD (mpz_t ,mpz_t,mpz_t);
    void puissance(mpz_t,mpz_t,mpz_t,mpz_t);
    void test_primalite(mpz_t,mpz_t);
    void InitialiseRandom(gmp_randstate_t );
    void nextprime (mpz_ptr , mpz_srcptr ) ;
    void Genere_publicKey( mpz_t  ,mpz_t  , mpz_t ,gmp_randstate_t  ); 
    void Genere_privateKey (mpz_t  , mpz_t  , mpz_t ) ; 
    void Genere_nbPremier( mpz_t , mpz_t , int , gmp_randstate_t  ) ; 
    void chiffre_Msg( mpz_t , mpz_t , mpz_t , mpz_t );  
    void dechiffre_Msg( mpz_t , mpz_t  , mpz_t , mpz_t ); 
    short int SetFichiers(string nomFichierDest, string nomFichierSource);
    string DeTranscoder(mpz_t  );
    mpz_t Transcoder(string ) ;
    ~Class_one();
}


Class_one::Class_one(){

    this->fichierDest="";
    this->fichierSource="";
    this->tailleBloc=256;
};
Class_one::~Class_one(){};

void  Class_one::PGCD ( mpz_t resultat, mpz_t a , mpz_t b ) 
{ 
    mpz_t r , r1 ,r2; 

    //intialiser les variables 
    mpz_init( r ); 
    mpz_init( r1 ); 
    mpz_init( r2 ); 

    // affectation 
    mpz_set (r , a ) ; 
    mpz_set (r1 , b) ; 

    while ( mpz_cmp_ui ( r1, 0) != 0) 
    { 
        mpz_mod ( r2, r, r1); 
        mpz_set (r , r1 ) ; 
        mpz_set (r1 , r2) ; 
    } 

    mpz_set (resultat , r) ; 
    // liberer l'espace de variable 
    mpz_clear( r ); 
    mpz_clear( r1 ); 
    mpz_clear( r2 ); 

} 


void Class_one::puissance (mpz_t resultat ,mpz_t a, mpz_t e, mpz_t n) 
{ 
    mpz_t temp,t,a_bis,e_bis ; 
    // initialise la variable local 
    mpz_init( temp ); 
    mpz_init( t ); 

    mpz_init( a_bis ); 
    mpz_set( a_bis , a ); 

    mpz_init( e_bis ); 
    mpz_set( e_bis , e ); 

    mpz_set_ui (temp , 1); 

    while ( mpz_cmp_ui ( e_bis,0 )> 0) 
    { 
        mpz_mod_ui( t , e_bis , 2); 
        if( mpz_cmp_ui( t , 0 ) != 0) 
        { 
            mpz_mul( temp , temp , a_bis); 
            mpz_mod( temp , temp ,n ); 
        } 
        mpz_mul(a_bis , a_bis, a_bis); 
        mpz_mod ( a_bis, a_bis, n); 

        mpz_tdiv_q_ui(e_bis,e_bis,2); 
    } 

    mpz_set( resultat , temp ); 
    // liberer l'espace utilisé 
    mpz_clear( temp );mpz_clear(t); 
    mpz_clear(a_bis );mpz_clear(e_bis ); 

} 


/* 
La test_primalite verifie si un nombre est premier,c'est une application 
de Miller_Rabin 
@ param long a, n( mod n) 
@return 1 ou 0 
*/ 
void Class_one::test_primalite ( mpz_t resultat , mpz_t n) 
{ 
    mpz_t var ,p, e, m , i , k ,temp ; 
    // initialiser les variables locals 
    mpz_init(var) ;mpz_init(p) ;mpz_init(e) ;mpz_init( temp ) ; 
    mpz_init( m) ;mpz_init( i) ;mpz_init( k) ; 

    mpz_sub_ui ( m , n , 1); 
    mpz_sub_ui ( e , n , 1); 
    mpz_set_ui( var , 10 ); 

    mpz_set_ui ( k , 0 ); 
    mpz_mod_ui ( temp , e , 2); 

    while ( mpz_cmp_ui ( temp , 0 )== 0) 
    { 
        mpz_tdiv_q_ui( e , e , 2); 
        mpz_add_ui ( k , k , 1); 
        mpz_mod_ui ( temp , e , 2); 
    } 

    Class_one::puissance( mpz_t p ,mpz_t var ,mpz_t  e , mpz_t n ); 

    if( mpz_cmp_ui ( p , 1) == 0) 
    { 
        mpz_set_ui( resultat , 1); 
        return; 
    } 

    mpz_set_ui( i , 0); 

    while( mpz_cmp ( i , k ) < 0) 
    { 
        if( mpz_cmp( p , m )== 0) 
        { 
            mpz_set_ui( resultat , 1); 
            break ; 
        } 

        if( mpz_cmp_ui( p , 1 )== 0) 
        { 
            mpz_set_ui( resultat , 0); 
            break ; 
        } 

        mpz_mul( p, p , p ); 
        mpz_mod( p , p , n) ; 

        mpz_add_ui (i, i , 1); 
    } 


    // liberer l'espace utilisé par les variables locals 
    mpz_init(var) ;mpz_init(p) ; mpz_init(e) ;mpz_init(temp) ; 
    mpz_init( m) ;mpz_init( i) ;mpz_init( k) ; 
} 


// la fonction initializeRandom permet d,initialiser le generateur de nombre aleatoire 
void Class_one::InitialiseRandom(gmp_randstate_t r_state ) 
{ 
    /* Initialisation de nombre aleatoire*/ 
    unsigned long int seed; 
    seed = time(0); 

    gmp_randinit_default (r_state); 
    gmp_randseed_ui(r_state, seed); 
} 


// le nextprime permet de calculer le nombre premier suivant 
void Class_one::nextprime (mpz_ptr p, mpz_srcptr t) 
{ 
    mpz_t test ; 
    mpz_init( test ); 
    mpz_add_ui (p, t, 13); 

    void Class_one::test_primalite ( mpz_t test ,mpz_t  p); 
    while (mpz_cmp_ui( test , 0)!= 1 ) 
    { 
        mpz_add_ui (p, p, 13); 
        void Class_one::test_primalite ( mpz_t test , mpz_t p); 
    } 

} 



// la fonction genere_PK() permet de créer la clé public e 

void Class_one:: Genere_publicKey( mpz_t e ,mpz_t p , mpz_t q ,gmp_randstate_t state ) 
{ 
    mpz_t a , b , c, r , y ,rand_Num; 

    // initialiser les avriable locale 
    mpz_init( a ); 
    mpz_init( b ); 
    mpz_init( c ); 
    mpz_init( y ); 
    mpz_init( r ); 
    mpz_init( rand_Num ); 

    mpz_sub_ui( a, p, 1 ); 
    mpz_sub_ui( b, q, 1 ); 

    mpz_mul( y, a, b ); 

    //Définition d'une valeur max de E. 
    mpz_t max; 
    mpz_init( max ); 
    mpz_set_str ( max , "97" ,0); 

    mpz_urandomm( rand_Num, state, max ); 
    mpz_add_ui ( rand_Num , rand_Num , 3); 
    mpz_mod(c,rand_Num,y); 
    void Class_one::PGCD( mpz_t r , mpz_t c, mpz_t y); 

    while (( mpz_cmp_ui( r,1 )!= 0) ||mpz_cmp( c ,max )>0 ||mpz_cmp_ui( c ,0) ==0 ) 
    { 
        mpz_urandomm( rand_Num, state, max ); 
        mpz_add_ui ( rand_Num , rand_Num , 3); 
        mpz_mod(c,rand_Num,y); 
        void Class_one::PGCD( mpz_t r , mpz_t c, mpz_t y); 
    } 
    mpz_set( e ,c ) ; 
    // effacer les espaces utilisées par les variables 
    mpz_clear( a );mpz_clear( b );mpz_clear( y );mpz_clear( r ); 
    mpz_clear( rand_Num );mpz_clear( max );mpz_clear( c ); 


} 



// La fonction genere_privateKey permet de determiner la clé public 
// algorithme euclide etendu 
void Class_one::Genere_privateKey (mpz_t d , mpz_t e , mpz_t phi) 
{ 
    mpz_t e0,t0 , t , q, r, n0, temp ,temp2; 

    // initialiser les variables 
    mpz_init ( e0);mpz_init ( t0 );mpz_init ( t );mpz_init ( q ); 
    mpz_init ( r );mpz_init ( n0 );mpz_init ( temp );mpz_init ( temp2 ); 

    mpz_set_ui( t , 1) ; 
    mpz_set ( n0 , phi ); 
    mpz_set ( e0 , e ); 
    mpz_tdiv_q( q , n0 , e0); 
    mpz_mod ( r ,n0 , e0) ; 

    while( mpz_cmp_ui ( r, 0) > 0) 
    { 
        mpz_mul( temp , q, t); 
        mpz_sub( temp , t0, temp ); 

        if( mpz_cmp_ui ( temp , 0) >= 0) 
        { 
            mpz_mod ( temp , temp ,phi); 
        } 
        else 
        { 
            mpz_mod( temp , temp , phi); 
        } 

        mpz_set( t0 , t); 
        mpz_set( t , temp); 
        mpz_set( n0, e0); 
        mpz_set( e0, r); 
        mpz_tdiv_q( q , n0 , e0); 
        mpz_mod ( r ,n0 , e0) ; 

    } 
    mpz_set ( d , t); 
    // liberer l'espaces des variables 
    mpz_clear( e0 );mpz_clear( t0 );mpz_clear( t );mpz_clear( q ); 
    mpz_clear( r );mpz_clear( n0 );mpz_clear( temp );mpz_clear( temp2 ); 
} 




/* 
La fonction Genere_nbPremier retourne les deux entiers P et Q 
aleatoires et premiers 
*/ 

void Class_one::Genere_nbPremier( mpz_t p, mpz_t q, int n, gmp_randstate_t state ) 
{ 
    //création de varaiable locale 
    mpz_t rand, nb_aleatoire, max , min , varp , varq; 

    // initialiser les variables 
    mpz_init( rand ); mpz_init( nb_aleatoire ); mpz_init( max ); 
    mpz_init( min );mpz_init( varp );mpz_init( varq ); 

    // calcule du Borne Superieur 
    mpz_ui_pow_ui( max, 2, n+1 ); 
    // calcule du borne inferieur 
    mpz_ui_pow_ui( min, 2, n ); 

    // Génère un nombre compris entre 0 et max et le stocke dans rand. state initialise le générateur aléatoire. 
    do 
    { 
        mpz_urandomm( rand, state, max ); 

    }while( mpz_cmp( rand, min) > 0 ); 
    // Vérifie que rand est supérieur à la borne inférieure 
    void Class_one::nextprime ( mpz_ptr p ,mpz_srcptr  rand ); 

    // Génère un nombre Q compris entre 0 et max et le stocke dans rand. state initialise le générateur aléatoire. 
    do 
    { 
        mpz_urandomm( nb_aleatoire, state, max ); 

    }while(( mpz_cmp( nb_aleatoire, min) > 0 )|| ( mpz_cmp ( p , q ) == 0)); 
    // Vérifie que rand est supérieur à la borne inférieure 
    void Class_one::nextprime(mpz_ptr q ,mpz_srcptr  nb_aleatoire ); 

    // clear l'espace utilisé 
    mpz_clear( nb_aleatoire );mpz_clear( rand );mpz_clear( max ); 
    mpz_clear( min );mpz_clear( varq );mpz_clear( varp ); 

} 

// fonction de chiffrement de message 
void Class_one::chiffre_Msg( mpz_t chiffre, mpz_t message , mpz_t e, mpz_t n) 
{ 
    mpz_t cipher; 
    mpz_t i; 
    mpz_t temp; 

    mpz_init(cipher); 
    mpz_init(i); 
    mpz_init(temp); 
    mpz_set_si(cipher,1); 

    void Class_one::puissance (mpz_t cipher ,mpz_t message,mpz_t  e,mpz_t  n); 
    mpz_set(chiffre,cipher); 

    mpz_clear(cipher); 
    mpz_clear(temp); 
} 


// fonction dechiffrement de message 
void Class_one:: dechiffre_Msg( mpz_t message2, mpz_t chiffre , mpz_t d, mpz_t n) 
{ 
    mpz_t message; 
    mpz_t i; 
    mpz_t temp; 

    mpz_init(message); 
    mpz_init(i); 
    mpz_init(temp); 
    mpz_set(temp,chiffre); 

    void Class_one::puissance ( mpz_t message,mpz_t temp ,mpz_t  d,mpz_t  n); 
    mpz_set(message2,message); 

    mpz_clear(message); 
    mpz_clear(temp); 
} 

short int Class_one::SetFichiers(string nomFichierDest, string nomFichierSource)
{
    FILE *f1;
    FILE *f2;
    f1=fopen(nomFichierSource.c_str(), "rb");
    f2=fopen(nomFichierDest.c_str(), "wb");

    if(f1==NULL || f2==NULL)
    {
        if (f1!=NULL)   fclose(f1);
        if (f2!=NULL)   fclose(f2);
        return -1;
    }

    fclose(f1);
    fclose(f2);
    this->fichierDest=""+nomFichierDest;
    this->fichierSource=""+nomFichierSource;
    return 0;
}
mpz_t Class_one::Transcoder(string str)/* 
La méthode Transcoder : Cette méthode prend une chaine de caractères, puis la transforme en un nombre équivalent. Le nombre est égale à la somme du
code ascii dernier caractère, l’avant dernier multiplié par 256, l’avant avant dernier multiplié par 2562…etc
*/
{
    mpz_t Somme;
    mpz_t var;
    mpz_t M;
    mpz_t Mul;
    mpz_t resultat ;
    signed long long int i;
    //initialisation des variables 
    mpz_init(Somme);mpz_init(var);
    mpz_init(Mul);
    mpz_init(resultat);

    //affectation
    mpz_set_ui(M,1);


    for(i=(signed long long int)(str.length()-1); i>=0; i--)
    {


        aux =(unsigned char)str[(unsigned int)i];//La classe string est composé de signed char
        void Class_one::puissance(mpz_t resultat ,mpz_t  256 , mpz_t i, mpzt n);
        mpz_mul(Mul,resultat,aux);
        mpz_add(Somme,Somme, Mul);
    }
    return Somme ;
    mpz_clear(Somme);mpz_clear(var);mpz_clear(Mul);mpz_clear(resultat);
}

string Class_one::DeTranscoder(mpz_t  msg)
/*La méthode DeTranscoder : En prenant un nombre en paramètre,
elle génère une chaine de caractères équivalente, le nombre va être divisé par 256 en concaténant la chaine 
déjà trouvée et le caractère dont le code ascii est le reste de la division par 256.*/

{
    mpz_t div;
    mpz_t aux;
    mpz_t reste;
    string str;
    //initialiser les variables 
    mpz_init(div);mpz_init(aux);mpz_init(reste);
    // affectation 
    mpz_set(aux,msg);
    mpz_set_ui(div,256);
    while(aux.size()>1 || aux!=0)
    {
        aux=mpz_div(aux, div, reste);
        str=(char)reste + str;
    }
    return str;
    //liberer  les variables 
    mpz_clear(div); mpz_clear(aux); mpz_clear(reste);
}


class Cryptage{
    void crypter_RSA();
}

// la fonction principal du rsa en mode Standard 

void Cryptage::crypter_RSA() 
{ 
    // Variable locales 
    mpz_t p , q , e,d , n , phi , message,msg_chiffre,cipher ; 
    int choix ;

    //initialiser les variables locales 
    mpz_init(msg_chiffre);  mpz_init(cipher);
    mpz_init(e); mpz_init(n); mpz_init(p); 
    mpz_init(q); mpz_init(d); mpz_init(phi); 
    ;mpz_init( message); 

    // initialisationn du generateur 
    gmp_randstate_t state; 
    Class_one::InitialiseRandom(gmp_randstate_t state); 
    Class_one::Genere_nbPremier(mpz_t  p,mpz_tq ,mpz_t 512, gmp_randstate_t state); 

    // la valeur de N 
    mpz_mul ( n , p , q); 

    // les variablesP et Q 
    gmp_printf ("\n\n \t P \t: \t%Zd \n", p ); 
    gmp_printf ("\n\n \t Q \t: \t%Zd \n", q ); 

    // Generer la clé public 
    Class_one::Genere_publicKey( mpz_t e, mpz_t p ,mpz_t q , gmp_randstate_t state); 
    gmp_printf("\n\n \t clef pubic : \t%Zd \n",e); 

    // Calculer la valeur de phi 
    mpz_sub_ui( p , p , 1); 
    mpz_sub_ui( q , q , 1); 
    mpz_mul( phi , p , q) ; 

    // genere la cle privee 
    Class_one::Genere_privateKey (mpz_t d ,mpz_t e , mpz_t phi ); 
    gmp_printf("\n\n \t clef prive : \t%Zd \n",d); 

    // set fichier 
    short int index= Class_one::SetFichiers(string nomFichierDest, string nomFichierSource);
    while (index!=0) {
    index= Class_one::SetFichiers(string nomFichierDest, string nomFichierSource);
    } 

    // le message a chiffre // le message a chiffre 
    printf("\n\n\n\t Entrez le message a crypter: "); 
    gmp_scanf("%Zd",&message); 

    cout<<"entrer \n 1)crypter\ n2)decrypter "<<endl;
    cin>>choix;
    switch(choix)
    {
    case 1 :
    //dechiffrement du message 
          unsigned long long int j,nbZero,m;
        FILE *f1;        
        FILE *f2;
        string str;
        string str2="e";
        string str3;
        mpz_t  msg;
        if(fichierSource.length()<1) break ;
        f1=fopen(this->fichierSource.c_str(), "rb");
        f2=fopen(this->fichierDest.c_str(), "wb");
        fseek(f1,0,SEEK_SET);
        for(j=0,m=1, nbZero=0;j<8;j++,m*=256) nbZero+=fgetc(f1)*m;
        str2[0]=fgetc(f1);
        while(str2[0]!=EOF)
        {
            str=""+str2;
            for(j=1;j<this->tailleBloc_; j++)
            {
                str2[0]=fgetc(f1);
                str=str+ str2 ;
            }
            str2[0]=fgetc(f1);

            msg=Class_one::Transcoder(str);
            Class_one::CrypterDecrypter(mpz_t msg,mpz_t ,mpz_t ,mpz_t);

            if (str2[0]==EOF)
            {
                for(j=0;j<(this->tailleBloc - nbZero); j++)
                    fputc((int)str[j], f2);
            }
            else
                for(j=0;j<this->tailleBloc ; j++)   fputc((int)str[j], f2);
        }
        fclose(f1);
        fclose(f2);

    Class_one::dechiffre_Msg (mpz_t cipher, mpz_t msg_chiffre ,mpz_t d ,mpz_t n); 
    gmp_printf("\n\n\t Le message dechiffre :\t%Zd\n\n",cipher); 
    break ;

    case 2 :
    //chiffrement du message 
    mpz_init_set_str(cipher, "1",0); 
     unsigned long long int j,aux;
            FILE *f1, *f2;
            unsigned char c;
            unsigned long long int nbZero ;
            string str ;
            string str2="e";
            mpz_t  msg;

            if(fichierSource.length()<1) return -1;
            f1=fopen(this->fichierSource.c_str(), "rb");
            f2=fopen(this->fichierDest.c_str(), "wb");
            str2[0]=fgetc(f1);
            if (str2[0]==EOF) break ;
            fseek(f1, 0, SEEK_END);
            //fpos_t <==> long long int pour notre compilateur
            fgetpos(f1,(fpos_t *)&nbZero);
            nbZero=nbZero%this->tailleBloc;
            if(nbZero!=0) nbZero=this->tailleBloc - nbZero;

            aux=nbZero;
            for(j=0;j<8;j++)
            {
                c=aux%256;
                aux=aux/256;
                fputc(c,f2);
            }

            fseek(f1,0, SEEK_SET);
            str2[0]=fgetc(f1);
            while(str2[0]!=EOF)
            {
                str=""+str2;
                for(j=1;j<(this->tailleBloc); j++)
                {
                    str2[0]=fgetc(f1);
                    str=str+str2 ;
                }
                str2[0]=fgetc(f1);
                if(str2[0]==EOF)
                {
                    for(j=this->tailleBloc-nbZero; j< this->tailleBloc; j++)
                        str[j]=0;
                }
                /*for(j=str.length();j<this->tailleBloc_; j++)
                    str=str2+str;*/
                msg=Class_one::Transcoder(str);
                Class_one::chiffre_Msg(mpz_t msg , mpz_t msg  ,  mpz_t e  , mpz_t n );
                str=Class_one::DeTranscoder(msg);
                for(j=str.length();j<this->tailleBloc_; j++)
                        fputc((int)0, f2);
                for(j=0;j<str.length(); j++)
                        fputc((int)str[j], f2);
            }
            fclose(f1);
            fclose(f2);

    break ;
    }
    // liberer les variables locales 
    mpz_clear(p); mpz_clear(q);
    mpz_clear(e);mpz_clear(phi);mpz_clear(n); 
    mpz_clear(message);mpz_clear( msg_chiffre);


} 
int main (){
    void Cryptage::crypter_RSA();


}
0
Rahil 27 Авг 2011 в 01:12

3 ответа

Лучший ответ

Я пытался установить / собрать GMP, а также MPIR в Windows. Очень сложно. Сначала нужно скомпилировать и собрать библиотеки и т. Д.

Через некоторое время я нашел Библиотеку больших целых чисел C ++ от Мэтта Маккатчена

https://mattmccutchen.net/bigint/

Только исходный код C ++. Очень просто использовать. Интегрируется за 10 минут.

1
RED SOFT ADAIR 23 Янв 2013 в 09:21

Несколько советов, даже если это не совсем ответ ... Вы не можете так работать даже с таким маленьким проектом: вам нужно решать одну проблему за раз.

По сути, вы пытались написать всю свою программу и затем только для ее компиляции: вам нужно написать свои различные функции и протестировать их по отдельности, тем более что вы новичок.

Например, если вы хотите скомпилировать с помощью gmplib, напишите что-то вроде этого:

#include <gmp.h>

int main ()
{
    mpz_t x;
    return 0;
}

Попробуйте скомпилировать и посмотреть, что получится. Если у вас есть ошибка компиляции, у вас будет небольшой фрагмент кода, который вы можете опубликовать здесь: добавьте точное сообщение вашего компилятора, и люди здесь помогут вам вместо того, чтобы закрывать ваш вопрос (снова ...).

Это будет первая проблема: компиляция с другой библиотекой. Как только это сработает, вы можете добавить небольшой кусок вашего собственного кода, перекомпилировать его и протестировать то, что у вас есть.

Например, добавьте объявление своего класса с минимальным определением функций: не пишите реализацию, просто почти пустое тело, например:

class OneClass {
   void pgcd (mpz_t, mpz_t, mpz_t) { /* empty function */ }
   // etc
};

Вы сможете (надеюсь, это будет легко) заметить, что вы пропустили точку с запятой в конце объявления класса и что ваша функция Transcoder возвращает mpz_t, что является незаконным, поскольку mpz_t является typedef для массива.

Затем, когда это сработает, добавьте реализации вашей функции одну за другой в порядке, позволяющем тестировать их по мере их написания .

Вы будете намного эффективнее, так как вам будет легче узнать, откуда возникла проблема.

Короче говоря, найти ошибку в двух только что добавленных строках (если вы знаете, что все остальное верное) легко, но найти все ошибки в таком большом файле долго и мучительно ...

Напишите один фрагмент кода, скомпилируйте его, протестируйте, а затем напишите только следующий: он окупится!

Изменить: на самом деле вам нужно будет использовать одну функцию в библиотеке, чтобы проверить, можете ли вы правильно с ней связать, но это та же идея.

3
Nicolas Grebille 26 Авг 2011 в 22:23

GMP не работает с Visual Studio, вместо этого следует использовать MPIR. Вам не нужно менять свой код, только библиотеку, которую вы используете.

0
john 26 Авг 2011 в 21:47