kaki-epithesi@home:~$

RSA with C

RSA

RSA (Rivest–Shamir–Adleman) is a public-key cryptosystem that is widely used for secure data transmission.

p,q are distinct primes.

n = p*q

phi = (p-1)*(q-1)

e is such that 
1 < e < phi and is coprime to phi.

d = modInverse(e)

Mod Inverse

Public Key pair  (n,e)
Private Key pair (n,d)

Encryption

For Padded Plaintext message ‘m’

c(m) = m^e mod n

c(m) = pow(m,e) % n

Decryption

m(c) = c^d mod n

m(c) = pow(c,d) % n

RSA in C

rsa.h file :

Encrypt function

encrypt which takes 3 arguments

1st argument the message to encrypt of type char*

2nd and 3rd argument the index values for p,q of type integer

returns an integer array of the same size of the message.

Decrypt function

decrypt which takes 3 arguments

1st argument is the encrypted integer array

2nd and 3rd argument the index values for p,q of type integer The same values used to encrypt the plaintext message.

It returns a char array, the decrypted message .

rsa.h Header file

#define ll long long
// #define ld long double
#ifndef RSA_H
#define RSA_H

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>

// prime numbers array for random values of p,q
int prime_list[400] = {11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777};
// the enc array which will have the encrypted numbers of the message
int enc[1000]={0};
unsigned ll p,q,n,phi,e,track,c,m,d;
char msg[1000];

// 1 < e < phi
void gcd(){
    int t,a,b;
    a = e;
    b = phi;
    while(1){
        t = a%b;
        if(!t){
            track = b;
            return;
        }   
        a = b;
        b = t;
    }
}

// the power function which will help to keep the number in range of mod
ll power(ll x, ll y, ll mod)
{
	ll res = 1;
	while (y > 0)
	{
		if (y & 1)
			res = res*x % mod;
		y = y>>1;
		x = x*x % mod; 
	}
	return res;
}

// computing the values and keys which will be required for encryption
// and decryption
void pre(ll v1, ll v2){
    p = prime_list[v1];
    q = prime_list[v2];
    n = p*q;
    phi = (p-1)*(q-1);
    e = 7;

    // 1 < e < phi
    while(e<phi){
        gcd();
        if(track==1)
            break;
        else
            e++;
    }
    // 1 < e < phi
}

// mod Inverse function to calculate the value of d, for decryption
ll modInverse(ll a, ll m)
{
    ll m0 = m;
    ll y = 0, x = 1;
 
    if (m == 1)
        return 0;
 
    while (a > 1) {
        int q = a / m;
        int t = m;
 
        m = a % m, a = t;
        t = y;
        y = x - q * y;
        x = t;
    }

    if (x < 0)
        x += m0;
    return x;
}

// public key pair (n,e)
// private key pair (n,d)


// encryption function 
int* encrypt(char *s, ll v1, ll v2){
    strcpy(msg, s);
    pre(v1, v2);
    for(int i=0; msg[i] != 0; ++i){
        int msg_letter;
        msg_letter = (int)msg[i];
        // m = pow(m, e) % n
        enc[i] = power(msg_letter, e, n);
    }
    return enc;
}


// decryption function 
char* decrypt(int *a, ll v1, ll v2){
    pre(v1, v2);
    d = modInverse(e,phi);
    char *dec_msg;
    int size;
    for(size=0; a[size] != 0; ++size);
    dec_msg = (char*)malloc((size+1) * sizeof(char));
    for(int i=0; i < size; ++i){
        // m = pow(c,d) % n
        m = power(a[i], d, n);
        dec_msg[i] = (char)(long)m;
    }
    dec_msg[size] = '\0';
    return dec_msg;
}

#endif

APPLICATION

#include<stdio.h>
#include<stdlib.h>  
#include<time.h>
#include "rsa.h"

#define ll long long

int main(){
    char *s = "This is a Sample Message";
    printf("Sample Message to Encrypt : %s\n",s);
    srand(time(0));
    unsigned ll v1, v2;
    // generating two random numbers in the range of 0->400
    v1 = rand() % 400;
    do{
        v2 = rand() % 400;
    }while(v1 == v2);// checking for v1 != v2

    int *a = encrypt(s, v1, v2);
    // encryption of plaintext message.
    printf("\nEncrypted array\n");
    for(int i=0; a[i] != 0;++i){
        printf("%d, ", a[i]);
    }

    // decryption of the encrypted array to get the plaintext message 'm'
    char *d = decrypt(a, v1, v2);
    printf("\n\nDecrypted Message : %s\n",d);
    return 0;
}

OUTPUT

Sample Message to Encrypt : This is a Sample Message

Encrypted array
2804921, 420449, 4929558, 2472507, 1556470, 4929558, 2472507, 1556470, 1195619, 1556470, 4898031, 1195619, 1279340, 2174968, 1035401, 5248057, 1556470, 1482633, 5248057, 2472507, 2472507, 1195619, 3230331, 5248057,

Decrypted Message : This is a Sample Message