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")

Reply via email to