blind-sign: add commitment in G1
This commit is contained in:
parent
de9132939a
commit
3c5237f12c
10
src/ccs08.rs
10
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);
|
let m = E::Fr::rand(rng);
|
||||||
|
|
||||||
// D = H^m
|
// D = H^m
|
||||||
let mut hm = self.com.h.clone();
|
let mut hm = self.com.h2.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 {
|
||||||
v.push(E::Fr::rand(rng));
|
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 ui = self.u.pow(i as u32);
|
||||||
let mut muiti = t[i].clone();
|
let mut muiti = t[i].clone();
|
||||||
muiti.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap());
|
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);
|
aux.mul_assign(muiti);
|
||||||
D.add_assign(&aux);
|
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<E>) -> bool {
|
fn verify_part1(&self, proof: &ProofUL<E>) -> bool {
|
||||||
let mut D = proof.comm.c.clone();
|
let mut D = proof.comm.c2.clone();
|
||||||
D.mul_assign(proof.ch);
|
D.mul_assign(proof.ch);
|
||||||
D.negate();
|
D.negate();
|
||||||
let mut hzr = self.com.h.clone();
|
let mut hzr = self.com.h2.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 {
|
for i in 0..self.l {
|
||||||
let ui = self.u.pow(i as u32);
|
let ui = self.u.pow(i as u32);
|
||||||
let mut muizsigi = proof.zsig[i as usize];
|
let mut muizsigi = proof.zsig[i as usize];
|
||||||
muizsigi.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap());
|
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);
|
aux.mul_assign(muizsigi);
|
||||||
D.add_assign(&aux);
|
D.add_assign(&aux);
|
||||||
}
|
}
|
||||||
|
|
74
src/cl.rs
74
src/cl.rs
|
@ -6,6 +6,7 @@ extern crate rand;
|
||||||
use super::*;
|
use super::*;
|
||||||
use pairing::{CurveAffine, CurveProjective, Engine};
|
use pairing::{CurveAffine, CurveProjective, Engine};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
use ped92::Commitment;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PublicParams<E: Engine> {
|
pub struct PublicParams<E: Engine> {
|
||||||
|
@ -29,7 +30,8 @@ pub struct PublicKey<E: Engine> {
|
||||||
//#[derive(Clone, Serialize, Deserialize)]
|
//#[derive(Clone, Serialize, Deserialize)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BlindPublicKey<E: Engine> {
|
pub struct BlindPublicKey<E: Engine> {
|
||||||
pub X: E::G2,
|
pub X1: E::G1,
|
||||||
|
pub X2: E::G2,
|
||||||
pub Y1: Vec<E::G1>,
|
pub Y1: Vec<E::G1>,
|
||||||
pub Y2: Vec<E::G2>,
|
pub Y2: Vec<E::G2>,
|
||||||
}
|
}
|
||||||
|
@ -189,11 +191,15 @@ impl<E: Engine> BlindPublicKey<E> {
|
||||||
Y1.push(g1y);
|
Y1.push(g1y);
|
||||||
Y2.push(g2y);
|
Y2.push(g2y);
|
||||||
}
|
}
|
||||||
// X = g2 ^ x
|
// X1 = g1 ^ x
|
||||||
let mut X = mpk.g2;
|
let mut X1 = mpk.g1;
|
||||||
X.mul_assign(secret.x);
|
X1.mul_assign(secret.x);
|
||||||
|
// X2 = g2 ^ x
|
||||||
|
let mut X2 = mpk.g2;
|
||||||
|
X2.mul_assign(secret.x);
|
||||||
BlindPublicKey {
|
BlindPublicKey {
|
||||||
X: X,
|
X1: X1,
|
||||||
|
X2: X2,
|
||||||
Y1: Y1,
|
Y1: Y1,
|
||||||
Y2: Y2
|
Y2: Y2
|
||||||
}
|
}
|
||||||
|
@ -216,7 +222,7 @@ impl<E: Engine> BlindPublicKey<E> {
|
||||||
Yt.mul_assign(message[l]);
|
Yt.mul_assign(message[l]);
|
||||||
L.add_assign(&Yt);
|
L.add_assign(&Yt);
|
||||||
|
|
||||||
let mut X2 = self.X;
|
let mut X2 = self.X2;
|
||||||
X2.add_assign(&L); // X2 = X + L
|
X2.add_assign(&L); // X2 = X + L
|
||||||
let lhs = E::pairing(signature.h, X2);
|
let lhs = E::pairing(signature.h, X2);
|
||||||
let rhs = E::pairing(signature.H, mpk.g2);
|
let rhs = E::pairing(signature.H, mpk.g2);
|
||||||
|
@ -275,6 +281,20 @@ impl<E: Engine> BlindKeyPair<E> {
|
||||||
self.secret.sign(csprng, message)
|
self.secret.sign(csprng, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// sign a commitment of a vector of messages
|
||||||
|
pub fn sign_blind<R: Rng>(&self, csprng: &mut R, mpk: &PublicParams<E>, com: Commitment<E>) -> Signature<E> {
|
||||||
|
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
|
/// computes a blind signature from an existing one
|
||||||
pub fn blind<R: Rng>(&self, csprng: &mut R, bf: &E::Fr, signature: &Signature<E>) -> Signature<E> {
|
pub fn blind<R: Rng>(&self, csprng: &mut R, bf: &E::Fr, signature: &Signature<E>) -> Signature<E> {
|
||||||
self.secret.blind(csprng, bf, signature)
|
self.secret.blind(csprng, bf, signature)
|
||||||
|
@ -332,6 +352,7 @@ mod tests {
|
||||||
use pairing::bls12_381::{Bls12, Fr};
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
use rand::{SeedableRng};
|
use rand::{SeedableRng};
|
||||||
use rand_xorshift::XorShiftRng;
|
use rand_xorshift::XorShiftRng;
|
||||||
|
use ped92::CSMultiParams;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sign_and_verify() {
|
fn sign_and_verify() {
|
||||||
|
@ -390,5 +411,46 @@ mod tests {
|
||||||
assert_eq!(keypair.verify(&mpk,&message1, &t1,&blind_sig), false);
|
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::<Bls12>::generate(&mut rng, &mpk, l);
|
||||||
|
|
||||||
|
let public_key = keypair.get_public_key(&mpk);
|
||||||
|
|
||||||
|
let mut message1 : Vec<Fr> = Vec::new();
|
||||||
|
let mut message2 : Vec<Fr> = 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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
103
src/ped92.rs
103
src/ped92.rs
|
@ -5,18 +5,22 @@ use ff::Rand;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CSParams<E: Engine> {
|
pub struct CSParams<E: Engine> {
|
||||||
pub g: E::G2,
|
pub g1: E::G1,
|
||||||
pub h: E::G2,
|
pub g2: E::G2,
|
||||||
|
pub h1: E::G1,
|
||||||
|
pub h2: E::G2,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Commitment<E: Engine> {
|
pub struct Commitment<E: Engine> {
|
||||||
pub c: E::G2
|
pub c1: E::G1,
|
||||||
|
pub c2: E::G2
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CSMultiParams<E: Engine> {
|
pub struct CSMultiParams<E: Engine> {
|
||||||
pub pub_bases: Vec<E::G2>
|
pub pub_bases1: 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> {
|
||||||
|
@ -59,9 +63,11 @@ 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 g = E::G2::rand(rng);
|
let g1 = E::G1::rand(rng);
|
||||||
let h = E::G2::rand(rng);
|
let g2 = E::G2::rand(rng);
|
||||||
let csp = CSParams { g, h };
|
let h1 = E::G1::rand(rng);
|
||||||
|
let h2 = E::G2::rand(rng);
|
||||||
|
let csp = CSParams { g1, g2, h1, h2 };
|
||||||
return csp;
|
return csp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,15 +80,21 @@ commit(pk, msg) -> cm where
|
||||||
pub fn commit<R: Rng>(&self, rng: &mut R, m: E::Fr, R: Option<E::Fr>) -> Commitment<E> {
|
pub fn commit<R: Rng>(&self, rng: &mut R, m: E::Fr, R: Option<E::Fr>) -> Commitment<E> {
|
||||||
let r = R.unwrap_or(E::Fr::rand(rng));
|
let r = R.unwrap_or(E::Fr::rand(rng));
|
||||||
|
|
||||||
let p = "commit -> m";
|
|
||||||
// c = g^m * h^r
|
// c = g^m * h^r
|
||||||
let mut c = self.g.clone();
|
let mut c1 = self.g1.clone();
|
||||||
c.mul_assign(m);
|
c1.mul_assign(m.clone());
|
||||||
let mut h = self.h.clone();
|
let mut h1 = self.h1.clone();
|
||||||
h.mul_assign(r);
|
h1.mul_assign(r.clone());
|
||||||
c.add_assign(&h);
|
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
|
- 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 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();
|
let mut dm2 = self.g2.clone();
|
||||||
dm.mul_assign(m.clone());
|
dm2.mul_assign(m.clone());
|
||||||
let mut h = self.h.clone();
|
let mut h2 = self.h2.clone();
|
||||||
h.mul_assign(r.clone());
|
h2.mul_assign(r.clone());
|
||||||
dm.add_assign(&h);
|
dm2.add_assign(&h2);
|
||||||
return dm == cm.c;
|
return dm2 == cm.c2 && dm1 == cm.c1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,40 +126,51 @@ impl<E: Engine> CSMultiParams<E> {
|
||||||
a vector of messages.
|
a vector of messages.
|
||||||
*/
|
*/
|
||||||
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 p: Vec<E::G2> = Vec::new();
|
let mut p1: Vec<E::G1> = Vec::new();
|
||||||
|
let mut p2: Vec<E::G2> = Vec::new();
|
||||||
for i in 0..len {
|
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<R: Rng>(&self, rng: &mut R, x: &Vec<E::Fr>, r: &E::Fr) -> Commitment<E> {
|
pub fn commit<R: Rng>(&self, rng: &mut R, x: &Vec<E::Fr>, r: &E::Fr) -> Commitment<E> {
|
||||||
//let r = R.unwrap_or(Fr::random(rng));
|
//let r = R.unwrap_or(Fr::random(rng));
|
||||||
// c = g1^m1 * ... * gn^mn * h^r
|
// c = g1^m1 * ... * gn^mn * h^r
|
||||||
let mut c = self.pub_bases[0].clone();
|
let mut c1 = self.pub_bases1[0].clone();
|
||||||
c.mul_assign(r.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() {
|
for i in 1..x.len() {
|
||||||
let mut basis = self.pub_bases[i];
|
let mut basis1 = self.pub_bases1[i];
|
||||||
basis.mul_assign(x[i]);
|
basis1.mul_assign(x[i]);
|
||||||
c.add_assign(&basis);
|
c1.add_assign(&basis1);
|
||||||
|
let mut basis2 = self.pub_bases2[i];
|
||||||
|
basis2.mul_assign(x[i]);
|
||||||
|
c2.add_assign(&basis2);
|
||||||
}
|
}
|
||||||
// return (c, r) <- r
|
// return (c, r) <- r
|
||||||
Commitment { c: c }
|
Commitment { c1, c2 }
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
// check that cm.r == x[0]
|
// check that cm.r == x[0]
|
||||||
let cr = r.clone();
|
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(cr);
|
dc1.mul_assign(r.clone());
|
||||||
|
dc2.mul_assign(r.clone());
|
||||||
for i in 1..l {
|
for i in 1..l {
|
||||||
let mut basis = self.pub_bases[i];
|
let mut basis1 = self.pub_bases1[i];
|
||||||
basis.mul_assign(x[i]);
|
basis1.mul_assign(x[i]);
|
||||||
dc.add_assign(&basis);
|
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 {
|
for i in 0..len {
|
||||||
m.push(Fr::rand(rng));
|
m.push(Fr::rand(rng));
|
||||||
}
|
}
|
||||||
let r = m[0].clone();
|
let r = Fr::rand(rng);
|
||||||
let c = csp.commit(rng, &m, &r);
|
let c = csp.commit(rng, &m, &r);
|
||||||
|
|
||||||
assert_eq!(csp.decommit(&c, &m, &r), true);
|
assert_eq!(csp.decommit(&c, &m, &r), true);
|
||||||
|
|
Loading…
Reference in New Issue