コード例 #1
0
    def test_many_generators(self):
        def all_powers(e):
            d = e.discriminant()
            e0 = e
            items = []
            while e0 not in items:
                items.append(e0)
                self.assertEqual(e0 * e0, e0.square())
                e0 *= e
                e0 = e0.normalized()
                if e0.discriminant() != d:
                    import pdb
                    pdb.set_trace()
            return items

        for _ in range(1000):
            D = -7 - _ * 8
            e_id = ClassGroup.identity_for_discriminant(D)
            self.assertEqual(e_id, (1, 1, 2 + 2 * _))
            e_id_inv = e_id.inverse()
            self.assertEqual(e_id, e_id_inv)
            e0 = ClassGroup.from_ab_discriminant(2, 1, D)
            e1 = e0.inverse()
            p0 = all_powers(e0)
            p1 = all_powers(e1)
            assert len(p0) == len(p1)
            assert e_id == p0[-1]
            assert e_id == p1[-1]
            for _0, _1 in zip(p0, p1):
                _ = _0 * _1
                assert _ == e_id
            print("discriminant = %d; group order = %d" % (D, len(p0)))
コード例 #2
0
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)
コード例 #3
0
 def test_pow(self):
     for _ in range(100):
         D = -7 - _ * 8
         e_gen = ClassGroup.from_ab_discriminant(2, 1, D)
         p = ClassGroup.identity_for_discriminant(D)
         for _ in range(10):
             self.assertEqual(pow(e_gen, _), p)
             p *= e_gen
コード例 #4
0
 def test_inverse(self):
     for _ in range(1000):
         D = -7 - _ * 8
         e_id = ClassGroup.identity_for_discriminant(D)
         e_gen = ClassGroup.from_ab_discriminant(2, 1, D)
         e_gen_inv = e_gen.inverse()
         e_prod = e_gen * e_gen_inv
         self.assertEqual(e_prod, e_id)
コード例 #5
0
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)
コード例 #6
0
 def test_generator_element(self):
     D = -103
     e_id = ClassGroup.identity_for_discriminant(D)
     self.assertEqual(e_id.discriminant(), D)
     self.assertEqual(e_id, (1, 1, 26))
     e = ClassGroup.from_ab_discriminant(2, 1, D)
     self.assertEqual(e.discriminant(), D)
     self.assertEqual(e, (2, 1, 13))
     e_inv = e.inverse()
     self.assertEqual(e_inv.discriminant(), D)
     self.assertEqual(e_inv, (2, -1, 13))
     self.assertEqual(e * e_inv, e_id)
     e2 = e.square()
     self.assertEqual(e2, (4, -3, 7))
     assert e2 == e * e
     e4 = e2.square()
     self.assertEqual(e4, (13, 1, 2))
     self.assertEqual(e4, e2 * e2)
コード例 #7
0
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))
コード例 #8
0
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)
コード例 #9
0
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)
コード例 #10
0
def compute_order(g: ClassGroup) -> int:
    d = g.discriminant()
    quadRoot = int((-d)**0.25)
    size = quadRoot
    order = 0
    while order == 0:
        babylist = list(
            accumulate(repeat(g, quadRoot - 1), ClassGroup.multiply))
        babyset = set(babylist)
        gSqrt = (g**quadRoot).normalized()
        bigStep = gSqrt
        result = next(
            filter(
                lambda giant: giant[1] in babyset,
                accumulate(repeat((1, bigStep), size), lambda old, new:
                           (old[0] + new[0], old[1] * new[1]))), None)
        if result is not None:
            order = (result[0] * quadRoot - babylist.index(result[1]) - 1)
            return order
        size *= 2
コード例 #11
0
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)
コード例 #12
0
def classgroup_functions():
    discriminant = int(''.join(textwrap.dedent("""
        -277932370013051706986565094977558440925863868724962956297798375079711
        1755935469152358189047817691469335967563030108724222799555095874359204
        6124379271342523117944672201940224307563498623282396336043787901362415
        6433157943598984236289762294443851324618151831207090436519745445815231
        7564548579388388954361501155915180650886278614483121267374719433736283
        5767292592316842392285011597319847853278165631070684231627247677822273
        5939990747234338712430307680633635599311944191428099762576753484986313
        5593175689179199446755860152120839703879033915840019194533960922418362
        5935566879000287625158572127711542235803324639115306136663""").split("\n")))

    discriminant = -497333706520175843802401785845247633092951073654583682148673589759912972969047267665487

    initial_x = ClassGroup.from_ab_discriminant(2, 1, discriminant)

    # |b| <= |a| <= |c| which is approx half the bytes of the discriminant
    # c can be calculated from a and b, so we only need to send (a, b)
    element_size_bytes = discriminant.bit_length() // 8
    return (initial_x, initial_x.identity(), element_size_bytes,
            int(discriminant.bit_length()))
