示例#1
0
def Prove(pk1, X1, Y1, pk2, X2, Y2, r1, r2, v):
    sr = SystemRandom()

    #Prover Stage 1
    a1 = sr.getrandbits(256)
    a2 = sr.getrandbits(256)
    b = sr.getrandbits(256)

    A1 = bn128.multiply(pk1, a1)
    A2 = bn128.multiply(pk2, a2)
    B1 = bn128.add(bn128.multiply(bn128.G1, a1), bn128.multiply(H, b))
    B2 = bn128.add(bn128.multiply(bn128.G1, a2), bn128.multiply(H, b))

    #Fiat Shamir
    hasher = keccak_256()
    hasher.update(A1[0].n.to_bytes(32, 'big'))
    hasher.update(A1[1].n.to_bytes(32, 'big'))
    hasher.update(A2[0].n.to_bytes(32, 'big'))
    hasher.update(A2[1].n.to_bytes(32, 'big'))
    hasher.update(B1[0].n.to_bytes(32, 'big'))
    hasher.update(B1[1].n.to_bytes(32, 'big'))
    hasher.update(B2[0].n.to_bytes(32, 'big'))
    hasher.update(B2[1].n.to_bytes(32, 'big'))
    e = int.from_bytes(hasher.digest(), 'big')

    #Prover Stage 2
    z1 = (a1 + e * r1) % bn128.curve_order
    z2 = (a2 + e * r2) % bn128.curve_order
    z3 = (b + e * v) % bn128.curve_order

    return (z1, z2, z3)
示例#2
0
def BuildCommitmentPublic(public_bit_commitments, indices):
    C_out = None

    for i in range(0, len(indices)):
        if bn128.is_inf(C_out):
            C_out = public_bit_commitments[indices[i]]
            C_out = (bn128.FQ(C_out[0]), bn128.FQ(C_out[1]))
        else:
            C_out = bn128.add(C_out, C_out)
            C_out = bn128.add(C_out, public_bit_commitments[indices[i]])

    return C_out
示例#3
0
def Dec(sk, X, Y):
    sk_inv = pow(sk, bn128.curve_order - 2, bn128.curve_order)
    denom = bn128.multiply(X, sk_inv)
    denom = (denom[0], -denom[1])

    Hm = bn128.add(Y, denom)
    P_test = H

    m = 1
    while not bn128.eq(Hm, P_test):
        m += 1
        P_test = bn128.add(P_test, H)

    return m
示例#4
0
async def constructBinaryRepresentation(client, attemptID, elGamalInstance,
                                        dCipher, answerAttempt, p, secretKey):
    ciphertextArray = []
    nizkps = []
    publicKey = bn128.multiply(bn128.G1, secretKey.n)

    # slice leading 0b
    binaryString = bin(answerAttempt.n)[2:]
    exponent = [i for i in range(len(binaryString))]
    exponent.reverse()
    for index in range(len(binaryString)):
        random = getRandomElement()
        if binaryString[index] == '0':
            # case: beta_i = 0 => Random encryption of 0
            encryption = elGamalInstance.encrypt(0, random)
            proof = FirstNIZKP.generateCommitment(publicKey, encryption.second,
                                                  encryption.first, random,
                                                  dCipher.first,
                                                  dCipher.second, True)
            challenge = bn128.FQ(client.getChallengeForNIZKP1(
                attemptID, proof))
            proof = FirstNIZKP.computeProof(proof, challenge)
            ciphertextArray.append(encryption)
            nizkps.append(proof)
        else:
            element = (bn128.FQ(2)**exponent[index]).n
            # c0,i = d_0 ** (2**i * beta_i) * (g_1 ** r) | case: beta_i = 1
            d0pow = bn128.multiply(dCipher.first, element)
            gr = bn128.multiply(bn128.G1, random.n)
            c0i = bn128.add(d0pow, gr)

            # c1,i = d_1 ** (2**i * beta_i) * (h ** r) | case: beta_i = 1
            d1pow = bn128.multiply(dCipher.second, element)
            hr = bn128.multiply(elGamalInstance.publicKey, random.n)
            c1i = bn128.add(d1pow, hr)

            proof = FirstNIZKP.generateCommitment(publicKey, c1i, c0i, random,
                                                  dCipher.first,
                                                  dCipher.second, False)
            challenge = bn128.FQ(client.getChallengeForNIZKP1(
                attemptID, proof))
            proof = FirstNIZKP.computeProof(proof, challenge)

            encryption = Ciphertext(c0i, c1i)
            ciphertextArray.append(encryption)
            nizkps.append(proof)

    return (ciphertextArray, nizkps)
