import simplesha3 hash = simplesha3.sha3512 # SHA-3 standard at maximum security level p = 2^224 - 2^96 + 1 # standard NIST P-224 prime k = GF(p) seedbytes = 20 # standard 160-bit size for seed def secure(A,B): E = EllipticCurve([k(A),k(B)]) E2 = E.quadratic_twist() for q in [2,3,5,7]: # quick check whether q divides n or 2*p+2-n, without computing n for r,e in E.division_polynomial(q).roots(): if E.is_x_coord(r): return False for r,e in E2.division_polynomial(q).roots(): if E2.is_x_coord(r): return False n = E.cardinality() return (n.is_prime() and (2*p+2-n).is_prime() and Integers(n)(p).multiplicative_order() * 100 >= n-1 and Integers(2*p+2-n)(p).multiplicative_order() * 100 >= 2*p+2-n-1) def int2str(seed,bytes): # standard big-endian encoding of integer seed return ''.join([chr((seed//256^i)%256) for i in reversed(range(bytes))]) def str2int(seed): return Integer(seed.encode('hex'),16) def complement(seed): # change all bits, eliminating Brainpool-type collisions return ''.join([chr(255-ord(s)) for s in seed]) def real2str(seed,bytes): # most significant bits of real number between 0 and 1 return int2str(Integer(RealField(8*bytes)(seed)*256^bytes),bytes) sizeofint = 4 # number of bytes in a 32-bit integer nums = real2str(cos(1),seedbytes - sizeofint) for counter in xrange(0,256^sizeofint): S = int2str(counter,sizeofint) + nums T = complement(S) A = str2int(hash(S)) B = str2int(hash(T)) if secure(A,B): print 'p',hex(p).upper() print 'A',hex(A).upper() print 'B',hex(B).upper() break # output: # p FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001 # A 7144BA12CE8A0C3BEFA053EDBADA555A42391FC64F052376E041C7D4AF23195EBD8D83625321D452E8A0C3BB0A048A26115704E45DCEB346A9F4BD9741D14D49 # B 5C32EC7FC48CE1802D9B70DBC3FA574EAF015FCE4E99B43EBE3468D6EFB2276BA3669AFF6FFC0F4C6AE4AE2E5D74C3C0AF97DCE17147688DDA89E734B56944A2