nizk: flip commitment to group 1

This commit is contained in:
Gijs Van Laer 2019-07-12 10:46:25 -04:00
parent eb5827a4d7
commit fa69707614
4 changed files with 69 additions and 104 deletions

View File

@ -44,7 +44,7 @@ proofUL contains the necessary elements for the ZK range proof with range [0,u^l
#[derive(Clone)] #[derive(Clone)]
struct ProofUL<E: Engine> { struct ProofUL<E: Engine> {
V: Vec<Signature<E>>, V: Vec<Signature<E>>,
D: E::G2, D: E::G1,
comm: Commitment<E>, comm: Commitment<E>,
sigProofs: Vec<SignatureProof<E>>, sigProofs: Vec<SignatureProof<E>>,
ch: E::Fr, ch: E::Fr,
@ -105,11 +105,11 @@ impl<E: Engine> ParamsUL<E> {
let mut proofStates = Vec::<ProofState<E>>::with_capacity(self.l as usize); let mut proofStates = Vec::<ProofState<E>>::with_capacity(self.l as usize);
let mut sigProofs = Vec::<SignatureProof<E>>::with_capacity(self.l as usize); let mut sigProofs = Vec::<SignatureProof<E>>::with_capacity(self.l as usize);
let mut V = Vec::<Signature<E>>::with_capacity(self.l as usize); let mut V = Vec::<Signature<E>>::with_capacity(self.l as usize);
let mut D = E::G2::zero(); let mut D = E::G1::zero();
let m = E::Fr::rand(rng); let m = E::Fr::rand(rng);
// D = H^m // D = H^m
let mut hm = self.com.h2.clone(); let mut hm = self.com.h.clone();
hm.mul_assign(m); hm.mul_assign(m);
for i in 0..self.l as usize { for i in 0..self.l as usize {
let signature = self.signatures.get(&decx[i].to_string()).unwrap(); let signature = self.signatures.get(&decx[i].to_string()).unwrap();
@ -119,8 +119,8 @@ impl<E: Engine> ParamsUL<E> {
proofStates.push(proofState); proofStates.push(proofState);
let ui = self.u.pow(i as u32); let ui = self.u.pow(i as u32);
let mut aux = self.com.g2.clone(); let mut aux = self.com.g.clone();
for j in 0..self.kp.public.Y2.len() { for j in 0..self.kp.public.Y1.len() {
let mut muiti = proofStates[i].t[j].clone(); let mut muiti = proofStates[i].t[j].clone();
muiti.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap()); muiti.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap());
aux.mul_assign(muiti); aux.mul_assign(muiti);
@ -183,16 +183,16 @@ impl<E: Engine> ParamsUL<E> {
} }
fn verify_part1(&self, proof: &ProofUL<E>) -> bool { fn verify_part1(&self, proof: &ProofUL<E>) -> bool {
let mut D = proof.comm.c2.clone(); let mut D = proof.comm.c.clone();
D.mul_assign(proof.ch); D.mul_assign(proof.ch);
D.negate(); D.negate();
let mut hzr = self.com.h2.clone(); let mut hzr = self.com.h.clone();
hzr.mul_assign(proof.zr); hzr.mul_assign(proof.zr);
D.add_assign(&hzr); D.add_assign(&hzr);
for i in 0..self.l as usize { for i in 0..self.l as usize {
let ui = self.u.pow(i as u32); let ui = self.u.pow(i as u32);
let mut aux = self.com.g2.clone(); let mut aux = self.com.g.clone();
for j in 0..self.kp.public.Y2.len() { for j in 0..self.kp.public.Y1.len() {
let mut muizsigi = proof.sigProofs[i].zsig[j]; let mut muizsigi = proof.sigProofs[i].zsig[j];
muizsigi.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap()); muizsigi.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap());
aux.mul_assign(muizsigi); aux.mul_assign(muizsigi);
@ -203,7 +203,7 @@ impl<E: Engine> ParamsUL<E> {
} }
} }
fn hash<E: Engine>(a: Vec<E::Fqk>, D: E::G2) -> E::Fr { fn hash<E: Engine>(a: Vec<E::Fqk>, D: E::G1) -> E::Fr {
// create a Sha256 object // create a Sha256 object
let mut a_vec: Vec<u8> = Vec::new(); let mut a_vec: Vec<u8> = Vec::new();
for a_el in a { for a_el in a {
@ -291,7 +291,7 @@ impl<E: Engine> RPPublicParams<E> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use pairing::bls12_381::{Bls12, G1, G2, Fq12, Fr}; use pairing::bls12_381::{Bls12, G1, Fq12, Fr};
use time::PreciseTime; use time::PreciseTime;
use std::ops::Add; use std::ops::Add;
use core::mem; use core::mem;
@ -462,8 +462,8 @@ mod tests {
#[test] #[test]
fn hash_works() { fn hash_works() {
let rng = &mut rand::thread_rng(); let rng = &mut rand::thread_rng();
let D = G2::rand(rng); let D = G1::rand(rng);
let D2 = G2::rand(rng); let D2 = G1::rand(rng);
let params = setup::<ThreadRng, Bls12>(rng); let params = setup::<ThreadRng, Bls12>(rng);
let kp = BlindKeyPair::generate(rng, &params, 2); let kp = BlindKeyPair::generate(rng, &params, 2);
let m1 = Fr::rand(rng); let m1 = Fr::rand(rng);

View File

@ -311,13 +311,10 @@ impl<E: Engine> BlindKeyPair<E> {
} }
pub fn generate_cs_multi_params(&self, mpk: &PublicParams<E>) -> CSMultiParams<E> { pub fn generate_cs_multi_params(&self, mpk: &PublicParams<E>) -> CSMultiParams<E> {
let mut com_bases1 = vec! {mpk.g1}; let mut com_bases = vec! {mpk.g1};
com_bases1.append(&mut self.public.Y1.clone()); com_bases.append(&mut self.public.Y1.clone());
let mut com_bases2 = vec! {mpk.g2}; CSMultiParams { pub_bases: com_bases}
com_bases2.append(&mut self.public.Y2.clone());
CSMultiParams { pub_bases1: com_bases1, pub_bases2: com_bases2}
} }
/// extract unblinded public key /// extract unblinded public key
@ -336,7 +333,7 @@ impl<E: Engine> BlindKeyPair<E> {
let mut h1 = mpk.g1; let mut h1 = mpk.g1;
h1.mul_assign(u); // g1 ^ u h1.mul_assign(u); // g1 ^ u
let mut com1 = com.c1.clone(); let mut com1 = com.c.clone();
let mut H1 = self.public.X1.clone(); let mut H1 = self.public.X1.clone();
H1.add_assign(&com1); // (X * com) H1.add_assign(&com1); // (X * com)
H1.mul_assign(u); // (X * com) ^ u (blinding factor) H1.mul_assign(u); // (X * com) ^ u (blinding factor)

View File

@ -14,8 +14,8 @@ use commit_scheme::commit;
struct Proof<E: Engine> { struct Proof<E: Engine> {
sig: Signature<E>, sig: Signature<E>,
sigProof: SignatureProof<E>, sigProof: SignatureProof<E>,
T: E::G2, T: E::G1,
D: E::G2, D: E::G1,
z: Vec<E::Fr>, z: Vec<E::Fr>,
} }
@ -24,10 +24,10 @@ fn prove<R: Rng, E: Engine>(rng: &mut R, comParams: &CSMultiParams<E>, com1: &Co
mpk: &PublicParams<E>, kp: &BlindKeyPair<E>) -> Proof<E> { mpk: &PublicParams<E>, kp: &BlindKeyPair<E>) -> Proof<E> {
//Commitment phase //Commitment phase
//Commit linear relationship //Commit linear relationship
let mut T = comParams.pub_bases2[2].clone(); let mut T = comParams.pub_bases[2].clone();
let t1 = E::Fr::rand(rng); let t1 = E::Fr::rand(rng);
T.mul_assign(t1); T.mul_assign(t1);
let mut h = comParams.pub_bases2[0].clone(); let mut h = comParams.pub_bases[0].clone();
let t2 = E::Fr::rand(rng); let t2 = E::Fr::rand(rng);
h.mul_assign(t2); h.mul_assign(t2);
T.add_assign(&h); T.add_assign(&h);
@ -36,9 +36,9 @@ fn prove<R: Rng, E: Engine>(rng: &mut R, comParams: &CSMultiParams<E>, com1: &Co
let proofState = kp.prove_commitment(rng, &mpk, &paymentToken); let proofState = kp.prove_commitment(rng, &mpk, &paymentToken);
//commit commitment //commit commitment
let mut D = E::G2::zero(); let mut D = E::G1::zero();
let mut t = Vec::<E::Fr>::with_capacity(comParams.pub_bases2.len() - 1); let mut t = Vec::<E::Fr>::with_capacity(comParams.pub_bases.len() - 1);
for g in comParams.pub_bases2.clone() { for g in comParams.pub_bases.clone() {
let ti = E::Fr::rand(rng); let ti = E::Fr::rand(rng);
t.push(ti); t.push(ti);
let mut gt = g.clone(); let mut gt = g.clone();
@ -87,28 +87,28 @@ fn verify<E: Engine>(proof: Proof<E>, epsilon: E::Fr, com1: &Commitment<E>, com2
let challenge = hash::<E>(proof.sigProof.a, proof.T, proof.D); let challenge = hash::<E>(proof.sigProof.a, proof.T, proof.D);
//verify linear relationship //verify linear relationship
let mut gWpk = comParams.pub_bases2[2].clone(); let mut gWpk = comParams.pub_bases[2].clone();
let mut minWpk = wpk.clone(); let mut minWpk = wpk.clone();
minWpk.negate(); minWpk.negate();
gWpk.mul_assign(minWpk.into_repr()); gWpk.mul_assign(minWpk.into_repr());
let mut gEps = comParams.pub_bases2[4].clone(); let mut gEps = comParams.pub_bases[4].clone();
gEps.mul_assign(epsilon.into_repr()); gEps.mul_assign(epsilon.into_repr());
let mut gMinEps = comParams.pub_bases2[3].clone(); let mut gMinEps = comParams.pub_bases[3].clone();
let mut mineps = epsilon.clone(); let mut mineps = epsilon.clone();
mineps.negate(); mineps.negate();
gMinEps.mul_assign(mineps.into_repr()); gMinEps.mul_assign(mineps.into_repr());
let mut commitment = com1.c2.clone(); let mut commitment = com1.c.clone();
commitment.sub_assign(&com2.c2.clone()); commitment.sub_assign(&com2.c.clone());
commitment.add_assign(&gWpk); commitment.add_assign(&gWpk);
commitment.add_assign(&gEps); commitment.add_assign(&gEps);
commitment.add_assign(&gMinEps); commitment.add_assign(&gMinEps);
commitment.mul_assign(challenge.into_repr()); commitment.mul_assign(challenge.into_repr());
commitment.add_assign(&proof.T); commitment.add_assign(&proof.T);
let mut g2 = comParams.pub_bases2[2].clone(); let mut g2 = comParams.pub_bases[2].clone();
g2.mul_assign(proof.z[0].into_repr()); g2.mul_assign(proof.z[0].into_repr());
let mut h = comParams.pub_bases2[0].clone(); let mut h = comParams.pub_bases[0].clone();
h.mul_assign(proof.z[1].into_repr()); h.mul_assign(proof.z[1].into_repr());
g2.add_assign(&h); g2.add_assign(&h);
let r = commitment == g2; let r = commitment == g2;
@ -117,12 +117,12 @@ fn verify<E: Engine>(proof: Proof<E>, epsilon: E::Fr, com1: &Commitment<E>, com2
let r1 = pk.verify_proof(&mpk, proof.sig, proof.sigProof, challenge); let r1 = pk.verify_proof(&mpk, proof.sig, proof.sigProof, challenge);
//verify knowledge of commitment //verify knowledge of commitment
let mut comc = com2.c2.clone(); let mut comc = com2.c.clone();
comc.mul_assign(challenge.into_repr()); comc.mul_assign(challenge.into_repr());
comc.add_assign(&proof.D.clone()); comc.add_assign(&proof.D.clone());
let mut x = E::G2::zero(); let mut x = E::G1::zero();
for i in 2..proof.z.len() { for i in 2..proof.z.len() {
let mut base = comParams.pub_bases2[i - 2].clone(); let mut base = comParams.pub_bases[i - 2].clone();
base.mul_assign(proof.z[i].into_repr()); base.mul_assign(proof.z[i].into_repr());
x.add_assign(&base); x.add_assign(&base);
} }
@ -131,7 +131,7 @@ fn verify<E: Engine>(proof: Proof<E>, epsilon: E::Fr, com1: &Commitment<E>, com2
r && r1 && r3 r && r1 && r3
} }
fn hash<E: Engine>(a: E::Fqk, T: E::G2, D: E::G2) -> E::Fr { fn hash<E: Engine>(a: E::Fqk, T: E::G1, D: E::G1) -> E::Fr {
let mut x_vec: Vec<u8> = Vec::new(); let mut x_vec: Vec<u8> = Vec::new();
x_vec.extend(format!("{}", a).bytes()); x_vec.extend(format!("{}", a).bytes());
x_vec.extend(format!("{}", T).bytes()); x_vec.extend(format!("{}", T).bytes());

View File

@ -5,22 +5,18 @@ use ff::Rand;
#[derive(Clone)] #[derive(Clone)]
pub struct CSParams<E: Engine> { pub struct CSParams<E: Engine> {
pub g1: E::G1, pub g: E::G1,
pub g2: E::G2, pub h: E::G1,
pub h1: E::G1,
pub h2: E::G2,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct Commitment<E: Engine> { pub struct Commitment<E: Engine> {
pub c1: E::G1, pub c: E::G1,
pub c2: E::G2
} }
#[derive(Clone)] #[derive(Clone)]
pub struct CSMultiParams<E: Engine> { pub struct CSMultiParams<E: Engine> {
pub pub_bases1: Vec<E::G1>, pub pub_bases: Vec<E::G1>,
pub pub_bases2: Vec<E::G2>
} }
//impl<E: Engine> fmt::Display for CSParams<E> { //impl<E: Engine> fmt::Display for CSParams<E> {
@ -63,12 +59,9 @@ impl<E: Engine> CSParams<E> {
Implements the setup algorithm for the Pedersen92 commitment scheme Implements the setup algorithm for the Pedersen92 commitment scheme
*/ */
pub fn setup<R: Rng>(rng: &mut R) -> Self { pub fn setup<R: Rng>(rng: &mut R) -> Self {
let g1 = E::G1::rand(rng); let g = E::G1::rand(rng);
let g2 = E::G2::rand(rng); let h = E::G1::rand(rng);
let h1 = E::G1::rand(rng); CSParams { g, h }
let h2 = E::G2::rand(rng);
let csp = CSParams { g1, g2, h1, h2 };
return csp;
} }
/* /*
@ -81,20 +74,13 @@ commit(pk, msg) -> cm where
let r = R.unwrap_or(E::Fr::rand(rng)); let r = R.unwrap_or(E::Fr::rand(rng));
// c = g^m * h^r // c = g^m * h^r
let mut c1 = self.g1.clone(); let mut c = self.g.clone();
c1.mul_assign(m.clone()); c.mul_assign(m.clone());
let mut h1 = self.h1.clone(); let mut h = self.h.clone();
h1.mul_assign(r.clone()); h.mul_assign(r.clone());
c1.add_assign(&h1); c.add_assign(&h);
// c = g^m * h^r Commitment { c }
let mut c2 = self.g2.clone();
c2.mul_assign(m);
let mut h2 = self.h2.clone();
h2.mul_assign(r);
c2.add_assign(&h2);
Commitment { c1, c2 }
} }
/* /*
@ -104,18 +90,12 @@ decommit(csp, cm, msg) -> bool where
- outputs T/F for whether the cm is a valid commitment to the msg - outputs T/F for whether the cm is a valid commitment to the msg
*/ */
pub fn decommit(&self, cm: &Commitment<E>, m: &E::Fr, r: &E::Fr) -> bool { pub fn decommit(&self, cm: &Commitment<E>, m: &E::Fr, r: &E::Fr) -> bool {
let mut dm1 = self.g1.clone(); let mut dm = self.g.clone();
dm1.mul_assign(m.clone()); dm.mul_assign(m.clone());
let mut h1 = self.h1.clone(); let mut h = self.h.clone();
h1.mul_assign(r.clone()); h.mul_assign(r.clone());
dm1.add_assign(&h1); dm.add_assign(&h);
dm == cm.c
let mut dm2 = self.g2.clone();
dm2.mul_assign(m.clone());
let mut h2 = self.h2.clone();
h2.mul_assign(r.clone());
dm2.add_assign(&h2);
return dm2 == cm.c2 && dm1 == cm.c1;
} }
} }
@ -126,49 +106,37 @@ impl<E: Engine> CSMultiParams<E> {
a vector of messages of length len. a vector of messages of length len.
*/ */
pub fn setup_gen_params<R: Rng>(rng: &mut R, len: usize) -> Self { pub fn setup_gen_params<R: Rng>(rng: &mut R, len: usize) -> Self {
let mut p1: Vec<E::G1> = Vec::new(); let mut p: Vec<E::G1> = Vec::new();
let mut p2: Vec<E::G2> = Vec::new();
// 1 extra base element for the random parameter // 1 extra base element for the random parameter
for i in 0..len + 1 { for i in 0..len + 1 {
p1.push(E::G1::rand(rng)); p.push(E::G1::rand(rng));
p2.push(E::G2::rand(rng));
} }
return CSMultiParams { pub_bases1: p1, pub_bases2: p2 }; CSMultiParams { pub_bases: p }
} }
pub fn commit(&self, x: &Vec<E::Fr>, r: &E::Fr) -> Commitment<E> { pub fn commit(&self, x: &Vec<E::Fr>, r: &E::Fr) -> Commitment<E> {
// c = g1^m1 * ... * gn^mn * h^r // c = g1^m1 * ... * gn^mn * h^r
let mut c1 = self.pub_bases1[0].clone(); let mut c = self.pub_bases[0].clone();
let mut c2 = self.pub_bases2[0].clone(); c.mul_assign(r.clone());
c1.mul_assign(r.clone());
c2.mul_assign(r.clone());
for i in 0..x.len() { for i in 0..x.len() {
let mut basis1 = self.pub_bases1[i+1]; let mut basis = self.pub_bases[i+1];
basis1.mul_assign(x[i]); basis.mul_assign(x[i]);
c1.add_assign(&basis1); c.add_assign(&basis);
let mut basis2 = self.pub_bases2[i+1];
basis2.mul_assign(x[i]);
c2.add_assign(&basis2);
} }
Commitment { c1, c2 } Commitment { c }
} }
pub fn decommit(&self, cm: &Commitment<E>, x: &Vec<E::Fr>, r: &E::Fr) -> bool { pub fn decommit(&self, cm: &Commitment<E>, x: &Vec<E::Fr>, r: &E::Fr) -> bool {
let l = x.len(); let l = x.len();
// pub_base[0] => h, x[0] => r // pub_base[0] => h, x[0] => r
let mut dc1 = self.pub_bases1[0].clone(); let mut dc = self.pub_bases[0].clone();
let mut dc2 = self.pub_bases2[0].clone(); dc.mul_assign(r.clone());
dc1.mul_assign(r.clone());
dc2.mul_assign(r.clone());
for i in 0..l { for i in 0..l {
let mut basis1 = self.pub_bases1[i+1]; let mut basis = self.pub_bases[i+1];
basis1.mul_assign(x[i]); basis.mul_assign(x[i]);
dc1.add_assign(&basis1); dc.add_assign(&basis);
let mut basis2 = self.pub_bases2[i+1];
basis2.mul_assign(x[i]);
dc2.add_assign(&basis2);
} }
return dc2 == cm.c2 && dc1 == cm.c1; return dc == cm.c;
} }
} }