def bench_classgroup(): D = create_discriminant(b"seed", 512) g = ClassGroup.from_ab_discriminant(2, 1, D) while g[0].bit_length() < g[2].bit_length() or g[1].bit_length( ) < g[2].bit_length(): g = pow(g, 2) g2 = pow(g, 2) start_bench() for _ in range(0, 10000): g2 = g2.multiply(g) end_bench("Classgroup 512 bit multiply", 10000) start_bench() for _ in range(0, 10000): g2 = g2.square() end_bench("Classgroup 512 bit square", 10000) D = create_discriminant(b"seed", 1024) g = ClassGroup.from_ab_discriminant(2, 1, D) while g[0].bit_length() < g[2].bit_length() or g[1].bit_length( ) < g[2].bit_length(): g = pow(g, 2) g2 = pow(g, 2) start_bench() for _ in range(0, 10000): g2 = g2.multiply(g) end_bench("Classgroup 1024 bit multiply", 10000) start_bench() for _ in range(0, 10000): g2 = g2.square() end_bench("Classgroup 1024 bit square", 10000) D = create_discriminant(b"seed", 2048) g = ClassGroup.from_ab_discriminant(2, 1, D) while g[0].bit_length() < g[2].bit_length() or g[1].bit_length( ) < g[2].bit_length(): g = pow(g, 2) g2 = pow(g, 2) start_bench() for _ in range(0, 10000): g2 = g2.multiply(g) end_bench("Classgroup 2048 bit multiply", 10000) start_bench() for _ in range(0, 10000): g2 = g2.square() end_bench("Classgroup 2048 bit square", 10000)
def bench_pietrzak(): iterations = 10000 discriminant_length = 512 discriminant = create_discriminant(b"seed", discriminant_length) delta = 8 x = ClassGroup.from_ab_discriminant(2, 1, discriminant) powers_to_calculate = proof_pietrzak.cache_indeces_for_count(iterations) start_t = time.time() * time_multiplier powers = iterate_squarings(x, powers_to_calculate) vdf_time = round(time.time() * time_multiplier - start_t) y = powers[iterations] identity = ClassGroup.identity_for_discriminant(discriminant) start_t = time.time() * time_multiplier start_bench() for _ in range(5): proof = proof_pietrzak.generate_proof(x, iterations, delta, y, powers, identity, generate_r_value, discriminant_length) end_bench( "Pietrzak " + str(discriminant_length) + "b class group, " + str(iterations) + " iterations, proof", 10) proof_time = round((time.time() * time_multiplier - start_t) / 10) print(" - Percentage of VDF time:", (proof_time / vdf_time) * 100, "%") start_bench() for _ in range(10): assert (proof_pietrzak.verify_proof(x, y, proof, iterations, delta, generate_r_value, discriminant_length)) end_bench( "Pietrzak " + str(discriminant_length) + "b class group, " + str(iterations) + " iterations, verification", 10)
def print_entry(length): for i in range(3): seed = int.to_bytes(i, 4, 'big') d = create_discriminant(seed, length) g = ClassGroup.from_ab_discriminant(2, 1, d) order = compute_order(g) c = (1 - d) // (4 * 2) print('%s %i %i %i %i %i' % (b2a_hex(seed).decode('latin-1'), length, 2, 1, c, order))
def test_known_prime_bar(self): prime_bar = -int( "0xac8e36c9233c59b94a7d340a90b15533064db1cb8de6e083c3128d8d091ca9eb01fb" "ce233d5eb801f71d98a480b413c943d84e9f36ad2ced7928a7288db0d60db14e7a9cbd" "53515476344b42bfa2e0d9a35f9cfb6a7a66ba0ebab829b6a71fabf1b202878fed608f" "7d6241c27f7efc11b485df7e0b4955404d9be05cf7eaa50d1cd11c170a99767ad5ad63" "f6e30fa8e3b3d88a03364a9c403e0609e74f15888d9d91ec9aef5bd2bcab90063eb0d6" "001e61a0c374c8d2626ffab951048573ea15da531c4dacf2218139715414cf5828dd10" "1b23c01fbafffde1f109780d123673f8b23e41495fa8bbb5b36f39f8d9693835036445" "075fbb770554a352f0dc91d7", 16 ) v = create_discriminant(b"bar", 2048) self.assertEqual(v, prime_bar)
def test_known_prime_foo(self): prime_foo = -int( "0xe5410e122e8cb95583522f57ec7b807177ff1dc53a7ac5c1fa8c3ee63a8a7298e019" "4e2048fd130bcebab490427195559a16b67640075770dd27d9fe5d6f9a27c186c3d161" "cb277d4f68ce6dc801355b44b472eb39902b7fd717da6e0b43ef9ae64bc49055a21cec" "72076359d2d9d754f1bfbb29070ed0cccdb04d8b4622148ad90b3e0779ecfef5f2b299" "b039f8e744a99322afef1de7df4dc7165c464a989e103ec27888ca883095bcffe9f6f4" "88d790488b98e2d7ccbeb081de5dd3a26be509cf58d632861671195e7daf29ebf81a13" "59a66f22c7a9ecd96a693889177be471298d33bb031d0643b591611ac4b20c12858c35" "1fa8d29057c8cca878c449d7", 16 ) v = create_discriminant(b"foo", 2048) self.assertEqual(v, prime_foo)
def bench_discriminant_generation(): start_bench() for i in range(100): create_discriminant(i.to_bytes(32, "big"), 512) end_bench("Generate 512 bit discriminant", 100) start_bench() for i in range(100): create_discriminant(i.to_bytes(32, "big"), 1024) end_bench("Generate 1024 bit discriminant", 100) start_bench() for i in range(100): create_discriminant(i.to_bytes(32, "big"), 2048) end_bench("Generate 2048 bit discriminant", 100)
def bench_nwesolowski(): iterations = 10000 discriminant_length = 512 discriminant = create_discriminant(b"seed", discriminant_length) L, k, _ = proof_wesolowski.approximate_parameters(iterations) x = ClassGroup.from_ab_discriminant(2, 1, discriminant) powers_to_calculate = [ i * k * L for i in range(0, math.ceil(iterations / (k * L)) + 1) ] start_t = time.time() * time_multiplier for _ in range(20): iterate_squarings(x, powers_to_calculate) vdf_time = round(time.time() * time_multiplier - start_t) / 20 start_t = time.time() * time_multiplier start_bench() for _ in range(20): result, proof = create_proof_of_time_nwesolowski(discriminant, x, iterations, discriminant_length, 2, depth=0) end_bench( "n-wesolowski depth 2 " + str(discriminant_length) + "b class group, " + str(iterations) + " iterations, proof", 20) proof_time = round((time.time() * time_multiplier - start_t) / 20) print(" - Percentage of VDF time:", (((proof_time - vdf_time) / vdf_time) * 100), "%") start_bench() for _ in range(20): assert (check_proof_of_time_nwesolowski(discriminant, x, result + proof, iterations, discriminant_length)) end_bench( "n-wesolowski depth 2 " + str(discriminant_length) + "b class group, " + str(iterations) + " iterations, verification", 20)
def bench_wesolowski(): iterations = 10000 discriminant_length = 512 discriminant = create_discriminant(b"seed", discriminant_length) L, k, _ = proof_wesolowski.approximate_parameters(iterations) x = ClassGroup.from_ab_discriminant(2, 1, discriminant) powers_to_calculate = [ i * k * L for i in range(0, math.ceil(iterations / (k * L)) + 1) ] powers_to_calculate += [iterations] start_t = time.time() * time_multiplier powers = iterate_squarings(x, powers_to_calculate) vdf_time = round(time.time() * time_multiplier - start_t) y = powers[iterations] identity = ClassGroup.identity_for_discriminant(discriminant) start_t = time.time() * time_multiplier start_bench() for _ in range(5): proof = proof_wesolowski.generate_proof(identity, x, y, iterations, k, L, powers) end_bench( "Wesolowski " + str(discriminant_length) + "b class group, " + str(iterations) + " iterations, proof", 5) proof_time = round((time.time() * time_multiplier - start_t) / 5) print(" - Percentage of VDF time:", (proof_time / vdf_time) * 100, "%") start_bench() for _ in range(10): assert (proof_wesolowski.verify_proof(x, y, proof, iterations)) end_bench( "Wesolowski " + str(discriminant_length) + "b class group, " + str(iterations) + " iterations, verification", 10)
def judge_entry(mystr): assert len(mystr) < 100000 lines = mystr.strip().split(b'\n') assert len(lines) == 3 ds = set() for line in lines: # File format: # challenge(in hex) length a b c order vals = [x.strip() for x in line.strip().split(b' ')] assert len(vals) == 6 length = int(vals[1]) assert length < 5000 assert all(len(x) < length for x in vals[2:]) assert len(vals[0]) <= 32 d = create_discriminant(a2b_hex(vals[0]), length) g = ClassGroup(int(vals[2]), int(vals[3]), int(vals[4])) assert g.discriminant() == d assert g != g.identity() order = int(vals[5]) assert order > 1 assert g**order == g.identity() assert d not in ds ds.add(d) return -max(ds)
def bench_vdf_iterations(): D = create_discriminant(b"seed", 512) g = ClassGroup.from_ab_discriminant(2, 1, D) start_bench() for _ in range(10): iterate_squarings(g, [10000]) end_bench("VDF 10000 iterations, 512bit classgroup", 10) D = create_discriminant(b"seed", 1024) g = ClassGroup.from_ab_discriminant(2, 1, D) start_bench() for _ in range(2): iterate_squarings(g, [10000]) end_bench("VDF 10000 iterations, 1024bit classgroup", 2) D = create_discriminant(b"seed", 2048) g = ClassGroup.from_ab_discriminant(2, 1, D) start_bench() for _ in range(2): iterate_squarings(g, [10000]) end_bench("VDF 10000 iterations, 2048bit classgroup", 2) # 2048 bit modulus prime = int(''.join( textwrap.dedent(""" 2634427397878110232503205795695468045251992992603340168049253044454387 1080897872360133472596339100961569230393163880927301060812730934043766 3646941725034559080490451986171041751558689035115943134790395616490035 9846986660803055891526943083539429058955074960014718229954545667371414 8029627597753998530121193913181474174423003742206534823264658175666814 0135440982296559552013264268674093709650866928458407571602481922443634 2306826340229149641664159565679297958087282612514993965471602016939198 7906354607787482381087158402527243744342654041944357821920600344804411 149211019651477131981627171025001255607692340155184929729""").split( "\n"))) initial_x = int_mod_n( 15619920774592561628351138998371642294622340518469892832433140464182509560910157, prime) start_bench() for _ in range(2): iterate_squarings(initial_x, [10000]) end_bench("VDF 10000 iterations, 2048bit RSA modulus", 2) # 4096 bit modulus prime = int(''.join( textwrap.dedent(""" 8466908771297228398108729385413406312941234872779790501232479567685076 4762372651919166693555570188656362906279057098994287649807661604067499 3053172889374223358861501556862285892231110003666671700028271837785598 2711897721600334848186874197010418494909265899320941516493102418008649 1453168421248338831347183727052419170386543046753155080120058844782449 2367606252473029574371603403502901208633055707823115620627698680602710 8443465519855901353485395338769455628849759950055397510380800451786140 7656499749760023191493764704430968335226478156774628814806959050849093 5035645687560103462845054697907307302184358040130405297282437884344166 7188530230135000709764482573583664708281017375197388209508666190855611 3020636147999796942848529907410787587958203267319164458728792653638371 7065019972034334447374200594285558460255762459285837794285154075321806 4811493971019446075650166775528463987738853022894781860563097254152754 1001763544907553312158598519824602240430350073539728131177239628816329 0179188493240741373702361870220590386302554494325819514615309801491107 2710093592877658471507118356670261129465668437063636041245619411937902 0658733974883998301959084381087966405508661151837877497650143949507846 1522640311670422105209760172585337397687461""").split("\n"))) initial_x = int_mod_n( 15619920774592561628351138998371642294622340518469892832433140464182509560910157, prime) start_bench() for _ in range(2): iterate_squarings(initial_x, [10000]) end_bench("VDF 10000 iterations, 4096bit RSA modulus", 2)
def print_entry(length): for i in range(3): seed = int.to_bytes(best_seeds[i], 4, 'big') d = create_discriminant(seed, length) print('%i' % (d))
from inkfish.create_discriminant import create_discriminant import hashlib import sys # This is the script that will get used to generate the # classgroup discriminants for the competition. The secret # seed will be revealed only after the deadline for # submissions. Here you can verify that commitment matches # the secret, once the secret is released. number_of_discriminants = 10 discriminant_bit_size = 2048 secret_seed_commitment = "4cacd6cf4ba40015815b37755342bd0dcce4016b61ae3d3c3c0eecbc9d4c9f8a" if __name__ == '__main__': # Checks that the commitment is valid, given an input secret seed # passed in from the command line. The secret seed will be released # at the end of the competition. seed = str.encode(sys.argv[1], "latin-1") hash_of_secret = hashlib.sha256(seed).digest() assert(hash_of_secret.hex() == secret_seed_commitment) # Generates the discriminants for i in range(10): print(create_discriminant(seed + bytes([i]), 2048))
def disc_from_seed(i): sd = int.to_bytes(seed + i, 4, 'big') return create_discriminant(sd, length)
all_candidates.sort() good_candidates = [all_candidates[x][1] for x in range(len(all_candidates))] # Round two: For top 10% promising candidate, use more primes to get a more accurate # approximation of the order, then we'll select top 3. all_candidates = [] for i in range(max(num_candidates // 10, 3)): d = disc_from_seed(good_candidates[i]) all_candidates.append( (find_approx_order_from_cpp(-d, max_prime_in_search), good_candidates[i])) all_candidates.sort() good_candidates = [all_candidates[x][1] for x in range(len(all_candidates))] # print time taken in phase one (refer to the pdf writeup). Choose parameters in a way such that # this is small compared to the other phases in following sections. print('exploration_time: ', time.time() - exploration_time) for i in range(num_disc): sd = int.to_bytes(seed + good_candidates[i], 4, 'big') d = create_discriminant(sd, length) od = find_order_from_cpp(-d) f.write('%s %i %i %i %i %i\n' % (b2a_hex(sd).decode('latin-1'), length, 2, 1, (-d + 1) // 8, od)) # These are time taken in phase 2, 3, 4 (refer to the pdf writeup). # Choose parameters in such a way that these times are approximately equal. print('approx time: ', approx_time) print('baby time: ', baby_time) print('giant time: ', giant_time)
if len(sys.argv) < 2: parser.print_help() sys.exit(0) args = parser.parse_args() with open(args.fileout, "w") as f: # first line is unused, description text f.write("bitsize:{} rstep:{} ntest:{}\n" "".format(args.bitsize, args.rstep, args.ntest)) # actual parameters for verification purposes f.write("{}\n".format(args.seed)) f.write("{}\n".format(args.rstep)) seedbytes = args.seed.encode("utf8") for i in range(args.ntest): d = create_discriminant(seedbytes + bytes([i]), args.bitsize) form = ClassGroup.from_ab_discriminant(2, 1, d) # do an initial square, equivalent to setting up the first cube form = form.square() # repeatedly apply squaring operation the requested number of times for _ in range(args.rstep): form = form.square() a, b, c = form f.write("{} {} {} {}\n".format(d, a, b, c))