def encryptC(self, a, p): random = getRandomElement().n hR = bn128.bn128_curve.multiply(self.publicKey, random) gM = bn128.multiply(bn128.multiply(bn128.G1, a.n), p.n) return Ciphertext(bn128.bn128_curve.multiply(bn128.G1, random), bn128.bn128_curve.add(hR, bn128.neg(gM)))
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
def set_monitor_parameters(self, address): ta, tb, tc, s = self.monitor_parameters(address) target1, _ = pedersen_c(ta, tb) target2 = multiply(G1, tc) shuffle = multiply(G1, s) tx_hash = self.contract.functions.setMonitorParameters(address, pasint(target1) + pasint(target2) + pasint(shuffle)).transact() receipt = self.wait_tx(tx_hash) return ta, tb, tc, s, receipt
def gen_signing_keypair() -> SigningKeyPair: """ Return a one-time signature key-pair composed of elements of F_q and G1. """ key_size_byte = ceil(len("{0:b}".format(ZETH_PRIME)) / 8) x = FQ(int(bytes(urandom(key_size_byte)).hex(), 16) % ZETH_PRIME) y = FQ(int(bytes(urandom(key_size_byte)).hex(), 16) % ZETH_PRIME) X = ec.multiply(ec.G1, x.n) Y = ec.multiply(ec.G1, y.n) return SigningKeyPair(x, y, X, Y)
def gen_signing_keypair() -> SigningKeyPair: """ Return a one-time signature key-pair composed of elements of F_q and G1. """ key_size_byte = ceil(len("{0:b}".format(ec.curve_order)) / 8) x = FQ(int(bytes(urandom(key_size_byte)).hex(), 16) % ec.curve_order) y = FQ(int(bytes(urandom(key_size_byte)).hex(), 16) % ec.curve_order) X = ec.multiply(ec.G1, x.n) Y = ec.multiply(ec.G1, y.n) # We include y_g1 in the signing key sk = SigningSecretKey(x, y, Y) vk = SigningVerificationKey(X, Y) return SigningKeyPair(sk, vk)
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)
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)
def __init__(self, prikey): if isinstance(prikey, PriKey): self.prikey = prikey pk = bn.multiply(bn.G1, self.prikey.sk) # pk = g^sk self.pubkey = PubKey(pk) else: raise TypeError("require PubKey and PriKey type!")
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)
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
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)
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
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))
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
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
def ecMul(p: Point, x: int) -> Point: pt = FQ(p[0]), FQ(p[1]) return fq2point(multiply(pt, x))
from typing import Tuple, List, Union from py_ecc import bn128 from py_ecc.bn128 import FQ, add, multiply, double # Signature :: (Initial construction value, array of public keys, link of unique signer) Point = Tuple[int, int] Signature = Tuple[int, List[int], Point] Scalar = int asint = lambda x: x.n if isinstance(x, bn128.FQ) else x fq2point = lambda x: (asint(x[0]), asint(x[1])) randsn = lambda: randint(1, N - 1) randsp = lambda: randint(1, P - 1) sbmul = lambda s: bn128.multiply(G, asint(s)) addmodn = lambda x, y: (x + y) % N addmodp = lambda x, y: (x + y) % P mulmodn = lambda x, y: (x * y) % N mulmodp = lambda x, y: (x * y) % P submodn = lambda x, y: (x - y) % N submodp = lambda x, y: (x - y) % P negp = lambda x: (x[0], -x[1]) def to_hex(x): if type(x) is tuple: return (to_hex(x[0]), to_hex(x[1])) if type(x) is int: return (x).to_bytes(32, 'big').hex()
def test_pairing_python(): assert pairing(G2, multiply(G1, 5)) == pairing(multiply(G2, 5), G1)
# -*- coding: utf-8 -*- from __future__ import print_function import sys import trstools as T from py_ecc import bn128 from random import randint from hashlib import sha256 from py_ecc.bn128 import add, multiply, double, curve_order, field_modulus, G1, eq from py_ecc.bn128.bn128_field_elements import inv bytes_to_int = lambda x: reduce(lambda o, b: (o << 8) + ord(b), [0] + list(x)) rands = lambda: randint(1, curve_order - 1) sbmul = lambda s: multiply(G1, s) hashs = lambda *x: bytes_to_int( sha256('.'.join(['%X' for _ in range(0, len(x))]) % x).digest()) % curve_order hashp = lambda *x: hashs(*[item.n for sublist in x for item in sublist]) expr_funcs = dict( G=sbmul, Point=lambda x: x if isinstance(x, tuple) else sbmul(x), PointInfinity=lambda: None, PointDouble=lambda x: double(x), Sub=lambda x, y: (x - y) % curve_order, Neg=lambda x: -x % curve_order, Inv=lambda x: inv(x, curve_order), #InvMul=lambda x, y: (x * pow(y, field_modulus-2, field_modulus)), Add=lambda x, y: (x + y) % curve_order, Mul=lambda x, y: (x * y) % curve_order, ScalarMult=multiply, PointNeg=lambda x: (x[0], -x[1]),
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 Gen(): sk = SystemRandom().getrandbits(256) pk = bn128.multiply(bn128.G1, sk) return (sk, pk)
def test_pairing_python_neg(): assert pairing(G2, multiply(G1, 5)) != pairing(multiply(G2, 5), neg(G1))
from random import randint from past.builtins import long from py_ecc import bn128 from py_ecc.bn128 import add, multiply, curve_order, G1 from py_ecc.bn128.bn128_field_elements import inv, field_modulus, FQ from .utils import hashs, bytes_to_int, powmod asint = lambda x: x.n if isinstance(x, FQ) else x randsn = lambda: randint(1, curve_order - 1) randsp = lambda: randint(1, field_modulus - 1) sbmul = lambda s: multiply(G1, asint(s)) hashsn = lambda *x: hashs(*x) % curve_order hashpn = lambda *x: hashsn(*[item.n for sublist in x for item in sublist]) hashp = lambda *x: hashs(*[item.n for sublist in x for item in sublist]) addmodn = lambda x, y: (x + y) % curve_order addmodp = lambda x, y: (x + y) % field_modulus mulmodn = lambda x, y: (x * y) % curve_order expmodn = lambda x, y: (x ** y) % curve_order mulmodp = lambda x, y: (x * y) % field_modulus submodn = lambda x, y: (x - y) % curve_order submodp = lambda x, y: (x - y) % field_modulus invmodn = lambda x: inv(x, curve_order) invmodp = lambda x: inv(x, field_modulus) negp = lambda x: (x[0], -x[1]) pasint = lambda p: (asint(p[0]), asint(p[1])) mpasint = lambda *mp: [list(pasint(p)) for p in mp] serring = lambda *x: [mpasint(*sublist) for sublist in x]
def interpolate(self, others): return bn128.multiply(bn128.multiply(bn128.G1, self.y.n), getLagrange(self.x, others).n)
# -*- coding: utf-8 -*- from __future__ import print_function import sys import trstools as T from py_ecc import bn128 from random import randint from hashlib import sha256 from py_ecc.bn128 import add, multiply, double, curve_order, field_modulus, G1, eq from py_ecc.bn128.bn128_field_elements import inv bytes_to_int = lambda x: reduce(lambda o, b: (o << 8) + ord(b), [0] + list(x)) rands = lambda: randint(1, curve_order - 1) sbmul = lambda s: multiply(G1, s) hashs = lambda *x: bytes_to_int( sha256('.'.join(['%X' for _ in range(0, len(x))]) % x).digest()) % curve_order hashp = lambda *x: hashs(*[item.n for sublist in x for item in sublist]) fake_g = rands() fake_G = sbmul(fake_g) fake_sbmul = lambda x: multiply(fake_G, x) expr_funcs = dict( TypeScalar=lambda x: x, TypePoint=lambda x: x, Opaque=lambda x: x, G=fake_sbmul, GDL=lambda: fake_g, Point=lambda x: x if isinstance(x, tuple) else fake_sbmul(x), PointDouble=lambda x: double(x), Sub=lambda x, y: (x - y) % curve_order,
def mulmodp(x, y): return (x * y) % P """ Section 3.4 (Page 16) Simple restriction for a single coefficient polynomial """ alpha = randsp() s = randsp() coefficient = randsp() # Verifier g_s = multiply(bn128.G1, s) g_alpha_s = multiply(bn128.G1, alpha * s) # Prover (doesn't have alpha) g_s_c = multiply(g_s, coefficient) g_alpha_s_c = multiply(g_alpha_s, coefficient) assert multiply(g_s_c, alpha) == g_alpha_s_c """ Section 3.4 (Page 17) Restriction for polynomials with multiple coefficients """ polynomial_degree = 4 G = 446827
from py_ecc import bn128 from sha3 import keccak_256 from random import SystemRandom #"Private Keys" sr = SystemRandom() p = sr.getrandbits(256) q = sr.getrandbits(256) #"Random Numbers" alpha = sr.getrandbits(256) 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')
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() + ",")
def test_pairing_check_pyecc(): sk = random_scalar(seed=1) pk = bn128.multiply(bn128.G1, sk) bls_pk = bn128.multiply(bn128.G2, sk) assert bn128.pairing(bn128.G2, pk) == bn128.pairing(bls_pk, bn128.G1)
def generateCommitment(c_0_tilde): r = getRandomElement() c_0_tilde_r = bn128.multiply(c_0_tilde, r.n) g_r = bn128.multiply(bn128.G1, r.n) return (r, c_0_tilde_r, g_r)