Ejemplo n.º 1
0
def dleq(g1: PointG1, h1: PointG1, g2: PointG1, h2: PointG1,
         alpha: int) -> Tuple[int, int]:
    """ dleq... discrete logarithm equality
        proofs that the caller knows alpha such that h1 = g1**alpha  and  h2 = g2**alpha
        without revealing alpha
    """
    w = random_scalar()
    a1 = multiply(g1, w)
    a2 = multiply(g2, w)
    c = soliditySha3(  # pylint: disable=E1120
        abi_types=["uint256"] * 12,  # 12,
        values=[
            a1[0],
            a1[1],
            a2[0],
            a2[1],
            g1[0],
            g1[1],
            h1[0],
            h1[1],
            g2[0],
            g2[1],
            h2[0],
            h2[1],
        ],
    )
    c = int.from_bytes(c, "big")
    r = (w - alpha * c) % CURVE_ORDER
    return c, r
Ejemplo n.º 2
0
def shared_key_proof(sk, other_pk: PointG1) -> Tuple[int, int]:
    """ non-iteractive zero-knowledge proof showing that
        shared_key(sk, other_pk) is indeed the correct encryption/decryption key
    """
    pk = multiply(G1, sk)
    shared_key = multiply(other_pk, sk)
    return dleq(G1, pk, other_pk, shared_key, alpha=sk)
Ejemplo n.º 3
0
def recover_point(id_and_point_list: List[Tuple[int, PointG1]]) -> PointG1:
    ids = [j for j, _ in id_and_point_list]
    i, sig = id_and_point_list[0]
    result = multiply(sig, lagrange_coefficient(i, ids))
    for i, sig in id_and_point_list[1:]:
        t = multiply(sig, lagrange_coefficient(i, ids))
        result = add(result, t)
    return result
def test_verify_decryption_key():
    sk1, sk2 = random_scalar(), random_scalar()
    pk1, pk2 = multiply(G1, sk1), multiply(G1, sk2)

    shared_key = vss.shared_key(sk1, pk2)
    chal, resp = vss.shared_key_proof(sk1, pk2)

    assert vss.dleq_verify(G1, pk1, pk2, shared_key, chal, resp)
    assert contract.verify_decryption_key(shared_key, [chal, resp], pk1, pk2)
Ejemplo n.º 5
0
def test_dleq():
    sk1 = random_scalar(seed=1)
    sk2 = random_scalar(seed=2)
    pk1 = multiply(G1, sk1)
    pk2 = multiply(G1, sk2)

    shared_key = multiply(pk2, sk1)
    assert shared_key == multiply(pk1, sk2)

    challenge, response = vss.dleq(G1, pk1, pk2, shared_key, alpha=sk1)
    assert vss.dleq_verify(G1, pk1, pk2, shared_key, challenge, response)

    response += 1
    assert not vss.dleq_verify(G1, pk1, pk2, shared_key, challenge, response)
Ejemplo n.º 6
0
    def derive_group_keys(self) -> None:
        """ computes the group public keys and the personal group key for the node itself
        """
        if not hasattr(self, "group"):
            # load_dispute_infos() was not called yet, we use call nodes which provided shares for our group
            # i.e. use the empty set for loading disputes
            self.load_dispute_infos(set())

        self.group_sk = sum([node.share for node in self.group
                             ])  # maybe needs to be product instead
        self.group_pk = multiply(G1, self.group_sk)
        self.group_bls_pk = multiply(neg(G2), self.group_sk)

        self.master_pk = crypto.sum_points([node.pk for node in self.group])
        self.master_bls_pk = crypto.sum_points(
            [node.bls_pk for node in self.group])
Ejemplo n.º 7
0
 def F(x):
     """ public polynomial
     """
     result = public_coefficients[0]
     for j, coef in enumerate(public_coefficients[1:]):
         result = add(result, multiply(coef, pow(x, j + 1, CURVE_ORDER)))
     return result
Ejemplo n.º 8
0
def test_sk_knowledge_with_account():
    sk = random_scalar()
    pk = multiply(G1, sk)
    challenge, response = vss.prove_sk_knowledge(
        sk, pk, account="0xe3D320ea4AF151Fc309568884C217f634E9c38f5")
    assert vss.verify_sk_knowledge(
        pk,
        challenge,
        response,
        account="0xe3D320ea4AF151Fc309568884C217f634E9c38f5")
Ejemplo n.º 9
0
def verify_sk_knowledge(pk: PointG1,
                        challenge: int,
                        response: int,
                        account: str = None) -> bool:

    t = add(multiply(G1, response), multiply(pk, challenge))

    types = ["uint256"] * 6
    values = list(G1 + pk + t)
    if account is not None:
        types.append("address")
        values.append(account)

    c = soliditySha3(abi_types=types, values=values)
    c = int.from_bytes(c, "big")

    print("values", values)

    print("t", t)
    print("c", c)

    return c == challenge
Ejemplo n.º 10
0
def verify(share_id: int, share: int,
           public_coefficients: List[PointG1]) -> bool:
    """ check share validity and return True if the share is valid, False otherwise
    """
    def F(x):
        """ public polynomial
        """
        result = public_coefficients[0]
        for j, coef in enumerate(public_coefficients[1:]):
            result = add(result, multiply(coef, pow(x, j + 1, CURVE_ORDER)))
        return result

    return F(share_id) == multiply(G1, share)