示例#5
0
def VerifyRangeProofs(proof_bytes, pct_check=100):
    sr = SystemRandom()
    proof_size, proof_count = GetProofSizeAndCount(proof_bytes)

    #Get asset address and H_neg
    asset_address = int.from_bytes(proof_bytes[0:20], 'big')
    G1 = bn128.G1
    H_neg = H_from_address(asset_address)
    H_neg = (H_neg[0], -H_neg[1])

    for i in range(0, proof_count):
        if pct_check == 100 or sr.randint(0, 100) < pct_check:
            #Extract Proof
            start = 20 + i * proof_size
            C = (bn128.FQ(int.from_bytes(proof_bytes[start:start + 32],
                                         'big')),
                 bn128.FQ(
                     int.from_bytes(proof_bytes[start + 32:start + 64],
                                    'big')))

            c0 = int.from_bytes(proof_bytes[start + 64:start + 96], 'big')
            s0 = int.from_bytes(proof_bytes[start + 96:start + 128], 'big')
            s1 = int.from_bytes(proof_bytes[start + 128:start + 160], 'big')

            #Segment 1
            A = bn128.add(bn128.multiply(C, c0), bn128.multiply(G1, s0))
            c1 = int.from_bytes(
                keccak_256(A[0].n.to_bytes(32, 'big') +
                           A[1].n.to_bytes(32, 'big')).digest(), 'big')

            #Segment 2
            A = bn128.add(bn128.multiply(bn128.add(C, H_neg), c1),
                          bn128.multiply(G1, s1))
            c0p = int.from_bytes(
                keccak_256(A[0].n.to_bytes(32, 'big') +
                           A[1].n.to_bytes(32, 'big')).digest(), 'big')

            if (c0 != c0p):
                return i

    return -1
示例#6
0
def Verify(pk1, X1, Y1, pk2, X2, Y2, A1, A2, B1, B2, z1, z2, z3):
    #Fiat Shamir
    hasher = keccak_256()
    hasher.update(A1[0].n.to_bytes(32, 'big'))
    hasher.update(A1[1].n.to_bytes(32, 'big'))
    hasher.update(A2[0].n.to_bytes(32, 'big'))
    hasher.update(A2[1].n.to_bytes(32, 'big'))
    hasher.update(B1[0].n.to_bytes(32, 'big'))
    hasher.update(B1[1].n.to_bytes(32, 'big'))
    hasher.update(B2[0].n.to_bytes(32, 'big'))
    hasher.update(B2[1].n.to_bytes(32, 'big'))
    e = int.from_bytes(hasher.digest(), 'big')

    #Verifier checks
    left = bn128.add(A1, bn128.multiply(X1, e))
    right = bn128.multiply(pk1, z1)
    if not eq(left, right):
        return False

    left = bn128.add(A2, bn128.multiply(X2, e))
    right = bn128.multiply(pk2, z2)
    if not eq(left, right):
        return False

    left = bn128.add(B1, bn128.multiply(Y1, e))
    right = bn128.add(bn128.multiply(bn128.G1, z1), bn128.multiply(H, z3))
    if not eq(left, right):
        return False

    left = bn128.add(B2, bn128.multiply(Y2, e))
    right = bn128.add(bn128.multiply(bn128.G1, z2), bn128.multiply(H, z3))
    if not eq(left, right):
        return False

    return True
示例#7
0
    def verify(self, proof):
        """Verify if a proof is correct for the given inputs"""
        if not isinstance(proof, Proof):
            raise TypeError("Invalid proof type")

        # Compute the linear combination vk_x
        # vk_x = IC[0] + IC[1]^x[0] + ... + IC[n+1]^x[n]
        vk_x = self.IC[0]
        for i, x in enumerate(proof.input):
            IC_mul_x = multiply(self.IC[i + 1], x)
            vk_x = add(vk_x, IC_mul_x)

        # e(V_a,P_a) * e(G2,-P_a_p) == 1
        if not pairingProd((proof.a, self.a), (neg(proof.a_p), bn128.G2)):
            raise RuntimeError("Proof step 1 failed")

        # e(P_b,V_b) * e(G2,-P_b_p) == 1
        if not pairingProd((self.b, proof.b), (neg(proof.b_p), bn128.G2)):
            raise RuntimeError("Proof step 2 failed")

        # e(V_c,P_c) * e(G2,-P_c_p) == 1
        if not pairingProd((proof.c, self.c), (neg(proof.c_p), bn128.G2)):
            raise RuntimeError("Proof step 3 failed")

        # e(V_g,P_k) * e(V_gb2,-(vk_x+P_a+P_c)) * e(P_b,-P_gb1) == 1
        if not pairingProd(
            (proof.k, self.g),
            (neg(add(vk_x, add(proof.a, proof.c))), self.gb2),
            (neg(self.gb1), proof.b)):
            raise RuntimeError("Proof step 4 failed")

        # e(P_b, vk_x+P_a) * e(V_z,-P_h) * e(G2,-P_c) == 1
        if not pairingProd(
            (add(vk_x, proof.a), proof.b),
            (neg(proof.h), self.z),
            (neg(proof.c), bn128.G2)):
            raise RuntimeError("Proof step 5 failed")

        return True
