Search code examples
linuxalgorithmencryptionrsaprivate-key

RSA Algorithm in C private key


Implement the encryption algorithm RSA. Specifically:

  1. Implement an algorithm that converts a message into an integer and the reverse. Suppose messages consist only of characters of the English alphabet.
  2. Create two prime numbers p and q size 512 bits. Calculate then N, a public key e and its corresponding private d. With the parameters you create, encrypt and decrypt a message of your choice to check the correctness of your implementation.

My code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gmp.h"
#define BASE 256  
#ifndef MAXLEN
#define MAXLEN 256
#endif   
void str_int(mpz_t r, char *str);
void int_str(char *str, mpz_t org_str_int);
void eukleidhs(mpz_t a,mpz_t b,mpz_t xx,mpz_t yy); 
gmp_randstate_t stat;
int main()
{
      gmp_randstate_t rand_state;
      gmp_randinit_default(rand_state);
      long sd = 0;
      mpz_t p, q, p1, q1, n, message_int, a, b, temp_p, temp_q, p_1, q_1, f, e, gcd, d, c, m, A, B, C, D, i, ed, ed_m, fl1, fl2, d1, d2;
      mpz_t seed;
      gmp_randinit(stat, GMP_RAND_ALG_LC, 120);
      mpz_init(p);
      mpz_init(q);
      mpz_init(p1);
      mpz_init(q1);
      mpz_init(n);
      mpz_init(p_1);
      mpz_init(q_1);
      mpz_init(f);
      mpz_init(e);
      mpz_init(fl1);
      mpz_init(fl2);
      mpz_init(d1);
      mpz_init(d2);
      mpz_init(gcd);
      mpz_init(d);
      mpz_init(c);
      mpz_init(A);
      mpz_init(m);
      mpz_init(B);
      mpz_init(C);
      mpz_init(D);
      mpz_init(i);
      mpz_init(ed);
      mpz_init(ed_m);
     mpz_init(message_int);
     mpz_init(seed);
      unsigned char message[MAXLEN], out_message[MAXLEN];
      mpz_init(a);
      mpz_init(b);
      mpz_init(temp_p);
      mpz_init(temp_q);
/* (create p  512 BITS)*/
      srand( (unsigned) getpid());
      sd=rand();
      mpz_set_ui(seed, sd);
      gmp_randseed(stat, seed);
      srand( (unsigned) getpid());                                 
      mpz_set_ui(seed, sd);                                          
      mpz_urandomb(p1, stat, 512);                                
   /*  (create q 512 BITS*/
 srand( (unsigned) getpid());
 sd=rand();
 mpz_set_ui(seed, sd);
gmp_randseed(stat, seed);
srand( (unsigned) getpid());                                 
 mpz_set_ui(seed, sd);                                        
 mpz_urandomb(q1, stat, 512);                             
      int primetest;   
      primetest = mpz_probab_prime_p(p1, 5);
      if (primetest != 0)
      {
            mpz_set(p, p1);
            printf("p= "); mpz_out_str(stdout, 10, p); 
            printf("\n");
            printf("\n");
      }
      else
      {
            mpz_nextprime(p, p1);
            printf("p= "); mpz_out_str(stdout, 10, p); 
            printf("\n");
            printf("\n");
      }    
      primetest = mpz_probab_prime_p(q1, 5); 
      if (primetest != 0) 
      {
           mpz_set(q, q1);
            printf("q= "); mpz_out_str(stdout, 10, q); 
            printf("\n");
            printf("\n");
      }
      else
      {
            mpz_nextprime(q, p);
            printf("q= "); mpz_out_str(stdout, 10, q); 
            printf("\n");
            printf("\n");    
      }    
 /*( n, p-1, q-1, f)*/
      mpz_mul(n, p, q);
      printf("n= "); mpz_out_str(stdout, 10, n);            // n=p*q
      printf("\n");
      printf("\n");
      mpz_sub_ui(p_1, p, 1);
      printf("p-1= "); mpz_out_str(stdout, 10, p_1);        // p-1
      printf("\n");
      printf("\n");  
      mpz_sub_ui(q_1, q, 1);
      printf("q-1= "); mpz_out_str(stdout, 10, q_1);        // q-1   
      printf("\n");   
      printf("\n");
      mpz_mul(f, p_1, q_1);
      printf("f= "); mpz_out_str(stdout, 10, f);            //f=(p-1)*(q-1)
      printf("\n");
      printf("\n");
/*( 1<e<f)*/
      sequence1: 
      mpz_urandomb(e, stat, 512);                  
      if ((mpz_cmp_si(e,1)) && (mpz_cmp (e,f)))   
      { 
            mpz_gcd(gcd, e, f);                 
            if (mpz_cmp_si(gcd,1))              
            {
                  printf("To e einai:\n");
                  printf("e= ");
                  mpz_out_str(stdout, 10, e);
                  printf("\n");
                  printf("\n");
            }
            else
            {
                  goto sequence1;
            }
      }

      else

      {
            goto sequence1;
      }

/*( d WSTE 1<d<f and e*d= 1 mod f)*/
      mpz_invert(d, e, f);
     printf("To d einai:\n");
      printf("d= ");
      mpz_out_str(stdout, 10, d);
      printf("\n");
      printf("\n");
/*keys)*/
      printf("The public key is :\n");           
      printf("(n,e)= ");
      printf(" (");
      mpz_out_str(stdout, 10, n);
      printf("  ,  ");
      mpz_out_str(stdout, 10, e);
      printf(") ");
      printf("\n");
      printf("\n");
      printf("The private key is:\n");          
      printf("d= ");  
      mpz_out_str(stdout, 10, d);
      printf("\n");
      printf("\n");
      printf("GRAPSE TO MYNHMA SOU(Mexri %d xarakthres) !!!! :", MAXLEN);
        fgets(message, MAXLEN - 1, stdin);  
      str_int(m, message);
      #ifdef HEX
        gmp_printf("TO MHNYMA(%d)  -> %Zx\n\n", strlen(message), m); // EKTTYPWSH MYNHMATOS SE ARITHMO
      #else
        gmp_printf("TO MHNYMA(%d)  -> %Zd\n\n", strlen(message), m);
      #endif  

/*( c = m^e mod n)*/

      mpz_powm(c, m, e, n);
      exit1:
      printf("TO KRYPTOGRAFHMENO KEIMENO EINAI:\n");         
      printf("c= ");
      mpz_out_str(stdout, 10, c);
      printf("\n");
      printf("\n");

    mpz_set_ui(m,0);          
/*( m = c^d mod n)*/  
      mpz_powm(m, c, d, n);
      exit2:

      printf("TO APOKRYPTOGRAFHMENO KEIMENO EINAI:\n");          
      printf("m= ");

      mpz_out_str(stdout, 10, m);

      printf("\n");

      printf("\n");


      int_str(out_message, m);

   #ifdef HEX

        gmp_printf("TO APOKRYPTOGRAFHMENO KEIMENO EINAI: %Zd\n            -> %s(%d)\n", m, out_message, strlen(out_message));

      #else

        gmp_printf("TO APOKRYPTOGRAFHMENO KEIMENO EINAI: %Zd\n            -> %s(%d)\n", m, out_message, strlen(out_message));

      #endif


return 0;

}
/* SYNARTHSH METATROPHS STRING SE AKERAIO*/

