Exemple #1
0
def verify_share(j: int, s_ij: int, Cik: List[PointG1]) -> bool:
    """ check share validity and return True if the share is valid, False otherwise
    """
    r = Cik[0]
    for k, c in enumerate(Cik[1:]):
        r = add(r, multiply(c, pow(j, k + 1, CURVE_ORDER)))
    return normalize(multiply(G1, s_ij)) == normalize(r)
Exemple #2
0
def dleq_verify(x1, y1, x2, y2, challenge, response):
    """
    Verify the proof computed with the dleq function in G1
    Args:
        x1: a point in G1
        y1: a point in G1
        x2: a point in G1
        y2: a point in G1
        challenge (int): the first coefficient of the proof
        response (int): the second coefficient of the proof

    Returns:
        True if the proof is correct, False else
    """
    a1 = add(multiply(x1, response), multiply(y1, challenge))
    a2 = add(multiply(x2, response), multiply(y2, challenge))
    c = keccak_256(  # pylint: disable=E1120
        abi_types=["uint256"] * 12,  # 12,
        values=[
            int(v) for v in normalize(a1) + normalize(a2) + normalize(x1) +
            normalize(y1) + normalize(x2) + normalize(y2)
        ],
    )
    c = int.from_bytes(c, "big")
    return c == challenge
    def send_share(self, file_info):
        """
        Send a share for a specific message along with its proof of correctness.
        Warning:
            Call the function share on CipherETHDKG, and so send a transaction.
        Args:
            row (dict): a row of the database containing the message
            message_id (int): the id of the message
        """
        db = get_db()
        gsk_sql = db.execute("SELECT * FROM gsk WHERE user_pk=? AND round=?", (self.private_key, file_info['round'])).fetchone()
        gsk = int(gsk_sql['gsk'])
        gpk = multiply(cru.H1, gsk)
        ui = int(gsk_sql['ui'])
        db.close()

        c1 = (int(file_info['c1x']), int(file_info['c1y']))
        c1 = cru.point_from_eth(c1)
        share_for_decryption = multiply(c1, gsk)
        proof = cru.dleq(c1, share_for_decryption, cru.H1, gpk, gsk)
        transaction = self.contract.functions.share_for_dec(
            ui,
            file_info['round'],
            cru.point_to_eth(share_for_decryption),
            proof
        ).buildTransaction(
            {
                'chainId': 1,
                'gas': 200000,
                'nonce': self.w3.eth.getTransactionCount(self.account)
            }
        )
        signed_tx = self.w3.eth.account.signTransaction(transaction, self.private_key)
        txn_hash = self.w3.eth.sendRawTransaction(signed_tx.rawTransaction)
        return txn_hash
Exemple #4
0
def dleq_verify(x1: PointG1, y1: PointG1, x2: PointG1, y2: PointG1,
                challenge: int, response: int) -> bool:
    a1 = add(multiply(x1, response), multiply(y1, challenge))
    a2 = add(multiply(x2, response), multiply(y2, challenge))
    c = keccak_256(  # pylint: disable=E1120
        abi_types=["uint256"] * 12,  # 12,
        values=[
            int(v) for v in normalize(a1) + normalize(a2) + normalize(x1) +
            normalize(y1) + normalize(x2) + normalize(y2)
        ],
    )
    c = int.from_bytes(c, "big")
    return c == challenge
