Пример #1
0
def hash_to_G2(message_hash: Hash32, domain: int) -> G2Uncompressed:
    x_coordinate = _get_x_coordinate(message_hash, domain)

    # Test candidate y coordinates until a one is found
    while 1:
        y_coordinate_squared = x_coordinate**3 + FQ2(
            [4, 4])  # The curve is y^2 = x^3 + 4(i + 1)
        y_coordinate = modular_squareroot_in_FQ2(y_coordinate_squared)
        if y_coordinate is not None:  # Check if quadratic residue found
            break
        x_coordinate += FQ2([1, 0])  # Add 1 and try again

    return multiply(
        (x_coordinate, y_coordinate, FQ2([1, 0])),
        G2_cofactor,
    )
Пример #2
0
def derive_public_child(master_pubkey_share: bytes,
                        path: bytes,
                        master_pubkey: bytes = None) -> tuple:
    if not master_pubkey:
        master_pubkey = master_pubkey_share

    root_public_key, root_public_chaincode = parse_master_pubkey(master_pubkey)
    root_pubkey_address = bls_conv.G1_to_pubkey(root_public_key)
    public_chaincode_address = bls_conv.G1_to_pubkey(root_public_chaincode)
    h = _hash_to_bls_field(
        _derivation_format_hash_input(root_pubkey_address,
                                      public_chaincode_address, path))

    public_key_share, public_chaincode_share = parse_master_pubkey(
        master_pubkey_share)
    return bls_curve.add(public_key_share,
                         bls_curve.multiply(public_chaincode_share, h))
Пример #3
0
    def _CoreSign(cls, SK: int, message: bytes, DST: bytes) -> BLSSignature:
        """
        The CoreSign algorithm computes a signature from SK, a secret key,
        and message, an octet string.
        Raise `ValidationError` when there is input validation error.
        """
        try:
            # Inputs validation
            assert cls._is_valid_privkey(SK)
            assert cls._is_valid_message(message)
        except Exception as e:
            raise ValidationError(e)

        # Procedure
        message_point = hash_to_G2(message, DST, cls.xmd_hash_function)
        signature_point = multiply(message_point, SK)
        return G2_to_signature(signature_point)
Пример #4
0
def hash_to_G2(message: bytes, domain: int) -> Tuple[FQ2, FQ2, FQ2]:
    domain_in_bytes = domain.to_bytes(8, 'big')

    # Initial candidate x coordinate
    x_re = big_endian_to_int(hash_eth2(domain_in_bytes + b'\x01' + message))
    x_im = big_endian_to_int(hash_eth2(domain_in_bytes + b'\x02' + message))
    x_coordinate = FQ2([x_re, x_im])  # x_re + x_im * i

    # Test candidate y coordinates until a one is found
    while 1:
        y_coordinate_squared = x_coordinate**3 + FQ2(
            [4, 4])  # The curve is y^2 = x^3 + 4(i + 1)
        y_coordinate = modular_squareroot(y_coordinate_squared)
        if y_coordinate is not None:  # Check if quadratic residue found
            break
        x_coordinate += FQ2([1, 0])  # Add 1 and try again

    return multiply((x_coordinate, y_coordinate, FQ2([1, 0])), G2_cofactor)
Пример #5
0
def _fft(vals, modulus, roots_of_unity):
    if len(vals) <= 4 and type(vals[0]) != tuple:
        #return vals
        return _simple_ft(vals, modulus, roots_of_unity)
    elif len(vals) == 1 and type(vals[0]) == tuple:
        return vals
    L = _fft(vals[::2], modulus, roots_of_unity[::2])
    R = _fft(vals[1::2], modulus, roots_of_unity[::2])
    o = [0 for i in vals]
    for i, (x, y) in enumerate(zip(L, R)):
        y_times_root = b.multiply(
            y,
            roots_of_unity[i]) if type(y) == tuple else y * roots_of_unity[i]
        o[i] = b.add(
            x,
            y_times_root) if type(x) == tuple else (x + y_times_root) % modulus
        o[i + len(L)] = b.add(x, b.neg(y_times_root)) if type(
            x) == tuple else (x - y_times_root) % modulus
    return o