void str_int(mpz_t r, char *str)

{

      long int str_len, j;

      unsigned char C;



      str_len = strlen(str);

      if(str[str_len - 1] == '\n')

            str[str_len - 1] = '\0';

      str_len = strlen(str);



      mpz_set_ui(r, 0UL);              



      for(j = str_len - 1; j >= 0; j--)           // r = str[str_len - 1] * BASE^(str_len - 1) + ... + str[1] * BASE + str[0]

      {

      C = str[j];



            mpz_mul_ui(r, r, (unsigned long)BASE);           

            mpz_add_ui(r, r, (unsigned long)C);

      }

}


void int_str(char *str, mpz_t org_str_int)

{

      long int str_len, i;

      mpz_t max_int, c_int, str_int;



      mpz_init(max_int);                  //ARXIKOPOIHSH

      mpz_init(c_int);

      mpz_init(str_int);



      mpz_set(str_int, org_str_int);



      mpz_set_ui(max_int, 1UL);          

      for(i = 0; i < MAXLEN; i++)

      {

            if(mpz_cmp(str_int, max_int) <= 0)

            {

                  str_len = i;
                break;
            }

            mpz_mul_ui(max_int, max_int, (unsigned long)BASE);
      }

      for(i = 0; i < str_len; i++)        //METATROPH SE GRAMMA

      {
            mpz_mod_ui(c_int, str_int, (unsigned long)BASE);

            mpz_sub(str_int, str_int, c_int);
            mpz_tdiv_q_ui(str_int, str_int, (unsigned long)BASE);
            str[i] = mpz_get_ui(c_int);

      }

      str[str_len] = '\0';

      mpz_clear(max_int);

      mpz_clear(c_int);
      mpz_clear(str_int);

}
/*ALGORITHMOS EUKLEIDH*/