Ejemplo n.º 11
0
def keygen(seed=None):
    """ generated a new bls keypair
    """
    if seed is None:
        sk = random_scalar()
    else:
        sk = hash_to_scalar(seed)

    # compute the corresponding public key
    # for bls_pk, we use neg(G2) which flips the sign of the y coordinates to be compatible with the ethereum
    # implementation of the pairing check
    bls_pk = multiply(neg(G2), sk)
    return sk, bls_pk
Ejemplo n.º 12
0
def dleq_verify(g1: PointG1, h1: PointG1, g2: PointG1, h2: PointG1,
                challenge: int, response: int):
    a1 = add(multiply(g1, response), multiply(h1, challenge))
    a2 = add(multiply(g2, response), multiply(h2, challenge))
    c = soliditySha3(  # pylint: disable=E1120
        abi_types=["uint256"] * 12,  # 12,
        values=[
            a1[0],
            a1[1],
            a2[0],
            a2[1],
            g1[0],
            g1[1],
            h1[0],
            h1[1],
            g2[0],
            g2[1],
            h2[0],
            h2[1],
        ],
    )
    c = int.from_bytes(c, "big")
    return c == challenge
def test_verify_sk_knowledge():
    sk = random_scalar()
    pk = multiply(G1, sk)
    addr = w3.eth.accounts[0]

    proof = vss.prove_sk_knowledge(sk, pk, addr)
    assert vss.verify_sk_knowledge(pk, proof[0], proof[1], addr)

    print("sk", sk)
    print("pk", pk)
    print("account", addr)
    print("proof", proof)

    assert contract.verify_sk_knowledge(pk, proof)
Ejemplo n.º 14
0
def share(secret: int, n: int, t: int) -> Tuple[List[int], List[PointG1]]:
    """ computes n shares of a given secret such that at least t shares are required for recovery of the secret
        additionally returns the public_coefficients used to verify the validity of the shares
    """
    coefficients = [secret] + [
        hash_to_scalar(f"vss:coefficient:{secret}:{j}") for j in range(1, t)
    ]

    def f(x):
        """ secret polynomial
        """
        return sum(coef * pow(x, j, CURVE_ORDER)
                   for j, coef in enumerate(coefficients)) % CURVE_ORDER

    shares = [f(id) for id in range(1, n + 1)]
    public_coefficients = [multiply(G1, coef) for coef in coefficients]

    return shares, public_coefficients
Ejemplo n.º 15
0
def prove_sk_knowledge(sk: int,
                       pk: PointG1,
                       account: str = None) -> Tuple[int, int]:
    """ proofs that the caller knows the discreate logarithm of pk to the generator g1
        (and that links the proof to an Ethereum account if provided)
    """
    w = random_scalar()
    t = multiply(G1, w)

    types = ["uint256"] * 6
    values = list(G1 + pk + t)
    if account is not None:
        types.append("address")
        values.append(account)

    c = soliditySha3(abi_types=types, values=values)
    c = int.from_bytes(c, "big")

    r = (w - sk * c) % CURVE_ORDER
    return c, r
Ejemplo n.º 16
0
def sign_message(msg, SECRET):
    E = Curve(0xffffffffffffffffffffffffffffffff7fffffff,
              0xffffffffffffffffffffffffffffffff7ffffffc,
              0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45)

    G = Point(E, 0x4a96b5688ef573284664698968c38bb913cbfc82,
              0x23a628553168947d59dcc912042351377ac5fb32)

    q = 0x100000000000000000001f4c8f927aed3ca752257

    h = int(sha1(msg).hexdigest(), 16)

    while True:
        k = rand(1, q)
        Q = normalize(multiply(G, k))
        r = Q.x % q
        if r != 0:
            break

    s = invmod(k, q) * (h + r * SECRET) % q
    return (r, s, k & 0x1f)
Ejemplo n.º 17
0
 def keygen(self, seed=None):
     """ generates a new secret/public key pair for the node
     """
     self.sk, self.bls_pk = bls.keygen(seed)
     self.pk = multiply(G1, self.sk)
Ejemplo n.º 18
0
def sign(sk: int, message: Any) -> PointG1:
    return multiply(hash_to_G1(message), sk)
def test_add():
    a = multiply(G1, 5)
    b = multiply(G1, 10)
    s = add(a, b)
    assert contract.bn128_add([a[0], a[1], b[0], b[1]]) == list(s)
Ejemplo n.º 20
0
def test_sk_knowledge_invalid_response():
    sk = random_scalar()
    pk = multiply(G1, sk)
    challenge, response = vss.prove_sk_knowledge(sk, pk)
    response += 1
    assert not vss.verify_sk_knowledge(pk, challenge, response)
def test_check_pairing():
    P1 = multiply(G1, 5)
    Q1 = G2
    Q2 = multiply(neg(G2), 5)
    P2 = G1
    assert check_pairing(P1, Q1, P2, Q2)
def test_multiply():
    assert G1 == (1, 2)
    assert contract.bn128_multiply([1, 2, 5]) == list(multiply(G1, 5))
Ejemplo n.º 23
0
def shared_key(sk, other_pk: PointG1) -> PointG1:
    """ Computes a shared key between given a node's secret key and and some other node public key.
        Used for individual encryption/decryption of the shares.
    """
    return multiply(other_pk, sk)