C Program to Implement the RSA Algorithm

The RSA algorithm is a very fast algorithm for encryption and decryption. It is used in many applications like encryption and decryption of messages. The algorithm is based on the idea that if we know the public and private keys, then we can encrypt and decrypt messages. An RSA user creates two large prime numbers, p and q, and computes n = pq. Then they computes the totient function, λ(n) = (p – 1)(q – 1). Choosing e as a relatively prime number to λ(n) and 1 < e < λ(n) they release e as the public key.

Then they computes the private key, d, as follows:
d * e = 1 mod λ(n)

Encrytion is done as follows:
c = me mod n
over all the characters.

Decryption is done as follows:
m = cd mod n
over all the characters.

Problem Description

Write a C program that will ask the user to enter two prime numbers and then encrypt and decrypt a message using the RSA algorithm.

Problem Solution
RSA Algorithm

1. Ask the user to enter two prime numbers and validate them.
2. Store the prime numbers in variables.
3. Compute n = pq.
4. Compute λ(n) = (p – 1)(q – 1).
5. Choose a random number e as a relatively prime number to λ(n) and 1 < e < λ(n).
6. Compute d = e-1 mod λ(n).
7. Print the public and private keys.
8. Ask the user to enter a message and store it in a variable.
9. Encrypt the message using the public key.
10. Decrypt the message using the private key.
11. Print the encrypted and decrypted message.

Let’s look at the RSA Algorithm in C with two examples.

advertisement
advertisement

Method 1: RSA Algorithm using Naive Approach

In this approach, we implement the RSA algorithm. This is a type of Public Key encryption or Asymmetric encryption/decryption algorithm, that uses two different but related keys. Plus knowing the one key will not help figure out the other is the key protection.

The RSA algorithm uses the fact that it’s easy to multiply two large prime numbers together and get a product. But you can’t take that product and reasonably guess the two original numbers, or guess one of the original primes if only the other is known.

Program/Source Code

Here is source code of the C Program to Implement the RSA Algorithm. The C program is successfully compiled and run on a Linux system. The program output is also shown below.

