next up previous contents
Next: A Connection Between Breaking Up: Examples Previous: A Small Example   Contents

A Bigger Example in PARI

? p=nextprime(random(10^30))
%3 = 738873402423833494183027176953
? q=nextprime(random(10^25))
%4 = 3787776806865662882378273
? n=p*q
%5 = 2798687536910915970127263606347911460948554197853542169
? e=random(n)
%6 = 1483959194866204179348536010284716655442139024915720699
? phin=(p-1)*(q-1)
%7 = 2798687536910915970127262867470721260308194351943986944
? while(gcd(e,phin)!=1,e=e+1)
? e
%8 = 1483959194866204179348536010284716655442139024915720699
? d = lift(Mod(e,phin)^(-1));
%9 = 2113367928496305469541348387088632973457802358781610803
? (e*d)%phin
%10 = 1
? log(n)/log(27)
%11 = 38.03851667699197952338510248
We can encode single blocks of up to 38 letters. Let's encode ``HARVARD'':
? m=8+27*1+27^2*18+27^3*22+27^4*1+27^5*18+27^6*4
%12 = 1808939906
? E(x)=lift(Mod(x,n)^e)
? D(x)=lift(Mod(x,n)^d)
? secret_message = E(m)
%14 = 625425724974078486559370130768554070421628674916144724
? D(secret_message)
%15 = 1808939906

The following complete PARI program automates the whole process, though it is a little clumsy. Call this file rsa.gp. It uses { and } so that functions can be extended over more than one line.

/* rsa.gp ------------------------------------------------ */
{alphabet=[" ","A","B","C","D","E","F","G","H","I","J","K","L","M",
           "N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
}
{letter_to_number(l, 
     n)=
     for(n=1,27,if(alphabet[n]==l,return(n-1))); 
     error("invalid input.")
}
{number_to_message(n,    
     s="")= 
     while(n>0, s = concat(s,alphabet[n%27+1]); n = n \ 27); 
     return(s)
}
{message_to_number(w,     
     i,n=0)=
     for(i=1,length(w), n = n + 27^(i-1)*letter_to_number(w[i]));
     return(n);
}
{make_rsa_key(len,  
     p,q,n,e,d)=
     p = nextprime(random(10^(len/2)));
     q = nextprime(random(10^(len/2+3)));
     n = p*q; phin = (p-1)*(q-1);
     e = random(phin);
     while(gcd(e,phin)!=1,e=e+1);
     d = lift(Mod(e,phin)^(-1));
     return([n,e,d]);
}
encrypt(message, n, e) = lift(Mod(message_to_number(message),n)^e);
decrypt(secret, n, d)  = number_to_message(lift(Mod(secret,n)^d));
/* rsa.gp ------------------------------------------------ */

Here is an example that uses the above little program.

? \r rsa
? setrand(1)   \\ default random number seed is 1!
? rsa=make_rsa_key(20)   \\ returns [n, e, d]
%2 = [89050154117716728145939, 33735260657253161660951, 
      49244741969289756040079]
? n = rsa[1]; e = rsa[2]; d = rsa[3]; 
? public_key = [n,e]
%3 = [89050154117716728145939, 33735260657253161660951]
? msg = ["H", "A", "R", "V", "A", "R", "D"];   \\ clumsy!!!
? secret = encrypt(msg,n,e)
%36 = 75524965161901413275866
? decrypt(secret, n, d)
%37 = "HARVARD"



William A Stein 2001-10-01