The Modulus (n) must be greater than 2256.
This number represented in decimal is very large. 90 odd decimal digits !
2^256 == 115792089237316195423570985008687907853269984665640564039457584007913129639936
Compared to the numbers generated by raising large numbers to large exponents, though, 2256 seems quite trivial.
The RSA encryption algorithms are based on taking large numbers to the power of a key value, and then applying the modulus of that result with a large pre-calculated value (n) based on a prime number multiplication.For instance 2256 to the power of a 6 digit key (say 5,000,000) produces a number of approximately 385,318,394 digits !
Obviously, such large intermediate results are impractical. For the purpose of this tool, intermediate values with up to 100,000 digits are shown (and can be dealt with directly using the unix bc utility ).
An effective way to break this problem down is to use results from residue theory . From residue theory we can state that where d is even:
calc_residue ( bigint c, bigint d, bigint n ) { if ( d == 1 ) return ( c ^ d % n ); return calc_residue ( c^2, d/2, n ) % n; # recursion }
Thus 'c' to the power of 323, could be written as (where ^ means to the power of, as in c and bc scripts)
or written as
In this form it is easy to see that any exponent can be broken down into powers of two for processing by the calc_residues algorithm.
The following pseudo code takes the variable d, and breaks it down into into its integer power of 2 parts.
break_down_into_powers_of_two ( bigint d ) { integer i = 0; # find biggest power of 2 left in exponentiation # while(d >= (2^i)) { i = i+1; } # subtract highest power of 2 possible from d # d = (d - (2^(i-1))); PRINT (2^(i-1)); if (d>0) { # d is greater than 0 so we need to break this down further # break_down_into_powers_of_two(d); # recurse with new d value return (2^(i-1)); } if (d == 0) { # d is 0, we have found the last power of 2 required # return (2^(i-1); } }
# bc program. Call with -q parameter # R.P. Clark 10APR2004 # recursive routine to calculate c^d%n # by breaking it down. Works only where # d is a power of 2. # define x ( c,d,n) { if ( d == 1 ) return (c^d%n); return x(c^2,d/2,n)%n; } r = 1; # recursive routine to break d into powers of 2 # and then to collect multiply the results # of the 2^n exponents. # define t(c,d,n) { auto i i = 0; # find biggest power of 2 left in exponentiation # while(d >= (2^i)) { i = i+1; } # subtract from exponent # d = (d - (2^(i-1))); if (d>0) { r=(r*x(c,2^(i-1),n))%n; # calculate this large exponentiation t(c,d,n); # recursion with new d value return (2^(i-1)); } if (d == 0) { r = (r*x(c,2^(i-1),n))%n; # last one return (2^(i-1)); } }
Thus the function t(c,d,n), will break down the exponent, and pass it on as powers of 2, to calculate the residues using the 'x' function. Thus very large exponentiation and mod equations,will be calculated without having to handle incredibly large intermediate results.
Some results, of timings for the equation 21255511266511%999999 run on a 1 Ghz Celeron laptop (Redhat 8.0 : bc version 1.06). Note that larger numbers than this in the exponent are rejected by bc.To see how large 21255511266511 is, a text file containing it is included here .
[robin@localhost bc]$ date; bc < calc_big_expon.bc | tail -1; date Sun Apr 11 17:21:10 BST 2004 407926 Sun Apr 11 17:26:37 BST 2004 [robin@localhost bc]$ date ; echo "21255511^266511%999999" | bc ; date Sun Apr 11 17:36:13 BST 2004 407926 Sun Apr 11 17:43:29 BST 2004 [robin@localhost bc]$ bc -v bc 1.06Thus the recursive algorithm is faster, and large exponents are not rejected.