Exemple #5
0
def ec_pair(data: List[int]) -> List[int]:
    if len(data) % 192:
        return []

    zero = (bn128.FQ2.one(), bn128.FQ2.one(), bn128.FQ2.zero())
    exponent = bn128.FQ12.one()
    bytes_data = bytearray(data)
    for i in range(0, len(bytes_data), 192):
        x1 = extract32(bytes_data, i)
        y1 = extract32(bytes_data, i + 32)
        x2_i = extract32(bytes_data, i + 64)
        x2_r = extract32(bytes_data, i + 96)
        y2_i = extract32(bytes_data, i + 128)
        y2_r = extract32(bytes_data, i + 160)
        p1 = validate_point(x1, y1)
        if p1 is False:
            return []
        for v in (x2_i, x2_r, y2_i, y2_r):
            if v >= bn128.field_modulus:
                return []
        fq2_x = bn128.FQ2([x2_r, x2_i])
        fq2_y = bn128.FQ2([y2_r, y2_i])
        if (fq2_x, fq2_y) != (bn128.FQ2.zero(), bn128.FQ2.zero()):
            p2 = (fq2_x, fq2_y, bn128.FQ2.one())
            if not bn128.is_on_curve(p2, bn128.b2):
                return []
        else:
            p2 = zero
        if bn128.multiply(p2, bn128.curve_order)[-1] != bn128.FQ2.zero():
            return []
        exponent *= bn128.pairing(p2, p1, final_exponentiate=False)
    result = bn128.final_exponentiate(exponent) == bn128.FQ12.one()
    return [0] * 31 + [1 if result else 0]
Exemple #6
0
def keygen() -> Tuple[int, PointG1]:
    """ Generates a random keypair on the BN128 curve.
        The public key is an element of the group G1.
        This key is used for deriving the encryption keys used to secure the shares.
        This is NOT a BLS key pair used for signing messages.
    """
    sk = random_scalar()
    pk = multiply(G1, sk)
    return sk, pk
Exemple #7
0
def test_jacobian_equations():
    k = rand_int()
    a = multiply_jacobian(G2, k)
    _a = multiply(G2, k)
    assert eq(normalize_jacobian(a), _normalize(_a))

    b = add_mixed_jacobian(a, G2)
    _b = add(_a, G2)
    assert eq(normalize_jacobian(b), _normalize(_b))
Exemple #8
0
def dleq(x1: PointG1, y1: PointG1, x2: PointG1, y2: PointG1,
         alpha: int) -> Tuple[int, int]:
    """ DLEQ... discrete logarithm equality
        Proofs that the caller knows alpha such that y1 = x1**alpha and y2 = x2**alpha
        without revealing alpha.
    """
    w = random_scalar()
    a1 = multiply(x1, w)
    a2 = multiply(x2, w)
    c = keccak_256(
        abi_types=["uint256"] * 12,
        values=[
            int(v) for v in normalize(a1) + normalize(a2) + normalize(x1) +
            normalize(y1) + normalize(x2) + normalize(y2)
        ],
    )
    c = int.from_bytes(c, "big")
    r = (w - alpha * c) % CURVE_ORDER
    return c, r
Exemple #9
0
def ec_mul(data: List[int]) -> List[int]:
    bytes_data = bytearray(data)
    x = extract32(bytes_data, 0)
    y = extract32(bytes_data, 32)
    m = extract32(bytes_data, 64)
    p = validate_point(x, y)
    if p is False:
        return []
    o = bn128.normalize(bn128.multiply(p, m))
    return [safe_ord(c) for c in (encode_int32(o[0].n) + encode_int32(o[1].n))]
Exemple #10
0
def map_to_g2(raw_hash: FQ2) -> G2Point:
    one = FQ2.one()
    x = raw_hash
    while True:
        y = x * x * x + b2
        y = sqrt(y)
        if y is not None:
            break
        x += one
    h = multiply((x, y, one), COFACTOR_G2)
    assert is_on_curve(h, b2)
    return h
Exemple #11
0
def _ecmull(data):
    x_bytes = pad32r(data[:32])
    y_bytes = pad32r(data[32:64])
    m_bytes = pad32r(data[64:96])

    x = big_endian_to_int(x_bytes)
    y = big_endian_to_int(y_bytes)
    m = big_endian_to_int(m_bytes)

    p = validate_point(x, y)

    result = bn128.normalize(bn128.multiply(p, m))
    return result
