IMPLEMENTING RSA

Steven J Miller, Williams College, sjm1@williams.edu

fltprimetest[a_,n_]:=Module[{},
(* does the FlT check, not prime and and maybe prime *)
(* does NOT do it efficiently with fast multiplication! *)
If[GCD[a,n]>1,Print["GCD Fails, cannot do test, n cannot be prime unless a=1."],
{
x=Mod[a^(n-1),n];
Print[a,"^",n-1," modulo ",m," = ",x,"."];
If[x>1,Print["Not Prime"],Print["Maybe Prime"]];
}];(*end of if*)]

p = NextPrime[RandomReal[] 10^41]  (* testing making large primes *)
PrimeQ[p]

digits = IntegerDigits[p,2]   (* converting a number to binary in list form *)

digits = IntegerDigits[101,2] (* testing conversion on a smaller number *)

(* testing fast multiplication algorithm *)
(* shows how much faster this is than the brute force approach! *)
p = NextPrime[142989898]
exponent = 1086798990;
digits = IntegerDigits[exponent,2]
number = 131;
power = number;
length = Length[digits];
If[digits[[length]] == 0,answer = 1, answer = number];
For[n = 2, n ≤ Length[digits], n++,
{
power= Mod[power*power,p];
If[digits[[length+1-n]] > 0, answer = Mod[answer*power,p]];
}]
Print["We are computing ", number, "^", exponent, " modulo ", p, "."];
Print[answer]
Print[Mod[number^exponent,p]]

{1,0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,1,1,0,0,1,0,0,0,1,1,1,0}

(* fast multiplication code *)
(* input is our number, exponent, and modulus *)
fastmultiply[inputnumber_,inputexponent_,inputmodulus_] := Module[{},
modulus = inputmodulus;
exponent =inputexponent;
digits = IntegerDigits[exponent,2];
number = inputnumber;
power = number;
length = Length[digits];
If[digits[[length]] == 0,answer = 1, answer = number];
For[n = 2, n ≤ Length[digits], n++,
{
power= Mod[power*power,modulus];
If[digits[[length+1-n]] > 0, answer = Mod[answer*power,modulus]];
}];
Print[answer];
Return[answer];
(*Print[Mod[number^exponent,modulus]];*)
];

fastmultiply[Floor[RandomReal[] 10^200], NextPrime[RandomReal[] 10^200], Floor[RandomReal[] 10^200]];

Theory of how to find x and y such that ax + by = 1 if  a > b are relatively prime.

euclideanxy[a_,b_,modulus_] := Module[{},
qlist = {};
q[0] = Floor[a/b]; r[0] = a - b q[0];
rcurrent = r[0];
larger = b;
smaller = r[0];
qlist = AppendTo[qlist,q[0]];
n = 0;
matrixproduct = Mod[{{q[0],1},{1,0}},modulus];
While[rcurrent ≠ 0,
{
n = n+1;
q[n] = Floor[larger/smaller]; r[n] = larger - smaller*q[n];
qlist = AppendTo[qlist, q[n]];
larger = smaller;
smaller = r[n];
rcurrent = r[n];
matrixproduct = Mod[matrixproduct . {{q[n],1},{1,0}}, modulus];
}]; (* end of while loop *)
x = (-1)^(n+1) matrixproduct[[2,2]];
y = (-1)^n matrixproduct[[1,2]];
Print[x, "*", a, " + ", y, "*", b];
Print[x a + y b]; 
Return[y];
]

euclideanxy[(Prime[121]-1)(Prime[231]-1),2141,(Prime[121]-1)(Prime[231]-1)]

euclideanxy[2142,1711,10000000]

gcdcreator[primep_,primeq_] := Module[{},
check = 0;
While[check == 0,
{
e = RandomInteger[{3,(primep-1) * (primeq - 1)-1}];
If[GCD[e,primep-1] ==  1 && GCD[e,primeq-1] == 1,
{
d = euclideanxy[(primep-1) * (primeq - 1),e,(primep-1) * (primeq - 1)];
check = 1;
d = Mod[y,(primep-1) * (primeq - 1)];
}]; (* end of if loop *)
}]; (* end of While loop *)
Print["e = ", e, " and d = ", d, "."];
Print["ed mod (p-1)(q-1) = ", Mod[e d, (primep-1) * (primeq - 1)]];
]

gcdcreator[11,17]

gcdcreator[NextPrime[10^80],NextPrime[10^80 + 343343456675]]

gcdcreator[NextPrime[RandomReal[] 10^200],NextPrime[RandomReal[] 10^200]]

IMPLEMENTING RSA - GENERATING THE PUBLIC AND PRIVATE ITEMS

createRSA[numdigits_] := Module[{},
firstprime = NextPrime[RandomReal[] 10^numdigits];
secondprime = NextPrime[RandomReal[] 10^numdigits];
publicN = firstprime * secondprime;
phiofN = (firstprime - 1)*(secondprime - 1);
gcdcreator[firstprime,secondprime];
Print["PUBLIC"];
Print["N = pq = ", publicN];
Print["e = ", e];
Print[" "];
Print["PRIVATE"];
Print["p = ", firstprime];
Print["q = ", secondprime];
Print["d = ", d];
];

createRSA[200]

SEND MESSAGE

sendRSA[inputmessage_,inputN_,inpute_] := Module[{},
If[GCD[inputmessage,inputN] > 1, Print["COMMON FACTOR -- CANNOT SEND."],
{
Print["Message = ", inputmessage];
Print["Encrypted message is:"];
encryptedtext = fastmultiply[inputmessage,inpute,inputN];
Return[encryptedtext];
}]; (* end of if *)
]

sendRSA[RandomInteger[{1,publicN}],publicN,e]

DECRYPT MESSAGE

fastmultiply[encryptedtext,d,publicN];