Пример #6
0
def toeplitz_part2(toeplitz_coefficients, xext_fft):
    """
    Performs the second part of the Toeplitz matrix multiplication algorithm
    """
    # Extend the toeplitz coefficients to get a circulant matrix into which the Toeplitz
    # matrix is embedded
    assert is_power_of_two(len(toeplitz_coefficients))

    root_of_unity = get_root_of_unity(len(xext_fft))

    toeplitz_coefficients_fft = fft(toeplitz_coefficients,
                                    MODULUS,
                                    root_of_unity,
                                    inv=False)
    hext_fft = [
        b.multiply(v, w) for v, w in zip(xext_fft, toeplitz_coefficients_fft)
    ]

    return hext_fft
Пример #7
0
def fft(vals, modulus, root_of_unity, inv=False):
    rootz = expand_root_of_unity(root_of_unity, modulus)
    # Fill in vals with zeroes if needed
    if len(rootz) > len(vals) + 1:
        vals = vals + [0] * (len(rootz) - len(vals) - 1)
    if inv:
        # Inverse FFT
        invlen = pow(len(vals), modulus - 2, modulus)
        if type(vals[0]) == tuple:
            return [
                b.multiply(x, invlen)
                for x in _fft(vals, modulus, rootz[:0:-1])
            ]
        else:
            return [(x * invlen) % modulus
                    for x in _fft(vals, modulus, rootz[:0:-1])]
    else:
        # Regular FFT
        return _fft(vals, modulus, rootz[:-1])
Пример #8
0
def semi_toeplitz_fft(toeplitz_coefficients, x):
    global xext_hat
    assert len(x) == WIDTH
    if xext_hat == None:
        a = time.time()
        if type(x[0]) == tuple:
            xext = x + [b.Z1 for a in x]
        else:
            xext = x + [0 * a for a in x]

        xext_hat = fft(xext, MODULUS, ROOT_OF_UNITY2, inv=False)
        print("Toeplitz preprocessing in %.3f seconds" % (time.time() - a))

    text = toeplitz_coefficients[:1] + [0 * a for a in toeplitz_coefficients] + toeplitz_coefficients[:0:-1]
    text_hat = fft(text, MODULUS, ROOT_OF_UNITY2, inv=False)
    yext_hat = [None for i in range(2*len(x))]
    for i in range(len(xext_hat)):
        if type(xext_hat[0]) == tuple:
            yext_hat[i] = b.multiply(xext_hat[i], text_hat[i])
        else:
            yext_hat[i] *= text_hat[i]
    return fft(yext_hat, MODULUS, ROOT_OF_UNITY2, inv=True)[:len(x)]
Пример #9
0
 def execute(cls, stack: MichelsonStack, stdout: List[str],
             context: AbstractContext):
     a, b = cast(
         Tuple[Union[IntType, NatType, MutezType, BLS12_381_FrType,
                     BLS12_381_G1Type, BLS12_381_G2Type], ...],
         stack.pop2())
     res_type, = dispatch_types(
         type(a),
         type(b),
         mapping={
             (NatType, NatType): (NatType, ),
             (NatType, IntType): (IntType, ),
             (IntType, NatType): (IntType, ),
             (IntType, IntType): (IntType, ),
             (MutezType, NatType): (MutezType, ),
             (NatType, MutezType): (MutezType, ),
             (NatType, BLS12_381_FrType): (BLS12_381_FrType, ),
             (IntType, BLS12_381_FrType): (BLS12_381_FrType, ),
             (BLS12_381_FrType, NatType): (BLS12_381_FrType, ),
             (BLS12_381_FrType, IntType): (BLS12_381_FrType, ),
             (BLS12_381_FrType, BLS12_381_FrType): (BLS12_381_FrType, ),
             (BLS12_381_G1Type, BLS12_381_FrType): (BLS12_381_G1Type, ),
             (BLS12_381_G2Type, BLS12_381_FrType): (BLS12_381_G2Type, ),
         })
     res_type = cast(
         Union[Type[IntType], Type[NatType], Type[TimestampType],
               Type[MutezType], Type[BLS12_381_FrType],
               Type[BLS12_381_G1Type], Type[BLS12_381_G2Type]], res_type)
     if issubclass(res_type, IntType):
         res = res_type.from_value(int(a) * int(b))  # type: ignore
     else:
         res = res_type.from_point(bls12_381.multiply(
             a.to_point(), int(b)))  # type: ignore
     stack.push(res)
     stdout.append(format_stdout(cls.prim, [a, b], [res]))  # type: ignore
     return cls(stack_items_added=1)
