1+ import os
2+ import random
3+ import sys
4+ import rabin_miller as rabinMiller , cryptomath_module as cryptoMath
5+
6+ min_primitive_root = 3
7+
8+
9+ def main ():
10+ print ('Making key files...' )
11+ makeKeyFiles ('elgamal' , 2048 )
12+ print ('Key files generation successful' )
13+
14+
15+ # I have written my code naively same as definition of primitive root
16+ # however every time I run this program, memory exceeded...
17+ # so I used 4.80 Algorithm in Handbook of Applied Cryptography(CRC Press, ISBN : 0-8493-8523-7, October 1996)
18+ # and it seems to run nicely!
19+ def primitiveRoot (p_val ):
20+ print ("Generating primitive root of p" )
21+ while True :
22+ g = random .randrange (3 ,p_val )
23+ if pow (g , 2 , p_val ) == 1 :
24+ continue
25+ if pow (g , p_val , p_val ) == 1 :
26+ continue
27+ return g
28+
29+
30+ def generateKey (keySize ):
31+ print ('Generating prime p...' )
32+ p = rabinMiller .generateLargePrime (keySize ) # select large prime number.
33+ e_1 = primitiveRoot (p ) # one primitive root on modulo p.
34+ d = random .randrange (3 , p ) # private_key -> have to be greater than 2 for safety.
35+ e_2 = cryptoMath .findModInverse (pow (e_1 , d , p ), p )
36+
37+ publicKey = (keySize , e_1 , e_2 , p )
38+ privateKey = (keySize , d )
39+
40+ return publicKey , privateKey
41+
42+
43+ def makeKeyFiles (name , keySize ):
44+ if os .path .exists ('%s_pubkey.txt' % name ) or os .path .exists ('%s_privkey.txt' % name ):
45+ print ('\n WARNING:' )
46+ print ('"%s_pubkey.txt" or "%s_privkey.txt" already exists. \n '
47+ 'Use a different name or delete these files and re-run this program.' %
48+ (name , name ))
49+ sys .exit ()
50+
51+ publicKey , privateKey = generateKey (keySize )
52+ print ('\n Writing public key to file %s_pubkey.txt...' % name )
53+ with open ('%s_pubkey.txt' % name , 'w' ) as fo :
54+ fo .write ('%d,%d,%d,%d' % (publicKey [0 ], publicKey [1 ], publicKey [2 ], publicKey [3 ]))
55+
56+ print ('Writing private key to file %s_privkey.txt...' % name )
57+ with open ('%s_privkey.txt' % name , 'w' ) as fo :
58+ fo .write ('%d,%d' % (privateKey [0 ], privateKey [1 ]))
59+
60+
61+ if __name__ == '__main__' :
62+ main ()
63+
0 commit comments