diff --git a/src/ccs08.rs b/src/ccs08.rs index 7f9743c..07017cc 100644 --- a/src/ccs08.rs +++ b/src/ccs08.rs @@ -9,11 +9,11 @@ extern crate rand; use super::*; use cl::{KeyPair, Signature, PublicParams, setup}; -use pairing::Engine; -use std::collections::HashMap; -use rand::Rng; +use ped92::{CSPublicKey, Commitment}; +use pairing::{Engine, CurveProjective}; use ff::PrimeField; -use commit_scheme::{ped92_setup, ped92_commit, ped92_decommit, Commitment}; +use std::collections::HashMap; +use std::fmt::Display; /* paramsUL contains elements generated by the verifier, which are necessary for the prover. @@ -22,8 +22,8 @@ This must be computed in a trusted setup. #[derive(Clone)] struct ParamsUL { pub mpk: PublicParams, - pub signatures: Vec<(i64, Signature)>, - pub h: E::G2, + pub signatures: HashMap>, + pub com: CSPublicKey, kp: KeyPair, // u determines the amount of signatures we need in the public params. // Each signature can be compressed to just 1 field element of 256 bits. @@ -40,9 +40,9 @@ proofUL contains the necessary elements for the ZK range proof. */ #[derive(Clone)] struct ProofUL { - v: Vec, + v: Vec, d: E::G2, - comm: Commitment, + comm: Commitment, a: Vec, s: Vec, t: Vec, @@ -80,14 +80,14 @@ fn setup_ul(u: i64, l: i64) -> ParamsUL { let mpk = setup(&mut rng); let kp = KeyPair::::generate(&mut rng, &mpk, 1); - let mut signatures: Vec<(i64, Signature)> = Vec::new(); + let mut signatures: HashMap> = HashMap::new(); for i in 0..u { let sig_i = kp.sign(&mut rng, &vec! {E::Fr::from_str(i.to_string().as_str()).unwrap()}); - signatures.push((i, sig_i)); + signatures.insert(i.to_string(), sig_i); } - let h = E::G2::rand(rng); - return ParamsUL { mpk, signatures, h, kp, u, l }; + let com = CSPublicKey::setup(rng); + return ParamsUL { mpk, signatures, com, kp, u, l }; } /* @@ -105,62 +105,93 @@ fn decompose(x: i64, u: i64) -> Vec { return result; } -///* -//prove_ul method is used to produce the ZKRP proof that secret x belongs to the interval [0,U^L]. -//*/ -//fn prove_ul(x: E::Fr, r: E::Fr, p: ParamsUL) -> ProofUL { -// let decx = decompose(x, p.u); -// -//// Initialize variables -// let mut v = Vec::::with_capacity(p.l as usize); -// let mut V = Vec::::with_capacity(p.l as usize); -// let mut a = Vec::::with_capacity(p.l as usize); -// let mut s = Vec::::with_capacity(p.l as usize); -// let mut t = Vec::::with_capacity(p.l as usize); -// let mut zsig = Vec::::with_capacity(p.l as usize); -// let mut zv = Vec::::with_capacity(p.l as usize); -// let mut one: E::G2::one(); -// let mut D = E::G2::zero().add_assign(one.negate()); -// let mut m = rand.Int(rand.Reader, bn256.Order); -// -//// D = H^m -// D = new(bn256.G2).ScalarMult(p.H, proof_out.m); -// for i in 0..p.l { -// v.push(rand.Int(rand.Reader, bn256.Order)); -// let A = p.signatures[strconv.FormatInt(decx[i], 10)]; -// V.push(new(bn256.G2).ScalarMult(A, v[i])); -// s.push(rand.Int(rand.Reader, bn256.Order)); -// t.push(rand.Int(rand.Reader, bn256.Order)); -// a.push(bn256.Pair(G1, proof_out.V[i])); -// a[i].ScalarMult(proof_out.a[i], proof_out.s[i]); -// a[i].Invert(proof_out.a[i]); -// a[i].Add(proof_out.a[i], new(bn256.GT).ScalarMult(E, proof_out.t[i])); -// -// let ui = new(big.Int).Exp(new(big.Int).SetInt64(p.u), new(big.Int).SetInt64(i), nil); -// let mut muisi = new(big.Int).Mul(proof_out.s[i], ui); -// muisi = Mod(muisi, bn256.Order); -// let aux = new(bn256.G2).ScalarBaseMult(muisi); -// D.Add(D, aux); -// } -// proof_out.D.Add(proof_out.D, D); -// -//// Consider passing C as input, -//// so that it is possible to delegate the commitment computation to an external party. -// let C = ped92_commit(p.H, x, r); //TODO: commit -//// Fiat-Shamir heuristic -// let mut c = Hash(proof_out.a, proof_out.D); -// c = Mod(proof_out.c, bn256.Order); -// -// let mut zr = Sub(proof_out.m, Multiply(r, proof_out.c)); -// zr = Mod(proof_out.zr, bn256.Order); -// for i in 0..p.l { -// proof_out.zsig[i] = Sub(proof_out.s[i], Multiply(new(big.Int).SetInt64(decx[i]), proof_out.c)); -// proof_out.zsig[i] = Mod(proof_out.zsig[i], bn256.Order); -// proof_out.zv[i] = Sub(proof_out.t[i], Multiply(v[i], proof_out.c)); -// proof_out.zv[i] = Mod(proof_out.zv[i], bn256.Order); -// } -// return ProofUL {v, d: D, comm: C, a, s, t, zsig, zv, ch: c, m, zr}; -//} +/* +prove_ul method is used to produce the ZKRP proof that secret x belongs to the interval [0,U^L]. +*/ +fn prove_ul(x: i64, r: E::Fr, p: ParamsUL) -> ProofUL { + let mut rng = &mut rand::thread_rng(); + let mut mutr = r.clone(); + + let decx = decompose(x, p.u); + let modx = E::Fr::from_str(&(x.to_string())).unwrap(); + +// Initialize variables + let mut v = Vec::::with_capacity(p.l as usize); + let mut V = Vec::::with_capacity(p.l as usize); + let mut a = Vec::::with_capacity(p.l as usize); + let mut s = Vec::::with_capacity(p.l as usize); + let mut t = Vec::::with_capacity(p.l as usize); + let mut zsig = Vec::::with_capacity(p.l as usize); + let mut zv = Vec::::with_capacity(p.l as usize); + let mut one = E::G2::one(); + let mut D = E::G2::zero(); + one.negate(); + D.add_assign(&one); + let mut m = E::Fr::rand(rng); + +// D = H^m + let mut Dnew = p.com.h; + Dnew.mul_assign(m); + for i in 0..p.l as usize { + v.push(E::Fr::rand(rng)); + let mut A = p.signatures.get(&decx[i].to_string()).unwrap().H; + A.mul_assign(v[i]); + V.push(A); + s.push(E::Fr::rand(rng)); + t.push(E::Fr::rand(rng)); + a.push(E::pairing( V[i], p.mpk.g2)); + a[i].pow(s[i].into_repr()); + a[i] = a[i].inverse().unwrap(); + let mut E = E::pairing(p.mpk.g1, p.mpk.g2); + E.pow(t[i].into_repr()); + a[i].add_assign(&E); + + let ui = p.u.pow(i as u32); + let mut muisi = s[i].clone(); + muisi.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap()); + let mut aux = p.mpk.g2.clone(); + aux.mul_assign(muisi); + D.add_assign(&aux); + } + D.add_assign(&Dnew); + + let C = p.com.commit(rng, modx, Some(mutr)); +// Fiat-Shamir heuristic + let c = Hash::(a.clone(), D.clone()); + + let mut zr = m.clone(); + mutr.mul_assign(&c); + zr.sub_assign(&mutr); + for i in 0..p.l as usize { + zsig[i] = s[i].clone(); + let mut dx = E::Fr::from_str(&decx[i].to_string()).unwrap(); + dx.mul_assign(&c); + zsig[i].sub_assign(&dx); + let mut vi = v[i].clone(); + vi.mul_assign(&c); + let mut ti = t[i].clone(); + ti.sub_assign(&vi); + zv[i] = ti.clone(); + } + return ProofUL {v: V, d: D, comm: C, a, s, t, zsig, zv, ch: c, m, zr}; +} + +fn Hash(a: Vec, D: E::G2) -> E::Fr { + // create a Sha256 object + let mut a_vec: Vec = Vec::new(); + for a_el in a { + a_vec.extend(format!("{}", a_el).bytes()); + } + + let mut x_vec: Vec = Vec::new(); + x_vec.extend(format!("{}", D).bytes()); + a_vec.extend(x_vec); + let sha2_digest = sha512::hash(a_vec.as_slice()); + + let mut hash_buf: [u8; 64] = [0; 64]; + hash_buf.copy_from_slice(&sha2_digest[0..64]); + return E::Fr::from_str(&str::from_utf8(&hash_buf).unwrap()).unwrap(); +} /* diff --git a/src/ped92.rs b/src/ped92.rs index 762377f..d37aa7a 100644 --- a/src/ped92.rs +++ b/src/ped92.rs @@ -1,12 +1,12 @@ // ped92.rs use rand::{thread_rng, Rng}; -use pairing::{Engine, CurveProjective, CurveAffine}; +use pairing::{Engine, CurveProjective}; use ff::Rand; #[derive(Clone)] pub struct CSPublicKey { - g: E::G2, - h: E::G2, + pub g: E::G2, + pub h: E::G2, } #[derive(Clone)]