Пример #10
0
def verify_evaluation(points, commitment, proof, x, y):
    # Crop the base points to just what we need. We add an additional base point,
    # which we will use to mix in the _evaluation_ of the polynomial.
    points, H = points[:2**len(proof.L)], points[2**len(proof.L)]
    # Powers of x, as in the prover
    xpowers = [pow(x, i, b.curve_order) for i in range(len(poly))]
    # Fiat-shamir randomness value
    r = hash(
        serialize_point(commitment) + x.to_bytes(32, 'little') +
        y.to_bytes(32, 'little'))
    # For security, we randomize H
    H = b.multiply(H, int.from_bytes(r, 'little') % b.curve_order)
    # We "mix in" H * the claimed evaluation P(x) = y. Notice that `H * P(x)` equals the
    # dot-product of `H * powers of x` and the polynomial coefficients, so it has the
    # "same format" as the polynomial commitment itself. This allows us to verify the
    # evaluation using the same technique that we use to just prove that the commitment
    # is valid
    commitment = b.add(commitment, b.multiply(H, y))
    # Track the linear combination so we can generate the final-round point and xpower,
    # just as before
    points_coeffs = [1]
    for i in range(len(proof.L)):
        # Generate random coefficient for recombining (same as the prover)
        r = hash(r + serialize_point(proof.L[i]) + serialize_point(proof.R[i]))
        a = int.from_bytes(r, 'little') % b.curve_order
        # print('a value: ', a)
        # Add L and R into the commitment, applying the appropriate coefficients
        commitment = b.add(
            proof.L[i],
            b.add(b.multiply(commitment, a), b.multiply(proof.R[i], a**2)))
        # print('intermediate commitment:', commitment)
        # Update the coefficients (as in basic verification above)
        points_coeffs = sum([[(x * a) % b.curve_order, x]
                             for x in points_coeffs], [])
    # Finally, we do the linear combination; same one for base points and x powers
    combined_point = lincomb(points, points_coeffs, b.add, b.Z1)
    combined_x_powers = sum(p * c for p, c in zip(xpowers, points_coeffs))
    # Base case check: base_point * coefficient ?= commitment. Note that here we
    # have to also mix H * the combined xpower into the final base point
    return b.eq(
        b.add(b.multiply(combined_point, proof.tip),
              b.multiply(H, (proof.tip * combined_x_powers) % b.curve_order)),
        commitment)
Пример #11
0
 def multiply(self, n: IntOrFE) -> "WrappedCurvePoint":
     return self.__class__(multiply(self.py_ecc_object, int(n)))
Пример #12
0
def sign(message_hash: Hash32, privkey: int, domain: int) -> BLSSignature:
    return G2_to_signature(
        multiply(
            hash_to_G2(message_hash, domain),
            privkey,
        ))
Пример #13
0
    result_1 = hash_to_G2(message_hash, domain_in_bytes)
    assert is_on_curve(result_1, b2)


def test_decompress_G2_with_no_modular_square_root_found():
    with pytest.raises(ValueError,
                       match="Failed to find a modular squareroot"):
        signature_to_G2(b'\x11' * 96)


@pytest.mark.parametrize(
    'pt,on_curve,is_infinity',
    [
        # On curve points
        (G1, True, False),
        (multiply(G1, 5), True, False),
        # Infinity point but still on curve
        (Z1, True, True),
        # Not on curve
        ((FQ(5566), FQ(5566), FQ.one()), False, None),
    ])
def test_G1_compress_and_decompress_flags(pt, on_curve, is_infinity):
    assert on_curve == is_on_curve(pt, b)
    z = compress_G1(pt)
    if on_curve:
        x = z % POW_2_381
        c_flag = (z % 2**384) // POW_2_383
        b_flag = (z % POW_2_383) // POW_2_382
        a_flag = (z % POW_2_382) // POW_2_381
        assert x < q
        assert c_flag == 1
Пример #14
0
def sign(message: bytes, privkey: int, domain: int) -> BLSSignature:
    return BLSSignature(
        compress_G2(multiply(hash_to_G2(message, domain), privkey)))
Пример #15
0
def privtopub(k: int) -> BLSPubkey:
    return BLSPubkey(compress_G1(multiply(G1, k)))
