RSA makes use of an expression with exponentials. Plaintext is encrypted in blocks, with each block having a binary value less than some integer n. That is, the block size must be less or equal to log2n; in practice, the block size is k bits, where 2k n2k1. Encryption and decryption are of the following form, for some plaintext block M and ciphertext block C:
n
Both sender and receiver must know the value of n. The sender knows the value of e, and only receiver knows the value of d. Thus, this is a public-key encryption algorithm with a public key of KU={e,n}, and a private key of KR={d,n}. For this algorithm to be satisfactory for public-key encryption, the following requirements must be met:
1. It is possible to find values of e,d,n such that Med Mmodn for all M<n 2. It is relatively easy to calculate Me and C for all values of M<nd
3. It is infeasible to determine d given e and d.
For now, we focus on the 1st requirement and consider the other questions later. We need to find a relationship of the form
n M Med mod A corollary to Euler’s theorem
(For every a and n that are relatively prime
n a(n) 1mod
where (n) is the Euler’s totient function – number of positive integers less than n and relatively prime to n),
fits the bill:
Given two prime numbers, p and q, and two integers, n and m, such that n=pq and 0<m<n, and arbitrary integer k, the following relationship holds:
n
This is equivalent to saying: mod ( )
That is, e and d are multiplicative inverses mod(n). Note that, according to the rules of modular arithmetic, this is true only if d (and therefore e) is relatively prime to (n). Equivalently, gcd((n),d)1.
We are now ready to state the RSA scheme. The ingredients are the following:
p,q, two prime numbers (private, chosen)
n=pq (public, calculated)
d (private, calculated)
The private key consists of {d,n}, and the public key consists of {e,n}. Suppose that user A has published its public key and that user B wishes to send message M to A. Then B calculates
n M
C emod and transmits C. On receipt of this ciphertext, user A decrypts by calculating n
C
M d mod . It is worthwhile to summarize the justification for this algorithm. We have chosen e and d such that d e1mod(n).
Therefore ed 1mod(n). Therefore, ed is of the form k(n)1. But by the corollary to Euler’s theorem (*), given two prime numbers, p and q, and integer n=pq and M, with 0<M<n:
n
An example is shown in Figure 9.6
For this example, the keys were generated as follows:
1. Select two prime numbers, p=17, q=11 2. Calculate n=pq=17x11=187
3. Calculate (n)=(p-1)(q-1)=16x10=160
4. Select e such that e is relatively prime to (n)=160 and less than (n); we choose e=7.
5. Determine d such that de1mod160 and d<160. The correct value is d=23, because 23x7=161=1x160+1; d can be calculated using the extended Euclid’s algorithm:
M=160, b=7
A=(1,0,m), B=(0,1,b) Q=A3/B3=160/7=22 T=A-QB=(1,-22,6) A=(0,1,b), B=(1,-22,6) Q=A3/B3=7/6=1 T=(-1,23,1)
A=(1,-22,6), B=(-1,23,1) B3=1 =>b-1=B2=23.
The resulting keys are public key KU={7,187} and private key KR={23,187}. The example shows the use of these keys for a plaintext input of M=88. For encryption, we need to calculate C=887 mod 187. Exploiting the properties of modular arithmetic, we can do this as follows:
887 mod 187= [(884 mod 187)x(882 mod 187)x(88mod 187)] mod 187 88 mod 187 = 88
882 mod 187 = 7744 mod 187 = 77 884 mod 187 = 772 mod 187 =132
887 mod 187 = (88x77x132) mod 187 = [((88x77) mod 187) x (132 mod 187)] mod 187 = (44x132) mod 187 = 5808 mod 187 = 11
For decryption, we calculate M=1123 mod 187:
1123 mod 187 = [(11 mod 187)x(112 mod 187)x(114 mod 187)x(118 mod 187)x (118 mod 187)] mod 187 = [11x121x 14641 mod 187 x (118 mod 187)x
(118 mod 187)] mod 187 = [11x121x55x (118 mod 187)x
(118 mod 187)] mod 187 = [11x121x55x (3025 mod 187)x (3025 mod 187)] mod 187 = [11x121x55x 33x33
] mod 187 = [((11x121) mod 187 )x((55x 33) mod 187) x 33 ] mod 187 = [(1331 mod 187)x(1815 mod 187)x33] mod 187 =
[ 22x132x33]mod 187 = [2904mod187x33]mod187= [99x33] mod 187=
3267 mod 187 = 88
/* Function Declarations */
int menu();
/* Global Arrays */
const __int64 maxsize = 50000;
__int64 r[maxsize]; //holds remainders __int64 q[maxsize]; //holds quotients const __int64 bytesize = 1024;
__int64 bin[bytesize];
__int64 top = 0;
__int64 bottom = 0;
//Start Main int main() {
__int64 method(0),max(0),gcd(0),counter(1),test(0);
__int64 b(0),c(0),d(0),e(0),f(0),i(0),j(0),p(0),q(0),t(0),a(0),n(0),m(0),theta(0);
while (method != 5)
cout<<"Enter the max value between 1000 and 9999"<<endl;
cin >> max;
if (max > 9999 || max < 1000){exit(0);}
system("CLS");
cout<<"Generating Keys";
while (p < 100) {
p = prime(max);//get p }
while (q <= p && q <= max) {
q = prime(max);//get q counter++;
test = counter %50; //track attempts if (test == 0 ){cout<<".";}
}
cout<<endl;
n = p * q; //compute n
theta = (p-1)*(q-1); //compute theta while (e == q || e == 0)
cout<<"Enter Ciphertext in decimal format"<<endl;
cin>> c;
FastEXP(c,d,n);
break;
cout<<"RSA Encryption"<<endl;
cout<<"Please make a selection?"<<endl;
cout<<"1. Generate Keys"<<endl;
cout<<"2. Encrypt "<<endl;
cout<<"3. Decrypt"<<endl;
cout<<"4. Exit"<<endl;
cin >> method;
int matrix[333][8]; //[row][column]
//all fixed top column numbers
int i(0),j(0),k(0),sr(0),modnum(0),row(0),col(0);
max = max / 30; //determine array-row size needed for storage for (i = 0; i < max; i++)//rows
//filtering the Matrix for Primes
for (k = 0; k < max; k++)//total rows
srand((unsigned)time(0)); //seed random number generator with clock while (prime == 0)
{ //until suitable primes are picked row = rand()%max;
col = rand()%8;
prime = matrix[row][col]; //assign prime to value in matrix }
return prime;
} //end function
/* This function will take 2 parameters and solve the GCD from Euclid's Algorithm a - smaller value
b - larger value */
__int64 ExtEuclid(__int64 a, __int64 b) {
__int64 rem(0),gcd(0),i(0),k(0);
//Initialize Array
{ //Does not divide r[i] = a;
rem = b - a * (b/a);
q[i] = b/a;
bottom = i+1;//store length of array for ExtEuclid loop return gcd;
}
/*This function will take 2 parameters sent in and solve a two variable equation using the Extended Euclid Algorithm
a - smaller value; b - larger value */
__int64 ExtEuclid(__int64 a, __int64 b) {
void FastEXP(__int64 a, __int64 m, __int64 n) {
IntBin(m); //convert m to a binary integer array
__int64 k = top; //k is equal to the length of the binary integer array cout<<"k "<<k<<endl;
__int64 d = 1;
int c = 0;
//Fast Exponentiation Algorithm for (int i = k; i > 0; i--)
cout<<""<<c <<""<< d <<endl;
}
cout << "The Power "<<a<<" raised to the "<<m<<" (Mod "<<n<< ") is "<<d<<endl;
}
/* This function will take a parameter sent in to determine the value that will be converted into a binary simulated integer array.
Once the array is created, the function will print out the binary number backwards m - Number to be converted into binary */
void IntBin(__int64 m) {
__int64 tmp(1),remain(1);
int c(0),i(0),j(0),test(0);
bool first(true);
for (i = 0; i < bytesize; i++) {
bin[i] = 0;
} //initialize array to 0 m = abs(m);
test = m%2; //determine if even or odd if (c == 0 && test==0)//special case; ones place
}
if (first == true)//run only once {
top = c;//identify the highest power
first = false; //prevent condition from happening again }
m = m - remain; //move to the next significant digit c = 0; //reset counter
remain = 1; //reset remain tmp = 1;//reset tmp
cout<<"m is "<<m<<endl;
}
for (i=1;i<top+1;i++){cout<<bin[i];} //print binary cout<<""<<endl;
}
Experiment no. 7
Objective of performing experiment: Implement Rabin-Miller Primality Testing Algorithm in 'C'.
program: Rabin miller
#include<iostream>
#include<cmath>
void main() {
int number = 5;
int max = 0;
int sr = 0;
int i;
int modnum = 0;
cout<<"how high do you want your prime number search to go to?"<<endl;
cin>> max;
if (max > 1 && max < 100000000) {
cout<<"Prime Numbers"<<endl;
cout<<" 2"<<endl;
cout<<" 3"<<endl;
while (number < max) {
sr = sqrt(number);
for ( i = 2; i < sr + 2; i++) {
modnum = number % i;
if (modnum == 0)
{ //not prime
i = sr + 3;
}
if (modnum != 0 && i == sr + 1) {
for (int j = 0; j < 7500000; j++); //delay
cout<<" "<<number<<endl; //print out prime number }
}
number++;
number++;
} }
else
cout<<"Your choice is not a prime number"<<endl;
}