Merge pull request #12 from boltlabs-inc/nizk

nizk: optimize range proofs
This commit is contained in:
J. Ayo Akinyele 2019-08-30 16:33:35 -04:00 committed by GitHub
commit 473fadb66a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 32 deletions

View File

@ -74,8 +74,8 @@ pub struct ProofUL<E: Engine> {
pub struct RangeProofState<E: Engine> {
pub com1: Commitment<E>,
pub ps1: ProofULState<E>,
pub com2: Commitment<E>,
pub ps2: ProofULState<E>,
pub com2: Option<Commitment<E>>,
pub ps2: Option<ProofULState<E>>,
}
/**
@ -94,7 +94,7 @@ RangeProof contains the necessary elements for the ZK range proof.
))]
pub struct RangeProof<E: Engine> {
pub p1: ProofUL<E>,
pub p2: ProofUL<E>,
pub p2: Option<ProofUL<E>>,
}
/**
@ -355,9 +355,14 @@ impl<E: Engine> RPPublicParams<E> {
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);
if rpState.ps2.is_some() {
a.push(rpState.ps2.clone().unwrap().proofStates[i].a);
}
let ch = hash::<E>(a, vec!(rpState.ps1.D.clone(), rpState.ps2.D.clone()));
}
let ch = match rpState.ps2.is_some() {
true => hash::<E>(a, vec!(rpState.ps1.D.clone(), rpState.ps2.clone().unwrap().D)),
false => hash::<E>(a, vec!(rpState.ps1.D.clone()))
};
self.prove_response(r, &rpState, ch, k, otherM)
}
@ -380,6 +385,9 @@ impl<E: Engine> RPPublicParams<E> {
comXB.c.add_assign(&gul);
let firstState = self.p.prove_ul_commitment(rng, xb, k, sOptional.clone(), mOptional.clone());
// x - a
let mut comXAOption = None;
let mut secondState = None;
if self.a != 0 || x < 0 {
let xa = x - self.a;
let mut ga = self.p.csParams.pub_bases[k].clone();
let mut a = E::Fr::from_str(&(self.a.to_string())).unwrap();
@ -387,13 +395,19 @@ impl<E: Engine> RPPublicParams<E> {
ga.mul_assign(a.into_repr());
let mut comXA = C.clone();
comXA.c.add_assign(&ga);
let secondState = self.p.prove_ul_commitment(rng, xa, k, sOptional.clone(), mOptional.clone());
RangeProofState { com1: comXB, ps1: firstState, com2: comXA, ps2: secondState }
comXAOption = Some(comXA);
secondState = Some(self.p.prove_ul_commitment(rng, xa, k, sOptional.clone(), mOptional.clone()));
}
RangeProofState { com1: comXB, ps1: firstState, com2: comXAOption, ps2: secondState }
}
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());
let mut second = None;
if rpState.com2.is_some() && rpState.ps2.is_some() {
second = Some(self.p.prove_ul_response(r.clone(), rpState.com2.clone().unwrap(), &rpState.ps2.clone().unwrap(), ch.clone(), k, otherM.clone()));
}
RangeProof { p1: first, p2: second }
}
@ -402,7 +416,10 @@ impl<E: Engine> RPPublicParams<E> {
*/
pub fn verify(&self, proof: RangeProof<E>, ch: E::Fr, k: usize) -> bool {
let first = self.p.verify_ul(&proof.p1, ch.clone(), k);
let second = self.p.verify_ul(&proof.p2, ch.clone(), k);
let mut second = true;
if proof.p2.is_some() {
second = self.p.verify_ul(&proof.p2.unwrap(), ch.clone(), k);
}
first && second
}
@ -410,9 +427,15 @@ impl<E: Engine> RPPublicParams<E> {
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);
if proof.p2.is_some() {
a.push(proof.p2.clone().unwrap().sigProofs[i].a);
}
}
match proof.p2.is_some() {
true => hash::<E>(a.clone(), vec!(proof.p1.D.clone(), proof.p2.clone().unwrap().D)),
false => hash::<E>(a, vec!(proof.p1.D.clone()))
}
hash::<E>(a, vec!(proof.p1.D.clone(), proof.p2.D.clone()))
}
}

View File

@ -100,7 +100,10 @@ impl<E: Engine> NIZKPublicParams<E> {
let rpStateBM = self.rpParamsBM.prove_commitment(rng, newWallet.bm.clone(), newWalletCom.clone(), 4, None, None);
//Compute challenge
let challenge = NIZKPublicParams::<E>::hash(proofState.a, vec! {D, rpStateBC.ps1.D, rpStateBC.ps2.D, rpStateBM.ps1.D, rpStateBM.ps2.D});
let challenge = match rpStateBC.ps2.is_some() && rpStateBM.ps2.is_some() {
true => NIZKPublicParams::<E>::hash(proofState.a, vec! {D, rpStateBC.ps1.D, rpStateBC.ps2.clone().unwrap().D, rpStateBM.ps1.D, rpStateBM.ps2.clone().unwrap().D}),
false => NIZKPublicParams::<E>::hash(proofState.a, vec! {D, rpStateBC.ps1.D, rpStateBM.ps1.D})
};
//Response phase
//response for signature
@ -141,7 +144,10 @@ impl<E: Engine> NIZKPublicParams<E> {
let r0 = proof.sig.h != E::G1::one();
//compute challenge
let challenge = NIZKPublicParams::<E>::hash(proof.sigProof.a, vec! {proof.comProof.T, proof.rpBC.p1.D, proof.rpBC.p2.D, proof.rpBM.p1.D, proof.rpBM.p2.D});
let challenge = match proof.rpBC.p2.is_some() && proof.rpBM.p2.is_some() {
true => NIZKPublicParams::<E>::hash(proof.sigProof.a.clone(), vec! {proof.comProof.T, proof.rpBC.p1.D, proof.rpBC.p2.clone().unwrap().D, proof.rpBM.p1.D, proof.rpBM.p2.clone().unwrap().D}),
false => NIZKPublicParams::<E>::hash(proof.sigProof.a.clone(), vec! {proof.comProof.T, proof.rpBC.p1.D, proof.rpBM.p1.D})
};
//verify knowledge of signature
let mut r1 = self.keypair.public.verify_proof(&self.mpk, proof.sig, proof.sigProof.clone(), challenge);