2019-06-14 15:14:06 -07:00
|
|
|
/*
|
|
|
|
Implementation of the ZK Range Proof scheme, based on:
|
|
|
|
Efficient Protocols for Set Membership and Range Proofs
|
|
|
|
Jan Camenisch, Rafik Chaabouni, and abhi shelat
|
|
|
|
Asiacrypt 2008
|
|
|
|
*/
|
|
|
|
extern crate pairing;
|
|
|
|
extern crate rand;
|
|
|
|
|
2019-06-16 13:29:48 -07:00
|
|
|
use rand::{thread_rng, Rng};
|
2019-06-14 15:14:06 -07:00
|
|
|
use super::*;
|
2019-07-03 16:05:27 -07:00
|
|
|
use cl::{KeyPair, Signature, PublicParams, setup, BlindKeyPair, ProofState, SignatureProof};
|
2019-07-12 16:52:16 -07:00
|
|
|
use ped92::{Commitment, CSMultiParams};
|
2019-06-16 09:27:35 -07:00
|
|
|
use pairing::{Engine, CurveProjective};
|
2019-06-14 15:14:06 -07:00
|
|
|
use ff::PrimeField;
|
2019-06-16 09:27:35 -07:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::fmt::Display;
|
2019-06-16 12:38:07 -07:00
|
|
|
use std::mem::transmute;
|
2019-07-03 16:05:27 -07:00
|
|
|
use util::fmt_bytes_to_int;
|
2019-06-14 15:14:06 -07:00
|
|
|
|
2019-07-02 15:39:23 -07:00
|
|
|
/**
|
2019-06-14 15:14:06 -07:00
|
|
|
paramsUL contains elements generated by the verifier, which are necessary for the prover.
|
|
|
|
This must be computed in a trusted setup.
|
|
|
|
*/
|
|
|
|
#[derive(Clone)]
|
|
|
|
struct ParamsUL<E: Engine> {
|
|
|
|
pub mpk: PublicParams<E>,
|
2019-06-16 09:27:35 -07:00
|
|
|
pub signatures: HashMap<String, Signature<E>>,
|
2019-07-12 16:52:16 -07:00
|
|
|
pub csParams: CSMultiParams<E>,
|
2019-07-01 18:51:24 -07:00
|
|
|
kp: BlindKeyPair<E>,
|
2019-06-14 15:14:06 -07:00
|
|
|
// 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.
|
|
|
|
// Then the parameters have minimum size equal to 256*u bits.
|
|
|
|
u: i64,
|
|
|
|
// l determines how many pairings we need to compute, then in order to improve
|
|
|
|
// verifier`s performance we want to minize it.
|
|
|
|
// Namely, we have 2*l pairings for the prover and 3*l for the verifier.
|
|
|
|
l: i64,
|
|
|
|
}
|
|
|
|
|
2019-07-12 13:43:48 -07:00
|
|
|
#[derive(Clone)]
|
2019-07-19 12:19:28 -07:00
|
|
|
pub struct ProofULState<E: Engine> {
|
|
|
|
pub decx: Vec<i64>,
|
|
|
|
pub proofStates: Vec<ProofState<E>>,
|
|
|
|
pub V: Vec<Signature<E>>,
|
|
|
|
pub D: E::G1,
|
|
|
|
pub m: E::Fr,
|
|
|
|
pub s: Vec<E::Fr>,
|
2019-07-12 13:43:48 -07:00
|
|
|
}
|
|
|
|
|
2019-07-02 15:39:23 -07:00
|
|
|
/**
|
|
|
|
proofUL contains the necessary elements for the ZK range proof with range [0,u^l).
|
2019-06-14 15:14:06 -07:00
|
|
|
*/
|
|
|
|
#[derive(Clone)]
|
2019-07-19 12:19:28 -07:00
|
|
|
pub struct ProofUL<E: Engine> {
|
|
|
|
pub V: Vec<Signature<E>>,
|
|
|
|
pub D: E::G1,
|
|
|
|
pub comm: Commitment<E>,
|
|
|
|
pub sigProofs: Vec<SignatureProof<E>>,
|
|
|
|
pub zr: E::Fr,
|
|
|
|
pub zs: Vec<E::Fr>,
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
|
|
|
|
2019-07-12 13:43:48 -07:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct RangeProofState<E: Engine> {
|
2019-07-19 12:19:28 -07:00
|
|
|
pub com1: Commitment<E>,
|
|
|
|
pub ps1: ProofULState<E>,
|
|
|
|
pub com2: Commitment<E>,
|
|
|
|
pub ps2: ProofULState<E>,
|
2019-07-12 13:43:48 -07:00
|
|
|
}
|
|
|
|
|
2019-07-02 15:39:23 -07:00
|
|
|
/**
|
|
|
|
RangeProof contains the necessary elements for the ZK range proof.
|
|
|
|
*/
|
2019-06-14 15:14:06 -07:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct RangeProof<E: Engine> {
|
2019-07-19 12:19:28 -07:00
|
|
|
pub p1: ProofUL<E>,
|
|
|
|
pub p2: ProofUL<E>,
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
2019-07-02 15:39:23 -07:00
|
|
|
|
|
|
|
/**
|
2019-06-14 15:14:06 -07:00
|
|
|
params contains elements generated by the verifier, which are necessary for the prover.
|
|
|
|
This must be computed in a trusted setup.
|
|
|
|
*/
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct RPPublicParams<E: Engine> {
|
|
|
|
p: ParamsUL<E>,
|
|
|
|
a: i64,
|
|
|
|
b: i64,
|
|
|
|
}
|
|
|
|
|
2019-06-16 13:29:48 -07:00
|
|
|
impl<E: Engine> ParamsUL<E> {
|
2019-07-02 15:39:23 -07:00
|
|
|
/**
|
|
|
|
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
|
|
|
|
order to get smaller parameters, at the cost of having worse performance.
|
|
|
|
*/
|
2019-07-12 16:52:16 -07:00
|
|
|
pub fn setup_ul<R: Rng>(rng: &mut R, u: i64, l: i64, csParams: CSMultiParams<E>) -> Self {
|
2019-06-16 13:29:48 -07:00
|
|
|
let mpk = setup(rng);
|
2019-07-01 18:51:24 -07:00
|
|
|
let kp = BlindKeyPair::<E>::generate(rng, &mpk, 1);
|
2019-06-14 15:14:06 -07:00
|
|
|
|
2019-06-16 13:29:48 -07:00
|
|
|
let mut signatures: HashMap<String, Signature<E>> = HashMap::new();
|
|
|
|
for i in 0..u {
|
|
|
|
let sig_i = kp.sign(rng, &vec! {E::Fr::from_str(i.to_string().as_str()).unwrap()});
|
|
|
|
signatures.insert(i.to_string(), sig_i);
|
|
|
|
}
|
2019-06-14 15:14:06 -07:00
|
|
|
|
2019-07-12 11:15:00 -07:00
|
|
|
return ParamsUL { mpk, signatures, csParams, kp, u, l };
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
|
|
|
|
2019-07-02 15:39:23 -07:00
|
|
|
/**
|
|
|
|
prove_ul method is used to produce the ZKRP proof that secret x belongs to the interval [0,U^L).
|
|
|
|
*/
|
2019-07-19 12:04:56 -07:00
|
|
|
pub fn prove_ul<R: Rng>(&self, rng: &mut R, x: i64, r: E::Fr, C: Commitment<E>, k: usize, otherM: Vec<E::Fr>) -> ProofUL<E> {
|
2019-07-12 16:52:16 -07:00
|
|
|
let proofUlState = self.prove_ul_commitment(rng, x, k);
|
2019-07-12 13:43:48 -07:00
|
|
|
|
|
|
|
// Fiat-Shamir heuristic
|
|
|
|
let mut a = Vec::<E::Fqk>::with_capacity(self.l as usize);
|
|
|
|
for state in proofUlState.proofStates.clone() {
|
|
|
|
a.push(state.a);
|
|
|
|
}
|
|
|
|
let c = hash::<E>(a, vec!(proofUlState.D.clone()));
|
|
|
|
|
2019-07-19 12:04:56 -07:00
|
|
|
self.prove_ul_response(r, C, &proofUlState, c, k, otherM)
|
2019-07-12 13:43:48 -07:00
|
|
|
}
|
|
|
|
|
2019-07-12 16:52:16 -07:00
|
|
|
fn prove_ul_commitment<R: Rng>(&self, rng: &mut R, x: i64, k: usize) -> ProofULState<E> {
|
2019-06-28 14:44:14 -07:00
|
|
|
if x > self.u.pow(self.l as u32) || x < 0 {
|
|
|
|
panic!("x is not within the range.");
|
|
|
|
}
|
2019-06-17 12:01:31 -07:00
|
|
|
let decx = decompose(x, self.u, self.l);
|
2019-06-16 09:27:35 -07:00
|
|
|
|
2019-07-02 15:39:23 -07:00
|
|
|
// Initialize variables
|
2019-07-03 12:56:41 -07:00
|
|
|
let mut proofStates = Vec::<ProofState<E>>::with_capacity(self.l as usize);
|
2019-07-02 15:39:23 -07:00
|
|
|
let mut V = Vec::<Signature<E>>::with_capacity(self.l as usize);
|
2019-07-19 12:04:56 -07:00
|
|
|
let mut s = Vec::<E::Fr>::with_capacity(self.csParams.pub_bases.len() - 2);
|
2019-07-12 07:46:25 -07:00
|
|
|
let mut D = E::G1::zero();
|
2019-06-26 10:33:08 -07:00
|
|
|
let m = E::Fr::rand(rng);
|
2019-06-16 09:27:35 -07:00
|
|
|
|
2019-06-18 13:20:16 -07:00
|
|
|
// D = H^m
|
2019-07-12 16:52:16 -07:00
|
|
|
let mut hm = self.csParams.pub_bases[0].clone();
|
2019-06-17 12:01:31 -07:00
|
|
|
hm.mul_assign(m);
|
2019-06-26 10:33:08 -07:00
|
|
|
for i in 0..self.l as usize {
|
2019-07-01 18:51:24 -07:00
|
|
|
let signature = self.signatures.get(&decx[i].to_string()).unwrap();
|
2019-07-03 12:56:41 -07:00
|
|
|
let proofState = self.kp.prove_commitment(rng, &self.mpk, &signature);
|
2019-07-01 18:51:24 -07:00
|
|
|
|
2019-07-03 12:56:41 -07:00
|
|
|
V.push(proofState.blindSig.clone());
|
|
|
|
proofStates.push(proofState);
|
2019-06-16 09:27:35 -07:00
|
|
|
|
2019-06-16 13:29:48 -07:00
|
|
|
let ui = self.u.pow(i as u32);
|
2019-07-12 16:52:16 -07:00
|
|
|
let mut aux = self.csParams.pub_bases[k].clone();
|
2019-07-12 07:46:25 -07:00
|
|
|
for j in 0..self.kp.public.Y1.len() {
|
2019-07-03 12:56:41 -07:00
|
|
|
let mut muiti = proofStates[i].t[j].clone();
|
2019-07-02 14:28:49 -07:00
|
|
|
muiti.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap());
|
|
|
|
aux.mul_assign(muiti);
|
|
|
|
}
|
2019-06-16 13:29:48 -07:00
|
|
|
D.add_assign(&aux);
|
2019-06-26 10:33:08 -07:00
|
|
|
}
|
2019-07-19 12:04:56 -07:00
|
|
|
for i in 1..self.csParams.pub_bases.len() {
|
|
|
|
if i != k {
|
|
|
|
let mut g = self.csParams.pub_bases[i].clone();
|
|
|
|
let s1 = E::Fr::rand(rng);
|
|
|
|
s.push(s1);
|
|
|
|
g.mul_assign(s1);
|
|
|
|
D.add_assign(&g);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-17 12:01:31 -07:00
|
|
|
D.add_assign(&hm);
|
2019-07-19 12:04:56 -07:00
|
|
|
ProofULState { decx, proofStates, V, D, m, s }
|
2019-07-12 13:43:48 -07:00
|
|
|
}
|
2019-06-16 13:29:48 -07:00
|
|
|
|
2019-07-19 12:04:56 -07:00
|
|
|
fn prove_ul_response(&self, r: E::Fr, C: Commitment<E>, proofUlState: &ProofULState<E>, c: E::Fr, k: usize, otherM: Vec<E::Fr>) -> ProofUL<E> {
|
2019-07-12 13:43:48 -07:00
|
|
|
let mut sigProofs = Vec::<SignatureProof<E>>::with_capacity(self.l as usize);
|
|
|
|
let mut zr = proofUlState.m.clone();
|
2019-06-17 12:01:31 -07:00
|
|
|
let mut rc = r.clone();
|
|
|
|
rc.mul_assign(&c);
|
2019-06-18 13:20:16 -07:00
|
|
|
zr.add_assign(&rc);
|
2019-06-16 13:29:48 -07:00
|
|
|
for i in 0..self.l as usize {
|
2019-07-12 13:43:48 -07:00
|
|
|
let mut dx = E::Fr::from_str(&proofUlState.decx[i].to_string()).unwrap();
|
2019-07-01 18:51:24 -07:00
|
|
|
|
2019-07-12 13:43:48 -07:00
|
|
|
let proof = self.kp.prove_response(&proofUlState.proofStates[i].clone(), c, &mut vec! {dx});
|
2019-07-01 18:51:24 -07:00
|
|
|
|
2019-07-03 12:56:41 -07:00
|
|
|
sigProofs.push(proof);
|
2019-06-17 12:01:31 -07:00
|
|
|
}
|
2019-07-19 12:04:56 -07:00
|
|
|
|
|
|
|
let mut zs = Vec::<E::Fr>::with_capacity(self.csParams.pub_bases.len() - 2);
|
|
|
|
for i in 1..self.csParams.pub_bases.len() {
|
|
|
|
let mut j: usize;
|
|
|
|
if i < k {
|
|
|
|
j = i - 1;
|
|
|
|
} else if i > k {
|
|
|
|
j = i - 2;
|
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
let mut mc = otherM[j].clone();
|
|
|
|
mc.mul_assign(&c);
|
|
|
|
let mut s = proofUlState.s[j].clone();
|
|
|
|
s.add_assign(&mc);
|
|
|
|
zs.push(s);
|
|
|
|
}
|
|
|
|
ProofUL { V: proofUlState.V.clone(), D: proofUlState.D.clone(), comm: C, sigProofs, zr, zs }
|
2019-06-17 12:01:31 -07:00
|
|
|
}
|
|
|
|
|
2019-07-02 15:39:23 -07:00
|
|
|
/**
|
|
|
|
verify_ul is used to validate the ZKRP proof. It returns true iff the proof is valid.
|
|
|
|
*/
|
2019-07-12 16:52:16 -07:00
|
|
|
pub fn verify_ul(&self, proof: &ProofUL<E>, ch: E::Fr, k: usize) -> bool {
|
|
|
|
let r1 = self.verify_part1(&proof, ch.clone(), k);
|
2019-07-12 08:01:40 -07:00
|
|
|
let r2 = self.verify_part2(&proof, ch.clone());
|
2019-07-19 12:04:56 -07:00
|
|
|
r1 && r2
|
2019-07-04 08:35:55 -07:00
|
|
|
}
|
|
|
|
|
2019-07-12 08:01:40 -07:00
|
|
|
fn compute_challenge(&self, proof: &ProofUL<E>) -> E::Fr {
|
2019-07-04 08:35:55 -07:00
|
|
|
let mut a = Vec::<E::Fqk>::with_capacity(self.l as usize);
|
|
|
|
for sigProof in proof.sigProofs.clone() {
|
|
|
|
a.push(sigProof.a);
|
|
|
|
}
|
2019-07-12 13:43:48 -07:00
|
|
|
hash::<E>(a, vec!(proof.D.clone()))
|
2019-06-17 12:01:31 -07:00
|
|
|
}
|
|
|
|
|
2019-07-12 08:01:40 -07:00
|
|
|
fn verify_part2(&self, proof: &ProofUL<E>, challenge: E::Fr) -> bool {
|
2019-06-17 12:01:31 -07:00
|
|
|
let mut r2 = true;
|
|
|
|
for i in 0..self.l as usize {
|
2019-07-12 08:01:40 -07:00
|
|
|
let subResult = self.kp.public.verify_proof(&self.mpk, proof.V[i].clone(), proof.sigProofs[i].clone(), challenge);
|
2019-06-18 13:20:16 -07:00
|
|
|
|
2019-07-01 18:51:24 -07:00
|
|
|
r2 = r2 && subResult;
|
|
|
|
}
|
|
|
|
r2
|
|
|
|
}
|
2019-06-18 13:20:16 -07:00
|
|
|
|
2019-07-12 16:52:16 -07:00
|
|
|
fn verify_part1(&self, proof: &ProofUL<E>, challenge: E::Fr, k: usize) -> bool {
|
2019-07-12 07:46:25 -07:00
|
|
|
let mut D = proof.comm.c.clone();
|
2019-07-12 08:01:40 -07:00
|
|
|
D.mul_assign(challenge);
|
2019-06-18 13:20:16 -07:00
|
|
|
D.negate();
|
2019-07-12 16:52:16 -07:00
|
|
|
let mut hzr = self.csParams.pub_bases[0].clone();
|
2019-06-17 12:01:31 -07:00
|
|
|
hzr.mul_assign(proof.zr);
|
|
|
|
D.add_assign(&hzr);
|
2019-07-02 14:28:49 -07:00
|
|
|
for i in 0..self.l as usize {
|
2019-06-17 12:01:31 -07:00
|
|
|
let ui = self.u.pow(i as u32);
|
2019-07-12 16:52:16 -07:00
|
|
|
let mut aux = self.csParams.pub_bases[k].clone();
|
2019-07-12 07:46:25 -07:00
|
|
|
for j in 0..self.kp.public.Y1.len() {
|
2019-07-03 12:56:41 -07:00
|
|
|
let mut muizsigi = proof.sigProofs[i].zsig[j];
|
2019-07-02 14:28:49 -07:00
|
|
|
muizsigi.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap());
|
|
|
|
aux.mul_assign(muizsigi);
|
|
|
|
}
|
2019-06-17 12:01:31 -07:00
|
|
|
D.add_assign(&aux);
|
2019-06-16 13:29:48 -07:00
|
|
|
}
|
2019-07-19 12:04:56 -07:00
|
|
|
for i in 1..self.csParams.pub_bases.len() {
|
|
|
|
let mut j: usize;
|
|
|
|
if i < k {
|
|
|
|
j = i - 1;
|
|
|
|
} else if i > k {
|
|
|
|
j = i - 2;
|
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
let mut g = self.csParams.pub_bases[i].clone();
|
|
|
|
g.mul_assign(proof.zs[j].into_repr());
|
|
|
|
D.add_assign(&g);
|
|
|
|
}
|
2019-07-04 08:35:55 -07:00
|
|
|
D == proof.D
|
2019-06-16 09:27:35 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-12 13:43:48 -07:00
|
|
|
fn hash<E: Engine>(a: Vec<E::Fqk>, D: Vec<E::G1>) -> E::Fr {
|
2019-07-19 12:04:56 -07:00
|
|
|
// create a Sha256 object
|
2019-06-16 09:27:35 -07:00
|
|
|
let mut a_vec: Vec<u8> = Vec::new();
|
|
|
|
for a_el in a {
|
2019-07-04 08:35:55 -07:00
|
|
|
a_vec.extend(format!("{}", a_el).bytes());
|
2019-06-16 09:27:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
let mut x_vec: Vec<u8> = Vec::new();
|
2019-07-12 13:43:48 -07:00
|
|
|
for d_el in D {
|
|
|
|
x_vec.extend(format!("{}", d_el).bytes());
|
|
|
|
}
|
2019-06-16 09:27:35 -07:00
|
|
|
a_vec.extend(x_vec);
|
|
|
|
|
2019-07-04 08:35:55 -07:00
|
|
|
util::hash_to_fr::<E>(a_vec)
|
2019-06-16 09:27:35 -07:00
|
|
|
}
|
2019-06-14 15:14:06 -07:00
|
|
|
|
2019-06-16 13:29:48 -07:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
2019-06-17 12:01:31 -07:00
|
|
|
fn decompose(x: i64, u: i64, l: i64) -> Vec<i64> {
|
2019-06-16 13:29:48 -07:00
|
|
|
let mut result = Vec::with_capacity(l as usize);
|
|
|
|
let mut decomposer = x.clone();
|
2019-06-26 10:33:08 -07:00
|
|
|
for _i in 0..l {
|
2019-06-16 13:29:48 -07:00
|
|
|
result.push(decomposer % u);
|
|
|
|
decomposer = decomposer / u;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-06-16 12:38:07 -07:00
|
|
|
impl<E: Engine> RPPublicParams<E> {
|
2019-07-02 15:39:23 -07:00
|
|
|
/**
|
|
|
|
Setup receives integers a and b, and configures the parameters for the rangeproof scheme.
|
2019-06-16 12:38:07 -07:00
|
|
|
*/
|
2019-07-12 16:52:16 -07:00
|
|
|
pub fn setup<R: Rng>(rng: &mut R, a: i64, b: i64, csParams: CSMultiParams<E>) -> Self {
|
2019-07-19 12:04:56 -07:00
|
|
|
// Compute optimal values for u and l
|
2019-06-16 12:38:07 -07:00
|
|
|
if a > b {
|
|
|
|
panic!("a must be less than or equal to b");
|
|
|
|
}
|
2019-07-19 12:04:56 -07:00
|
|
|
//TODO: optimize u?
|
2019-06-28 14:44:14 -07:00
|
|
|
let logb = (b as f64).log2();
|
2019-07-01 18:51:24 -07:00
|
|
|
let loglogb = logb.log2();
|
|
|
|
if loglogb > 0.0 {
|
|
|
|
let mut u = (logb / loglogb) as i64;
|
|
|
|
if u < 2 {
|
|
|
|
u = 2;
|
2019-06-16 12:38:07 -07:00
|
|
|
}
|
2019-07-01 18:51:24 -07:00
|
|
|
let l = (b as f64).log(u as f64).ceil() as i64;
|
2019-07-12 11:15:00 -07:00
|
|
|
|
|
|
|
let params_out: ParamsUL<E> = ParamsUL::<E>::setup_ul(rng, u, l, csParams.clone());
|
2019-07-01 18:51:24 -07:00
|
|
|
return RPPublicParams { p: params_out, a, b };
|
2019-06-14 15:14:06 -07:00
|
|
|
} else {
|
2019-07-01 18:51:24 -07:00
|
|
|
panic!("log(log(b)) is zero");
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
|
|
|
}
|
2019-06-18 15:17:51 -07:00
|
|
|
|
2019-07-02 15:39:23 -07:00
|
|
|
/**
|
|
|
|
Prove method is responsible for generating the zero knowledge range proof.
|
2019-06-18 15:17:51 -07:00
|
|
|
*/
|
2019-07-19 12:04:56 -07:00
|
|
|
pub fn prove<R: Rng>(&self, rng: &mut R, x: i64, C: Commitment<E>, r: E::Fr, k: usize, otherM: Vec<E::Fr>) -> RangeProof<E> {
|
2019-07-12 16:52:16 -07:00
|
|
|
let rpState = self.prove_commitment(rng, x, C, k);
|
2019-07-12 13:43:48 -07:00
|
|
|
|
|
|
|
let mut a = Vec::<E::Fqk>::with_capacity(self.p.l as usize);
|
|
|
|
for i in 0..rpState.ps1.proofStates.len() {
|
|
|
|
a.push(rpState.ps1.proofStates[i].a);
|
|
|
|
a.push(rpState.ps2.proofStates[i].a);
|
|
|
|
}
|
|
|
|
let ch = hash::<E>(a, vec!(rpState.ps1.D.clone(), rpState.ps2.D.clone()));
|
|
|
|
|
2019-07-19 12:04:56 -07:00
|
|
|
self.prove_response(r, &rpState, ch, k, otherM)
|
2019-07-12 13:43:48 -07:00
|
|
|
}
|
|
|
|
|
2019-07-12 16:52:16 -07:00
|
|
|
pub fn prove_commitment<R: Rng>(&self, rng: &mut R, x: i64, C: Commitment<E>, k: usize) -> RangeProofState<E> {
|
2019-06-28 14:44:14 -07:00
|
|
|
if x > self.b || x < self.a {
|
|
|
|
panic!("x is not within the range.");
|
|
|
|
}
|
2019-06-18 15:17:51 -07:00
|
|
|
let ul = self.p.u.pow(self.p.l as u32);
|
|
|
|
// x - b + ul
|
2019-06-26 09:37:27 -07:00
|
|
|
let xb = x - self.b + ul;
|
2019-07-12 16:52:16 -07:00
|
|
|
let mut gb = self.p.csParams.pub_bases[k].clone();
|
2019-07-12 11:15:00 -07:00
|
|
|
let mut b = E::Fr::from_str(&(self.b.to_string())).unwrap();
|
|
|
|
b.negate();
|
|
|
|
gb.mul_assign(b.into_repr());
|
2019-07-12 16:52:16 -07:00
|
|
|
let mut gul = self.p.csParams.pub_bases[k].clone();
|
2019-07-12 11:15:00 -07:00
|
|
|
gul.mul_assign(E::Fr::from_str(&(ul.to_string())).unwrap().into_repr());
|
|
|
|
let mut comXB = C.clone();
|
|
|
|
comXB.c.add_assign(&gb);
|
|
|
|
comXB.c.add_assign(&gul);
|
2019-07-12 16:52:16 -07:00
|
|
|
let firstState = self.p.prove_ul_commitment(rng, xb, k);
|
2019-06-18 15:17:51 -07:00
|
|
|
// x - a
|
|
|
|
let xa = x - self.a;
|
2019-07-12 16:52:16 -07:00
|
|
|
let mut ga = self.p.csParams.pub_bases[k].clone();
|
2019-07-12 11:15:00 -07:00
|
|
|
let mut a = E::Fr::from_str(&(self.a.to_string())).unwrap();
|
|
|
|
a.negate();
|
|
|
|
ga.mul_assign(a.into_repr());
|
|
|
|
let mut comXA = C.clone();
|
|
|
|
comXA.c.add_assign(&ga);
|
2019-07-12 16:52:16 -07:00
|
|
|
let secondState = self.p.prove_ul_commitment(rng, xa, k);
|
2019-07-19 12:04:56 -07:00
|
|
|
RangeProofState { com1: comXB, ps1: firstState, com2: comXA, ps2: secondState }
|
2019-07-12 13:43:48 -07:00
|
|
|
}
|
2019-06-18 15:17:51 -07:00
|
|
|
|
2019-07-19 12:04:56 -07:00
|
|
|
pub fn prove_response(&self, r: E::Fr, rpState: &RangeProofState<E>, ch: E::Fr, k: usize, otherM: Vec<E::Fr>) -> RangeProof<E> {
|
|
|
|
let first = self.p.prove_ul_response(r.clone(), rpState.com1.clone(), &rpState.ps1, ch.clone(), k, otherM.clone());
|
|
|
|
let second = self.p.prove_ul_response(r.clone(), rpState.com2.clone(), &rpState.ps2, ch.clone(), k, otherM.clone());
|
2019-07-12 13:43:48 -07:00
|
|
|
RangeProof { p1: first, p2: second }
|
2019-06-18 15:17:51 -07:00
|
|
|
}
|
|
|
|
|
2019-07-02 15:39:23 -07:00
|
|
|
/**
|
|
|
|
Verify is responsible for validating the range proof.
|
2019-06-18 15:17:51 -07:00
|
|
|
*/
|
2019-07-12 16:52:16 -07:00
|
|
|
pub fn verify(&self, proof: RangeProof<E>, ch: E::Fr, k: usize) -> bool {
|
2019-07-19 12:04:56 -07:00
|
|
|
//TODO: add verification of commitment
|
2019-07-12 16:52:16 -07:00
|
|
|
let first = self.p.verify_ul(&proof.p1, ch.clone(), k);
|
|
|
|
let second = self.p.verify_ul(&proof.p2, ch.clone(), k);
|
2019-07-19 12:04:56 -07:00
|
|
|
first & &second
|
2019-07-12 16:52:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn compute_challenge(&self, proof: &RangeProof<E>) -> E::Fr {
|
2019-07-12 13:43:48 -07:00
|
|
|
let mut a = Vec::<E::Fqk>::with_capacity(self.p.l as usize);
|
|
|
|
for i in 0..proof.p1.sigProofs.len() {
|
|
|
|
a.push(proof.p1.sigProofs[i].a);
|
|
|
|
a.push(proof.p2.sigProofs[i].a);
|
|
|
|
}
|
2019-07-12 16:52:16 -07:00
|
|
|
hash::<E>(a, vec!(proof.p1.D.clone(), proof.p2.D.clone()))
|
2019-06-18 15:17:51 -07:00
|
|
|
}
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2019-07-12 07:46:25 -07:00
|
|
|
use pairing::bls12_381::{Bls12, G1, Fq12, Fr};
|
2019-06-28 14:44:14 -07:00
|
|
|
use time::PreciseTime;
|
|
|
|
use std::ops::Add;
|
|
|
|
use core::mem;
|
2019-07-04 08:35:55 -07:00
|
|
|
use rand::rngs::ThreadRng;
|
2019-06-14 15:14:06 -07:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn setup_ul_works() {
|
2019-06-16 13:29:48 -07:00
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
2019-07-12 11:15:00 -07:00
|
|
|
|
2019-07-12 16:52:16 -07:00
|
|
|
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 3, csParams.clone());
|
2019-06-17 12:01:31 -07:00
|
|
|
assert_eq!(params.signatures.len(), 2);
|
2019-06-16 13:29:48 -07:00
|
|
|
for (m, s) in params.signatures {
|
2019-07-02 14:28:49 -07:00
|
|
|
assert_eq!(params.kp.verify(¶ms.mpk, &vec! {Fr::from_str(m.to_string().as_str()).unwrap()}, &Fr::zero(), &s), true);
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-16 13:29:48 -07:00
|
|
|
#[test]
|
|
|
|
fn prove_ul_works() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
2019-07-12 11:15:00 -07:00
|
|
|
|
2019-07-12 16:52:16 -07:00
|
|
|
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 4, csParams.clone());
|
2019-06-16 13:29:48 -07:00
|
|
|
let fr = Fr::rand(rng);
|
2019-07-12 11:15:00 -07:00
|
|
|
let modx = Fr::from_str(&(10.to_string())).unwrap();
|
2019-07-12 16:52:16 -07:00
|
|
|
let C = csParams.commit(&vec!(modx), &fr.clone());
|
2019-07-19 12:04:56 -07:00
|
|
|
let proof = params.prove_ul(rng, 10, fr, C, 1, vec!{});
|
2019-06-28 14:44:14 -07:00
|
|
|
assert_eq!(proof.V.len(), 4);
|
2019-07-03 12:56:41 -07:00
|
|
|
assert_eq!(proof.sigProofs.len(), 4);
|
2019-06-28 14:44:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic(expected = "x is not within the range")]
|
|
|
|
fn prove_ul_not_in_range() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
|
|
|
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 3, csParams.clone());
|
2019-06-28 14:44:14 -07:00
|
|
|
let fr = Fr::rand(rng);
|
2019-07-12 11:15:00 -07:00
|
|
|
let modx = Fr::from_str(&(100.to_string())).unwrap();
|
2019-07-12 16:52:16 -07:00
|
|
|
let C = csParams.commit(&vec!(modx), &fr.clone());
|
2019-07-19 12:04:56 -07:00
|
|
|
params.prove_ul(rng, 100, fr, C, 1, vec!{});
|
2019-06-17 12:01:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn prove_and_verify_part1_ul_works() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
|
|
|
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 4, csParams.clone());
|
2019-06-17 12:01:31 -07:00
|
|
|
let fr = Fr::rand(rng);
|
2019-07-12 11:15:00 -07:00
|
|
|
let modx = Fr::from_str(&(10.to_string())).unwrap();
|
2019-07-12 16:52:16 -07:00
|
|
|
let C = csParams.commit(&vec!(modx), &fr.clone());
|
2019-07-19 12:04:56 -07:00
|
|
|
let proof = params.prove_ul(rng, 10, fr, C, 1, vec!{});
|
2019-07-12 08:01:40 -07:00
|
|
|
let ch = params.compute_challenge(&proof);
|
2019-07-12 16:52:16 -07:00
|
|
|
assert_eq!(params.verify_part1(&proof, ch, 1), true);
|
2019-06-17 12:01:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn prove_and_verify_part2_ul_works() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
|
|
|
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 4, csParams.clone());
|
2019-06-17 12:01:31 -07:00
|
|
|
let fr = Fr::rand(rng);
|
2019-07-12 11:15:00 -07:00
|
|
|
let modx = Fr::from_str(&(10.to_string())).unwrap();
|
2019-07-12 16:52:16 -07:00
|
|
|
let C = csParams.commit(&vec!(modx), &fr.clone());
|
2019-07-19 12:04:56 -07:00
|
|
|
let proof = params.prove_ul(rng, 10, fr, C, 1, vec!{});
|
2019-07-12 08:01:40 -07:00
|
|
|
let ch = params.compute_challenge(&proof);
|
|
|
|
assert_eq!(params.verify_part2(&proof, ch), true);
|
2019-06-17 12:01:31 -07:00
|
|
|
}
|
2019-06-16 13:29:48 -07:00
|
|
|
|
2019-06-17 12:01:31 -07:00
|
|
|
#[test]
|
|
|
|
fn prove_and_verify_ul_works() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
|
|
|
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 4, csParams.clone());
|
2019-06-17 12:01:31 -07:00
|
|
|
let fr = Fr::rand(rng);
|
2019-07-12 11:15:00 -07:00
|
|
|
let modx = Fr::from_str(&(10.to_string())).unwrap();
|
2019-07-12 16:52:16 -07:00
|
|
|
let C = csParams.commit(&vec!(modx), &fr.clone());
|
2019-07-19 12:04:56 -07:00
|
|
|
let proof = params.prove_ul(rng, 10, fr, C, 1, vec!{});
|
2019-07-12 13:43:48 -07:00
|
|
|
let ch = params.compute_challenge(&proof);
|
2019-07-12 16:52:16 -07:00
|
|
|
assert_eq!(params.verify_ul(&proof, ch, 1), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn prove_and_verify_ul_bigger_commit_works() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 3);
|
|
|
|
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 4, csParams.clone());
|
|
|
|
let fr = Fr::rand(rng);
|
|
|
|
let modx = Fr::from_str(&(10.to_string())).unwrap();
|
2019-07-19 12:04:56 -07:00
|
|
|
let fr1 = Fr::rand(rng);
|
|
|
|
let fr2 = Fr::rand(rng);
|
|
|
|
let C = csParams.commit(&vec!(fr1, modx, fr2), &fr.clone());
|
|
|
|
let proof = params.prove_ul(rng, 10, fr, C, 2, vec!{fr1, fr2});
|
2019-07-12 16:52:16 -07:00
|
|
|
let ch = params.compute_challenge(&proof);
|
|
|
|
assert_eq!(params.verify_ul(&proof, ch, 2), true);
|
2019-06-16 13:29:48 -07:00
|
|
|
}
|
|
|
|
|
2019-06-18 15:17:51 -07:00
|
|
|
#[test]
|
|
|
|
fn prove_and_verify_works() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
|
|
|
let params = RPPublicParams::<Bls12>::setup(rng, 2, 25, csParams.clone());
|
2019-07-12 11:15:00 -07:00
|
|
|
let fr = Fr::rand(rng);
|
|
|
|
let modx = Fr::from_str(&(10.to_string())).unwrap();
|
2019-07-12 16:52:16 -07:00
|
|
|
let C = csParams.commit(&vec!(modx), &fr.clone());
|
2019-07-19 12:04:56 -07:00
|
|
|
let proof = params.prove(rng, 10, C, fr, 1, vec!{});
|
2019-07-12 16:52:16 -07:00
|
|
|
let ch = params.compute_challenge(&proof);
|
|
|
|
|
|
|
|
assert_eq!(params.verify(proof, ch, 1), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn prove_and_verify_bigger_commit_works() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 3);
|
|
|
|
let params = RPPublicParams::<Bls12>::setup(rng, 2, 25, csParams.clone());
|
|
|
|
let fr = Fr::rand(rng);
|
|
|
|
let modx = Fr::from_str(&(10.to_string())).unwrap();
|
2019-07-19 12:04:56 -07:00
|
|
|
let fr1 = Fr::rand(rng);
|
|
|
|
let fr2 = Fr::rand(rng);
|
|
|
|
let C = csParams.commit(&vec!(fr1, modx, fr2), &fr.clone());
|
|
|
|
let proof = params.prove(rng, 10, C, fr, 2, vec!{fr1, fr2});
|
2019-07-12 16:52:16 -07:00
|
|
|
let ch = params.compute_challenge(&proof);
|
|
|
|
|
|
|
|
assert_eq!(params.verify(proof, ch, 2), true);
|
2019-06-18 15:17:51 -07:00
|
|
|
}
|
|
|
|
|
2019-06-28 14:44:14 -07:00
|
|
|
#[test]
|
|
|
|
#[should_panic(expected = "x is not within the range")]
|
|
|
|
fn prove_not_in_range() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
|
|
|
let params = RPPublicParams::<Bls12>::setup(rng, 2, 25, csParams.clone());
|
2019-07-12 11:15:00 -07:00
|
|
|
let fr = Fr::rand(rng);
|
|
|
|
let modx = Fr::from_str(&(26.to_string())).unwrap();
|
2019-07-12 16:52:16 -07:00
|
|
|
let C = csParams.commit(&vec!(modx), &fr.clone());
|
2019-07-19 12:04:56 -07:00
|
|
|
params.prove(rng, 26, C, fr, 1, vec!{});
|
2019-06-28 14:44:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[ignore]
|
|
|
|
fn prove_and_verify_performance() {
|
|
|
|
let rng = &mut rand::thread_rng();
|
|
|
|
let mut averageSetup = time::Duration::nanoseconds(0);
|
|
|
|
let mut averageSetupSize = 0;
|
|
|
|
let mut averageProve = time::Duration::nanoseconds(0);
|
|
|
|
let mut averageProofSize = 0;
|
|
|
|
let mut averageVerify = time::Duration::nanoseconds(0);
|
|
|
|
let iter = 5;
|
|
|
|
for i in 0..iter {
|
|
|
|
let a = rng.gen_range(0, 1000000);
|
|
|
|
let b = rng.gen_range(a, 1000000);
|
|
|
|
let x = rng.gen_range(a, b);
|
|
|
|
|
|
|
|
let sSetup = PreciseTime::now();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
|
|
|
let params = RPPublicParams::<Bls12>::setup(rng, a, b, csParams.clone());
|
2019-06-28 14:44:14 -07:00
|
|
|
averageSetup = averageSetup.add(sSetup.to(PreciseTime::now()));
|
|
|
|
averageSetupSize += mem::size_of_val(¶ms);
|
|
|
|
|
|
|
|
let sProve = PreciseTime::now();
|
2019-07-12 11:15:00 -07:00
|
|
|
let fr = Fr::rand(rng);
|
|
|
|
let modx = Fr::from_str(&(x.to_string())).unwrap();
|
2019-07-12 16:52:16 -07:00
|
|
|
let C = csParams.commit(&vec!(modx), &fr.clone());
|
2019-07-19 12:04:56 -07:00
|
|
|
let proof = params.prove(rng, x, C, fr, 1, vec!{});
|
2019-06-28 14:44:14 -07:00
|
|
|
averageProve = averageProve.add(sProve.to(PreciseTime::now()));
|
|
|
|
averageProofSize += mem::size_of_val(&proof);
|
|
|
|
|
|
|
|
let sVerify = PreciseTime::now();
|
2019-07-12 16:52:16 -07:00
|
|
|
let ch = params.compute_challenge(&proof);
|
|
|
|
params.verify(proof, ch, 1);
|
2019-06-28 14:44:14 -07:00
|
|
|
averageVerify = averageVerify.add(sVerify.to(PreciseTime::now()));
|
|
|
|
}
|
|
|
|
print!("Setup: {}\n", averageSetup.num_milliseconds() / iter);
|
|
|
|
print!("Setup size: {}\n", averageSetupSize / iter as usize);
|
|
|
|
print!("Prove: {}\n", averageProve.num_milliseconds() / iter);
|
|
|
|
print!("Proof size: {}\n", averageProofSize / iter as usize);
|
|
|
|
print!("Verify: {}\n", averageVerify.num_milliseconds() / iter);
|
|
|
|
}
|
|
|
|
|
2019-06-14 15:14:06 -07:00
|
|
|
#[test]
|
|
|
|
fn decompose_works() {
|
2019-06-17 12:01:31 -07:00
|
|
|
assert_eq!(decompose(25, 3, 3), vec! {1, 2, 2});
|
|
|
|
assert_eq!(decompose(336, 7, 3), vec! {0, 6, 6});
|
|
|
|
assert_eq!(decompose(285, 8, 3), vec! {5, 3, 4});
|
|
|
|
assert_eq!(decompose(125, 13, 2), vec! {8, 9});
|
|
|
|
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);
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn setup_works() {
|
2019-06-16 13:29:48 -07:00
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
2019-07-12 11:15:00 -07:00
|
|
|
let public_params = RPPublicParams::<Bls12>::setup(rng, 2, 10, csParams);
|
2019-06-17 12:01:31 -07:00
|
|
|
assert_eq!(public_params.a, 2);
|
|
|
|
assert_eq!(public_params.b, 10);
|
2019-07-01 18:51:24 -07:00
|
|
|
assert_eq!(public_params.p.signatures.len(), 2);
|
|
|
|
assert_eq!(public_params.p.u, 2);
|
|
|
|
assert_eq!(public_params.p.l, 4);
|
2019-06-14 15:14:06 -07:00
|
|
|
for (m, s) in public_params.p.signatures {
|
2019-07-02 14:28:49 -07:00
|
|
|
assert_eq!(public_params.p.kp.verify(&public_params.p.mpk, &vec! {Fr::from_str(m.to_string().as_str()).unwrap()}, &Fr::zero(), &s), true);
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic(expected = "a must be less than or equal to b")]
|
|
|
|
fn setup_wrong_a_and_b() {
|
2019-06-16 13:29:48 -07:00
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
2019-07-12 11:15:00 -07:00
|
|
|
RPPublicParams::<Bls12>::setup(rng, 10, 2, csParams);
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2019-07-01 18:51:24 -07:00
|
|
|
#[should_panic(expected = "log(log(b)) is zero")]
|
2019-06-14 15:14:06 -07:00
|
|
|
fn setup_wrong_logb() {
|
2019-06-16 13:29:48 -07:00
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 16:52:16 -07:00
|
|
|
let csParams = CSMultiParams::setup_gen_params(rng, 1);
|
2019-07-12 11:15:00 -07:00
|
|
|
RPPublicParams::<Bls12>::setup(rng, -2, -1, csParams);
|
2019-06-16 12:38:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn hash_works() {
|
2019-06-16 13:29:48 -07:00
|
|
|
let rng = &mut rand::thread_rng();
|
2019-07-12 07:46:25 -07:00
|
|
|
let D = G1::rand(rng);
|
|
|
|
let D2 = G1::rand(rng);
|
2019-07-04 08:35:55 -07:00
|
|
|
let params = setup::<ThreadRng, Bls12>(rng);
|
2019-07-03 12:56:41 -07:00
|
|
|
let kp = BlindKeyPair::generate(rng, ¶ms, 2);
|
|
|
|
let m1 = Fr::rand(rng);
|
|
|
|
let m2 = Fr::rand(rng);
|
|
|
|
let sig = kp.sign(rng, &vec! {m1, m2});
|
|
|
|
let state = kp.prove_commitment(rng, ¶ms, &sig);
|
|
|
|
let state1 = kp.prove_commitment(rng, ¶ms, &sig);
|
|
|
|
let state2 = kp.prove_commitment(rng, ¶ms, &sig);
|
|
|
|
let state3 = kp.prove_commitment(rng, ¶ms, &sig);
|
|
|
|
let state4 = kp.prove_commitment(rng, ¶ms, &sig);
|
2019-07-04 08:35:55 -07:00
|
|
|
let a = vec! {state.a, state1.a, state2.a};
|
|
|
|
let a2 = vec! {state3.a, state4.a};
|
2019-07-12 13:43:48 -07:00
|
|
|
assert_eq!(hash::<Bls12>(a.clone(), vec!(D.clone())).is_zero(), false);
|
|
|
|
assert_ne!(hash::<Bls12>(a2.clone(), vec!(D.clone())), hash::<Bls12>(a.clone(), vec!(D.clone())));
|
|
|
|
assert_ne!(hash::<Bls12>(a.clone(), vec!(D2.clone())), hash::<Bls12>(a.clone(), vec!(D.clone())));
|
|
|
|
assert_ne!(hash::<Bls12>(a2.clone(), vec!(D2.clone())), hash::<Bls12>(a.clone(), vec!(D.clone())))
|
2019-06-14 15:14:06 -07:00
|
|
|
}
|
|
|
|
}
|