Sanfoundry Certification Contest of the Month is Live. 100+ Subjects. Participate Now!
  1. /*
  2.  * C program to Implement the RSA Algorithm
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<conio.h>
  7. #include<stdlib.h>
  8. #include<math.h>
  9. #include<string.h>
  10.  
  11. long int p, q, n, t, flag, e[100], d[100], temp[100], j, m[100], en[100], i;
  12. char msg[100];
  13. int prime(long int);
  14. void ce();
  15. long int cd(long int);
  16. void encrypt();
  17. void decrypt();
  18. void main()
  19. {
  20.     printf("\nENTER FIRST PRIME NUMBER\n");
  21.     scanf("%d", &p);
  22.     flag = prime(p);
  23.     if (flag == 0)
  24.     {
  25.         printf("\nWRONG INPUT\n");
  26.         getch();
  27.         exit(1);
  28.     }
  29.     printf("\nENTER ANOTHER PRIME NUMBER\n");
  30.     scanf("%d", &q);
  31.     flag = prime(q);
  32.     if (flag == 0 || p == q)
  33.     {
  34.         printf("\nWRONG INPUT\n");
  35.         getch();
  36.         exit(1);
  37.     }
  38.     printf("\nENTER MESSAGE\n");
  39.     fflush(stdin);
  40.     scanf("%s", msg);
  41.     for (i = 0; msg[i] != NULL; i++)
  42.         m[i] = msg[i];
  43.     n = p * q;
  44.     t = (p - 1) * (q - 1);
  45.     ce();
  46.     printf("\nPOSSIBLE VALUES OF e AND d ARE\n");
  47.     for (i = 0; i < j - 1; i++)
  48.         printf("\n%ld\t%ld", e[i], d[i]);
  49.     encrypt();
  50.     decrypt();
  51. }
  52. int prime(long int pr)
  53. {
  54.     int i;
  55.     j = sqrt(pr);
  56.     for (i = 2; i <= j; i++)
  57.     {
  58.         if (pr % i == 0)
  59.             return 0;
  60.     }
  61.     return 1;
  62. }
  63. void ce()
  64. {
  65.     int k;
  66.     k = 0;
  67.     for (i = 2; i < t; i++)
  68.     {
  69.         if (t % i == 0)
  70.             continue;
  71.         flag = prime(i);
  72.         if (flag == 1 && i != p && i != q)
  73.         {
  74.             e[k] = i;
  75.             flag = cd(e[k]);
  76.             if (flag > 0)
  77.             {
  78.                 d[k] = flag;
  79.                 k++;
  80.             }
  81.             if (k == 99)
  82.                 break;
  83.         }
  84.     }
  85. }
  86. long int cd(long int x)
  87. {
  88.     long int k = 1;
  89.     while (1)
  90.     {
  91.         k = k + t;
  92.         if (k % x == 0)
  93.             return (k / x);
  94.     }
  95. }
  96. void encrypt()
  97. {
  98.     long int pt, ct, key = e[0], k, len;
  99.     i = 0;
  100.     len = strlen(msg);
  101.     while (i != len)
  102.     {
  103.         pt = m[i];
  104.         pt = pt - 96;
  105.         k = 1;
  106.         for (j = 0; j < key; j++)
  107.         {
  108.             k = k * pt;
  109.             k = k % n;
  110.         }
  111.         temp[i] = k;
  112.         ct = k + 96;
  113.         en[i] = ct;
  114.         i++;
  115.     }
  116.     en[i] = -1;
  117.     printf("\nTHE ENCRYPTED MESSAGE IS\n");
  118.     for (i = 0; en[i] != -1; i++)
  119.         printf("%c", en[i]);
  120. }
  121. void decrypt()
  122. {
  123.     long int pt, ct, key = d[0], k;
  124.     i = 0;
  125.     while (en[i] != -1)
  126.     {
  127.         ct = temp[i];
  128.         k = 1;
  129.         for (j = 0; j < key; j++)
  130.         {
  131.             k = k * ct;
  132.             k = k % n;
  133.         }
  134.         pt = k + 96;
  135.         m[i] = pt;
  136.         i++;
  137.     }
  138.     m[i] = -1;
  139.     printf("\nTHE DECRYPTED MESSAGE IS\n");
  140.     for (i = 0; m[i] != -1; i++)
  141.         printf("%c", m[i]);
  142. }
Runtime Test Cases

In this case, we enter two prime numbers “7” and “19” and then use the RSA algorithm to encrypt and decrypt a message.

$ gcc RSA.c
$ ./a.out
 
ENTER FIRST PRIME NUMBER: 7
 
ENTER ANOTHER PRIME NUMBER: 19
 
ENTER MESSAGE: Dharmendra
 
POSSIBLE VALUES OF e AND d ARE
 
5	65
11	59
13	25
17	89
23	47
29	41
31	7
37	73
41	29
THE ENCRYPTED MESSAGE IS
=’a…º¢É½…a
THE DECRYPTED MESSAGE IS
Dharmendra

Method 2: Additional Program for RSA Algorithm

In this approach we use a temp array to store some intermediate values to be later used in decrypt function.

advertisement

Methods used:

  • int isPrime(int) – This function checks if the number is prime or not.
  • int gcd(int, int) – This function returns the greatest common divisor of two numbers.
  • int totient(int, int) – This function returns the totient of a number.
  • int randome(int) – This function returns a random number less than the given number.
  • int private_key(int, int) – This function returns the private key.
  • long pomod(long, long, long) – This function returns the modular exponentiation of a number.
  • char *encrypt(char *, long, long) – This function encrypts the message.
  • char *decrypt(char *, long, long) – This function decrypts the message.

Example:
Enter the value of p: 7
Enter the value of q: 19

n = pq = 7 * 19 = 133
λ(n) = (p – 1)(q – 1) = λ(n) = (7 – 1)(19 – 1) = 108

The number e should be less than 108 and greater than 1.
Thus, (i * e) % λ(n) = 1, (65 * 5) % 108 = 1
The value of n is 133
The value of λ(n) is 108
The value of e is 5
The value of d is 65

Program/Source Code

Here is source code of the C Program to Implement the RSA Algorithm. The C program is successfully compiled and run on a Linux system. The program output is also shown below.

advertisement
  1. /*
  2.  * C program to Implement the RSA Algorithm
  3.  */
  4.  
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. int isPrime(int n)
  11. {
  12.     int i;
  13.     for (i = 2; i <= sqrt(n); i++)
  14.     {
  15.         if (n % i == 0)
  16.         {
  17.             return 0;
  18.         }
  19.     }
  20.     return 1;
  21. }
  22.  
  23. int gcd(int a, int b)
  24. {
  25.     if (a == 0)
  26.     {
  27.         return b;
  28.     }
  29.     return gcd(b % a, a);
  30. }
  31.  
  32. int totient(int p, int q)
  33. {
  34.     return (p - 1) * (q - 1);
  35. }
  36.  
  37. int randome(int lambda_n)
  38. {
  39.     printf("\nThe number e should be less than %d\n and greater than 1.",
  40.          lambda_n);
  41.     for (int i = 2; i < lambda_n; i++)
  42.     {
  43.         if (gcd(i, lambda_n) == 1)
  44.         {
  45.             return i;
  46.         }
  47.     }
  48.     return -1;
  49. }
  50.  
  51. int private_key(int e, int lambda_n)
  52. {
  53.     for (int i = 1; i < lambda_n; i++)
  54.     {
  55.         if ((i * e) % lambda_n == 1)
  56.         {
  57.             printf("\nThus, (i * e) %% lambda_n = 1, (%d * %d) %% %d = 1", i, e,
  58.              lambda_n);
  59.             return i;
  60.         }
  61.     }
  62.     return -1;
  63. }
  64.  
  65. long pomod(long a, long b, long m)
  66. {
  67.     long x = 1, y = a;
  68.     while (b > 0)
  69.     {
  70.         if (b % 2 == 1)
  71.         {
  72.             x = (x * y) % m;
  73.         }
  74.         y = (y * y) % m;
  75.         b /= 2;
  76.     }
  77.     return x % m;
  78. }
  79.  
  80. /* Encryption
  81.  * A function which takes the message, the public key and a number n which is the
  82.  * product of p and q. The function encrypts the message using the public key
  83.  * and returns the encrypted message.
  84.  */
  85.  
  86. char *encrypt(char *message, long e, long n)
  87. {
  88.     long i;
  89.     long len = strlen(message);
  90.     char *cipher = (char *)malloc(len * sizeof(char));
  91.     for (i = 0; i < len; i++)
  92.     {
  93.         cipher[i] = pomod(message[i], e, n);
  94.         printf("\n%c -> %c", message[i], cipher[i]);
  95.     }
  96.     return cipher;
  97. }
  98.  
  99. /* Decryption
  100.  * A function which takes the cipher text, the private key and a number n which
  101.  * is he product of p and q. The function decrypts the cipher text using the
  102.  * private key and returns the decrypted message.
  103.  */
  104.  
  105. char *decrypt(char *cipher, long d, long n)
  106. {
  107.     long i;
  108.     long len = strlen(cipher);
  109.     char *message = (char *)malloc(len * sizeof(char));
  110.     for (i = 0; i < len; i++)
  111.     {
  112.         // message[i] = (long) pow(cipher[i], d) % n;
  113.         message[i] = pomod(cipher[i], d, n);
  114.         printf("\n%c -> %c", cipher[i], message[i]);
  115.     }
  116.     return message;
  117. }
  118.  
  119. int main()
  120. {
  121.     int p, q, lambda_n;
  122.     long n, e, d;
  123.     char *message;
  124.     char *cipher;
  125.     printf("\nEnter the value of p: ");
  126.     scanf("%d", &p);
  127.     printf("\nEnter the value of q: ");
  128.     scanf("%d", &q);
  129.     if (isPrime(p) && isPrime(q))
  130.     {
  131.         n = p * q;
  132.         lambda_n = totient(p, q);
  133.         e = randome(lambda_n);
  134.         d = private_key(e, lambda_n);
  135.         printf("\nThe value of n is %ld", n);
  136.         printf("\nThe value of lambda_n is %d", lambda_n);
  137.         printf("\nThe value of e is %ld", e);
  138.         printf("\nThe value of d is %ld", d);
  139.         printf("\nEnter the message: ");
  140.         message = (char *)malloc(sizeof(char) * 100);
  141.         scanf("%s", message);
  142.         cipher = encrypt(message, e, n);
  143.         puts("\nThe encrypted message is: ");
  144.         printf("%s", cipher);
  145.         message = decrypt(cipher, d, n);
  146.         puts("\nThe original message was: ");
  147.         printf("%s", message);
  148.     }
  149.     else
  150.     {
  151.         printf("\nThe value of p and q should be prime.");
  152.     }
  153.     return 0;
  154. }
