From 3c5237f12c5f0bf25391f15bbf436d5b15b70f70 Mon Sep 17 00:00:00 2001 From: Gijs Van Laer Date: Sun, 7 Jul 2019 14:10:11 -0400 Subject: [PATCH] blind-sign: add commitment in G1 --- src/ccs08.rs | 10 ++--- src/cl.rs | 74 +++++++++++++++++++++++++++++++++--- src/ped92.rs | 103 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 138 insertions(+), 49 deletions(-) diff --git a/src/ccs08.rs b/src/ccs08.rs index 8f4e205..ba69177 100644 --- a/src/ccs08.rs +++ b/src/ccs08.rs @@ -113,7 +113,7 @@ prove_ul method is used to produce the ZKRP proof that secret x belongs to the i let m = E::Fr::rand(rng); // D = H^m - let mut hm = self.com.h.clone(); + let mut hm = self.com.h2.clone(); hm.mul_assign(m); for i in 0..self.l as usize { v.push(E::Fr::rand(rng)); @@ -143,7 +143,7 @@ prove_ul method is used to produce the ZKRP proof that secret x belongs to the i let ui = self.u.pow(i as u32); let mut muiti = t[i].clone(); muiti.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap()); - let mut aux = self.com.g.clone(); + let mut aux = self.com.g2.clone(); aux.mul_assign(muiti); D.add_assign(&aux); } @@ -206,17 +206,17 @@ verify_ul is used to validate the ZKRP proof. It returns true iff the proof is v } fn verify_part1(&self, proof: &ProofUL) -> bool { - let mut D = proof.comm.c.clone(); + let mut D = proof.comm.c2.clone(); D.mul_assign(proof.ch); D.negate(); - let mut hzr = self.com.h.clone(); + let mut hzr = self.com.h2.clone(); hzr.mul_assign(proof.zr); D.add_assign(&hzr); for i in 0..self.l { let ui = self.u.pow(i as u32); let mut muizsigi = proof.zsig[i as usize]; muizsigi.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap()); - let mut aux = self.com.g.clone(); + let mut aux = self.com.g2.clone(); aux.mul_assign(muizsigi); D.add_assign(&aux); } diff --git a/src/cl.rs b/src/cl.rs index e08da98..6c387d4 100644 --- a/src/cl.rs +++ b/src/cl.rs @@ -6,6 +6,7 @@ extern crate rand; use super::*; use pairing::{CurveAffine, CurveProjective, Engine}; use rand::Rng; +use ped92::Commitment; #[derive(Clone)] pub struct PublicParams { @@ -29,7 +30,8 @@ pub struct PublicKey { //#[derive(Clone, Serialize, Deserialize)] #[derive(Clone)] pub struct BlindPublicKey { - pub X: E::G2, + pub X1: E::G1, + pub X2: E::G2, pub Y1: Vec, pub Y2: Vec, } @@ -189,11 +191,15 @@ impl BlindPublicKey { Y1.push(g1y); Y2.push(g2y); } - // X = g2 ^ x - let mut X = mpk.g2; - X.mul_assign(secret.x); + // X1 = g1 ^ x + let mut X1 = mpk.g1; + X1.mul_assign(secret.x); + // X2 = g2 ^ x + let mut X2 = mpk.g2; + X2.mul_assign(secret.x); BlindPublicKey { - X: X, + X1: X1, + X2: X2, Y1: Y1, Y2: Y2 } @@ -216,7 +222,7 @@ impl BlindPublicKey { Yt.mul_assign(message[l]); L.add_assign(&Yt); - let mut X2 = self.X; + let mut X2 = self.X2; X2.add_assign(&L); // X2 = X + L let lhs = E::pairing(signature.h, X2); let rhs = E::pairing(signature.H, mpk.g2); @@ -275,6 +281,20 @@ impl BlindKeyPair { self.secret.sign(csprng, message) } + /// sign a commitment of a vector of messages + pub fn sign_blind(&self, csprng: &mut R, mpk: &PublicParams, com: Commitment) -> Signature { + let u = E::Fr::rand(csprng); + let mut h1 = mpk.g1; + h1.mul_assign(u); // g1 ^ u + + let mut com1 = com.c1.clone(); + let mut H1 = self.public.X1.clone(); + H1.add_assign(&com1); // (X * com ^ g) + H1.mul_assign(u); // com ^ u (blinding factor) + + Signature { h: h1, H: H1 } + } + /// computes a blind signature from an existing one pub fn blind(&self, csprng: &mut R, bf: &E::Fr, signature: &Signature) -> Signature { self.secret.blind(csprng, bf, signature) @@ -332,6 +352,7 @@ mod tests { use pairing::bls12_381::{Bls12, Fr}; use rand::{SeedableRng}; use rand_xorshift::XorShiftRng; + use ped92::CSMultiParams; #[test] fn sign_and_verify() { @@ -390,5 +411,46 @@ mod tests { assert_eq!(keypair.verify(&mpk,&message1, &t1,&blind_sig), false); } + #[test] + fn blind_sign_and_verify_works() { + let mut rng = &mut rand::thread_rng(); + + let l = 5; + let mpk = setup(&mut rng); + let keypair = BlindKeyPair::::generate(&mut rng, &mpk, l); + + let public_key = keypair.get_public_key(&mpk); + + let mut message1 : Vec = Vec::new(); + let mut message2 : Vec = Vec::new(); + + for i in 0..l { + message1.push(Fr::rand(&mut rng)); + message2.push(Fr::rand(&mut rng)); + } + let mut com_bases1 = vec! {mpk.g1}; + com_bases1.append(&mut keypair.public.Y1.clone()); + + let mut com_bases2 = vec! {mpk.g2}; + com_bases2.append(&mut keypair.public.Y2.clone()); + + let com_params = CSMultiParams { pub_bases1: com_bases1, pub_bases2: com_bases2}; + let t = Fr::rand(rng); + let com = com_params.commit(rng, &message1, &t); + + let signature = keypair.sign_blind(rng, &mpk, com); + + let unblinded_sig = keypair.unblind(&t, &signature); + + let t1 = Fr::rand(&mut rng); + + assert_eq!(keypair.verify(&mpk,&message1, &t,&unblinded_sig), true); + assert_eq!(keypair.verify(&mpk,&message1, &t, &signature), true); + assert_eq!(keypair.verify(&mpk,&message2, &t,&unblinded_sig), false); + assert_eq!(keypair.verify(&mpk,&message2, &t,&signature), false); + assert_eq!(keypair.verify(&mpk,&message1, &t1,&unblinded_sig), false); + assert_eq!(keypair.verify(&mpk,&message1, &t1,&signature), false); + } + } diff --git a/src/ped92.rs b/src/ped92.rs index 1abd923..8f794ef 100644 --- a/src/ped92.rs +++ b/src/ped92.rs @@ -5,18 +5,22 @@ use ff::Rand; #[derive(Clone)] pub struct CSParams { - pub g: E::G2, - pub h: E::G2, + pub g1: E::G1, + pub g2: E::G2, + pub h1: E::G1, + pub h2: E::G2, } #[derive(Clone)] pub struct Commitment { - pub c: E::G2 + pub c1: E::G1, + pub c2: E::G2 } #[derive(Clone)] pub struct CSMultiParams { - pub pub_bases: Vec + pub pub_bases1: Vec, + pub pub_bases2: Vec } //impl fmt::Display for CSParams { @@ -59,9 +63,11 @@ impl CSParams { Implements the setup algorithm for the Pedersen92 commitment scheme */ pub fn setup(rng: &mut R) -> Self { - let g = E::G2::rand(rng); - let h = E::G2::rand(rng); - let csp = CSParams { g, h }; + let g1 = E::G1::rand(rng); + let g2 = E::G2::rand(rng); + let h1 = E::G1::rand(rng); + let h2 = E::G2::rand(rng); + let csp = CSParams { g1, g2, h1, h2 }; return csp; } @@ -74,15 +80,21 @@ commit(pk, msg) -> cm where pub fn commit(&self, rng: &mut R, m: E::Fr, R: Option) -> Commitment { let r = R.unwrap_or(E::Fr::rand(rng)); - let p = "commit -> m"; // c = g^m * h^r - let mut c = self.g.clone(); - c.mul_assign(m); - let mut h = self.h.clone(); - h.mul_assign(r); - c.add_assign(&h); + let mut c1 = self.g1.clone(); + c1.mul_assign(m.clone()); + let mut h1 = self.h1.clone(); + h1.mul_assign(r.clone()); + c1.add_assign(&h1); - Commitment { c } + // c = g^m * h^r + 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 } } /* @@ -92,14 +104,18 @@ decommit(csp, cm, msg) -> bool where - outputs T/F for whether the cm is a valid commitment to the msg */ pub fn decommit(&self, cm: &Commitment, m: &E::Fr, r: &E::Fr) -> bool { - let p = "decommit -> m"; + let mut dm1 = self.g1.clone(); + dm1.mul_assign(m.clone()); + let mut h1 = self.h1.clone(); + h1.mul_assign(r.clone()); + dm1.add_assign(&h1); - let mut dm = self.g.clone(); - dm.mul_assign(m.clone()); - let mut h = self.h.clone(); - h.mul_assign(r.clone()); - dm.add_assign(&h); - return 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; } } @@ -110,40 +126,51 @@ impl CSMultiParams { a vector of messages. */ pub fn setup_gen_params(rng: &mut R, len: usize) -> Self { - let mut p: Vec = Vec::new(); + let mut p1: Vec = Vec::new(); + let mut p2: Vec = Vec::new(); for i in 0..len { - p.push(E::G2::rand(rng)); + p1.push(E::G1::rand(rng)); + p2.push(E::G2::rand(rng)); } - return CSMultiParams { pub_bases: p }; + return CSMultiParams { pub_bases1: p1, pub_bases2: p2 }; } pub fn commit(&self, rng: &mut R, x: &Vec, r: &E::Fr) -> Commitment { //let r = R.unwrap_or(Fr::random(rng)); // c = g1^m1 * ... * gn^mn * h^r - let mut c = self.pub_bases[0].clone(); - c.mul_assign(r.clone()); + let mut c1 = self.pub_bases1[0].clone(); + let mut c2 = self.pub_bases2[0].clone(); + c1.mul_assign(r.clone()); + c2.mul_assign(r.clone()); for i in 1..x.len() { - let mut basis = self.pub_bases[i]; - basis.mul_assign(x[i]); - c.add_assign(&basis); + let mut basis1 = self.pub_bases1[i]; + basis1.mul_assign(x[i]); + c1.add_assign(&basis1); + let mut basis2 = self.pub_bases2[i]; + basis2.mul_assign(x[i]); + c2.add_assign(&basis2); } // return (c, r) <- r - Commitment { c: c } + Commitment { c1, c2 } } pub fn decommit(&self, cm: &Commitment, x: &Vec, r: &E::Fr) -> bool { let l = x.len(); // pub_base[0] => h, x[0] => r // check that cm.r == x[0] - let cr = r.clone(); - let mut dc = self.pub_bases[0].clone(); - dc.mul_assign(cr); + let mut dc1 = self.pub_bases1[0].clone(); + let mut dc2 = self.pub_bases2[0].clone(); + dc1.mul_assign(r.clone()); + dc2.mul_assign(r.clone()); for i in 1..l { - let mut basis = self.pub_bases[i]; - basis.mul_assign(x[i]); - dc.add_assign(&basis); + let mut basis1 = self.pub_bases1[i]; + basis1.mul_assign(x[i]); + dc1.add_assign(&basis1); + let mut basis2 = self.pub_bases2[i]; + basis2.mul_assign(x[i]); + dc2.add_assign(&basis2); } - return dc == cm.c && cr == x[0]; + return dc2 == cm.c2 && dc1 == cm.c1; } } @@ -178,7 +205,7 @@ mod tests { for i in 0..len { m.push(Fr::rand(rng)); } - let r = m[0].clone(); + let r = Fr::rand(rng); let c = csp.commit(rng, &m, &r); assert_eq!(csp.decommit(&c, &m, &r), true);