diff --git a/src/nizk.rs b/src/nizk.rs index 1870af5..f70572b 100644 --- a/src/nizk.rs +++ b/src/nizk.rs @@ -15,12 +15,14 @@ struct Proof { sig: Signature, sigProof: SignatureProof, T: E::G2, + D: E::G2, z: Vec, } fn prove(rng: &mut R, comParams: &CSMultiParams, com1: &Commitment, com2: &Commitment, oldWallet: Vec, r: E::Fr, newWallet: Vec, rPrime: E::Fr, paymentToken: &Signature, mpk: &PublicParams, kp: &BlindKeyPair) -> Proof { + //Commitment phase let mut T = comParams.pub_bases[2].clone(); let t1 = E::Fr::rand(rng); T.mul_assign(t1); @@ -29,23 +31,48 @@ fn prove(rng: &mut R, comParams: &CSMultiParams, com1: &Co h.mul_assign(t2); T.add_assign(&h); let proofState = kp.prove_commitment(rng, &mpk, &paymentToken); - let challenge = hash::(proofState.a, T); + + let mut D = E::G2::zero(); + let mut t = Vec::::with_capacity(comParams.pub_bases.len() - 1); + for g in comParams.pub_bases.clone() { + let ti = E::Fr::rand(rng); + t.push(ti); + let mut gt = g.clone(); + gt.mul_assign(ti.into_repr()); + D.add_assign(>); + } + + //Compute challenge + let challenge = hash::(proofState.a, T, D); + + //Response phase let sigProof = kp.prove_response(&proofState, challenge, &mut vec! {hash_g2_to_fr::(&com1.c)}); + let mut z = Vec::::with_capacity(t.len() + 2); let mut z1 = newWallet[2].clone(); z1.negate(); z1.mul_assign(&challenge); z1.add_assign(&t1); + z.push(z1); let mut z2 = r.clone(); z2.sub_assign(&rPrime.clone()); z2.mul_assign(&challenge); z2.add_assign(&t2); - Proof { sig: proofState.blindSig, sigProof, T, z: vec! {z1, z2} } + z.push(z2); + + for i in 0..t.len() { + let mut zi = newWallet[i].clone(); + zi.mul_assign(&challenge); + zi.add_assign(&t[i]); + z.push(zi); + } + + Proof { sig: proofState.blindSig, sigProof, T, D, z } } fn verify(proof: Proof, epsilon: E::Fr, com1: &Commitment, com2: &Commitment, paymentToken: &Signature, wpk: E::Fr, comParams: &CSMultiParams, mpk: &PublicParams, pk: &BlindPublicKey) -> bool { - let challenge = hash::(proof.sigProof.a, proof.T); + let challenge = hash::(proof.sigProof.a, proof.T, proof.D); let mut gWpk = comParams.pub_bases[2].clone(); let mut minWpk = wpk.clone(); @@ -75,13 +102,24 @@ fn verify(proof: Proof, epsilon: E::Fr, com1: &Commitment, com2 let r = pk.verify_proof(&mpk, proof.sig, proof.sigProof, challenge); - r && commitment == g2 + let mut comc = com2.c.clone(); + comc.mul_assign(challenge.into_repr()); + comc.add_assign(&proof.D.clone()); + let mut x = E::G2::zero(); + for i in 2..proof.z.len() { + let mut base = comParams.pub_bases[i - 2].clone(); + base.mul_assign(proof.z[i].into_repr()); + x.add_assign(&base); + } + + r && commitment == g2 && x == comc } -fn hash(a: E::Fqk, T: E::G2) -> E::Fr { +fn hash(a: E::Fqk, T: E::G2, D: E::G2) -> E::Fr { let mut x_vec: Vec = Vec::new(); x_vec.extend(format!("{}", a).bytes()); x_vec.extend(format!("{}", T).bytes()); + x_vec.extend(format!("{}", D).bytes()); util::hash_to_fr::(x_vec) }