void eukleidhs(mpz_t a,mpz_t b,mpz_t xx,mpz_t yy)

{
      int flag=0;
      mpz_t d,x,y,x1,x2,y1,y2,q,r;
      mpz_t qb,a_qb,temp;
      mpz_t qx1,x2_x1;
      mpz_t qy1,y2_y1;
      mpz_init(x);
      mpz_init(y);
      mpz_init(d);

      if(mpz_cmp(b,a)>0) {

            flag=1;

            mpz_init(temp);

            mpz_set(temp,b);
            mpz_set(b,a);
            mpz_set(a,temp);
            mpz_clear(temp);
      }

      if(mpz_cmp_ui(b,0)==0) {

            mpz_set(d,a);

            mpz_set_ui(x,1);

            mpz_set_ui(y,0);

      }

      else {

           mpz_init(q);
            mpz_init(r);  
            mpz_init(x1);
            mpz_init(x2);

            mpz_init(y1);
            mpz_init(y2);
            mpz_init(qb);
            mpz_init(a_qb);
           mpz_init(qx1);
            mpz_init(qy1);
            mpz_init(x2_x1);    
            mpz_init(y2_y1);
            mpz_set_ui(x2,1);
           mpz_set_ui(x1,0);
            mpz_set_ui(y1,1);
            mpz_set_ui(y2,0);
            while(mpz_cmp_ui(b,0)>0) {
                  mpz_tdiv_q(q,a,b);
                  mpz_mul(qb,q,b);       
                  mpz_sub(a_qb,a,qb);
                  mpz_set(r,a_qb);
                  mpz_mul(qx1,q,x1);           
                  mpz_sub(x2_x1,x2,qx1);
                  mpz_set(x,x2_x1);
                  mpz_mul(qy1,q,y1);           
                  mpz_sub(y2_y1,y2,qy1);
                  mpz_set(y,y2_y1);
                 mpz_set(a,b);  
                  mpz_set(b,r); 
                  mpz_set(x2,x1); 
                  mpz_set(x1,x);
                  mpz_set(y2,y1);
                 mpz_set(y1,y);                                                   
            }
      }
      mpz_set(d,a);
      mpz_set(x,x2);
      mpz_set(y,y2);  
      if(flag==1){
            mpz_set(yy,x);
            mpz_set(xx,y);
      }
      else {
            mpz_set(yy,y);
            mpz_set(xx,x);
      }
      mpz_clear(d);
      mpz_clear(x);
      mpz_clear(y);
      mpz_clear(x1);
      mpz_clear(x2);
      mpz_clear(y1);
      mpz_clear(y2);
      mpz_clear(q);
      mpz_clear(r);
      mpz_clear(qb);
      mpz_clear(a_qb);
      mpz_clear(qx1);
      mpz_clear(x2_x1);
      mpz_clear(qy1);
      mpz_clear(y2_y1);
}

I run the program but the private key comes out 0 and i cant find the mistake!


Solution

  • The most obvious issue is that you are repeatedly reseeding the system random number generator with the same value, e.g.

    srand( (unsigned) getpid());
    sd=rand();
    mpz_set_ui(seed, sd);
    gmp_randseed(stat, seed);
    

    Don't do this. You end up getting the same random number each time, and it's likely that reusing the same numbers for multiple purposes is giving bad results.