nizk: make range proof independent + check for identity + partial reveal

This commit is contained in:
Gijs Van Laer 2019-08-08 16:21:01 +02:00
parent 4a478cb19f
commit 95122147b4
2 changed files with 21 additions and 40 deletions

View File

@ -167,7 +167,6 @@ pub struct BlindKeyPair<E: Engine> {
#[derive(Clone)]
pub struct ProofState<E: Engine> {
pub v: E::Fr,
pub s: E::Fr,
pub t: Vec<E::Fr>,
pub tt: E::Fr,
pub a: E::Fqk,
@ -186,7 +185,6 @@ pub struct ProofState<E: Engine> {
<E as pairing::Engine>::Fqk: serde::Deserialize<'de>"
))]
pub struct SignatureProof<E: Engine> {
pub zx: E::Fr,
pub zsig: Vec<E::Fr>,
pub zv: E::Fr,
pub a: E::Fqk,
@ -363,7 +361,7 @@ impl<E: Engine> BlindPublicKey<E> {
/// outputs: boolean
pub fn verify_proof(&self, mpk: &PublicParams<E>, blindSig: Signature<E>, p: SignatureProof<E>, challenge: E::Fr) -> bool {
let mut gx = E::pairing(blindSig.h, self.X2);
gx = gx.pow(p.zx.into_repr());
gx = gx.pow(challenge.into_repr());
for j in 0..self.Y2.len() {
let mut gy = E::pairing(blindSig.h, self.Y2[j]);
gy = gy.pow(p.zsig[j].into_repr());
@ -492,23 +490,21 @@ impl<E: Engine> BlindKeyPair<E> {
tOptional: Option<Vec<E::Fr>>, ttOptional: Option<E::Fr>) -> ProofState<E> {
let v = E::Fr::rand(rng);
let blindSig = self.blind(rng, &v, signature);
let s = E::Fr::rand(rng);
let mut t = tOptional.unwrap_or(Vec::<E::Fr>::with_capacity(self.public.Y2.len()));
let tt = ttOptional.unwrap_or(E::Fr::rand(rng));
let mut gx = E::pairing(blindSig.h, self.public.X2);
gx = gx.pow(s.into_repr());
let mut a = E::Fqk::one();
for j in 0..self.public.Y2.len() {
if t.len() == j {
t.push(E::Fr::rand(rng));
}
let mut gy = E::pairing(blindSig.h, self.public.Y2[j]);
gy = gy.pow(t[j].into_repr());
gx.mul_assign(&gy);
a.mul_assign(&gy);
}
let mut h = E::pairing(blindSig.h, mpk.g2);
h = h.pow(tt.into_repr());
gx.mul_assign(&h);
ProofState { v, s, t, tt, a: gx, blindSig }
a.mul_assign(&h);
ProofState { v, t, tt, a, blindSig }
}
/// prove knowledge of a signature: response phase
@ -525,13 +521,11 @@ impl<E: Engine> BlindKeyPair<E> {
}
}
let mut zx = ps.s.clone();
zx.add_assign(&challenge);
let mut zv = ps.tt.clone();
let mut vic = ps.v.clone();
vic.mul_assign(&challenge);
zv.add_assign(&vic);
SignatureProof { zsig, zx, zv, a: ps.a }
SignatureProof { zsig, zv, a: ps.a }
}
}

View File

@ -67,7 +67,7 @@ impl<E: Engine> NIZKPublicParams<E> {
let mut D = E::G1::zero();
let w_len = newWallet.as_fr_vec().len();
let diff = self.comParams.pub_bases.len() - w_len;
let max = match (diff > 1) {
let max = match diff > 1 {
true => w_len,
false => self.comParams.pub_bases.len()
};
@ -82,16 +82,16 @@ impl<E: Engine> NIZKPublicParams<E> {
}
//commit signature
let fr1 = E::Fr::rand(rng);
let tOptional = match (max > 4) {
true => Some(vec!(t[1], fr1, t[3].clone(), t[4].clone())),
false => Some(vec!(t[1], fr1, t[3].clone()))
let zero = E::Fr::zero();
let tOptional = match max > 4 {
true => Some(vec!(t[1], zero, t[3].clone(), t[4].clone())),
false => Some(vec!(t[1], zero, t[3].clone()))
};
let proofState = self.keypair.prove_commitment(rng, &self.mpk, &paymentToken, tOptional, None);
//commit range proof
let rpStateBC = self.rpParamsBC.prove_commitment(rng, newWallet.bc.clone(), newWalletCom.clone(), 3, Some(t[1..].to_vec()), Some(t[0].clone()));
let rpStateBM = self.rpParamsBM.prove_commitment(rng, newWallet.bm.clone(), newWalletCom.clone(), 4, Some(t[1..].to_vec()), Some(t[0].clone()));
let rpStateBC = self.rpParamsBC.prove_commitment(rng, newWallet.bc.clone(), newWalletCom.clone(), 3, None, None);
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});
@ -135,11 +135,17 @@ impl<E: Engine> NIZKPublicParams<E> {
}
pub fn verify(&self, proof: Proof<E>, epsilon: E::Fr, com2: &Commitment<E>, wpk: E::Fr) -> bool {
//verify signature is not the identity
let r0 = proof.sig.h != E::G1::one();
//compute challenge
let challenge = NIZKPublicParams::<E>::hash(proof.sigProof.a, vec! {proof.D, proof.rpBC.p1.D, proof.rpBC.p2.D, proof.rpBM.p1.D, proof.rpBM.p2.D});
//verify knowledge of signature
let r1 = self.keypair.public.verify_proof(&self.mpk, proof.sig, proof.sigProof.clone(), challenge);
let mut r1 = self.keypair.public.verify_proof(&self.mpk, proof.sig, proof.sigProof.clone(), challenge);
let mut wpkc = wpk.clone();
wpkc.mul_assign(&challenge.clone());
r1 = r1 && proof.sigProof.zsig[1] == wpkc;
//verify knowledge of commitment
let mut comc = com2.c.clone();
@ -168,26 +174,7 @@ impl<E: Engine> NIZKPublicParams<E> {
zsig3.add_assign(&epsC.clone());
r5 = r5 && proof.z[4] == zsig3;
r5 = r5 && proof.z[0] == proof.rpBC.p1.zr;
r5 = r5 && proof.z[0] == proof.rpBC.p2.zr;
r5 = r5 && proof.z[0] == proof.rpBM.p1.zr;
r5 = r5 && proof.z[0] == proof.rpBM.p2.zr;
for i in 1..proof.z.len() {
if i == 3 {
r5 = r5 && proof.z[i] == proof.rpBM.p1.zs[i-1];
r5 = r5 && proof.z[i] == proof.rpBM.p2.zs[i-1].clone();
} else if i >= 4 {
r5 = r5 && proof.z[i] == proof.rpBC.p1.zs[i-2].clone();
r5 = r5 && proof.z[i] == proof.rpBC.p2.zs[i-2].clone();
} else {
r5 = r5 && proof.z[i] == proof.rpBC.p1.zs[i-1].clone();
r5 = r5 && proof.z[i] == proof.rpBC.p2.zs[i-1].clone();
r5 = r5 && proof.z[i] == proof.rpBM.p1.zs[i-1].clone();
r5 = r5 && proof.z[i] == proof.rpBM.p2.zs[i-1].clone();
}
}
r1 && r2 && r3 && r4 && r5
r0 && r1 && r2 && r3 && r4 && r5
}
fn hash(a: E::Fqk, T: Vec<E::G1>) -> E::Fr {