Пример #16
0
def sign(message: bytes, privkey: int, domain: int) -> Tuple[int, int]:
    return compress_G2(multiply(hash_to_G2(message, domain), privkey))
Пример #17
0
def privtopub(k: int) -> int:
    return compress_G1(multiply(G1, k))
Пример #18
0
# Alternatively, this can be used to turn an already existing validator into a secret shared validator;
# however, if the key was compromised before the split happened, it does not help.

from python_ibft.bls_threshold import eval_poly, generate_keys
import sys
import random
import base64
import py_ecc.optimized_bls12_381 as b
from py_ecc.bls.g2_primatives import G1_to_pubkey

if len(sys.argv) != 2:
    print("Usage: python privkey_to_threshold.py {privkey_as_hex}")
    sys.exit(1)

privkey = int(sys.argv[1], base=16)
printable_pubkey = G1_to_pubkey(b.multiply(b.G1, privkey)).hex()
print("Generating threshold keys for validator {0}".format(printable_pubkey))

coefs = [privkey] + [random.randint(0, b.curve_order) for i in range(2)]
privkeys = [eval_poly(x, coefs) for x in range(1,5)]

printable_pubkeys = [G1_to_pubkey(b.multiply(b.G1, p)).hex() for p in privkeys]
printable_privkeys = [base64.encodebytes(p.to_bytes(32, byteorder="big")).decode()[:-1] for p in privkeys]


for i, p in enumerate(zip(printable_pubkeys, printable_privkeys)):
    print("Pubkey {0}:".format(i), p[0])
    print("Privkey {0}:".format(i), p[1])

print()
print("Copy this into validators.json:")
Пример #19
0
    io = remote(Host, Port)
    # io = process('./server.py')
    for i in data:
        j = dumps({"Name": i["Name"], "Vote": i["Vote"], "Sign": i["Sign"]})
        io.recvuntil(b'> ')
        io.sendline(j)
    # io.interactive()
    io.recvuntil(b'reward : ')
    return io.recvline().strip()


order = 52435875175126190479447740508185965837690552500527637822603658699938581184513
m1, m2 = [int(sha256(i).hexdigest(), 16) for i in [b"D", b"R"]]
idx, ny = [(i, j) for i, j in enumerate(result) if j["Name"] == 'New York'][0]
ny["Sign"] = G2_to_signature(
    multiply(multiply(signature_to_G2(unhex(ny["Sign"])), invert(m1, order)),
             m2)).hex()
ny["Vote"] = "R"
assert bls.Verify(unhex(ny["PK"]), ny["Vote"].encode(), unhex(ny["Sign"]))
result[idx] = ny

xored_flag = unhex(connect(result).decode())

fake_result = result[:]
w = fake_result[idx + 1]
ny = fake_result[idx]
ny["Sign"] = G2_to_signature(
    add(signature_to_G2(unhex(ny["Sign"])),
        multiply(signature_to_G2(unhex(w["Sign"])), 2))).hex()
w["Sign"] = G2_to_signature(neg(signature_to_G2(unhex(w["Sign"])))).hex()
assert bls.Verify(bls._AggregatePKs([unhex(ny["PK"]),
                                     unhex(w["PK"])]), b'R',
Пример #20
0
 def _CoreSign(SK: int, message: bytes, DST: bytes) -> BLSSignature:
     message_point = hash_to_G2(message, DST)
     signature_point = multiply(message_point, SK)
     return G2_to_signature(signature_point)
Пример #21
0
def singlechecker(agg_pk, agg_sig, msg):
    final_exp = final_exponentiate(
        pairing(agg_sig, G1, final_exponentiate=False) * pairing(
            multiply(G2, hasher(msg)), neg(agg_pk), final_exponentiate=False))
    isok = (final_exp == FQ12.one())
    return isok
Пример #22
0
        (735),
        (127409812145),
        (90768492698215092512159),
    ]
)
def test_sign_verify(privkey):
    msg = str(privkey).encode('utf-8')
    pub = G2Basic.SkToPk(privkey)
    sig = G2Basic._CoreSign(privkey, msg, G2Basic.DST)
    assert G2Basic._CoreVerify(pub, msg, sig, G2Basic.DST)


