This is an automated email from the ASF dual-hosted git repository. sandreoli pushed a commit to branch update-model-no-replay in repository https://gitbox.apache.org/repos/asf/incubator-milagro-MPC.git
commit 95f99e64334f7655c9976afb48951531fdb03cbf Author: Samuele Andreoli <[email protected]> AuthorDate: Wed Feb 5 09:57:59 2020 +0000 Amend model and test vectors generation for receiver ZK proof --- model/examples/run_mta.py | 30 +++--- model/sec256k1/mta.py | 208 +++++++++++++++++++++++++++++++++++------ model/vectors/mta/genVector.py | 174 +++++++++++++++++++++++++++++----- model/vectors/mta/genZK.py | 100 ++++++++++++++++++++ 4 files changed, 446 insertions(+), 66 deletions(-) diff --git a/model/examples/run_mta.py b/model/examples/run_mta.py index 88ea519..cea22d0 100755 --- a/model/examples/run_mta.py +++ b/model/examples/run_mta.py @@ -96,7 +96,7 @@ def check_zk_setup(prover, verifier, k): prover["zk_pq"], prover["zk_P"], prover["zk_Q"]) - + prover["zk_r0"] = r0 prover["zk_r1"] = r1 prover["zk_c0"] = c0 @@ -109,14 +109,14 @@ def check_zk_setup(prover, verifier, k): prover["zk_c0"], prover["zk_c1"], k) - + verifier["zk_e0"] = e0 verifier["zk_e1"] = e1 - + p0, p1 = commitments.bc_setup_proof( prover["zk_r0"], prover["zk_r1"], - verifier["zk_e0"], + verifier["zk_e0"], verifier["zk_e1"], prover["zk_alpha"], prover["zk_ialpha"], @@ -201,7 +201,7 @@ if __name__ == "__main__": alice["mta_rp_z"], alice["mta_rp_u"], alice["mta_rp_w"]) s, s1, s2 = mta.rp_prove( - alice["mta_mult_share"], alice["mta_r"], alice["mta_CA"], + alice["mta_mult_share"], alice["mta_r"], bob["mta_rp_e"], alice["mta_rp_alpha"], alice["mta_rp_beta"], alice["mta_rp_gamma"], alice["mta_rp_rho"], alice["paillier_p"], alice["paillier_q"]) @@ -211,13 +211,13 @@ if __name__ == "__main__": alice["mta_rp_s2"] = s2 if not mta.rp_verify( - alice["mta_rp_s"], alice["mta_rp_s1"], alice["mta_rp_s2"], + alice["mta_CA"], alice["mta_rp_s"], alice["mta_rp_s1"], alice["mta_rp_s2"], alice["mta_rp_z"], alice["mta_rp_u"], alice["mta_rp_w"], bob["mta_rp_e"], alice["paillier_g"], alice["zk_b0"], alice["zk_b1"], curve.r, alice["paillier_n"], alice["zk_P"], alice["zk_Q"]): - + dumpgame(alice, bob) print("Range Proof Failed") sys.exit(1) @@ -254,7 +254,9 @@ if __name__ == "__main__": bob["mta_rrp_v"] = v bob["mta_rrp_w"] = w - alice["mta_rrp_e"] = mta.mta_challenge(curve.r) + alice["mta_rrp_e"] = mta.mta_challenge( + alice["paillier_g"], alice["zk_N"], alice["zk_b0"], alice["zk_b1"], curve.r, + alice["mta_CA"], bob["mta_CB"], bob["mta_rrp_z"], bob["mta_rrp_z1"], bob["mta_rrp_t"], bob["mta_rrp_v"], bob["mta_rrp_w"]) s, s1, s2, t1, t2 = mta.mta_prove( bob["mta_mult_share"], bob["mta_beta1"], bob["mta_r"], @@ -276,7 +278,7 @@ if __name__ == "__main__": alice["mta_rrp_e"], alice["paillier_g"], alice["zk_b0"], alice["zk_b1"], - curve.r, alice["paillier_n"], alice["zk_N"]): + curve.r, alice["paillier_p"], alice["paillier_q"], alice["zk_P"], alice["zk_Q"]): dumpgame(alice, bob) print("Receiver Range Proof Failed") @@ -303,7 +305,7 @@ if __name__ == "__main__": if mta_mult != mta_add: dumpgame(alice, bob) print("MtA Failed") - sys.exit(1) + sys.exit(1) print("Done!\n") @@ -340,7 +342,9 @@ if __name__ == "__main__": bob["mtawc_rrp_v"] = v bob["mtawc_rrp_w"] = w - alice["mtawc_rrp_e"] = mta.mtawc_challenge(curve.r) + alice["mtawc_rrp_e"] = mta.mtawc_challenge( + alice["paillier_g"], alice["zk_N"], alice["zk_b0"], alice["zk_b1"], curve.r, + alice["mta_CA"], bob["mtawc_CB"], bob["mtawc_rrp_u"], bob["mtawc_rrp_z"], bob["mtawc_rrp_z1"], bob["mtawc_rrp_t"], bob["mtawc_rrp_v"], bob["mtawc_rrp_w"]) s, s1, s2, t1, t2 = mta.mtawc_prove( bob["mta_mult_share"], bob["mtawc_beta1"], bob["mtawc_r"], @@ -362,7 +366,7 @@ if __name__ == "__main__": alice["mtawc_rrp_e"], alice["paillier_g"], alice["zk_b0"], alice["zk_b1"], - curve.r, alice["paillier_n"], alice["zk_N"]): + curve.r, alice["paillier_p"], alice["paillier_q"], alice["zk_P"], alice["zk_Q"]): dumpgame(alice, bob) print("Receiver Range Proof Failed") @@ -389,7 +393,7 @@ if __name__ == "__main__": if mtawc_mult != mtawc_add: dumpgame(alice, bob) print("MtA Failed") - sys.exit(1) + sys.exit(1) print("Done!\n") diff --git a/model/sec256k1/mta.py b/model/sec256k1/mta.py index 2bba046..e6262a6 100644 --- a/model/sec256k1/mta.py +++ b/model/sec256k1/mta.py @@ -81,10 +81,10 @@ def rp_commit(m, Gamma, h1, h2, q, P, Q, Nt, alpha=None, beta=None, gamma=None, if beta is None: beta = big.rand(N) - + if gamma is None: gamma = big.rand(q3*Nt) - + if rho is None: rho = big.rand(q*Nt) @@ -117,17 +117,17 @@ def rp_challenge(Gamma, Nt, h1, h2, q, c, z, u, w): sha = hashlib.new('sha256') q_bytes = big.to_bytes(q) - + Gamma_bytes = Gamma.to_bytes(FS_2048, byteorder='big') Nt_bytes = Nt.to_bytes(FS_2048, byteorder='big') h1_bytes = h1.to_bytes(FS_2048, byteorder='big') h2_bytes = h2.to_bytes(FS_2048, byteorder='big') c_bytes = c.to_bytes(DFS_2048, byteorder='big') - + z_bytes = z.to_bytes(FS_2048, byteorder='big') u_bytes = u.to_bytes(DFS_2048, byteorder='big') w_bytes = w.to_bytes(FS_2048, byteorder='big') - + sha.update(Gamma_bytes) sha.update(Nt_bytes) sha.update(h1_bytes) @@ -184,31 +184,96 @@ def rp_verify(c,s,s1,s2,z,u,w,e,Gamma,h1,h2,q,N,Pt, Qt): ## MtA ZK proof -def mta_commit(x, y, c, Gamma, h1, h2, q, N, Nt): +def mta_commit( + x, y, c1, + Gamma, h1, h2, q, N, Nt, + alpha = None, beta = None, gamma = None, rho = None, rho1 = None, sigma=None, tau = None): + q3 = q**3 N2 = N**2 - alpha = big.rand(q3) - beta = big.rand(N) - gamma = big.rand(N) - rho = big.rand(q*Nt) - rho1 = big.rand(q3*Nt) - sigma = big.rand(q*Nt) - tau = big.rand(q*Nt) + if alpha is None: + alpha = big.rand(q3) + + if beta is None: + beta = big.rand(N) + + if gamma is None: + gamma = big.rand(N) + + if rho is None: + rho = big.rand(q*Nt) + + if rho1 is None: + rho1 = big.rand(q3*Nt) + + if sigma is None: + sigma = big.rand(q*Nt) + + if tau is None: + tau = big.rand(q*Nt) z = big.modmul(pow(h1, x, Nt), pow(h2, rho, Nt), Nt) z1 = big.modmul(pow(h1, alpha, Nt), pow(h2, rho1, Nt), Nt) t = big.modmul(pow(h1, y, Nt), pow(h2, sigma, Nt), Nt) w = big.modmul(pow(h1, gamma, Nt), pow(h2, tau, Nt), Nt) - v = big.modmul(pow(c, alpha, N2), pow(Gamma, gamma, N2), N2) + v = big.modmul(pow(c1, alpha, N2), pow(Gamma, gamma, N2), N2) v = big.modmul(v, pow(beta, N, N2), N2) return alpha, beta, gamma, rho, rho1, sigma, tau, z, z1, t, v, w -def mta_challenge(q): - return big.rand(q) +def mta_challenge(Gamma, Nt, h1, h2, q, c1, c2, z, z1, t, v, w): + ''' + Use Fiat-Shamir to make this NIZK. + + Bind to public parameters: + * Gamma (Paillier) + * Nt, h1, h2 (BC commitment setup) + * q - range + * c1 public ciphertext + + Bind to commitment: + * z, z1, t, w, v + + Returns e = H(Gamma, Nt, h1, h2, q, c, z, z1, t, v, w) mod q + ''' + sha = hashlib.new('sha256') + + q_bytes = big.to_bytes(q) + + Gamma_bytes = Gamma.to_bytes(FS_2048, byteorder='big') + Nt_bytes = Nt.to_bytes(FS_2048, byteorder='big') + h1_bytes = h1.to_bytes(FS_2048, byteorder='big') + h2_bytes = h2.to_bytes(FS_2048, byteorder='big') + c1_bytes = c1.to_bytes(DFS_2048, byteorder='big') + c2_bytes = c2.to_bytes(DFS_2048, byteorder='big') + + z_bytes = z.to_bytes(FS_2048, byteorder='big') + z1_bytes = z1.to_bytes(FS_2048, byteorder='big') + t_bytes = t.to_bytes(FS_2048, byteorder='big') + w_bytes = w.to_bytes(FS_2048, byteorder='big') + v_bytes = v.to_bytes(2 * FS_2048, byteorder='big') + + sha.update(Gamma_bytes) + sha.update(Nt_bytes) + sha.update(h1_bytes) + sha.update(h2_bytes) + sha.update(q_bytes) + sha.update(c1_bytes) + sha.update(c2_bytes) + + sha.update(z_bytes) + sha.update(z1_bytes) + sha.update(t_bytes) + sha.update(v_bytes) + sha.update(w_bytes) + + e_bytes = sha.digest() + e = big.from_bytes(e_bytes) + + return e % q def mta_prove(x,y,r,e,alpha,beta,gamma,rho,rho1,sigma,tau,N): @@ -222,24 +287,48 @@ def mta_prove(x,y,r,e,alpha,beta,gamma,rho,rho1,sigma,tau,N): return s, s1, s2, t1, t2 -def mta_verify(c1, c2, s, s1, s2, t1, t2, z, z1, t, v, w, e, Gamma, h1, h2, q, N, Nt): +def mta_verify(c1, c2, s, s1, s2, t1, t2, z, z1, t, v, w, e, Gamma, h1, h2, q, P, Q, Pt, Qt): if s1 > q**3: return False - s_proof = big.modmul(pow(h1, s1, Nt), pow(h2, s2, Nt), Nt) - s_gt = big.modmul(pow(z, e, Nt), z1, Nt) + # Compute s using CRT + sp = big.modmul(pow(h1 % Pt, s1, Pt), pow(h2 % Pt, s2 % (Pt-1), Pt), Pt) + sq = big.modmul(pow(h1 % Qt, s1, Qt), pow(h2 % Qt, s2 % (Qt-1), Qt), Qt) + s_proof = big.crt(sp, sq, Pt, Qt) + + sp = big.modmul(pow(z % Pt, e, Pt), z1 % Pt, Pt) + sq = big.modmul(pow(z % Qt, e, Qt), z1 % Qt, Qt) + s_gt = big.crt(sp, sq, Pt, Qt) + if s_proof != s_gt: return False - t_proof = big.modmul(pow(h1, t1, Nt), pow(h2, t2, Nt), Nt) - t_gt = big.modmul(pow(t, e, Nt), w, Nt) + # Compute t using CRT + tp = big.modmul(pow(h1 % Pt, t1 % (Pt-1), Pt), pow(h2 % Pt, t2 % (Pt-1), Pt), Pt) + tq = big.modmul(pow(h1 % Qt, t1 % (Qt-1), Qt), pow(h2 % Qt, t2 % (Qt-1), Qt), Qt) + t_proof = big.crt(tp, tq, Pt, Qt) + + tp = big.modmul(pow(t % Pt, e, Pt), w % Pt, Pt) + tq = big.modmul(pow(t % Qt, e, Qt), w % Qt, Qt) + t_gt = big.crt(tp, tq, Pt, Qt) + if t_proof != t_gt: return False - N2 = N**2 - c_proof = big.modmul(pow(c1, s1, N2), pow(s, N, N2), N2) - c_proof = big.modmul(c_proof, pow(Gamma, t1, N2), N2) - c_gt = big.modmul(pow(c2, e, N2), v, N2) + N = P*Q + P2 = P**2 + Q2 = P**2 + + # Compute c using CRT + cp = big.modmul(pow(c1 % P2, s1, P2), pow(s, N, P2), P2) + cp = big.modmul(cp, pow(Gamma, t1, P2), P2) + cq = big.modmul(pow(c1 % Q2, s1, Q2), pow(s, N, Q2), Q2) + cq = big.modmul(cq, pow(Gamma, t1 , Q2), Q2) + c_proof = big.crt(cp, cq, P, Q) + + cp = big.modmul(pow(c2 % P2, e, P2), v % P2, P2) + cq = big.modmul(pow(c2 % Q2, e, Q2), v % Q2, Q2) + c_gt = big.crt(cp, cq, P, Q) return c_proof == c_gt @@ -247,10 +336,15 @@ def mta_verify(c1, c2, s, s1, s2, t1, t2, z, z1, t, v, w, e, Gamma, h1, h2, q, N ## MtAwC ZK proof -def mtawc_commit(x, y, c, Gamma, h1, h2, q, N, Nt): +def mtawc_commit( + x, y, c1, + Gamma, h1, h2, q, N, Nt, + alpha = None, beta = None, gamma = None, rho = None, rho1 = None, sigma=None, tau = None): + # Regular MtA range and DLOG knowledge proof commit alpha, beta, gamma, rho, rho1, sigma, tau, z, z1, t, v, w = mta_commit( - x, y, c, Gamma, h1, h2, q, N, Nt + x, y, c1, Gamma, h1, h2, q, N, Nt, + alpha, beta, gamma, rho, rho1, sigma, tau ) # Additional DLOG knowledge proof commit @@ -259,8 +353,58 @@ def mtawc_commit(x, y, c, Gamma, h1, h2, q, N, Nt): return alpha, beta, gamma, rho, rho1, sigma, tau, u, z, z1, t, v, w -def mtawc_challenge(q): - return big.rand(q) +def mtawc_challenge(Gamma, Nt, h1, h2, q, c1, c2, u, z, z1, t, v, w): + ''' + Use Fiat-Shamir to make this NIZK. + + Bind to public parameters: + * Gamma (Paillier) + * Nt, h1, h2 (BC commitment setup) + * q - range + * c1 public ciphertext + + Bind to commitment: + * u, z, z1, t, w, v + + Returns e = H(Gamma, Nt, h1, h2, q, c, z, z1, t, v, w) mod q + ''' + sha = hashlib.new('sha256') + + q_bytes = big.to_bytes(q) + + Gamma_bytes = Gamma.to_bytes(FS_2048, byteorder='big') + Nt_bytes = Nt.to_bytes(FS_2048, byteorder='big') + h1_bytes = h1.to_bytes(FS_2048, byteorder='big') + h2_bytes = h2.to_bytes(FS_2048, byteorder='big') + c1_bytes = c1.to_bytes(DFS_2048, byteorder='big') + c2_bytes = c2.to_bytes(DFS_2048, byteorder='big') + + u_bytes = u.toBytes(True) + z_bytes = z.to_bytes(FS_2048, byteorder='big') + z1_bytes = z1.to_bytes(FS_2048, byteorder='big') + t_bytes = t.to_bytes(FS_2048, byteorder='big') + w_bytes = w.to_bytes(FS_2048, byteorder='big') + v_bytes = v.to_bytes(2 * FS_2048, byteorder='big') + + sha.update(Gamma_bytes) + sha.update(Nt_bytes) + sha.update(h1_bytes) + sha.update(h2_bytes) + sha.update(q_bytes) + sha.update(c1_bytes) + sha.update(c2_bytes) + + sha.update(u_bytes) + sha.update(z_bytes) + sha.update(z1_bytes) + sha.update(t_bytes) + sha.update(v_bytes) + sha.update(w_bytes) + + e_bytes = sha.digest() + e = big.from_bytes(e_bytes) + + return e % q def mtawc_prove(x,y,r,e,alpha,beta,gamma,rho,rho1,sigma,tau,N): @@ -269,12 +413,14 @@ def mtawc_prove(x,y,r,e,alpha,beta,gamma,rho,rho1,sigma,tau,N): return mta_prove(x,y,r,e,alpha,beta,gamma,rho,rho1,sigma,tau,N) -def mtawc_verify(c1, c2, X, s, s1, s2, t1, t2, u, z, z1, t, v, w, e, Gamma, h1, h2, q, N, Nt): +def mtawc_verify(c1, c2, X, s, s1, s2, t1, t2, u, z, z1, t, v, w, e, Gamma, h1, h2, q, P, Q, Pt, Qt): # Verify knowldege of DLOG dsa_proof = s1 * ecp.generator() dsa_gt = u.add(e * X) if dsa_proof != dsa_gt: + print(dsa_proof.toBytes(True).hex()) + print(dsa_gt.toBytes(True).hex()) return False # Carry on with the regular verification for the MtA - return mta_verify(c1, c2, s, s1, s2, t1, t2, z, z1, t, v, w, e, Gamma, h1, h2, q, N, Nt) + return mta_verify(c1, c2, s, s1, s2, t1, t2, z, z1, t, v, w, e, Gamma, h1, h2, q, P, Q, Pt, Qt) diff --git a/model/vectors/mta/genVector.py b/model/vectors/mta/genVector.py index d3f8e49..0d575c0 100644 --- a/model/vectors/mta/genVector.py +++ b/model/vectors/mta/genVector.py @@ -1,7 +1,7 @@ import sys sys.path.append("../../") -from sec256k1 import mta, paillier, big, curve, commitments +from sec256k1 import mta, paillier, big, ecp, curve, commitments def genMTAVector(test_no, p, q, ps, a=None, b=None, r1=None, r2=None, beta_in=None): @@ -45,25 +45,25 @@ def genMTAVector(test_no, p, q, ps, a=None, b=None, r1=None, r2=None, beta_in=No alpha = mta.complete(p, q, lp, mp, lq, mq, ps, cb) # Form test vector - vector["TEST"] = test_no - vector['P'] = hex(p)[2:].zfill(256) - vector['Q'] = hex(q)[2:].zfill(256) - vector['N'] = hex(n)[2:].zfill(512) - vector['G'] = hex(g)[2:].zfill(512) - vector['LP'] = hex(lp)[2:].zfill(256) - vector['LQ'] = hex(lq)[2:].zfill(256) - vector['MP'] = hex(mp)[2:].zfill(256) - vector['MQ'] = hex(mq)[2:].zfill(256) - vector["A"] = hex(a)[2:].zfill(128) - vector["B"] = hex(b)[2:].zfill(128) - vector["PS"] = hex(ps)[2:].zfill(128) - vector["R1"] = hex(r1)[2:].zfill(512) - vector["R2"] = hex(r2)[2:].zfill(512) - vector["CA"] = hex(ca)[2:].zfill(512) - vector["CB"] = hex(cb)[2:].zfill(512) + vector["TEST"] = test_no + vector['P'] = hex(p)[2:].zfill(256) + vector['Q'] = hex(q)[2:].zfill(256) + vector['N'] = hex(n)[2:].zfill(512) + vector['G'] = hex(g)[2:].zfill(512) + vector['LP'] = hex(lp)[2:].zfill(256) + vector['LQ'] = hex(lq)[2:].zfill(256) + vector['MP'] = hex(mp)[2:].zfill(256) + vector['MQ'] = hex(mq)[2:].zfill(256) + vector["A"] = hex(a)[2:].zfill(128) + vector["B"] = hex(b)[2:].zfill(128) + vector["PS"] = hex(ps)[2:].zfill(128) + vector["R1"] = hex(r1)[2:].zfill(512) + vector["R2"] = hex(r2)[2:].zfill(512) + vector["CA"] = hex(ca)[2:].zfill(512) + vector["CB"] = hex(cb)[2:].zfill(512) vector["BETA_IN"] = hex(beta_in)[2:].zfill(128) - vector["ALPHA"] = hex(alpha)[2:].zfill(128) - vector["BETA"] = hex(beta)[2:].zfill(128) + vector["ALPHA"] = hex(alpha)[2:].zfill(128) + vector["BETA"] = hex(beta)[2:].zfill(128) # Check consistency of test vector x = big.modmul(a, b, ps) @@ -115,11 +115,9 @@ def genRPVector(test_no, P, Q, Pt, Qt, h1 = None, h2 = None, m=None, r=None, c=N if m is None: m = big.rand(curve.r) + if c is None or r is None: c, r = paillier.encrypt(P*Q, Gamma, m, r) - - - alpha, beta, gamma, rho, z, u, w = mta.rp_commit(m, Gamma, h1, h2, curve.r, P, Q, Pt*Qt, alpha, beta, gamma, rho) e = mta.rp_challenge(Gamma, Pt*Qt, h1, h2, curve.r, c, z, u, w) s, s1, s2 = mta.rp_prove(m, r, e, alpha, beta, gamma, rho, P, Q) @@ -156,3 +154,135 @@ def genRPVector(test_no, P, Q, Pt, Qt, h1 = None, h2 = None, m=None, r=None, c=N vector['S2'] = hex(s2)[2:].zfill(768) return vector + + +def genMTAZKVector(test_no, P, Q, Pt, Qt, check, h1 = None, h2 = None, m=None, x=None, y=None, r=None, c1=None, c2=None, alpha=None, beta=None, gamma=None, rho=None, rho1=None, sigma=None, tau=None): + """Generate a single test vector for the MTA/WC ZK Range Proof + + Use parameters to generate a single test vector + + Args:: + + test_no: Test vector identifier + P: prime number for Paillier + Q: prime number for Paillier + Pt: prime number for BC setup + Qt: prime number for BC setup + check: flag to generate the mtawc challenge instead of the mta challenge + h1: generator for the BC setup + h2: generator for the BC setup + ps: prime number for the multiplicative shares + m: value encrypted in c1 + x: value homomorphically multiplied to c1 to get c2 + y: value homomorphically added to c1 to get c2 + r: random value for the homomorphic multiplication + c1: public ciphertext for the zk proof + c2: ciphertext with homomorphic addition/multiplication for the zk proof + alpha: random value [0,..,q^3] for the commitment + beta: random value [0,..,P*Q] for the commitment + gamma: random value [0,..,Nt*q^3] for the commitment + rho: random value [0,..,q*Nt] for the commitment + + Returns:: + + vector: A test vector + + Raises:: + + Exception + """ + + vector = {} + + Gamma = P*Q+1 + + if h1 is None or h2 is None: + _, _, _, _, _, _, h1, h2 = commitments.bc_setup(2048, Pt, Qt) + + if m is None: + m = big.rand(curve.r) + + if c1 is None: + c1, _ = paillier.encrypt(P*Q, Gamma, m, r) + + if x is None: + x = big.rand(curve.r) + + if y is None: + y = big.rand(curve.r) + + if c2 is None or r is None: + c2 = paillier.mult(c1, x, P*Q) + t, r = paillier.encrypt(P*Q, Gamma, y, r) + c2 = paillier.add(c2, t, P*Q) + + X = x * ecp.generator() + + alpha, beta, gamma, rho, rho1, sigma, tau, U, z, z1, t, v, w = mta.mtawc_commit( + x, y, c1, + Gamma, h1, h2, curve.r, P*Q, Pt*Qt, + alpha, beta, gamma, rho, rho1, sigma, tau) + + if check: + e = mta.mtawc_challenge( + Gamma, Pt*Qt, h1, h2, curve.r, + c1, c2, + U, z, z1, t, v, w) + else: + e = mta.mta_challenge( + Gamma, Pt*Qt, h1, h2, curve.r, + c1, c2, + z, z1, t, v, w) + + s, s1, s2, t1, t2 = mta.mtawc_prove( + x, y, r, e, + alpha, beta, gamma, rho, rho1, sigma, tau, + P*Q) + + assert mta.mtawc_verify( + c1, c2, X, + s, s1, s2, t1, t2, + U, z, z1, t, v, w, + e, + Gamma, h1, h2, curve.r, P, Q, Pt, Qt), "Inconsistent Test Vector" + + vector['TEST'] = test_no + vector['P'] = hex(P)[2:].zfill(256) + vector['Q'] = hex(Q)[2:].zfill(256) + vector['N'] = hex(P*Q)[2:].zfill(512) + vector['PT'] = hex(Pt)[2:].zfill(256) + vector['QT'] = hex(Qt)[2:].zfill(256) + vector['NT'] = hex(Pt*Qt)[2:].zfill(512) + vector['H1'] = hex(h1)[2:].zfill(512) + vector['H2'] = hex(h2)[2:].zfill(512) + vector['X'] = hex(x)[2:].zfill(64) + vector['Y'] = hex(y)[2:].zfill(64) + vector['R'] = hex(r)[2:].zfill(1024) + vector['C1'] = hex(c1)[2:].zfill(1024) + vector['C2'] = hex(c2)[2:].zfill(1024) + vector['ECPX'] = "{}".format(X.toBytes(True).hex()) + + vector['ALPHA'] = hex(alpha)[2:].zfill(256) + vector['BETA'] = hex(beta)[2:].zfill(512) + vector['GAMMA'] = hex(gamma)[2:].zfill(512) + vector['RHO'] = hex(rho)[2:].zfill(768) + vector['RHO1'] = hex(rho1)[2:].zfill(768) + vector['SIGMA'] = hex(sigma)[2:].zfill(768) + vector['TAU'] = hex(tau)[2:].zfill(768) + + vector['U'] = "{}".format(U.toBytes(True).hex()) + vector['Z'] = hex(z)[2:].zfill(512) + vector['Z1'] = hex(z1)[2:].zfill(512) + vector['T'] = hex(t)[2:].zfill(512) + vector['W'] = hex(w)[2:].zfill(512) + vector['V'] = hex(v)[2:].zfill(1024) + + vector['E'] = hex(e)[2:].zfill(64) + + vector['S'] = hex(s)[2:].zfill(512) + vector['S1'] = hex(s1)[2:].zfill(256) + vector['S2'] = hex(s2)[2:].zfill(768) + vector['T1'] = hex(t1)[2:].zfill(512) + vector['T2'] = hex(t2)[2:].zfill(768) + + return vector diff --git a/model/vectors/mta/genZK.py b/model/vectors/mta/genZK.py new file mode 100755 index 0000000..4964b1e --- /dev/null +++ b/model/vectors/mta/genZK.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 + +import json +import argparse +from genVector import genMTAZKVector +from Crypto.Util import number + +""" + Generates a set of test vectors for the MTA/WC ZK Proof. + + usage: genZK.py +""" + + +# Pre-generated safe primes for k=2048 to speed up tv generation +primes = [ + 0xC421122418EF6FE4D4F14F0F03EABA927C20B1A22BCBE90EC227EFE34AC912095D389ADE615CF55C80874533F4270BB705ABFFDB6007FEF0B44B2DBF31EDA0D5F39523B5826F9854FBF733B98EF450E77DD8B5B15C4E3CE5C195F46E524C8BF6F0C9F6D86CE8642A8B9A0C79CA64A103AB76CD65261F97AED4C17C433CEA5DEF, + 0xED7859031659B9A5AC011687A60444B19F5A73F31F9EE83D710F2FEAE1C4FED558A1C5C3842EA01DB86C6D07BE9971F8AA7820DD1E8BB8C9AE888319F0E03BDCD8D3DBEBF8A48765188C001A121F7E48D458E1E8A43684A861F0FBE87DC541A06CA98CECB6954F906A52C2B3D0978AE945A1EA2F9285978F76F01E99FD8B6EEF, + 0xD93E4899805ED36219F38C3030D6FF92012E2B41ADC38DFFFFDB110AEAA36D619A5CFD63B02711EA482941E20A3F89A36E2CAF0BD675B154FDE6D5A457BCBD337383EE65B33CDAB078EE8F8E36E55D22BB5DF75D14F570E529A4681B4947A4F5ECCC575763BD765FDE1038DEDF24BEF02BA9A1EA4C17ACA3A1B33D2FB7D974AB, + 0xE4481CEDDBDDDF6E980FBC825B004E52D028784CD3B8290D9810FD987AF2053C3F4056C3A354BFF55B9BB5867A819A22B71BC1069A310087E4FBF98FD291DBCC443AB910301B34A2DEE68D1365E77EDF9A0A21B3928C38046BC15AC338F7E38B9E4586E02655F98523CD041FBB51A358E505A5D1B0A161955B6AC60CB0E37707, + 0XF5F3BB1CEECD21110EFB4BC9CF0AA7AEBB98675A7567D6A1EA4E866FED4838F1B41D8232599718CD82F2936CD15198DC16ADD280C32D6860882704AEF397E1A956DB17E36AEB92D5CF76689DACC9CEFE418EF699C948CE680AFF878768CE8F4BB68F14AB5E8C38209E6C2C54125533B22960BBD350CF76C3B12BBC9FBAAAAA27, + 0XE8E1F9281CB8C10BC01B42197E834F648A5C8AE111F7DB40DD25A6F8896A703D0F84D36EB6D1FC048DC74FD3164742CA86607C81670199FC3F1BF5AB22F2B11E4E2434E757C0484A4162E26B75A0715167C5E8E293B7CEFD475FAA8B10F2324D78150E56B1186E257066D8860603FBCE59865FB0A25FB41014C1740C8EAA29AF, + 0XC3278DF1CD5330CD6DABE2FC9E32B9A560C32F7F140C601D2A5788F856A387531EFA695D728038F8CA2945D01C10A5DA823025BA27D7640E96593C031674380592AF4B8FE29A9C464FF41B1CACD47A4B255A5CA93E2F2A806AF00A67FB78A15D3ED8A37CEBA10CA7D0036412805AEBB88EC8A745F237AC01002D49C459EB2AB7, + 0XDCE9B24D4DE749296335C0F0DB421A330E21DF04C722ADDECC4B72448C387072C84CD7DB1146E1E07BE78585DEF4F1D5E15F53B0942CCA89B0E812B0F6653C7DA8ACB771593D4B2B37A28AD80DD7184698742C110F0506B86BF8A2A20E8975DF2D2A57930438B8528E63C3430DBFCE204712E8D40550E81DA03622953BEA2DFB, + 0XD09A3ECE562DD033EC2C562C2B0B4EEB0D2262FE046C030BAAFD7CBA8F73E9734E337D3551FC6B487CA359A84F598EC5EC6FDBA014A0A0009EF582B9F90DE90C0BA7F941648C4F3A8CF904974BA05E8C23EDA5895025441251B2CFC5A216568E702427DEA178D37BF3D28F1B35E17E58F5551511331961703F3D410924859107, + 0XC03136A1E1E5BA88568A19142F41E9FAC2E76A2D839B550038005E420008AF7D6D7C80EA8A31A936D39C93D2031B20845F23464371909EE589BF80E850C94B9F0FBF516C3DE362868C811505EE15B869844A54FFB32B0620A7FC5BA040898A91AA68657D8B43990166E5A5AF06828AE0F7C1D0EE333C2AF8DE7603F2F662792F, + 0xDF88593FBF2482954BAAA2A48C59E2FDF85936C282514FFB47F18B8D1484C7E8BE1862D0A84D5B753389A2BFBAFF63B03406AC29893B88911F8664E547A63CB58E9A941463D7946CF0909E24E7BD8EF11AFC4EEAFC8F3366DB0A9AB091325AC82C9BAE218B115F8700BAA1F478E194A927F1FBE3A3EF423BCFAE78850059B69B, + 0xD3AE06CD993690F64104D4ECBE6B2386693B766431B86E038CAE39EE81BD8A71387FBCB9D17B5BFAAFB883D68B005E228CD455A4BFF69843F948A9168D1F87545FCBB969260E07BDD44F10E79E7409DED45ADDF32BA1CF33F9B2F68758622FE660F4E47A651F6403D99E7B148768CDDBEC71EBE931D5A95B820B5A75BD495003, + 0xDAA27689A7D8F9B21106DBE472C324EB1CA899F58F0F72F336957312A8ECDB4EBC3B50C38D5A2E9C2D1E552C7EA8D89315DD9C5CA7F9EB99C41F7A857D44F420109FE17092799E60E3537FC9193056979E0FF886B36C2898F45F599E4C5CCDDF9A8EC8DA0D20A53A6849124E027D30D641E21E69FF374792534BD682FCDCA35B, + 0xFBF9D46697C40BCA51A759C47E360F2DD8B81B6241B0A3645645FAC692E9E8F3407EFB6F238AE91F9DEA49240D26E37904673F55E91927CDEA248FE1352B97B226AB159A1539747383B1168FE8CF1B1DF4CD9147053E3702AE491FBCA4CCE835B4B351DF44F5333C185275DB21B807D0BC180BF697EC07AB843E0FA595851A87, + 0xFD44B39DF09A18F215EB391D50D21CD5EAC8BE2E5CC901DF852DE85C93341F82633AAAD07C19863E0CD7861AEEE1C0B4B69275AA8DD2D33C0F5E048EA13E9A6D8E01B77FED72347D527BD7508D2F5EC18E5CB2B27D40BAB5C10A17123E75042F4047C3B1AEB6D36BF0F93BB214501ECBB8F95CC1A3A99219F6933763580CDA2F, + 0xC2442E9569C8999831594E818A159C8C0AF6F7ED2989358E8D9E01D6B8A0D354F5F97D9CEAB766AF12F3CC5C511FE19A587FF1E7029C8E500432D357D90E3EF042E4F308C325760D726BC9B1D78BA439FB0236D85DB301E548C4201B9E74D5832AD3ED06E37CD6DBFD9C23D194068DB1B9209813557FBC0714142AD6F6C56AA3, + 0xDC3B22CFF90690B10EC73C115FED0E3AD3FA01A68F8C8AA1905CA47008E8C4AF9D7922AE4D41794D8123D1768A3E0F8B35DA0001086ADC5EBB92640DD2514CBAD000283F7C5A6C340C040C09654A204C3947A22AC05F72E13C3EBDE61B9D281016E40C559474D33381C974767408EE9E108619AE96E4CC87EB11E39772BA00B3, + 0xC5E0280A5F1B358D16EDEF14540C3C9D468D4AEBC74C9DB605A2E4CEC9F27095A3FDE659E1E6C95FB4BB60533DD89E71D808A8C5EB5A8A51B9FED24F7AE9003FFD6F5401D991153C52002E7DB4F6766363B2CA77E9A113808E7C35713D188AD55CE25B9DB1308A08F3366523E425F77D924346078D8E0E9948674BAD88EA59B7, + 0xFC33DF361A7B1D3C3D1C06FBF3CCAD6C067B27FF28B61B1EFDB364FFFEE79993D9D10213A778A02C6C823DB101CB7C7A483B9F2B060BD1B7EDC13DB890B323AE02B7209DA66B3289069EE8C7747A6D7242194DC48DBDFFB740534A591AE2F41446B08F9966DA045FC9C3F9188F1EF1308509D50BC970314B6AA335EA2839993B, + 0xE63B5740DDB573CF1F0A72DAF3EA00D65CA2A538036D20078CC7E3BDC95529F1D13ABC182EBF8BE42CA87C0AEED4952C1D1FADC3C3C8A363F66FABCA012890FBC76C935B479B4F302F1DC12289D34F1F69EC2278045603F5FE532B0CD86E6261852F99517B6226F013B04DCE1D940DF7FB8BC8A799D153C1490A915A8342B77F +] + +typeKeys = { + 'commit': [ + 'TEST', 'X', 'Y', 'C1', 'N', 'H1', 'H2', 'NT', 'ALPHA', 'BETA', 'GAMMA', 'RHO', 'RHO1', 'SIGMA', 'TAU', 'Z', 'Z1', 'T', 'V', 'W' + ], + 'challenge': [ + 'TEST', 'N', 'NT', 'H1', 'H2', 'C1', 'C2', 'Z', 'Z1', 'T', 'V', 'W', 'E' + ], + 'prove': [ + 'TEST', 'X', 'Y', 'R', 'E', 'ALPHA', 'BETA', 'GAMMA', 'RHO', 'RHO1', 'SIGMA', 'TAU', 'N', 'S', 'S1', 'S2', 'T1', 'T2' + ], + 'verify': [ + 'TEST', 'C1', 'C2', 'S', 'S1', 'S2', 'T1', 'T2', 'Z', 'Z1', 'T', 'V', 'W' , 'E', 'P', 'Q', 'H1', 'H2', 'PT', 'QT' + ], +} + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument('-n', dest='n', type=int, default=10, choices=[i for i in range(1, 11)], + help='number of test vectors') + parser.add_argument('-wc', action='store_true', + help='generate vectors for the MTAWC proof') + parser.add_argument('-t', dest='t', type=str, choices=['commit', 'challenge', 'prove', 'verify'], default='commit', + help='type of test vector to generate') + + args = parser.parse_args() + + nVec = args.n + tvType = args.t + keys = typeKeys[tvType] + wc = args.wc + + if wc and (tvType != 'prove'): + keys.append('ECPX') + + vectors = [] + + for i in range(nVec): + Pt = primes[2*i] + Qt = primes[2*i+1] + + P = number.getStrongPrime(1024) + Q = number.getStrongPrime(1024) + + vector = genMTAZKVector(i, P, Q, Pt, Qt, wc) + vector = {k: vector[k] for k in keys} + + vectors.append(vector) + + protocol_name = "mta" + if wc: + protocol_name = protocol_name + "wc" + + filename = "{}_{}".format(protocol_name, tvType) + + json.dump(vectors, open(filename + ".json", "w"), indent=2) + + with open(filename + ".txt", "w") as f: + for vector in vectors: + for k in keys: + f.write("{} = {},\n".format(k.upper(), vector[k])) + f.write("\n")
