ccs08: verification algorithm, non-working part 2

This commit is contained in:
Gijs Van Laer 2019-06-17 15:01:31 -04:00
parent 5310eeb564
commit b4f895f477
2 changed files with 146 additions and 44 deletions

View File

@ -42,8 +42,8 @@ proofUL contains the necessary elements for the ZK range proof.
*/ */
#[derive(Clone)] #[derive(Clone)]
struct ProofUL<E: Engine> { struct ProofUL<E: Engine> {
v: Vec<E::G1>, V: Vec<E::G1>,
d: E::G2, D: E::G2,
comm: Commitment<E>, comm: Commitment<E>,
a: Vec<E::Fqk>, a: Vec<E::Fqk>,
s: Vec<E::Fr>, s: Vec<E::Fr>,
@ -77,7 +77,7 @@ setup_ul generates the signature for the interval [0,u^l).
The value of u should be roughly b/log(b), but we can choose smaller values in The value of u should be roughly b/log(b), but we can choose smaller values in
order to get smaller parameters, at the cost of having worse performance. order to get smaller parameters, at the cost of having worse performance.
*/ */
pub fn setup_ul<R: Rng>(rng: &mut R, u: i64, l: i64) -> ParamsUL<E> { pub fn setup_ul<R: Rng>(rng: &mut R, u: i64, l: i64) -> Self {
let mpk = setup(rng); let mpk = setup(rng);
let kp = KeyPair::<E>::generate(rng, &mpk, 1); let kp = KeyPair::<E>::generate(rng, &mpk, 1);
@ -95,9 +95,7 @@ order to get smaller parameters, at the cost of having worse performance.
prove_ul method is used to produce the ZKRP proof that secret x belongs to the interval [0,U^L]. prove_ul method is used to produce the ZKRP proof that secret x belongs to the interval [0,U^L].
*/ */
pub fn prove_ul<R: Rng>(&self, rng: &mut R, x: i64, r: E::Fr) -> ProofUL<E> { pub fn prove_ul<R: Rng>(&self, rng: &mut R, x: i64, r: E::Fr) -> ProofUL<E> {
let mut mutr = r.clone(); let decx = decompose(x, self.u, self.l);
let decx = decompose(x, self.u);
let modx = E::Fr::from_str(&(x.to_string())).unwrap(); let modx = E::Fr::from_str(&(x.to_string())).unwrap();
// Initialize variables // Initialize variables
@ -108,20 +106,18 @@ prove_ul method is used to produce the ZKRP proof that secret x belongs to the i
let mut t = Vec::<E::Fr>::with_capacity(self.l as usize); let mut t = Vec::<E::Fr>::with_capacity(self.l as usize);
let mut zsig = Vec::<E::Fr>::with_capacity(self.l as usize); let mut zsig = Vec::<E::Fr>::with_capacity(self.l as usize);
let mut zv = Vec::<E::Fr>::with_capacity(self.l as usize); let mut zv = Vec::<E::Fr>::with_capacity(self.l as usize);
let mut one = E::G2::one();
let mut D = E::G2::zero(); let mut D = E::G2::zero();
one.negate();
D.add_assign(&one);
let mut m = E::Fr::rand(rng); let mut m = E::Fr::rand(rng);
// D = H^m // D = H^m
let mut Dnew = self.com.h; let mut hm = self.com.h.clone();
Dnew.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));
let mut A = self.signatures.get(&decx[i].to_string()).unwrap().H; let mut A = self.signatures.get(&decx[i].to_string()).unwrap().H;
A.mul_assign(v[i]); A.mul_assign(v[i]);
V.push(A); V.push(A);
assert_eq!(A, V[i]); //TODO: remove
s.push(E::Fr::rand(rng)); s.push(E::Fr::rand(rng));
t.push(E::Fr::rand(rng)); t.push(E::Fr::rand(rng));
a.push(E::pairing(V[i], self.mpk.g2)); a.push(E::pairing(V[i], self.mpk.g2));
@ -129,36 +125,87 @@ prove_ul method is used to produce the ZKRP proof that secret x belongs to the i
a[i] = a[i].inverse().unwrap(); a[i] = a[i].inverse().unwrap();
let mut E = E::pairing(self.mpk.g1, self.mpk.g2); let mut E = E::pairing(self.mpk.g1, self.mpk.g2);
E.pow(t[i].into_repr()); E.pow(t[i].into_repr());
a[i].add_assign(&E); a[i].mul_assign(&E); //TODO: add or mul
let ui = self.u.pow(i as u32); let ui = self.u.pow(i as u32);
let mut muisi = s[i].clone(); let mut muisi = s[i].clone();
muisi.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap()); muisi.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap());
let mut aux = self.mpk.g2.clone(); let mut aux = self.com.g.clone();
aux.mul_assign(muisi); aux.mul_assign(muisi);
D.add_assign(&aux); D.add_assign(&aux);
} }
D.add_assign(&Dnew); D.add_assign(&hm);
let C = self.com.commit(rng, modx, Some(mutr)); let C = self.com.commit(rng, modx, Some(r));
// Fiat-Shamir heuristic // Fiat-Shamir heuristic
let c = Hash::<E>(a.clone(), D.clone()); let c = Hash::<E>(a.clone(), D.clone());
let mut zr = m.clone(); let mut zr = m.clone();
mutr.mul_assign(&c); let mut rc = r.clone();
zr.sub_assign(&mutr); rc.mul_assign(&c);
zr.sub_assign(&rc);
for i in 0..self.l as usize { for i in 0..self.l as usize {
zsig.push(s[i].clone()); zsig.push(s[i].clone());
assert_eq!(s[i], zsig[i]); //TODO: remove
let mut dx = E::Fr::from_str(&decx[i].to_string()).unwrap(); let mut dx = E::Fr::from_str(&decx[i].to_string()).unwrap();
dx.mul_assign(&c); dx.mul_assign(&c);
zsig[i].sub_assign(&dx); zsig[i].sub_assign(&dx);
let mut vi = v[i].clone(); let mut vic = v[i].clone();
vi.mul_assign(&c); vic.mul_assign(&c);
let mut ti = t[i].clone(); let mut ti = t[i].clone();
ti.sub_assign(&vi); ti.sub_assign(&vic);
zv.push(ti.clone()); zv.push(ti);
} }
return ProofUL { v: V, d: D, comm: C, a, s, t, zsig, zv, ch: c, m, zr };
return ProofUL { V, D, comm: C, a, s, t, zsig, zv, ch: c, m, zr };
}
/*
verify_ul is used to validate the ZKRP proof. It returns true iff the proof is valid.
*/
pub fn verify_ul(&self, proof: &ProofUL<E>) -> bool {
// D == C^c.h^ zr.g^zsig ?
let r1 = self.verify_part1(&proof);
let r2 = self.verify_part2(&proof);
return r1 && r2;
}
fn verify_part2(&self, proof: &ProofUL<E>) -> bool {
let mut r2 = true;
for i in 0..self.l as usize {
// a == [e(V,y)^c].[e(V,g)^-zsig].[e(g,g)^zv]
let mut p1 = E::pairing(proof.V[i], self.kp.public.X);
p1.pow(proof.ch.into_repr());
let mut p2 = E::pairing(proof.V[i], self.mpk.g2);
p2.pow(proof.zsig[i].into_repr());
p2 = p2.inverse().unwrap();
p1.mul_assign(&p2); // TODO: add or mul
let mut E = E::pairing(self.mpk.g1, self.mpk.g2);
E.pow(proof.zv[i].into_repr());
p1.mul_assign(&E); //TODO: add or mul
print!("{}\n", p1);
print!("{}\n", proof.a[i]);
r2 = r2 && p1 == proof.a[i];
}
return r2;
}
fn verify_part1(&self, proof: &ProofUL<E>) -> bool {
let mut D = proof.comm.c.clone();
D.mul_assign(proof.ch);
let mut hzr = self.com.h.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();
aux.mul_assign(muizsigi);
D.add_assign(&aux);
}
return D == proof.D;
} }
} }
@ -185,8 +232,7 @@ fn Hash<E: Engine>(a: Vec<E::Fqk>, D: E::G2) -> E::Fr {
Decompose receives as input an integer x and outputs an array of integers such that Decompose receives as input an integer x and outputs an array of integers such that
x = sum(xi.u^i), i.e. it returns the decomposition of x into base u. x = sum(xi.u^i), i.e. it returns the decomposition of x into base u.
*/ */
fn decompose(x: i64, u: i64) -> Vec<i64> { fn decompose(x: i64, u: i64, l: i64) -> Vec<i64> {
let l = (x as f64).log(u as f64).ceil() as usize;
let mut result = Vec::with_capacity(l as usize); let mut result = Vec::with_capacity(l as usize);
let mut decomposer = x.clone(); let mut decomposer = x.clone();
for i in 0..l { for i in 0..l {
@ -211,7 +257,7 @@ impl<E: Engine> RPPublicParams<E> {
/* /*
Setup receives integers a and b, and configures the parameters for the rangeproof scheme. Setup receives integers a and b, and configures the parameters for the rangeproof scheme.
*/ */
pub fn setup<R: Rng>(rng: &mut R, a: i64, b: i64) -> RPPublicParams<E> { pub fn setup<R: Rng>(rng: &mut R, a: i64, b: i64) -> Self {
// Compute optimal values for u and l // Compute optimal values for u and l
if a > b { if a > b {
panic!("a must be less than or equal to b"); panic!("a must be less than or equal to b");
@ -243,9 +289,9 @@ mod tests {
fn setup_ul_works() { fn setup_ul_works() {
let rng = &mut rand::thread_rng(); let rng = &mut rand::thread_rng();
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 3); let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 3);
assert_eq!(2, params.signatures.len()); assert_eq!(params.signatures.len(), 2);
for (m, s) in params.signatures { for (m, s) in params.signatures {
assert_eq!(true, params.kp.verify(&params.mpk, &vec! {Fr::from_str(m.to_string().as_str()).unwrap()}, &s)); assert_eq!(params.kp.verify(&params.mpk, &vec! {Fr::from_str(m.to_string().as_str()).unwrap()}, &s), true);
} }
} }
@ -255,29 +301,85 @@ mod tests {
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 3); let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 3);
let fr = Fr::rand(rng); let fr = Fr::rand(rng);
let proof = params.prove_ul(rng, 10, fr); let proof = params.prove_ul(rng, 10, fr);
assert_eq!(proof.a.len(), 3);
assert_eq!(proof.s.len(), 3);
assert_eq!(proof.t.len(), 3);
assert_eq!(proof.V.len(), 3);
assert_eq!(proof.zsig.len(), 3);
let mut s = proof.s[0].clone();
let mut ch = proof.ch.clone();
ch.mul_assign(&Fr::from_str(&decompose(10, 2, 4).get(0).unwrap().to_string()).unwrap());
s.sub_assign(&ch);
assert_eq!(proof.zsig[0], s);
assert_eq!(proof.zv.len(), 3);
}
#[test]
fn prove_and_verify_part1_ul_works() {
let rng = &mut rand::thread_rng();
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 4);
let fr = Fr::rand(rng);
let proof = params.prove_ul(rng, 10, fr);
assert_eq!(params.verify_part1(&proof), true);
}
#[test]
#[ignore]
fn prove_and_verify_part2_ul_works() {
let rng = &mut rand::thread_rng();
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 4);
let fr = Fr::rand(rng);
let proof = params.prove_ul(rng, 10, fr);
assert_eq!(params.verify_part2(&proof), true);
}
#[test]
#[ignore]
fn prove_and_verify_ul_works() {
let rng = &mut rand::thread_rng();
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 4);
let fr = Fr::rand(rng);
let proof = params.prove_ul(rng, 10, fr);
assert_eq!(params.verify_ul(&proof), true);
} }
#[test] #[test]
fn decompose_works() { fn decompose_works() {
assert_eq!(vec! {1, 2, 2}, decompose(25, 3)); assert_eq!(decompose(25, 3, 3), vec! {1, 2, 2});
assert_eq!(vec! {0, 6, 6}, decompose(336, 7)); assert_eq!(decompose(336, 7, 3), vec! {0, 6, 6});
assert_eq!(vec! {5, 3, 4}, decompose(285, 8)); assert_eq!(decompose(285, 8, 3), vec! {5, 3, 4});
assert_eq!(vec! {8, 9}, decompose(125, 13)); assert_eq!(decompose(125, 13, 2), vec! {8, 9});
assert_eq!(vec! {5, 2, 0, 3, 2, 0, 3}, decompose(143225, 6)); assert_eq!(decompose(143225, 6, 7), vec! {5, 2, 0, 3, 2, 0, 3});
}
#[test]
fn decompose_recompose_works() {
let vec1 = decompose(25, 3, 5);
let mut result = 0;
for i in 0..5 {
result += vec1[i] * 3i64.pow(i as u32);
}
assert_eq!(result, 25);
let vec1 = decompose(143225, 6, 7);
let mut result = 0;
for i in 0..7 {
result += vec1[i] * 6i64.pow(i as u32);
}
assert_eq!(result, 143225);
} }
#[test] #[test]
fn setup_works() { fn setup_works() {
let rng = &mut rand::thread_rng(); let rng = &mut rand::thread_rng();
let public_params = RPPublicParams::<Bls12>::setup(rng, 2, 10); let public_params = RPPublicParams::<Bls12>::setup(rng, 2, 10);
assert_eq!(2, public_params.a); assert_eq!(public_params.a, 2);
assert_eq!(10, public_params.b); assert_eq!(public_params.b, 10);
assert_eq!(10, public_params.p.signatures.len()); assert_eq!(public_params.p.signatures.len(), 10);
assert_eq!(10 / ((10 as f64).log10() as i64), public_params.p.u); assert_eq!(public_params.p.u, 10 / ((10 as f64).log10() as i64));
assert_eq!(((10 / (10 / ((10 as f64).log10() as i64))) as f64).ceil() as i64, public_params.p.l); assert_eq!(public_params.p.l, ((10 / (10 / ((10 as f64).log10() as i64))) as f64).ceil() as i64);
for (m, s) in public_params.p.signatures { for (m, s) in public_params.p.signatures {
assert_eq!(true, public_params.p.kp.verify(&public_params.p.mpk, &vec! {Fr::from_str(m.to_string().as_str()).unwrap()}, &s)); assert_eq!(public_params.p.kp.verify(&public_params.p.mpk, &vec! {Fr::from_str(m.to_string().as_str()).unwrap()}, &s), true);
} }
} }
@ -304,8 +406,8 @@ mod tests {
#[test] #[test]
fn fmt_byte_to_int_works() { fn fmt_byte_to_int_works() {
assert_eq!("122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123", assert_eq!(fmt_bytes_to_int([12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123]),
fmt_bytes_to_int([12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123])); "122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123");
} }
#[test] #[test]
@ -315,7 +417,7 @@ mod tests {
let D2 = G2::rand(rng); let D2 = G2::rand(rng);
let a = vec! {Fq12::rand(rng), Fq12::rand(rng), Fq12::rand(rng)}; let a = vec! {Fq12::rand(rng), Fq12::rand(rng), Fq12::rand(rng)};
let a2 = vec! {Fq12::rand(rng), Fq12::rand(rng), Fq12::rand(rng)}; let a2 = vec! {Fq12::rand(rng), Fq12::rand(rng), Fq12::rand(rng)};
assert_eq!(false, Hash::<Bls12>(a.clone(), D.clone()).is_zero()); assert_eq!(Hash::<Bls12>(a.clone(), D.clone()).is_zero(), false);
assert_ne!(Hash::<Bls12>(a2.clone(), D.clone()), Hash::<Bls12>(a.clone(), D.clone())); assert_ne!(Hash::<Bls12>(a2.clone(), D.clone()), Hash::<Bls12>(a.clone(), D.clone()));
assert_ne!(Hash::<Bls12>(a.clone(), D2.clone()), Hash::<Bls12>(a.clone(), D.clone())); assert_ne!(Hash::<Bls12>(a.clone(), D2.clone()), Hash::<Bls12>(a.clone(), D.clone()));
assert_ne!(Hash::<Bls12>(a2.clone(), D2.clone()), Hash::<Bls12>(a.clone(), D.clone())); assert_ne!(Hash::<Bls12>(a2.clone(), D2.clone()), Hash::<Bls12>(a.clone(), D.clone()));

View File

@ -170,8 +170,8 @@ mod tests {
let r = Fr::rand(rng); let r = Fr::rand(rng);
let c = pk.commit(rng, m1, Some(r)); let c = pk.commit(rng, m1, Some(r));
assert_eq!(true, pk.decommit(&c, m1)); assert_eq!(pk.decommit(&c, m1), true);
assert_eq!(false, pk.decommit(&c, m2)); assert_eq!(pk.decommit(&c, m2), false);
} }
#[test] #[test]
@ -187,6 +187,6 @@ mod tests {
let r = m[0].clone(); let r = m[0].clone();
let c = csp.commit(rng, &m, r); let c = csp.commit(rng, &m, r);
assert_eq!(true, csp.decommit(&c, &m)); assert_eq!(csp.decommit(&c, &m), true);
} }
} }