Program Explanation

1. This program will ask the user to enter two prime numbers and then encrypt and decrypt a message using the RSA algorithm.
2. After accepting the values of p and q, the program will check if the values are prime or not.
3. If they are prime, the program will calculate the value of n, lambda_n, e and d using the above mentioned theory.
4. After this, the message will be encrypted and decrypted.

Runtime Test Cases

In this case, we enter two prime numbers “7” and “19” and then use the RSA algorithm to encrypt and decrypt a message.

Enter the value of p: 7
Enter the value of q: 19
 
The number e should be less than 108 and greater than 1.
Thus, (i * e) % lambda_n = 1, (65 * 5) % 108 = 1
The value of n is 133
The value of lambda_n is 108
The value of e is 5
The value of d is 65
Enter the message: apple
 
a -> 
p -> ?
p -> ?
l -> !
e -> 
The encrypted message is: 
??!
 -> a
? -> p
? -> p
! -> l
 -> e
The original message was: 
apple

Note:
Method 2 (Additional program) is not a perfect implementation for large value of n (p * q), as the character set implementation in C is very small, during the encryption and decryption process, many characters are lost. Therefore, for this program to work correctly for large values, as a workaround, all the intermediate calculation should be done on a long long int type array.

To practice programs on every topic in C, please visit “Programming Examples in C”, “Data Structures in C” and “Algorithms in C”.

If you find any mistake above, kindly email to [email protected]

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He lives in Bangalore, and focuses on development of Linux Kernel, SAN Technologies, Advanced C, Data Structures & Alogrithms. Stay connected with him at LinkedIn.

Subscribe to his free Masterclasses at Youtube & discussions at Telegram SanfoundryClasses.