nixk: group variables of PoK of signature
This commit is contained in:
parent
49bb55da5f
commit
7e3d08bcf9
80
src/ccs08.rs
80
src/ccs08.rs
|
@ -9,7 +9,7 @@ extern crate rand;
|
|||
|
||||
use rand::{thread_rng, Rng};
|
||||
use super::*;
|
||||
use cl::{KeyPair, Signature, PublicParams, setup, BlindKeyPair};
|
||||
use cl::{KeyPair, Signature, PublicParams, setup, BlindKeyPair, ProofState, Proof};
|
||||
use ped92::{CSParams, Commitment};
|
||||
use pairing::{Engine, CurveProjective};
|
||||
use ff::PrimeField;
|
||||
|
@ -45,10 +45,7 @@ struct ProofUL<E: Engine> {
|
|||
V: Vec<Signature<E>>,
|
||||
D: E::G2,
|
||||
comm: Commitment<E>,
|
||||
a: Vec<E::Fqk>,
|
||||
zx: Vec<E::Fr>,
|
||||
zsig: Vec<Vec<E::Fr>>,
|
||||
zv: Vec<E::Fr>,
|
||||
sigProofs: Vec<Proof<E>>,
|
||||
ch: E::Fr,
|
||||
zr: E::Fr,
|
||||
}
|
||||
|
@ -104,15 +101,9 @@ impl<E: Engine> ParamsUL<E> {
|
|||
let modx = E::Fr::from_str(&(x.to_string())).unwrap();
|
||||
|
||||
// Initialize variables
|
||||
let mut v = Vec::<E::Fr>::with_capacity(self.l as usize);
|
||||
let mut proofStates = Vec::<ProofState<E>>::with_capacity(self.l as usize);
|
||||
let mut sigProofs = Vec::<Proof<E>>::with_capacity(self.l as usize);
|
||||
let mut V = Vec::<Signature<E>>::with_capacity(self.l as usize);
|
||||
let mut a = Vec::<E::Fqk>::with_capacity(self.l as usize);
|
||||
let mut s = Vec::<E::Fr>::with_capacity(self.l as usize);
|
||||
let mut t = Vec::<Vec<E::Fr>>::with_capacity(self.l as usize);
|
||||
let mut tt = Vec::<E::Fr>::with_capacity(self.l as usize);
|
||||
let mut zx = Vec::<E::Fr>::with_capacity(self.l as usize);
|
||||
let mut zsig = Vec::<Vec<E::Fr>>::with_capacity(self.l as usize);
|
||||
let mut zv = Vec::<E::Fr>::with_capacity(self.l as usize);
|
||||
let mut D = E::G2::zero();
|
||||
let m = E::Fr::rand(rng);
|
||||
|
||||
|
@ -121,19 +112,15 @@ impl<E: Engine> ParamsUL<E> {
|
|||
hm.mul_assign(m);
|
||||
for i in 0..self.l as usize {
|
||||
let signature = self.signatures.get(&decx[i].to_string()).unwrap();
|
||||
let (v1, s1, t1, tt1, gx, V1) = self.kp.prove_commitment(rng, &self.mpk, &signature);
|
||||
let proofState = self.kp.prove_commitment(rng, &self.mpk, &signature);
|
||||
|
||||
s.push(s1);
|
||||
t.push(t1);
|
||||
v.push(v1);
|
||||
tt.push(tt1);
|
||||
V.push(V1);
|
||||
a.push(gx);
|
||||
V.push(proofState.blindSig.clone());
|
||||
proofStates.push(proofState);
|
||||
|
||||
let ui = self.u.pow(i as u32);
|
||||
let mut aux = self.com.g.clone();
|
||||
for j in 0..self.kp.public.Y2.len() {
|
||||
let mut muiti = t[i][j].clone();
|
||||
let mut muiti = proofStates[i].t[j].clone();
|
||||
muiti.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap());
|
||||
aux.mul_assign(muiti);
|
||||
}
|
||||
|
@ -143,7 +130,7 @@ impl<E: Engine> ParamsUL<E> {
|
|||
|
||||
let C = self.com.commit(rng, modx, Some(r));
|
||||
// Fiat-Shamir heuristic
|
||||
let c = Hash::<E>(a.clone(), D.clone());
|
||||
let c = hash::<E>(proofStates.clone(), D.clone());
|
||||
|
||||
let mut zr = m.clone();
|
||||
let mut rc = r.clone();
|
||||
|
@ -152,14 +139,12 @@ impl<E: Engine> ParamsUL<E> {
|
|||
for i in 0..self.l as usize {
|
||||
let mut dx = E::Fr::from_str(&decx[i].to_string()).unwrap();
|
||||
|
||||
let (zsig1, zx1, zv1) = self.kp.prove_response(v[i], s[i], &mut t[i], tt[i], c, &mut vec!{dx});
|
||||
let proof = self.kp.prove_response(proofStates[i].clone(), c, &mut vec!{dx});
|
||||
|
||||
zv.push(zv1);
|
||||
zx.push(zx1);
|
||||
zsig.push(zsig1);
|
||||
sigProofs.push(proof);
|
||||
}
|
||||
|
||||
return ProofUL { V, D, comm: C, a, zx, zsig, zv, ch: c, zr };
|
||||
return ProofUL { V, D, comm: C, sigProofs, ch: c, zr };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,14 +160,7 @@ impl<E: Engine> ParamsUL<E> {
|
|||
fn verify_part2(&self, proof: &ProofUL<E>) -> bool {
|
||||
let mut r2 = true;
|
||||
for i in 0..self.l as usize {
|
||||
let blindSig = proof.V[i].clone();
|
||||
let zx = proof.zx[i];
|
||||
let zsig = proof.zsig[i].clone();
|
||||
let zv = proof.zv[i];
|
||||
let challenge = proof.ch;
|
||||
let a = proof.a[i];
|
||||
|
||||
let subResult = self.kp.public.verify_proof(&self.mpk, blindSig, zx, zsig, zv, challenge, &a);
|
||||
let subResult = self.kp.public.verify_proof(&self.mpk, proof.V[i].clone(), proof.sigProofs[i].clone(), proof.ch);
|
||||
|
||||
r2 = r2 && subResult;
|
||||
}
|
||||
|
@ -200,7 +178,7 @@ impl<E: Engine> ParamsUL<E> {
|
|||
let ui = self.u.pow(i as u32);
|
||||
let mut aux = self.com.g.clone();
|
||||
for j in 0..self.kp.public.Y2.len() {
|
||||
let mut muizsigi = proof.zsig[i][j];
|
||||
let mut muizsigi = proof.sigProofs[i].zsig[j];
|
||||
muizsigi.mul_assign(&E::Fr::from_str(&ui.to_string()).unwrap());
|
||||
aux.mul_assign(muizsigi);
|
||||
}
|
||||
|
@ -210,11 +188,11 @@ impl<E: Engine> ParamsUL<E> {
|
|||
}
|
||||
}
|
||||
|
||||
fn Hash<E: Engine>(a: Vec<E::Fqk>, D: E::G2) -> E::Fr {
|
||||
fn hash<E: Engine>(a: Vec<ProofState<E>>, D: E::G2) -> E::Fr {
|
||||
// create a Sha256 object
|
||||
let mut a_vec: Vec<u8> = Vec::new();
|
||||
for a_el in a {
|
||||
a_vec.extend(format!("{}", a_el).bytes());
|
||||
a_vec.extend(format!("{}", a_el.a).bytes());
|
||||
}
|
||||
|
||||
let mut x_vec: Vec<u8> = Vec::new();
|
||||
|
@ -335,10 +313,8 @@ mod tests {
|
|||
let params = ParamsUL::<Bls12>::setup_ul(rng, 2, 4);
|
||||
let fr = Fr::rand(rng);
|
||||
let proof = params.prove_ul(rng, 10, fr);
|
||||
assert_eq!(proof.a.len(), 4);
|
||||
assert_eq!(proof.V.len(), 4);
|
||||
assert_eq!(proof.zsig.len(), 4);
|
||||
assert_eq!(proof.zv.len(), 4);
|
||||
assert_eq!(proof.sigProofs.len(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -494,11 +470,21 @@ mod tests {
|
|||
let rng = &mut rand::thread_rng();
|
||||
let D = G2::rand(rng);
|
||||
let D2 = G2::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)};
|
||||
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>(a.clone(), D2.clone()), Hash::<Bls12>(a.clone(), D.clone()));
|
||||
assert_ne!(Hash::<Bls12>(a2.clone(), D2.clone()), Hash::<Bls12>(a.clone(), D.clone()));
|
||||
let params = setup(rng);
|
||||
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);
|
||||
let a = vec! {state, state1, state2};
|
||||
let a2 = vec! {state3, state4};
|
||||
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>(a.clone(), D2.clone()), hash::<Bls12>(a.clone(), D.clone()));
|
||||
assert_ne!(hash::<Bls12>(a2.clone(), D2.clone()), hash::<Bls12>(a.clone(), D.clone()));
|
||||
}
|
||||
}
|
||||
|
|
80
src/cl.rs
80
src/cl.rs
|
@ -53,6 +53,24 @@ pub struct BlindKeyPair<E: Engine> {
|
|||
pub public: BlindPublicKey<E>
|
||||
}
|
||||
|
||||
#[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,
|
||||
pub blindSig: Signature<E>
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Proof<E: Engine> {
|
||||
pub zx: E::Fr,
|
||||
pub zsig: Vec<E::Fr>,
|
||||
pub zv: E::Fr,
|
||||
pub a: E::Fqk
|
||||
}
|
||||
|
||||
|
||||
impl<E: Engine> SecretKey<E> {
|
||||
pub fn generate<R: Rng>(csprng: &mut R, l: usize) -> Self {
|
||||
|
@ -225,20 +243,22 @@ impl<E: Engine> BlindPublicKey<E> {
|
|||
}
|
||||
|
||||
/// Verify a proof of knowledge of a signature
|
||||
pub fn verify_proof(&self, mpk: &PublicParams<E>, blindSig: Signature<E>, zx: E::Fr, zsig: Vec<E::Fr>, zv: E::Fr, challenge: E::Fr, a: &E::Fqk) -> bool {
|
||||
/// Takes in a proof generated by prove_response(), a blind signature, and a challenge
|
||||
/// outputs: boolean
|
||||
pub fn verify_proof(&self, mpk: &PublicParams<E>, blindSig: Signature<E>, p: Proof<E>, challenge: E::Fr) -> bool {
|
||||
let mut gx = E::pairing(blindSig.h, self.X);
|
||||
gx = gx.pow(zx.into_repr());
|
||||
gx = gx.pow(p.zx.into_repr());
|
||||
for j in 0..self.Y2.len() {
|
||||
let mut gy = E::pairing(blindSig.h, self.Y2[j]);
|
||||
gy = gy.pow(zsig[j].into_repr());
|
||||
gy = gy.pow(p.zsig[j].into_repr());
|
||||
gx.mul_assign(&gy);
|
||||
}
|
||||
let mut h = E::pairing(blindSig.h, mpk.g2);
|
||||
h = h.pow(zv.into_repr());
|
||||
h = h.pow(p.zv.into_repr());
|
||||
gx.mul_assign(&h);
|
||||
let mut g = E::pairing(blindSig.H, mpk.g2);
|
||||
g = g.pow(challenge.into_repr());
|
||||
g.mul_assign(&a);
|
||||
g.mul_assign(&p.a);
|
||||
gx == g
|
||||
}
|
||||
|
||||
|
@ -321,41 +341,43 @@ impl<E: Engine> BlindKeyPair<E> {
|
|||
}
|
||||
|
||||
/// prove knowledge of a signature: commitment phase
|
||||
pub fn prove_commitment<R: Rng>(&self, rng: &mut R, mpk: &PublicParams<E>, signature: &Signature<E>) -> (E::Fr, E::Fr, Vec<E::Fr>, E::Fr, E::Fqk, Signature<E>) {
|
||||
let v1 = E::Fr::rand(rng);
|
||||
let blindSig = self.blind(rng, &v1, signature);
|
||||
let s1 = E::Fr::rand(rng);
|
||||
let mut t1 = Vec::<E::Fr>::with_capacity(self.public.Y2.len());
|
||||
let tt1 = E::Fr::rand(rng);
|
||||
/// returns the proof state, including commitment a and a blind signature blindSig
|
||||
pub fn prove_commitment<R: Rng>(&self, rng: &mut R, mpk: &PublicParams<E>, signature: &Signature<E>) -> ProofState<E> {
|
||||
let v = E::Fr::rand(rng);
|
||||
let blindSig = self.blind(rng, &v, signature);
|
||||
let s = E::Fr::rand(rng);
|
||||
let mut t = Vec::<E::Fr>::with_capacity(self.public.Y2.len());
|
||||
let tt = E::Fr::rand(rng);
|
||||
let mut gx = E::pairing(blindSig.h, self.public.X);
|
||||
gx = gx.pow(s1.into_repr());
|
||||
gx = gx.pow(s.into_repr());
|
||||
for j in 0..self.public.Y2.len() {
|
||||
t1.push(E::Fr::rand(rng));
|
||||
t.push(E::Fr::rand(rng));
|
||||
let mut gy = E::pairing(blindSig.h, self.public.Y2[j]);
|
||||
gy = gy.pow(t1[j].into_repr());
|
||||
gy = gy.pow(t[j].into_repr());
|
||||
gx.mul_assign(&gy);
|
||||
}
|
||||
let mut h = E::pairing(blindSig.h, mpk.g2);
|
||||
h = h.pow(tt1.into_repr());
|
||||
h = h.pow(tt.into_repr());
|
||||
gx.mul_assign(&h);
|
||||
(v1, s1, t1, tt1, gx, blindSig)
|
||||
ProofState { v, s, t, tt, a: gx, blindSig }
|
||||
}
|
||||
|
||||
/// prove knowledge of a signature: response phase
|
||||
pub fn prove_response(&self, v: E::Fr, s: E::Fr, t: &mut Vec<E::Fr>, tt: E::Fr, challenge: E::Fr, message: &mut Vec<E::Fr>) -> (Vec<E::Fr>, E::Fr, E::Fr) {
|
||||
let mut zsig1 = t.clone();
|
||||
for i in 0..zsig1.len() {
|
||||
/// returns a proof that can be send to the verifier together with the challenge and the blind signature
|
||||
pub fn prove_response(&self, ps: ProofState<E>, challenge: E::Fr, message: &mut Vec<E::Fr>) -> Proof<E> {
|
||||
let mut zsig = ps.t.clone();
|
||||
for i in 0..zsig.len() {
|
||||
let mut message1 = message[i];
|
||||
message1.mul_assign(&challenge);
|
||||
zsig1[i].add_assign(&message1);
|
||||
zsig[i].add_assign(&message1);
|
||||
}
|
||||
let mut zx1 = s.clone();
|
||||
zx1.add_assign(&challenge);
|
||||
let mut zv1 = tt.clone();
|
||||
let mut vic = v.clone();
|
||||
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);
|
||||
zv1.add_assign(&vic);
|
||||
(zsig1, zx1, zv1)
|
||||
zv.add_assign(&vic);
|
||||
Proof {zsig, zx, zv, a: ps.a }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -464,11 +486,11 @@ mod tests {
|
|||
}
|
||||
|
||||
let sig = keypair.sign(&mut rng, &message1);
|
||||
let (v, s, mut t, tt, a, sig) = keypair.prove_commitment(rng, &mpk, &sig);
|
||||
let proof_state = keypair.prove_commitment(rng, &mpk, &sig);
|
||||
let challenge = Fr::rand(&mut rng);
|
||||
let proof_part2 = keypair.prove_response(v, s, &mut t, tt, challenge, &mut message1);
|
||||
let proof = keypair.prove_response(proof_state.clone(), challenge, &mut message1);
|
||||
|
||||
assert_eq!(keypair.public.verify_proof(&mpk, sig, proof_part2.1, proof_part2.0, proof_part2.2, challenge, &a), true);
|
||||
assert_eq!(keypair.public.verify_proof(&mpk, proof_state.blindSig, proof, challenge), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue