Example #1
0
def _wrap(point):
    if len(point) == 2:
        x, y = point
        return bn128.FQ(x), bn128.FQ(y)

    if len(point) == 4:
        ai, a, bi, b = point
        return bn128.FQ2([a, ai]), bn128.FQ2([b, bi])

    raise ValueError(f"Invalid argument point: {point}")
Example #2
0
def hash_to_G1_old(msg: Any) -> PointG1:
    i = 0
    while True:
        h = hashlib.sha3_256(f"{i} || {msg}".encode()).digest()
        x = int.from_bytes(h, "big") % bn128.field_modulus
        y = sympy.sqrt_mod(x**3 + 3, bn128.field_modulus)
        if y:
            assert y**2 % bn128.field_modulus == (x**3 +
                                                  3) % bn128.field_modulus
            return _unwrap((bn128.FQ(x), bn128.FQ(y)))
        i += 1
Example #3
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
Example #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)
Example #5
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
Example #6
0
    def evaluate(self, x):
        result = 0
        i = 0

        for coefficient in self.coefficients:
            result = (result + (coefficient.n * pow(x, i, bn128.curve_order))
                      ) % bn128.curve_order
            i += 1

        return bn128.FQ(result % bn128.curve_order)
Example #7
0
def H_from_address(address):
    if type(address) == bytes:
        x = bn128.FQ(int.from_bytes(keccak_256(address).digest(), 'big'))
    else:
        x = bn128.FQ(
            int.from_bytes(
                keccak_256(address.to_bytes(20, 'big')).digest(), 'big'))

    on_curve = False
    while not on_curve:
        y2 = x**3 + bn128.b
        y = y2**((bn128.field_modulus + 1) // 4)

        if (y**2 == y2):
            on_curve = True
        else:
            x += 1

    return (x, y)
def hashPointsToCurve(points):
    hashableString = ""

    for point in points:
        hashableString += repr(point[0]) + repr(point[1])

    hashableString = hashableString.encode('utf-8')

    return bn128.FQ((int(hashlib.sha256(hashableString).hexdigest(), 16) %
                     bn128.curve_order))
Example #9
0
async def constructPartyPart(senderAddress, ciphertext, challenge,
                             secretKeyPart, x, client, attemptID):
    psi = getRandomElement()

    c0I = bn128.multiply(bn128.multiply(ciphertext.first, psi.n),
                         secretKeyPart.n)
    k_i = bn128.multiply(bn128.multiply(bn128.G2, challenge.n),
                         inv(psi.n, bn128.curve_order))

    com = SecondNIZKP.generateCommitment(ciphertext.first)
    challenge = bn128.FQ(
        client.getChallengeNZIK2(attemptID, com[1], com[2], bn128.FQ(x)))

    nzik2 = SecondNIZKP.generateProof(com[0], com[1], com[2], secretKeyPart,
                                      challenge)

    cost = client.verifyNZIK2(attemptID, senderAddress, nzik2.c_0_tilde_r,
                              nzik2.g_r, nzik2.proof)

    return (c0I, k_i, nzik2, cost)
Example #10
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
Example #11
0
def getLagrange(x, others):
    product = 1

    for xOther in others:
        if x != xOther.n:
            upperTerm = (-(xOther.n) + bn128.curve_order) % bn128.curve_order
            lowerTerm = inv(
                ((x - xOther.n) + bn128.curve_order) % bn128.curve_order,
                bn128.curve_order)
            product = (product *
                       ((upperTerm * lowerTerm) % bn128.curve_order) %
                       bn128.curve_order)

    return bn128.FQ(product)
Example #12
0
    def computeProof(commitment, challenge):
        # we calculate the proof depending on which encryption we have
        if commitment.isZeroEncryption:
            commitment.d2 = bn128.FQ(
                (challenge.n - commitment.d1.n + bn128.curve_order) %
                bn128.curve_order)
            commitment.r2 = bn128.FQ(
                ((commitment.w.n -
                  ((commitment.secretRandomness.n * commitment.d2.n) %
                   bn128.curve_order)) + bn128.curve_order) %
                bn128.curve_order)
        else:
            commitment.d1 = bn128.FQ(
                ((challenge.n - commitment.d2.n) + bn128.curve_order) %
                bn128.curve_order)
            commitment.r1 = bn128.FQ(
                ((commitment.w.n -
                  ((commitment.secretRandomness.n * commitment.d1.n) %
                   bn128.curve_order)) + bn128.curve_order) %
                bn128.curve_order)

        # now holds the proof as well
        return commitment
 def fromBlockchain(array):
     return Ciphertext((bn128.FQ(array[0][0]), bn128.FQ(array[0][1])),
                       (bn128.FQ(array[1][0]), bn128.FQ(array[1][1])))
    def generateProof(r, c_0_tilde_r, g_r, secretKey, challenge):
        z = (((secretKey.n * challenge.n) % bn128.curve_order) +
             r.n) % bn128.curve_order

        return SecondNIZKP(c_0_tilde_r, g_r, bn128.FQ(z))
Example #15
0
from random import SystemRandom
from py_ecc import bn128
from sha3 import keccak_256

H = (bn128.FQ(
    0x231c7944cd500565013d56c25cc8c77a6613cb6b2ccd0831240d1e8d3eea33e3),
     bn128.FQ(
         0x909c50f22cfb8da32dc5a2ad0380e1c0f5b0d9860dd49a566da7f77c600d03c))


def Gen():

    sk = SystemRandom().getrandbits(256)
    pk = bn128.multiply(bn128.G1, sk)

    return (sk, pk)


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)


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
def getRandomElement():
    newElement = 0
    while (newElement == 0 or newElement == 1):
        newElement = secrets.randbelow(bn128.curve_order)
    return bn128.FQ(newElement)
