assert r1 != 0 s1 = (c1 + r1 * q) * mod_inv(k1, ec.n) % ec.n # if s1 == 0 (extremely unlikely for large ec.n) go back to a different k assert s1 != 0 print(f" r1: {hex(r1).upper()}") print(f" s1: {hex(s1).upper()}") print("3. Verify signature") w = mod_inv(s1, ec.n) u = (c1 * w) % ec.n v = (r1 * w) % ec.n assert u != 0 assert v != 0 U = mult(u, ec.G) V = mult(v, Q) x, y = ec.add(U, V) print(r1 == x % ec.n) print("\n** Malleated signature") sm = ec.n - s1 print(f" r1: {hex(r1).upper()}") print(f" sm: {hex(sm).upper()}") print("** Verify malleated signature") w = mod_inv(sm, ec.n) u = c1 * w % ec.n v = r1 * w % ec.n assert u != 0 assert v != 0 U = mult(u, ec.G) V = mult(v, Q)
def test_double_mult() -> None: H = second_generator(secp256k1) G = secp256k1.G # 0*G + 1*H T = double_mult(1, H, 0, G) assert T == H T = multi_mult([1, 0], [H, G]) assert T == H # 0*G + 2*H exp = mult(2, H) T = double_mult(2, H, 0, G) assert T == exp T = multi_mult([2, 0], [H, G]) assert T == exp # 0*G + 3*H exp = mult(3, H) T = double_mult(3, H, 0, G) assert T == exp T = multi_mult([3, 0], [H, G]) assert T == exp # 1*G + 0*H T = double_mult(0, H, 1, G) assert T == G T = multi_mult([0, 1], [H, G]) assert T == G # 2*G + 0*H exp = mult(2, G) T = double_mult(0, H, 2, G) assert T == exp T = multi_mult([0, 2], [H, G]) assert T == exp # 3*G + 0*H exp = mult(3, G) T = double_mult(0, H, 3, G) assert T == exp T = multi_mult([0, 3], [H, G]) assert T == exp # 0*G + 5*H exp = mult(5, H) T = double_mult(5, H, 0, G) assert T == exp T = multi_mult([5, 0], [H, G]) assert T == exp # 0*G - 5*H exp = mult(-5, H) T = double_mult(-5, H, 0, G) assert T == exp T = multi_mult([-5, 0], [H, G]) assert T == exp # 1*G - 5*H exp = secp256k1.add(G, T) T = double_mult(-5, H, 1, G) assert T == exp
mprvkey = 1 + secrets.randbelow(ec.n - 1) print(f"\nmaster prvkey: {hex(mprvkey).upper()}") # Master Pubkey: mpubkey = mult(mprvkey, ec.G) print(f"Master Pubkey: {hex(mpubkey[0]).upper()}") print(f" {hex(mpubkey[1]).upper()}") r = secrets.randbits(ec.nlen) print(f"\npublic random number: {hex(r).upper()}") rbytes = r.to_bytes(ec.nsize, "big") nKeys = 3 for i in range(nKeys): ibytes = i.to_bytes(ec.nsize, "big") hd = hf(ibytes + rbytes).digest() offset = int_from_bits(hd, ec.nlen) % ec.n q = (mprvkey + offset) % ec.n Q = mult(q, ec.G, ec) print(f"\nprvkey #{i}: {hex(q).upper()}") print(f"Pubkey #{i}: {hex(Q[0]).upper()}") print(f" {hex(Q[1]).upper()}") # Pubkeys could also be calculated without using prvkeys for i in range(nKeys): ibytes = i.to_bytes(ec.nsize, "big") hd = hf(ibytes + rbytes).digest() offset = int_from_bits(hd, ec.nlen) % ec.n Q = ec.add(mpubkey, mult(offset, ec.G, ec)) assert Q == mult((mprvkey + offset) % ec.n, ec.G, ec)