Exemple #12
0
def _ecmull(data: bytes) -> Tuple[bn128.FQ, bn128.FQ]:
    x_bytes = pad32r(data[:32])
    y_bytes = pad32r(data[32:64])
    m_bytes = pad32r(data[64:96])

    x = big_endian_to_int(x_bytes)
    y = big_endian_to_int(y_bytes)
    m = big_endian_to_int(m_bytes)

    p = validate_point(x, y)

    result = bn128.normalize(bn128.multiply(p, m))
    return result
Exemple #13
0
    def compute_group_keys(self, round, fj_ui):
        self.gski[round] = sum(fj_ui)
        self.gpki[round] = multiply(H1, self.gski[round])

        db = get_db()
        my_ui = self.tp_key_list[round][1]
        value = [str(self.gski[round]), str(my_ui), round, self.private_key]
        db.execute("INSERT INTO gsk (gsk, ui, round,user_pk) VALUES (?,?,?,?)",
                   value)
        db.commit()
        db.close()
        print("group secret key:", self.gski)
        print("group public key:", self.gpki)
Exemple #14
0
def hash_to_G2(m):
    k2 = m
    while 1:
        k1 = blake(k2)
        k2 = blake(k1)
        x1 = int.from_bytes(k1, 'big') % field_modulus
        x2 = int.from_bytes(k2, 'big') % field_modulus
        x = FQ2([x1, x2])
        xcb = x**3 + b2
        if xcb ** ((field_modulus ** 2 - 1) // 2) == FQ2([1,0]):
            break
    y = sqrt_fq2(xcb)
    return multiply((x, y, FQ2([1,0])), 2*field_modulus-curve_order)
Exemple #15
0
def share_secret(secret: int, indices: List[int],
                 threshold: int) -> Tuple[Dict[int, int], List[PointG1]]:
    """ Computes shares of a given secret such that at least threshold + 1 shares are required to 
        recover the secret. Additionally returns the commitents to the coefficient of the polynom
        used to verify the validity of the shares.
    """
    coefficients = [secret] + [random_scalar() for j in range(threshold)]

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

    shares = {x: f(x) for x in indices}
    commitments = [multiply(G1, coef) for coef in coefficients]
    return shares, commitments
Exemple #16
0
def proc_ecmul(ext, msg):
    if not ext.post_metropolis_hardfork():
        return 1, msg.gas, []
    import py_ecc.optimized_bn128 as bn128
    FQ = bn128.FQ
    print('ecmul proc', msg.gas)
    if msg.gas < opcodes.GECMUL:
        return 0, 0, []
    x = msg.data.extract32(0)
    y = msg.data.extract32(32)
    m = msg.data.extract32(64)
    p = validate_point(x, y)
    if p is False:
        return 0, 0, []
    o = bn128.normalize(bn128.multiply(p, m))
    return (1, msg.gas - opcodes.GECMUL,
            [safe_ord(c) for c in (encode_int32(o[0].n) + encode_int32(o[1].n))])
Exemple #17
0
def proc_ecmul(ext, msg):
    import py_ecc.optimized_bn128 as bn128

    FQ = bn128.FQ
    if msg.gas < opcodes.GECMUL:
        return 0, 0, []
    x = msg.data.extract32(0)
    y = msg.data.extract32(32)
    m = msg.data.extract32(64)
    p = validate_point(x, y)
    if p is False:
        return 0, 0, []
    o = bn128.normalize(bn128.multiply(p, m))
    return (
        1,
        msg.gas - opcodes.GECMUL,
        [safe_ord(c) for c in (encode_int32(o[0].n) + encode_int32(o[1].n))],
    )
Exemple #18
0
def hash_to_G2(m: bytes) -> Tuple[FQ2, FQ2, FQ2]:
    """
    WARNING: this function has not been standardized yet.
    """
    if m in CACHE:
        return CACHE[m]
    k2 = m
    while 1:
        k1 = blake(k2)
        k2 = blake(k1)
        x1 = int.from_bytes(k1, 'big') % field_modulus
        x2 = int.from_bytes(k2, 'big') % field_modulus
        x = FQ2([x1, x2])
        xcb = x**3 + b2
        if xcb**((field_modulus**2 - 1) // 2) == FQ2([1, 0]):
            break
    y = sqrt_fq2(xcb)
    o = multiply((x, y, FQ2([1, 0])), 2 * field_modulus - curve_order)
    CACHE[m] = o
    return o
    def compute_mpk(self):
        if len(self.gpk_0) > self.threshold and not self.has_mpk:
            self.has_mpk = True
            self.mpk = Z1

            for gpki, ui in self.gpk_0[0:self.threshold + 1]:
                coeff = 1
                for gpkj, uj in self.gpk_0[0:self.threshold + 1]:
                    if uj != ui:
                        coeff *= uj * sympy.mod_inverse(
                            (uj - ui) % CURVE_ORDER, CURVE_ORDER)
                        coeff %= CURVE_ORDER
                self.mpk = add(self.mpk, multiply(gpki, coeff))
            self.mpk = normalize(self.mpk)

            db = get_db()
            value = (str(self.mpk[0]), str(self.mpk[1]))
            db.execute("INSERT INTO mpk (x,y) VALUES (?,?)", value)
            db.commit()
            db.close()
Exemple #20
0
def _process_point(data_buffer: bytes, exponent: int) -> bn128.FQP:
    x1, y1, x2_i, x2_r, y2_i, y2_r = _extract_point(data_buffer)
    p1 = validate_point(x1, y1)

    for v in (x2_i, x2_r, y2_i, y2_r):
        if v >= bn128.field_modulus:
            raise ValidationError("value greater than field modulus")

    fq2_x = bn128.FQ2([x2_r, x2_i])
    fq2_y = bn128.FQ2([y2_r, y2_i])

    p2 = ZERO
    if (fq2_x, fq2_y) != (bn128.FQ2.zero(), bn128.FQ2.zero()):
        p2 = (fq2_x, fq2_y, bn128.FQ2.one())
        if not bn128.is_on_curve(p2, bn128.b2):
            raise ValidationError("point is not on curve")

    if bn128.multiply(p2, bn128.curve_order)[-1] != bn128.FQ2.zero():
        raise ValidationError("TODO: what case is this?????")

    return exponent * bn128.pairing(FQP_point_to_FQ2_point(p2), p1, final_exponentiate=False)
Exemple #21
0
def _share_secret_int_indices(s_i: int, n: int,
                              t: int) -> Tuple[Dict[int, int], List[PointG1]]:
    """ Computes n shares of a given secret such that at least t + 1 shares are required for recovery 
        of the secret. Additionally returns the commitents to the coefficient of the polynom
        used to verify the validity of the shares.

        Assumes nodes use the indices [1, 2, ..., n].
        See share_secret function of a generalized variant with arbitary indices.
    """
    coefficients = [s_i] + [random_scalar() for j in range(t)
                            ]  # coefficients c_i0, c_i1, ..., c_it

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

    shares = {x: f(x) for x in range(1, n + 1)}
    commitments = [multiply(G1, coef) for coef in coefficients]
    return shares, commitments
Exemple #22
0
def proc_ecpairing(ext, msg):
    if not ext.post_metropolis_hardfork():
        return 1, msg.gas, []
    import py_ecc.optimized_bn128 as bn128
    FQ = bn128.FQ
    print('pairing proc', msg.gas)
    # Data must be an exact multiple of 192 byte
    if msg.data.size % 192:
        return 0, 0, []
    gascost = opcodes.GPAIRINGBASE + msg.data.size // 192 * opcodes.GPAIRINGPERPOINT
    if msg.gas < gascost:
        return 0, 0, []
    zero = (bn128.FQ2.one(), bn128.FQ2.one(), bn128.FQ2.zero())
    exponent = bn128.FQ12.one()
    for i in range(0, msg.data.size, 192):
        x1 = msg.data.extract32(i)
        y1 = msg.data.extract32(i + 32)
        x2_i = msg.data.extract32(i + 64)
        x2_r = msg.data.extract32(i + 96)
        y2_i = msg.data.extract32(i + 128)
        y2_r = msg.data.extract32(i + 160)
        p1 = validate_point(x1, y1)
        if p1 is False:
            return 0, 0, []
        for v in (x2_i, x2_r, y2_i, y2_r):
            if v >= bn128.field_modulus:
                return 0, 0, []
        fq2_x = bn128.FQ2([x2_r, x2_i])
        fq2_y = bn128.FQ2([y2_r, y2_i])
        if (fq2_x, fq2_y) != (bn128.FQ2.zero(), bn128.FQ2.zero()):
            p2 = (fq2_x, fq2_y, bn128.FQ2.one())
            if not bn128.is_on_curve(p2, bn128.b2):
                return 0, 0, []
        else:
            p2 = zero
        if bn128.multiply(p2, bn128.curve_order)[-1] != bn128.FQ2.zero():
            return 0, 0, []
        exponent *= bn128.pairing(p2, p1, final_exponentiate=False)
    result = bn128.final_exponentiate(exponent) == bn128.FQ12.one()
    return 1, msg.gas - gascost, [0] * 31 + [1 if result else 0]
Exemple #23
0
def _process_point(data_buffer, exponent):
    x1, y1, x2_i, x2_r, y2_i, y2_r = _extract_point(data_buffer)
    p1 = validate_point(x1, y1)

    for v in (x2_i, x2_r, y2_i, y2_r):
        if v >= bn128.field_modulus:
            raise ValidationError("value greater than field modulus")

    fq2_x = bn128.FQ2([x2_r, x2_i])
    fq2_y = bn128.FQ2([y2_r, y2_i])

    if (fq2_x, fq2_y) != (bn128.FQ2.zero(), bn128.FQ2.zero()):
        p2 = (fq2_x, fq2_y, bn128.FQ2.one())
        if not bn128.is_on_curve(p2, bn128.b2):
            raise ValidationError("point is not on curve")
    else:
        p2 = ZERO

    if bn128.multiply(p2, bn128.curve_order)[-1] != bn128.FQ2.zero():
        raise ValidationError("TODO: what case is this?????")

    return exponent * bn128.pairing(p2, p1, final_exponentiate=False)
Exemple #24
0
 def multiply(self, n: IntOrFE) -> "WrappedCurvePoint":
     return self.__class__(multiply(self.py_ecc_object, int(n)))
Exemple #25
0
def privtopub(k):
    return compress_G1(multiply(G1, k))
Exemple #26
0
def sign(m, k):
    return compress_G2(multiply(hash_to_G2(m), k))
Exemple #27
0
def sign(m: bytes, k: int) -> Tuple[int, int]:
    return compress_G2(multiply(hash_to_G2(m), k))
Exemple #28
0
def rand_g2():
    return normalize(multiply(G2, rand_int()))
Exemple #29
0
def sign(msg: Message, priv: PrivateKey) -> Signature:
    x, y = normalize(multiply(hash_to_g2(msg), priv))
    g2 = (x, y, FQ2.one())
    return G2_to_signature(g2)
Exemple #30
0
def priv_to_pub(priv: PrivateKey) -> Pubkey:
    x, y = normalize(multiply(G1, priv))
    g1 = (x, y, FQ.one())
    return G1_to_pubkey(g1)
Exemple #31
0
def privtopub(k: int) -> int:
    return compress_G1(multiply(G1, k))
Exemple #32
0
def shared_key(sk_i: int, pk_j: PointG1) -> PointG1:
    k_ij = multiply(pk_j, sk_i)
    return k_ij