def hashToCurve(message):
    return bn128.FQ(
        (int(hashlib.sha256(message).hexdigest(), 16) % bn128.curve_order))
Example #18
0
async def run(threshold, amount, runID, contractAddress):

    runtimeInfo = {}

    accounts = BlockchainProvider.getAccounts(providerURL)
    secretKeys = []
    members = []

    client = BlockchainProvider(providerURL, contractABIPath, contractAddress,
                                accounts[10 + runID])

    # Setup secret sharing and generate a sharing for the parties
    secretKey = getRandomElement()
    publicKey = bn128.multiply(bn128.G1, secretKey.n)

    shares = generateSharing(secretKey, threshold, amount)

    p = getRandomElement()

    # a is the input string a user would give, mapped into FQ. For this prototype we just use a random value.
    a = getRandomElement()
    elGamalInstance = ElGamal(publicKey)
    dCipher = elGamalInstance.encrypt(p)
    cCipher = elGamalInstance.encryptC(a, p)

    for i in range(amount):
        members.append(toChecksum(accounts[i + 1]))
        secretKeys.append(shares[i].y)

    # Create the group
    runtimeInfo['GroupCreation'] = client.createCommittee(
        members, amount, cCipher, dCipher, None)
    print("Group with ", amount, " members created!")

    runtimeInfo['AddKey'] = 0
    runtimeInfo['AddPart'] = 0
    runtimeInfo['PoK1'] = 0
    runtimeInfo['PoK2'] = 0
    runtimeInfo['Validation'] = 0

    # Each party posts its public keys
    for i in range(amount):
        cost = client.addKey(bn128.multiply(bn128.G1, secretKeys[i].n),
                             members[i])
        runtimeInfo['AddKey'] += cost
        runtimeInfo['GroupCreation'] += cost

    print("Constructing query. This will take a while ...")

    # For now we only want to send one attempt
    attemptIDAsBytes = bytes('0x' + str(1), 'utf8')

    # Construct the query as encryption of the binary encoding
    encodedQuery = await constructBinaryRepresentation(client,
                                                       attemptIDAsBytes,
                                                       elGamalInstance,
                                                       dCipher, a, p,
                                                       secretKey)

    # Add up the binary encoding and calculate c0_tilde and c1_tilde
    addedCiphertexts = encodedQuery[0][0]
    for i in range(len(encodedQuery[0])):
        if i != 0:
            addedCiphertexts *= encodedQuery[0][i]

    cTilde = cCipher * addedCiphertexts

    challenge = bn128.FQ(client.getKScalar(attemptIDAsBytes))
    k = bn128.multiply(bn128.G2, challenge.n)

    runtimeInfo['Query'] = client.query(attemptIDAsBytes, encodedQuery[0],
                                        encodedQuery[1], cTilde.first,
                                        cTilde.second, k)

    print("Query sent")

    xOthers = []
    for x in range(1, amount + 1):
        xOthers.append(bn128.FQ(x))

    # each party now calculates its parts based on its secret key
    for i in range(amount):
        partyPartSingle = await constructPartyPart(members[i], cTilde,
                                                   challenge, shares[i].y,
                                                   i + 1, client,
                                                   attemptIDAsBytes)
        cost = client.addPart(attemptIDAsBytes, members[i], partyPartSingle[0],
                              partyPartSingle[1])
        runtimeInfo['AddPart'] += cost
        runtimeInfo['Validation'] += cost + partyPartSingle[3]

    print("Parties have submitted their parts")
    await asyncio.sleep(1)

    runtimeInfo['Verify'] = client.verdict(attemptIDAsBytes)

    return runtimeInfo