# This is an implementation of modexp function. This should # work even once we promote ourself :-). Knuth's Algorithm A, # from p462 of latest edition of Seminumerical Algorithms. # (Actually al-Kashi's method from A.D. 1427). module Crypto_math def mod_exp(n,q) counter=0 n_p=n.clone # N y_p=1 # Y z_p=self.clone # Z while n_p != 0 # if N is odd, multiply Y * Z # Whoa, we can access the bits of our integer as if they were # an array! But will this work on big-endian machines? if n_p[0]==1 y_p=(y_p*z_p) % q end # divide n_p by 2. Whoa, shifts! n_p = n_p >> 1 # and square Z. z_p = (z_p * z_p) % q counter += 1 end return y_p end # define a random number of size . is a number of bytes, # *NOT* a # of bits! This will need to be modified to # work on anything other than Unix, because it uses /dev/urandom. If you # are on a Unix without a dev/urandom, such as Solaris, use # Ocotillo (http://ocotillo.sourceforge.net) as your PRNG. def random() n=self.clone fh=open("/dev/urandom","r") if (!fh) fh=open("/dev/orandom","r") # optional place. Used on OpenBSD? end if (!fh) raise "NO RANDOM DEVICE" end i=0 s=fh.read(n) # fancy iterator stuff w/Ruby: # n times go thru the loop, assigning then-extant value of n to j: n.times { |j| i = i << 8 i = i | s[j] # yep, a 1 char slice in an integer context is guess what? } fh.close() return i end end class Bignum include Crypto_math end class Integer include Crypto_math end def test2 a=2 while ! a.prime? a=128.random end end # This is a function which uses a known good x, prime, and modulus and # calculates the Diffie-Hellman public key X. It then compares that to # the known result (verified using GNU 'dc') of that computation. def modexp_test xx = 49117580844089262911901355287841171890576818657783650753208599277090946608629052545518247108642827866451823318941178603034571795108477894778537021991948831723834734775338379867275461698639906953156054434705292259216951056048592911855948753912610254573728484318415808276565668885865182466683752111480091234494 xx_p = 30158485397977097914735031672721612436752995275618102225850571305439073652645575546335570053366437128295206695951378422564597822594563680088505296658477187110003231072414234938371090319047261957332420471075050710901794412840771927620865592590749106381943024352923477346561065087247748578874293152671594497151 field=106711310550942323238863446954494903303206603796265590798875260590060843568007841918927773348877395895791048832517368787533445258799160241834659776192282820736018472427221910874308833884006430888272214561307777629540843737689598751552666502301405808925850579645658786877473119117134988654123934303586903124139 #result=xx.mod_exp(2,field) result=2.mod_exp(xx,field) print "\n XX=#{xx_p}\n\nresult=#{result}\n" print "\nRandom number test: 2.random, 5 times:\n #{2.random},#{2.random},#{2.random},#{2.random},#{2.random}\n" end