2019-06-14 16:57:52 -07:00
|
|
|
// ped92.rs
|
2019-06-14 15:54:18 -07:00
|
|
|
use rand::{thread_rng, Rng};
|
2019-06-16 09:27:35 -07:00
|
|
|
use pairing::{Engine, CurveProjective};
|
2019-06-14 15:54:18 -07:00
|
|
|
use ff::Rand;
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
2019-06-17 12:09:09 -07:00
|
|
|
pub struct CSParams<E: Engine> {
|
2019-07-07 11:10:11 -07:00
|
|
|
pub g1: E::G1,
|
|
|
|
pub g2: E::G2,
|
|
|
|
pub h1: E::G1,
|
|
|
|
pub h2: E::G2,
|
2019-06-14 15:54:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Commitment<E: Engine> {
|
2019-07-07 11:10:11 -07:00
|
|
|
pub c1: E::G1,
|
|
|
|
pub c2: E::G2
|
2019-06-14 15:54:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
2019-06-17 12:09:09 -07:00
|
|
|
pub struct CSMultiParams<E: Engine> {
|
2019-07-07 11:10:11 -07:00
|
|
|
pub pub_bases1: Vec<E::G1>,
|
|
|
|
pub pub_bases2: Vec<E::G2>
|
2019-06-14 15:54:18 -07:00
|
|
|
}
|
|
|
|
|
2019-06-17 12:09:09 -07:00
|
|
|
//impl<E: Engine> fmt::Display for CSParams<E> {
|
2019-06-14 15:54:18 -07:00
|
|
|
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
// let g_vec: Vec<u8> = encode(&self.g, Infinite).unwrap();
|
|
|
|
// let h_vec: Vec<u8> = encode(&self.h, Infinite).unwrap();
|
|
|
|
// let mut g_s = String::new();
|
|
|
|
// for x in g_vec.iter() {
|
|
|
|
// g_s = format!("{}{:x}", g_s, x);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// let mut h_s = String::new();
|
|
|
|
// for y in h_vec.iter() {
|
|
|
|
// h_s = format!("{}{:x}", h_s, y);
|
|
|
|
// }
|
|
|
|
//
|
2019-06-17 12:09:09 -07:00
|
|
|
// write!(f, "CSP : (g=0x{}, h=0x{})", g_s, h_s)
|
2019-06-14 15:54:18 -07:00
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
//impl<E: Engine> fmt::Display for Commitment<E> {
|
|
|
|
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
// let c_vec: Vec<u8> = encode(&self.c, Infinite).unwrap();
|
|
|
|
// let mut c_s = String::new();
|
|
|
|
// for x in c_vec.iter() {
|
|
|
|
// c_s = format!("{}{:x}", c_s, x);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// let d_vec: Vec<u8> = encode(&self.r, Infinite).unwrap();
|
|
|
|
// let mut d_s = String::new();
|
|
|
|
// for x in d_vec.iter() {
|
|
|
|
// d_s = format!("{}{:x}", d_s, x);
|
|
|
|
// }
|
|
|
|
// write!(f, "Commitment : (c=0x{}, r=0x{})", c_s, d_s)
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
|
2019-06-17 12:09:09 -07:00
|
|
|
impl<E: Engine> CSParams<E> {
|
2019-06-14 17:55:02 -07:00
|
|
|
/*
|
2019-06-14 15:54:18 -07:00
|
|
|
Implements the setup algorithm for the Pedersen92 commitment scheme
|
|
|
|
*/
|
2019-06-14 17:55:02 -07:00
|
|
|
pub fn setup<R: Rng>(rng: &mut R) -> Self {
|
2019-07-07 11:10:11 -07:00
|
|
|
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 };
|
2019-06-17 12:09:09 -07:00
|
|
|
return csp;
|
2019-06-14 17:55:02 -07:00
|
|
|
}
|
2019-06-14 15:54:18 -07:00
|
|
|
|
2019-06-14 17:55:02 -07:00
|
|
|
/*
|
2019-06-14 15:54:18 -07:00
|
|
|
commit(pk, msg) -> cm where
|
|
|
|
- pk is the public key generated from setup()
|
|
|
|
- msg is the message structure for the commitment scheme
|
|
|
|
- cm is the output commitment message for the given message
|
|
|
|
*/
|
2019-06-14 17:55:02 -07:00
|
|
|
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));
|
|
|
|
|
|
|
|
// c = g^m * h^r
|
2019-07-07 11:10:11 -07:00
|
|
|
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);
|
2019-06-14 17:55:02 -07:00
|
|
|
|
2019-07-07 11:10:11 -07:00
|
|
|
// 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 }
|
2019-06-14 17:55:02 -07:00
|
|
|
}
|
2019-06-14 15:54:18 -07:00
|
|
|
|
2019-06-14 17:55:02 -07:00
|
|
|
/*
|
2019-06-17 12:09:09 -07:00
|
|
|
decommit(csp, cm, msg) -> bool where
|
2019-06-14 15:54:18 -07:00
|
|
|
- cm is the commitment
|
|
|
|
- m is the message to validate
|
|
|
|
- outputs T/F for whether the cm is a valid commitment to the msg
|
|
|
|
*/
|
2019-06-17 12:09:09 -07:00
|
|
|
pub fn decommit(&self, cm: &Commitment<E>, m: &E::Fr, r: &E::Fr) -> bool {
|
2019-07-07 11:10:11 -07:00
|
|
|
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 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;
|
2019-06-14 17:55:02 -07:00
|
|
|
}
|
2019-06-14 15:54:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-06-17 12:09:09 -07:00
|
|
|
impl<E: Engine> CSMultiParams<E> {
|
2019-06-14 16:57:52 -07:00
|
|
|
/*
|
|
|
|
Implements the setup algorithm for the Pedersen92 commitment scheme over
|
|
|
|
a vector of messages.
|
|
|
|
*/
|
|
|
|
pub fn setup_gen_params<R: Rng>(rng: &mut R, len: usize) -> Self {
|
2019-07-07 11:10:11 -07:00
|
|
|
let mut p1: Vec<E::G1> = Vec::new();
|
|
|
|
let mut p2: Vec<E::G2> = Vec::new();
|
2019-06-14 16:57:52 -07:00
|
|
|
for i in 0..len {
|
2019-07-07 11:10:11 -07:00
|
|
|
p1.push(E::G1::rand(rng));
|
|
|
|
p2.push(E::G2::rand(rng));
|
2019-06-14 16:57:52 -07:00
|
|
|
}
|
2019-07-07 11:10:11 -07:00
|
|
|
return CSMultiParams { pub_bases1: p1, pub_bases2: p2 };
|
2019-06-14 15:54:18 -07:00
|
|
|
}
|
|
|
|
|
2019-06-17 12:09:09 -07:00
|
|
|
pub fn commit<R: Rng>(&self, rng: &mut R, x: &Vec<E::Fr>, r: &E::Fr) -> Commitment<E> {
|
2019-06-14 16:57:52 -07:00
|
|
|
//let r = R.unwrap_or(Fr::random(rng));
|
|
|
|
// c = g1^m1 * ... * gn^mn * h^r
|
2019-07-07 11:10:11 -07:00
|
|
|
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());
|
2019-06-14 16:57:52 -07:00
|
|
|
for i in 1..x.len() {
|
2019-07-07 11:10:11 -07:00
|
|
|
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);
|
2019-06-14 16:57:52 -07:00
|
|
|
}
|
|
|
|
// return (c, r) <- r
|
2019-07-07 11:10:11 -07:00
|
|
|
Commitment { c1, c2 }
|
2019-06-14 15:54:18 -07:00
|
|
|
}
|
|
|
|
|
2019-06-17 12:09:09 -07:00
|
|
|
pub fn decommit(&self, cm: &Commitment<E>, x: &Vec<E::Fr>, r: &E::Fr) -> bool {
|
2019-06-14 16:57:52 -07:00
|
|
|
let l = x.len();
|
|
|
|
// pub_base[0] => h, x[0] => r
|
|
|
|
// check that cm.r == x[0]
|
2019-07-07 11:10:11 -07:00
|
|
|
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());
|
2019-06-14 16:57:52 -07:00
|
|
|
for i in 1..l {
|
2019-07-07 11:10:11 -07:00
|
|
|
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);
|
2019-06-14 16:57:52 -07:00
|
|
|
}
|
2019-07-07 11:10:11 -07:00
|
|
|
return dc2 == cm.c2 && dc1 == cm.c1;
|
2019-06-14 15:54:18 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
use pairing::bls12_381::{Bls12, Fr};
|
|
|
|
use ff::Field;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn commit_one_message_works() {
|
|
|
|
let rng = &mut thread_rng();
|
2019-06-17 12:09:09 -07:00
|
|
|
let csp = CSParams::<Bls12>::setup(rng);
|
2019-06-14 15:54:18 -07:00
|
|
|
|
|
|
|
let m1 = Fr::rand(rng);
|
|
|
|
let mut m2 = m1.clone();
|
|
|
|
m2.add_assign(&Fr::one());
|
|
|
|
let r = Fr::rand(rng);
|
2019-06-17 12:09:09 -07:00
|
|
|
let c = csp.commit(rng, m1, Some(r));
|
2019-06-14 15:54:18 -07:00
|
|
|
|
2019-06-18 14:46:54 -07:00
|
|
|
assert_eq!(csp.decommit(&c, &m1, &r), true);
|
|
|
|
assert_eq!(csp.decommit(&c, &m2, &r), false);
|
2019-06-14 15:54:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn commit_n_message_works() {
|
|
|
|
let rng = &mut thread_rng();
|
|
|
|
let len = 3;
|
2019-06-17 12:09:09 -07:00
|
|
|
let csp = CSMultiParams::<Bls12>::setup_gen_params(rng, len);
|
2019-06-14 15:54:18 -07:00
|
|
|
|
|
|
|
let mut m: Vec<Fr> = Vec::new();
|
2019-06-14 15:59:33 -07:00
|
|
|
for i in 0..len {
|
2019-06-14 15:54:18 -07:00
|
|
|
m.push(Fr::rand(rng));
|
|
|
|
}
|
2019-07-07 11:10:11 -07:00
|
|
|
let r = Fr::rand(rng);
|
2019-06-17 12:09:09 -07:00
|
|
|
let c = csp.commit(rng, &m, &r);
|
2019-06-14 15:54:18 -07:00
|
|
|
|
2019-06-18 14:46:54 -07:00
|
|
|
assert_eq!(csp.decommit(&c, &m, &r), true);
|
2019-06-17 12:09:09 -07:00
|
|
|
let mut r1 = r.clone();
|
|
|
|
r1.add_assign(&Fr::one());
|
2019-06-18 14:46:54 -07:00
|
|
|
assert_eq!(csp.decommit(&c, &m, &r1), false);
|
2019-06-14 15:54:18 -07:00
|
|
|
}
|
|
|
|
}
|