@pytest.mark.parametrize(
    'signature_points,result_point',
    [
        ([multiply(G2, 2), multiply(G2, 3)], multiply(G2, 2 + 3)),
        ([multiply(G2, 42), multiply(G2, 69)], multiply(G2, 42 + 69)),
    ]
)
def test_aggregate(signature_points, result_point):
    signatures = [G2_to_signature(pt) for pt in signature_points]
    result_signature = G2_to_signature(result_point)
    assert G2Basic.Aggregate(signatures) == result_signature


@pytest.mark.parametrize(
    'SKs,messages',
    [
        (list(range(1, 6)), list(range(1, 6))),
    ]
)
Пример #23
0
def hash_to_G2(msg, DST, hash):
    m = int(hash(msg).hexdigest(), 16)
    return multiply(G2, m)
Пример #24
0
 def mul(xxx: G1Point, nnn: int) -> G1Point:
     return bls12_381.multiply(xxx, nnn)
Пример #25
0
def privtopub(k: int) -> BLSPubkey:
    return G1_to_pubkey(multiply(G1, k))
Пример #26
0
def generate_keys(n_parties, t):
    coefs = [random.randint(0, b.curve_order - 1) for i in range(t + 1)]
    aggregate_public = G1_to_pubkey(b.multiply(b.G1, coefs[0]))
    private = [eval_poly(x, coefs) for x in range(1, n_parties + 1)]
    public = [G1_to_pubkey(b.multiply(b.G1, x)) for x in private]
    return aggregate_public, public, private
Пример #27
0
)


@pytest.mark.parametrize('sk', [
    42,
    69,
    31415926,
])
def test_pop(sk):
    pk = G2ProofOfPossession.PrivToPub(sk)
    proof = G2ProofOfPossession.PopProve(sk)
    assert G2ProofOfPossession.PopVerify(pk, proof)


@pytest.mark.parametrize('signature_points,result_point', [
    ([multiply(G1, 2), multiply(G1, 3)], multiply(G1, 2 + 3)),
    ([multiply(G1, 42), multiply(G1, 69)], multiply(G1, 42 + 69)),
])
def test_aggregate_pks(signature_points, result_point):
    signatures = [G1_to_pubkey(pt) for pt in signature_points]
    result_signature = G1_to_pubkey(result_point)
    assert G2ProofOfPossession._AggregatePKs(signatures) == result_signature


@pytest.mark.parametrize('SKs,message', [
    (range(5), b'11' * 48),
])
def test_fast_aggregate_verify(SKs, message):
    PKs = [G2ProofOfPossession.PrivToPub(sk) for sk in SKs]
    signatures = [G2ProofOfPossession.Sign(sk, message) for sk in SKs]
    aggregate_signature = G2ProofOfPossession.Aggregate(signatures)
Пример #28
0
 def __mul__(self, x):
     assert type(x) in (int, Fp)
     if type(x) is Fp:
         x = x.n
     return SS_BLS12_381(multiply(self.m1, x), multiply(self.m2, x))
Пример #29
0
def subgroup_check(P: Optimized_Point3D) -> bool:
    return is_inf(multiply(P, curve_order))
Пример #30
0
    pub = pubkey_to_G1(bytes.fromhex(wow[i]["PK"]))
    sig = signature_to_G2(bytes.fromhex(wow[i]["Sign"]))
    print("pubkey check", i, subgroup_check(pub))
    print("sig check", i, subgroup_check(sig))
    if wow[i]["Vote"] == "D":
        if ex:
            ex = False
            fin = creator(wow[i]["Name"], "D", wow[i]["Sign"])
            r.sendline(fin)
            continue
        res1 = hasher(b"D")
        res2 = hasher(b"R")

        tt = (res2 * inverse(res1, cv)) % cv
        sigs = signature_to_G2(bytes.fromhex(wow[i]["Sign"]))
        sigs = multiply(sigs, tt)
        # do this part only if you want fake flag
        if cnt == 0:
            sigs = add(sigs, G2)
        if cnt == 1:
            sigs = add(sigs, neg(G2))
        # end
        cnt += 1
        sig = G2_to_signature(sigs).hex()
        wow[i]["Sign"] = sig
        wow[i]["Vote"] = "R"

    fin = creator(wow[i]["Name"], "R", wow[i]["Sign"])
    pub = pubkey_to_G1(bytes.fromhex(wow[i]["PK"]))
    sig = signature_to_G2(bytes.fromhex(wow[i]["Sign"]))
    print("sig check2", i, subgroup_check(sig))