import simplesha3 # Keccak, the SHA-3 winner hash = simplesha3.keccakc1024 # maximum security level: 512-bit output seedbytes = 64 # maximum-security 512-bit seed, same size as output p = 2^224 - 2^96 + 1 # standard NIST P-224 prime k = GF(p) def secure(A,B): n = EllipticCurve([k(A),k(B)]).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 little-endian encoding of integer seed return ''.join([chr((seed//256^i)%256) for i in range(bytes)]) def str2int(seed): return sum([ord(seed[i])*256^i for i in range(len(seed))]) def rotate(seed): # rotate seed by 1 bit, eliminating Brainpool-like collisions x = str2int(seed) x = 2*x + (x >> (8*len(seed)-1)) return int2str(x,len(seed)) def real2str(seed,bytes): # most significant bits of real number between 0 and 1 return int2str(Integer(floor(RealField(8*bytes+8)(seed)*256^bytes)),bytes) counterbytes = 3 # minimum number of bytes needed to guarantee success nums = real2str(exp(1)/4,seedbytes - counterbytes) for counter in xrange(0,256^counterbytes): S = int2str(counter,counterbytes) + nums R = rotate(S) A = str2int(hash(R)) B = str2int(hash(S)) if secure(A,B): print 'p',hex(p).upper() print 'A',hex(A).upper() print 'B',hex(B).upper() break # output: # p FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001 # A 8F0FF20E1E3CF4905D492E04110683948BFC236790BBB59E6E6B33F24F348ED2E16C64EE79F9FD27E9A367FF6415B41189E4FB6BADA555455DC44C4F87011EEF # B E85067A95547E30661C854A43ED80F36289043FFC73DA78A97E37FB96A2717009088656B948865A660FF3959330D8A1CA1E4DE31B7B7D496A4CDE555E57D05C