示例#8
0
    def verify(self, proof):
        """Verify if a proof is correct for the given inputs"""
        if not isinstance(proof, Proof):
            raise TypeError("Invalid proof type")

        # Compute the linear combination vk_x
        # vk_x = gammaABC[0] + gammaABC[1]^x[0] + ... + gammaABC[n+1]^x[n]
        vk_x = self.gammaABC[0]
        for i, x in enumerate(proof.input):
            vk_x = add(vk_x, multiply(self.gammaABC[i + 1], x))

        # e(B, A) * e(gamma, -vk_x) * e(delta, -C) * e(beta, -alpha)
        return pairingProd((proof.A, proof.B), (neg(vk_x), self.gamma),
                           (neg(proof.C), self.delta),
                           (neg(self.alpha), self.beta))
示例#9
0
def verify(vk: SigningVerificationKey, m: bytes, sigma: int) -> bool:
    """
    Return true if the signature sigma is valid on message m and vk.
    We assume here that the message is an hexadecimal string written in
    less than 256 bits to conform with Ethereum bytes32 type.
    """
    # Encode and hash the verifying key and input hashes
    challenge_to_hash = g1_to_bytes(vk.spk) + m

    challenge = int(sha256(challenge_to_hash).hexdigest(), 16)
    challenge = challenge % ZETH_PRIME

    left_part = ec.multiply(ec.G1, FQ(sigma).n)
    right_part = ec.add(vk.spk, ec.multiply(vk.ppk, FQ(challenge).n))

    return ec.eq(left_part, right_part)
示例#10
0
def MixCommitments(a_bytes, b_bytes):
    #Fetch individual commitments
    a_asset, a_commitments = ExtractCommitments(a_bytes)
    b_asset, b_commitments = ExtractCommitments(b_bytes)

    #Create Mixture
    c_bytes = bytes()
    for i in range(0, len(a_commitments)):
        A = (bn128.FQ(a_commitments[i][0]), bn128.FQ(a_commitments[i][1]))

        for j in range(0, len(b_commitments)):
            B = (bn128.FQ(b_commitments[j][0]), bn128.FQ(b_commitments[j][1]))

            C = bn128.add(A, B)
            c_bytes += C[0].n.to_bytes(32, 'big') + C[1].n.to_bytes(32, 'big')

    return c_bytes
示例#11
0
    def generateCommitment(publicKey, alpha, beta, secretRandomness,
                           currentD0_2i, currentD1_2i, isZeroEncryption):
        com = Proof()
        com.secretRandomness = secretRandomness
        com.isZeroEncryption = isZeroEncryption
        com.publicKey = publicKey
        com.alpha = alpha
        com.beta = beta
        com.currentD0_2i = currentD0_2i
        com.currentD1_2i = currentD1_2i

        if isZeroEncryption == False:
            com.r2 = getRandomElement()
            com.d2 = getRandomElement()
            com.w = getRandomElement()

            # a1 = w G
            # b1 = w H
            com.a1 = bn128.multiply(bn128.G1, com.w.n)
            com.b1 = bn128.multiply(publicKey, com.w.n)

            # a2 = r_2G + d2 beta
            com.a2 = bn128.add(bn128.multiply(bn128.G1, com.r2.n),
                               bn128.multiply(beta, com.d2.n))
            # b2 = r_2H + d2 alpha
            com.b2 = bn128.add(bn128.multiply(publicKey, com.r2.n),
                               bn128.multiply(alpha, com.d2.n))
        else:
            com.r1 = getRandomElement()
            com.d1 = getRandomElement()
            com.w = getRandomElement()

            # a1 = r_1 G + d1 (beta - 2iD0)
            inner = bn128.add(beta, bn128.neg(currentD0_2i))
            com.a1 = bn128.add(bn128.multiply(bn128.G1, com.r1.n),
                               bn128.multiply(inner, com.d1.n))
            # b1 = r_1 H + d1 (alpha - 2i D_1)
            inner = bn128.add(alpha, bn128.neg(currentD1_2i))
            com.b1 = bn128.add(bn128.multiply(publicKey, com.r1.n),
                               bn128.multiply(inner, com.d1.n))

            # a2 = w G
            # b2 = w H
            com.a2 = bn128.multiply(bn128.G1, com.w.n)
            com.b2 = bn128.multiply(publicKey, com.w.n)

        return com