コード例 #13
0
 def test_bad_multiply(self):
     n1 = ClassGroup(2243390248, -565721959, 35664920)
     n2 = ClassGroup(2, 1, 370)
     n = n1 * n2
     self.assertEqual(n.discriminant(), n1.discriminant())
     self.assertEqual(n.discriminant(), n2.discriminant())
コード例 #14
0
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)
コード例 #15
0
def find_group_order(discriminant):
    generator = ClassGroup.from_ab_discriminant(2, 1, d)
    order = compute_order(generator)
    return generator, order
コード例 #16
0
def find_order_from_cpp(abs_disc):
    global correction, approx_time
    g = ClassGroup.from_ab_discriminant(2, 1, -abs_disc)
    num_baby_steps = int(abs_disc**.2 * baby_factor)
    num_baby_steps = min(baby_max, num_baby_steps)
    while True:
        fa = (g**(num_baby_steps * 4))[0]
        if miller_rabin_test(fa) and fa >= num_baby_steps:
            break
        num_baby_steps += 1
    approx_time -= time.time()
    num_approxers = 16
    max_prime = int(abs_disc**.2 * prime_factor)
    primes_per_process = 1 + max_prime // num_approxers
    primes_per_process = min(primes_per_process, max_primes_per_proc)
    approx_partial = [0.] * num_approxers

    def approx(idx):
        val = 1.
        start = idx * primes_per_process
        while start < max_prime:
            args = [
                './a.out', 'approx',
                str(abs_disc),
                str(start),
                str(start + primes_per_process)
            ]
            # print (' '.join(args))
            val *= float(subprocess.check_output(args).strip())
            start += primes_per_process * num_approxers
        approx_partial[idx] = val

    threads = [
        threading.Thread(target=approx, args=[x]) for x in range(num_approxers)
    ]
    for t in threads:
        t.start()
    for t in threads:
        t.join()

    # print (approx_partial)
    middle = (abs_disc**0.5) / 2.
    for v in approx_partial:
        middle *= v
    middle *= correction
    middle = int(middle)
    if middle % 2 == 1:
        middle += 1
    num_hashes_per_giant = min(int(abs_disc**.20), 1000000)
    num_giants = 16

    approx_time += time.time()
    od = find_order_parameterized(abs_disc, num_baby_steps, middle,
                                  num_hashes_per_giant, num_giants)
    correction_required = (correction * od) / middle
    correction = correction_required * learn_factor + correction * (
        1. - learn_factor)
    # print the true order, our approximate guess, and the updated value of correction.
    # Currently we manually set the initial value of this from the output back into the code.
    # Then for future order calculation the initial estimate is better. Can be automated.
    print(od, middle, correction)
    return od
コード例 #17
0
    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))
コード例 #18
0
 def test_identity(self):
     for _ in range(1000):
         D = -7 - _ * 8
         e_id = ClassGroup.identity_for_discriminant(D)
         e_prod = e_id * e_id
         self.assertEqual(e_prod, e_id)
コード例 #19
0
 def test_new_failure(self):
     t2_1_6 = ClassGroup(2, 1, 6)
     t4_1_3 = ClassGroup(4, 1, 3)
     p = t2_1_6 * t4_1_3
     self.assertEqual(p, (3, 1, 4))
コード例 #20
0
 def test_new_failure1(self):
     t6_5_7 = ClassGroup(6, 5, 7)
     t2_1_18 = ClassGroup(2, 1, 18)
     p = t6_5_7 * t2_1_18
     self.assertEqual(p, (4, -1, 9))
コード例 #21
0
    def test_paper_check(self):
        t12_11_3 = ClassGroup(12, 11, 3)
        t93_109_32 = ClassGroup(93, 109, 32)

        self.assertEqual(t12_11_3.discriminant(), -23)
        self.assertEqual(t93_109_32.discriminant(), -23)

        t = t12_11_3 * t93_109_32
        self.assertEqual(t, ClassGroup(1, -15, 62))
        self.assertEqual(t.discriminant(), -23)

        t1 = t93_109_32 * t12_11_3
        self.assertEqual(t, t1)

        # the normalize and reduce example from the paper
        f = ClassGroup(195751, 1212121, 1876411)
        self.assertEqual(f.normalized(), (195751, 37615, 1807))
        self.assertEqual(f.reduced(), (1, 1, 1))