import sys import hashlib # for a PRNG, SHA-1 is standard and sufficiently secure def hash(seed): h = hashlib.sha1(); h.update(seed); return h.digest() seedbytes = 20 # 160-bit size for seed, determined by SHA-1 output size 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 update(seed): # add 1 to seed, viewed as integer return int2str(str2int(seed) + 1,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) sizes = [160,192,224,256,320,384,512] S = real2str(pi/16,len(sizes)*seedbytes) primeseeds = [S[i:i+seedbytes] for i in range(0,len(S),seedbytes)] S = real2str(exp(1)/16,len(sizes)*seedbytes) curveseeds = [S[i:i+seedbytes] for i in range(0,len(S),seedbytes)] for j in range(len(sizes)): L,S = sizes[j],primeseeds[j] v = (L-1)//160 def fullhash(seed,bits): h = hash(seed) for i in range(v): seed = update(seed); h += hash(seed) return str2int(h) % 2^bits while True: p = fullhash(S,L) while not (p % 4 == 3 and p.is_prime()): p += 1 if 2^(L-1) - 1 < p and p < 2^L: break S = update(S) k = GF(p) R. = k[] def secure(A,B): E = EllipticCurve([k(A),k(B)]) for q in [2,3,5,7]: # quick check whether q divides n, without computing n for r,e in E.division_polynomial(q).roots(): if E.is_x_coord(r): return False n = E.cardinality() return (n < p and n.is_prime() and Integers(n)(p).multiplicative_order() * 100 >= n-1) S = curveseeds[j] while True: A = fullhash(S,L-1) if not (k(A)*x^4+3).roots(): S = update(S); continue while True: S = update(S) B = fullhash(S,L-1) if not k(B).is_square(): break if not secure(A,B): S = update(S); continue print 'p',hex(p).upper() print 'A',hex(A).upper() print 'B',hex(B).upper() sys.stdout.flush() break # output: # p E95E4A5F737059DC60DFC7AD95B3D8139515620F # A 340E7BE2A280EB74E2BE61BADA745D97E8F7C300 # B 1E589A8595423412134FAA2DBDEC95C8D8675E58 # p C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297 # A 6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF # B 469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9 # p D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF # A 68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43 # B 2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B # p A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377 # A 7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9 # B 26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6 # p D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27 # A 3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4 # B 520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6 # p 8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53 # A 7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826 # B 4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11 # p AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3 # A 7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA # B 3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723