def generate_elgamal_keypair(): """Return an ElGamal object with newly generated keypair""" if 'SFLVAULT_IN_TEST' in os.environ: print "WARNING: IN TEST MODE, EVERY KEYPAIR GENERATION IS BYPASSED AND USES A PRE-GENERATED AND WORLD-KNOWN KEYPAIR. REMOVE 'SFLVAULT_IN_TEST' FROM YOUR ENVIRONMENT IF YOU ARE DOING THIS ON PRODUCTION" eg = ElGamal.ElGamalobj() keys = [ (177089723724552644256797243527295142469255734138493329314329932362154457094059269514887621456192343485606008571733849784882603220703971587460034382850082611103881050702039214183956206957248098956098183898169452181835193285526486693996807247957663965314452283162788463761928354944430848933147875443419511844733534867714246125293090881680286010834371853006350372947758409794906981881841508329191534306452090259107460058479336274992461969572007575859837L, 2368830913657867259423174096782984007672147302922056255072161233714845396747550413964785336340342087070536608406864241095864284199288769810784864221075742905057068477336098276284927890562488210509136821440679916802167852789973929164278286140181738520594891315446533462206307248550944558426698389577513200698569512147125339722576147002382255876258436727504192479647579172625910816774587488928783787624267035610900290120258307919121453927670441700811482181614216947L, 5861471316007038922650757021308043193803646029154275389954930654765928019938681282006482343772842302607960473277926921384673235972813815577111985557701858831111694263179407993690846841997398288866685890418702914928188654979371728552059661796422031090374692580710906447170464105162673344042938184790777466702148445760745296149876416417949678454708511011740073066144877868339403040477747772225977519821312965207L, 1169412825199936698700035513185825593893938895474876750007859746409857305379860678064015124546593449912724002752383066585681624318254362438491372548721947497497739043831382430104856590871057670575051579668363576657397472353061812950884556034822611307705562237354213497368218843244103113882159981178841442771150519161251285978446459307942619668439466357674240712609844734284943761543870187004331653216116937988266963743961096619840352159665738163357566198583064435L ), (363126185715790250119395282425017818083421673278440118808474954552806007436370887232958142538070938460903011757636551318850215594111019699633958587914824512339681573953775134121488999147928038505883131989323638021781157246124428000084118138446325126739005521403114471077697023469488488105229388102971903306007555362613775010306064798678761753948810755236011346132218974049446116094394433461746597812371697367173395113014824646850943586174124632464143L, 1989666736598081965365973787349938627625613245335951894925228395719349924579514682166704542464221001327015131231101009506582078440087637470784673000661958376397578391397303146171320274531265903747455382524598808613766406694744319576824028880703970997080651320662468590292703565426391011134523391035995750230341849776175803186815053305823053143914398318121693692044542134832809759905437953710838534372887584358442203447387293183908262967797038874535690090799742911L, 133850088107174975861015682594827971956767368440585898108600141692889215241539178575381178799995195531301157505453120993980045956642227472649664668888717884598815932243844750408878011387532720932159839454554017574665882963054750224693505390054364096154711586190837517112644639757613967217614109546151313073865262488626822109764294618345504453742784825659007630866924661811701179640013729327586347L, 742665583685283032188129474839034185107068199926583417281240975739235100098517297493350864258177674271267050862217567671938790648634008735784684115797768392310253433978502694449565453913758801583487678024491118014887051643096970952295790434950566748516670079663712282848262006606082748685002561868381598918739708181310245226480020229450553192469536632519293406262550081671717685585065331112633947328611250435010734072352883491446355872734313855711051794348490960L ) ] eg.g, eg.p, eg.x, eg.y = keys[random.randint(0, 1)] return eg # Otherwise, generate, really :) return ElGamal.generate(1536, randfunc)
def __ElGamal_generate(self, bits, randfunc): """Randomly generate a new ElGamal key but with pre-computed group. Based on public domain code from PyCrypto - ElGamal.py : ElGamal encryption/decryption and signatures - Part of the Python Cryptography Toolkit - Originally written by: A.M. Kuchling The key will be safe for use for both encryption and signature (although it should be used for **only one** purpose). :Parameters: bits : int Key length, or size (in bits) of the modulus *p*. Recommended value is 2048. randfunc : callable Random number generation function; it should accept a single integer N and return a string of random data N bytes long. :attention: You should always use a cryptographically secure random number generator, such as the one defined in the ``Crypto.Random`` module; **don't** just use the current time and the ``random`` module. :Return: An ElGamal key object (`ElGamalobj`). """ # Creating ElGamal keys is slow, especially with PyCrypto. The # key-generation is done over a cyclic group created based on a safe # prime. # A safe prime is a prime `p` of the form `p = 2*q + 1` where `q` is # *also* a prime; computing this can be as slow as taking ~3-5 minutes # for a 2048-bit number and upwards of an hour for a 4096-bit number. # However, we can pre-compute the prime `p` for common key-lengths # and use that instead, without impacting security of the scheme. obj = ElGamal.ElGamalobj() # Generate a safe prime p # See Algorithm 4.86 in Handbook of Applied Cryptography ## if using some commonly used key-lengths, use a pre-computed p if bits in self.__safe_primes: obj.p = int(self.__safe_primes[bits], 16) q = (obj.p - 1) // 2 else: # no-precomputed value available. Default to creating new prime # XXX This is very slow for large key-sizes. while 1: q = bignum(getPrime(bits - 1, randfunc)) obj.p = 2 * q + 1 if number.isPrime(obj.p, randfunc=randfunc): break # Generate generator g # See Algorithm 4.80 in Handbook of Applied Cryptography # Note that the order of the group is n=p-1=2q, where q is prime while 1: # We must avoid g=2 because of Bleichenbacher's attack described # in "Generating ElGamal signatures without knowning the secret key", # 1996 # obj.g = number.getRandomRange(3, obj.p, randfunc) safe = 1 if pow(obj.g, 2, obj.p) == 1: safe = 0 if safe and pow(obj.g, q, obj.p) == 1: safe = 0 # Discard g if it divides p-1 because of the attack described # in Note 11.67 (iii) in HAC if safe and divmod(obj.p - 1, obj.g)[1] == 0: safe = 0 # g^{-1} must not divide p-1 because of Khadir's attack # described in "Conditions of the generator for forging ElGamal # signature", 2011 ginv = number.inverse(obj.g, obj.p) if safe and divmod(obj.p - 1, ginv)[1] == 0: safe = 0 if safe: break # Generate private key x obj.x = number.getRandomRange(2, obj.p - 1, randfunc) # Generate public key y obj.y = pow(obj.g, obj.x, obj.p) return obj
def elgamal(self): """Return the ElGamal object, ready to encrypt stuff.""" e = ElGamal.ElGamalobj() (e.p, e.g, e.y) = unserial_elgamal_pubkey(self.pubkey) return e