示例#12
0
def pedersen_c(v, r=None):
  if r is None:
    r = randsn()
  return add(multiply(G1, v), multiply(H, r)), r
示例#13
0
from time import time

from py_eth_pairing import curve_add, curve_mul, pairing2, curve_negate
from py_ecc.bn128 import G1, G2, add, multiply, curve_order, pairing

print("curve_add")
t0 = time()
actual = curve_add(G1, G1)
print(time() - t0)
expected = add(G1, G1)
assert actual == expected

print("curve_mul")
sc = curve_order - 10
g1_pk = multiply(G1, sc)
t0 = time()
actual = curve_mul(g1_pk, sc)
print(time() - t0)
expected = multiply(g1_pk, sc)
assert actual == expected

print("pairing2: expect true")
sc = 123
g1_pk = multiply(G1, sc)
g2_pk = multiply(G2, sc)
t0 = time()
actual = pairing2(curve_negate(g1_pk), G2, G1, g2_pk)
print(time() - t0)
expected = True
assert actual == expected
示例#14
0
def GenerateOneBitRangeProofs(
        count=16,
        asset_address=0x0000000000000000000000000000000000000000,
        compress_proofs=False,
        print_proof=False):
    sr = SystemRandom()

    #Pick values and blinding factors
    #Pick equal number of each
    assert (IsPowerOf2(count))
    if count == 1:
        pc = [(sr.randint(0, 1), sr.getrandbits(256))]
        pcp = []
    else:
        pc = [(sr.randint(0, 1), sr.getrandbits(256))
              for i in range(0, count // 2)]
        pcp = [(1 - pc[i][0], sr.getrandbits(256))
               for i in range(0, count // 2)]

    private_commitments = pc + pcp

    if (count % 1 == 1):
        private_commitments += (sr.randint(0, 1), sr.getrandbits(256))

    #Get generator points
    G1 = bn128.G1
    H = H_from_address(asset_address)

    #Initialize proof memory
    proofs = asset_address.to_bytes(20, 'big')

    for x in private_commitments:
        #Calculate Ring
        C = bn128.multiply(G1, x[1])

        if x[0] == 1:
            C = bn128.add(C, H)

            #Random Numbers
            alpha = sr.getrandbits(256)
            s0 = sr.getrandbits(256)

            #Begin Ring
            A = bn128.multiply(G1, alpha)
            c0 = int.from_bytes(
                keccak_256(A[0].n.to_bytes(32, 'big') +
                           A[1].n.to_bytes(32, 'big')).digest(), 'big')

            #Segment 0
            A = bn128.multiply(C, c0)
            B = bn128.multiply(G1, s0)
            A = bn128.add(A, B)
            c1 = int.from_bytes(
                keccak_256(A[0].n.to_bytes(32, 'big') +
                           A[1].n.to_bytes(32, 'big')).digest(), 'big')

            #Complete Ring
            s1 = (alpha - c1 * x[1]) % bn128.curve_order

        else:
            #"Random Numbers"
            alpha = sr.getrandbits(256)
            s1 = sr.getrandbits(256)

            #Being Ring
            A = bn128.multiply(G1, alpha)
            c1 = int.from_bytes(
                keccak_256(A[0].n.to_bytes(32, 'big') +
                           A[1].n.to_bytes(32, 'big')).digest(), 'big')

            #Segment 1
            Cp = bn128.add(C, (H[0], -H[1]))
            A = bn128.multiply(Cp, c1)
            B = bn128.multiply(G1, s1)
            A = bn128.add(A, B)
            c0 = int.from_bytes(
                keccak_256(A[0].n.to_bytes(32, 'big') +
                           A[1].n.to_bytes(32, 'big')).digest(), 'big')

            #Complete Ring
            s0 = (alpha - c0 * x[1]) % bn128.curve_order

        #Store proof data
        if compress_proofs:
            c_compressed = C[0].n

            if (C[1].n & 1 == 1):
                c_compressed |= 0x8000000000000000000000000000000000000000000000000000000000000000

            proofs += c_compressed.to_bytes(32, 'big')
        else:
            proofs += C[0].n.to_bytes(32, 'big')
            proofs += C[1].n.to_bytes(32, 'big')

        proofs += c0.to_bytes(32, 'big')
        proofs += s0.to_bytes(32, 'big')
        proofs += s1.to_bytes(32, 'big')

    if (print_proof):
        print("Proof:")
        print("0x" + proofs.hex())

    return private_commitments, proofs
示例#15
0
def ecAdd(p1: Point, p2: Point) -> Point:
    p1 = FQ(p1[0]), FQ(p1[1])
    p2 = FQ(p2[0]), FQ(p2[1])
    return fq2point(add(p1, p2))
示例#16
0
s0 = sr.getrandbits(256)

G1 = bn128.G1
P = bn128.multiply(G1, p)
Q = bn128.multiply(G1, q)

#Being Ring
A = bn128.multiply(G1, alpha)
c0 = int.from_bytes(
    keccak_256(A[0].n.to_bytes(32, 'big') +
               A[1].n.to_bytes(32, 'big')).digest(), 'big')

#Segment 0
A = bn128.multiply(P, c0)
B = bn128.multiply(G1, s0)
A = bn128.add(A, B)
c1 = int.from_bytes(
    keccak_256(A[0].n.to_bytes(32, 'big') +
               A[1].n.to_bytes(32, 'big')).digest(), 'big')

#Complete Ring
s1 = (alpha - c1 * q) % bn128.curve_order

#Mix Ring
if sr.randrange(0, 2) == 0:
    P, Q, c0, s0, s1 = Q, P, c1, s1, s0

#Output
print(hex(P[0].n))
print(hex(P[1].n))
print(hex(Q[0].n))
示例#17
0
# t(x) = 0x^3 + 1x^2 - 3x + 2
t_coefficients = [0, 1, 3, 2][::-1]

# h(x) = 0x^3 + 0x^2 - 1x + 0
h_coefficients = [0, 0, 1, 0][::-1]

s = randsn()
alpha = randsn()

### Setup
g_s_i = [multiply(bn128.G2, pow(s, i)) for i in range(polynomial_degree)]
g_alpha_s_i = list(map(lambda x: multiply(x, alpha), g_s_i))

g_alpha = multiply(bn128.G1, alpha)
g_t_s = reduce(lambda acc, x: add(acc, x), [
    multiply(bn128.G1, t_coefficients[i] * pow(s, i))
    for i in range(polynomial_degree)
])

### Proving
g_p_s = reduce(
    lambda acc, x: add(acc, x),
    [multiply(g_s_i[i], p_coefficients[i]) for i in range(polynomial_degree)])

g_h_s = reduce(
    lambda acc, x: add(acc, x),
    [multiply(g_s_i[i], h_coefficients[i]) for i in range(polynomial_degree)])

g_alpha_p_s = reduce(lambda acc, x: add(acc, x), [
    multiply(g_alpha_s_i[i], p_coefficients[i])
示例#18
0
if __name__ == "__main__":
    #Open DB
    db = TinyDB('client_db.json')
    tbl = db.table('commitments')
    data = tbl.all()
    assert (len(data) > 0)

    #Index private commitments and sort by hidden value bit
    v = 100
    asset_address = 0
    private_bit_commitments = data[0]['private']
    indices, total_bf = BuildCommitmentPrivate(v,
                                               private_bit_commitments,
                                               target_bits=64)
    C_expected = bn128.add(bn128.multiply(bn128.G1, total_bf),
                           bn128.multiply(H_from_address(asset_address), v))
    print("Commitment Generated")
    print("asset_address = 0x" + asset_address.to_bytes(20, 'big').hex())
    print("value = " + str(v))
    print("bf = " + hex(total_bf)[2:])
    print("(" + C_expected[0].n.to_bytes(32, 'big').hex() + ",")
    print(C_expected[1].n.to_bytes(32, 'big').hex() + ")")
    print()

    #Test commitment build
    _, public_bit_commitments = ExtractCommitments(
        bytes.fromhex(data[0]['data']))
    C_out = BuildCommitmentPublic(public_bit_commitments, indices)
    print("Assembled Commitment")
    print("(" + C_out[0].n.to_bytes(32, 'big').hex() + ",")
    print(C_out[1].n.to_bytes(32, 'big').hex() + ")")
示例#19
0
def add(pointA: Point, pointB: Point) -> Point:
    # wrapper for bn128.add, adding/removing the FQ class
    return _unwrap(bn128.add(_wrap(pointA), _wrap(pointB)))
示例#20
0
def Enc(pk, m, r):
    X = bn128.multiply(pk, r)
    Y = bn128.add(bn128.multiply(bn128.G1, r), bn128.multiply(H, m))
    return (X, Y)