nizk: start implementation of nizk

This commit is contained in:
Gijs Van Laer 2019-07-03 19:05:27 -04:00
parent b3e1b76a05
commit e4c1129a20
5 changed files with 128 additions and 24 deletions

View File

@ -9,13 +9,14 @@ extern crate rand;
use rand::{thread_rng, Rng};
use super::*;
use cl::{KeyPair, Signature, PublicParams, setup, BlindKeyPair, ProofState, Proof};
use cl::{KeyPair, Signature, PublicParams, setup, BlindKeyPair, ProofState, SignatureProof};
use ped92::{CSParams, Commitment};
use pairing::{Engine, CurveProjective};
use ff::PrimeField;
use std::collections::HashMap;
use std::fmt::Display;
use std::mem::transmute;
use util::fmt_bytes_to_int;
/**
paramsUL contains elements generated by the verifier, which are necessary for the prover.
@ -45,7 +46,7 @@ struct ProofUL<E: Engine> {
V: Vec<Signature<E>>,
D: E::G2,
comm: Commitment<E>,
sigProofs: Vec<Proof<E>>,
sigProofs: Vec<SignatureProof<E>>,
ch: E::Fr,
zr: E::Fr,
}
@ -102,7 +103,7 @@ impl<E: Engine> ParamsUL<E> {
// Initialize variables
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 sigProofs = Vec::<SignatureProof<E>>::with_capacity(self.l as usize);
let mut V = Vec::<Signature<E>>::with_capacity(self.l as usize);
let mut D = E::G2::zero();
let m = E::Fr::rand(rng);
@ -221,17 +222,6 @@ fn decompose(x: i64, u: i64, l: i64) -> Vec<i64> {
return result;
}
fn fmt_bytes_to_int(bytearray: [u8; 64]) -> String {
let mut result: String = "".to_string();
for byte in bytearray.iter() {
// Decide if you want upper- or lowercase results,
// padding the values to two characters, spaces
// between bytes, etc.
result = result + &format!("{}", *byte as u8);
}
result.to_string()
}
impl<E: Engine> RPPublicParams<E> {
/**
Setup receives integers a and b, and configures the parameters for the rangeproof scheme.
@ -459,12 +449,6 @@ mod tests {
RPPublicParams::<Bls12>::setup(rng, -2, -1);
}
#[test]
fn fmt_byte_to_int_works() {
assert_eq!(fmt_bytes_to_int([12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123]),
"122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123");
}
#[test]
fn hash_works() {
let rng = &mut rand::thread_rng();

View File

@ -64,7 +64,7 @@ pub struct ProofState<E: Engine> {
}
#[derive(Clone)]
pub struct Proof<E: Engine> {
pub struct SignatureProof<E: Engine> {
pub zx: E::Fr,
pub zsig: Vec<E::Fr>,
pub zv: E::Fr,
@ -245,7 +245,7 @@ impl<E: Engine> BlindPublicKey<E> {
/// Verify a proof of knowledge of a signature
/// 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 {
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.X);
gx = gx.pow(p.zx.into_repr());
for j in 0..self.Y2.len() {
@ -364,7 +364,7 @@ impl<E: Engine> BlindKeyPair<E> {
/// prove knowledge of a signature: response phase
/// 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> {
pub fn prove_response(&self, ps: ProofState<E>, challenge: E::Fr, message: &mut Vec<E::Fr>) -> SignatureProof<E> {
let mut zsig = ps.t.clone();
for i in 0..zsig.len() {
let mut message1 = message[i];
@ -377,7 +377,7 @@ impl<E: Engine> BlindKeyPair<E> {
let mut vic = ps.v.clone();
vic.mul_assign(&challenge);
zv.add_assign(&vic);
Proof {zsig, zx, zv, a: ps.a }
SignatureProof {zsig, zx, zv, a: ps.a }
}
}

View File

@ -70,6 +70,8 @@ pub mod commit_scheme;
pub mod ped92;
pub mod clproto;
pub mod serialization_wrappers;
pub mod nizk;
pub mod util;
const E_MIN: i32 = 1;
const E_MAX: i32 = 255; // TODO: should be 2^32 - 1

70
src/nizk.rs Normal file
View File

@ -0,0 +1,70 @@
extern crate rand;
use rand::{thread_rng, Rng};
use pairing::{Engine, CurveProjective};
use cl::{KeyPair, Signature, PublicParams, setup, BlindKeyPair, ProofState, SignatureProof, BlindPublicKey};
use ped92::{CSMultiParams, Commitment};
use ff::{Rand, Field, PrimeField};
use util::hash_g2_to_fr;
#[derive(Clone)]
struct Proof<E: Engine> {
sigProof: SignatureProof<E>,
T: E::G1,
z: Vec<E::Fr>
}
fn prove<R: Rng, E: Engine>(rng: &mut R, com1: &Commitment<E>, com2: &Commitment<E>, oldWallet: Vec<E::Fr>, r: E::Fr,
newWallet: Vec<E::Fr>, rprime: E::Fr, paymentToken: &Signature<E>,
mpk: &PublicParams<E>, kp: &BlindKeyPair<E>) -> Proof<E> {
let proofState = kp.prove_commitment(rng, &mpk, &paymentToken);
let mut challenge = E::Fr::one();
challenge.double();
let sigProof = kp.prove_response(proofState, challenge, &mut vec! {hash_g2_to_fr::<E>(&com1.c)});
Proof {sigProof, T: E::G1::rand(rng), z: vec!{}}
}
fn verify<E: Engine>(proof: Proof<E>, epsilon: E::Fr, com1: &Commitment<E>, com2: &Commitment<E>,
paymentToken: &Signature<E>, wpk: E::Fr, mpk: &PublicParams<E>, pk: &BlindPublicKey<E>) -> bool {
let mut challenge = E::Fr::one();
challenge.double();
pk.verify_proof(&mpk, paymentToken.clone(), proof.sigProof, challenge)
}
#[cfg(test)]
mod tests {
use super::*;
use pairing::bls12_381::{Bls12, G1, G2, Fq12, Fr};
#[test]
#[ignore]
fn nizk_proof_works() {
let rng = &mut rand::thread_rng();
let pkc = Fr::rand(rng);
let wpk = Fr::rand(rng);
let wpkprime = Fr::rand(rng);
let bc = Fr::rand(rng);
let mut bc2 = bc.clone();
let bm = Fr::rand(rng);
let mut bm2 = bm.clone();
let epsilon = &Fr::rand(rng);
bc2.sub_assign(epsilon);
bm2.add_assign(epsilon);
let r = Fr::rand(rng);
let rprime = Fr::rand(rng);
let com_params = CSMultiParams::<Bls12>::setup_gen_params(rng, 4);
let wallet1 = vec! {pkc, wpk, bc, bm};
let commitment1 = com_params.commit(rng, &wallet1, &r);
let wallet2 = vec! {pkc, wpkprime, bc2, bm2};
let commitment2 = com_params.commit(rng, &wallet2, &rprime);
let mpk = setup(rng);
let keypair = BlindKeyPair::<Bls12>::generate( rng, &mpk, 1);
let payment_token = keypair.sign(rng, &vec! {hash_g2_to_fr::<Bls12>(&commitment1.c)});
let proof = prove(rng, &commitment1, &commitment2, wallet1, r, wallet2, rprime, &payment_token, &mpk, &keypair);
assert_eq!(verify(proof, *epsilon, &commitment1, &commitment2, &payment_token, wpk, &mpk, &keypair.public), true);
}
}

48
src/util.rs Normal file
View File

@ -0,0 +1,48 @@
use sodiumoxide::crypto::hash::sha512;
use pairing::Engine;
use ff::PrimeField;
pub fn hash_g2_to_fr<E: Engine>(x: &E::G2) -> E::Fr {
let mut x_vec: Vec<u8> = Vec::new();
x_vec.extend(format!("{}", x).bytes());
let sha2_digest = sha512::hash(x_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(&fmt_bytes_to_int(hash_buf)).unwrap();
}
pub fn fmt_bytes_to_int(bytearray: [u8; 64]) -> String {
let mut result: String = "".to_string();
for byte in bytearray.iter() {
// Decide if you want upper- or lowercase results,
// padding the values to two characters, spaces
// between bytes, etc.
result = result + &format!("{}", *byte as u8);
}
result.to_string()
}
#[cfg(test)]
mod tests {
use super::*;
use pairing::bls12_381::{Bls12, G2, Fr};
use pairing::CurveProjective;
use ff::Field;
#[test]
fn hash_g2_to_fr_works() {
let mut two = G2::one();
two.double();
print!("{}\n", hash_g2_to_fr::<Bls12>(&two));
assert_eq!(format!("{}", hash_g2_to_fr::<Bls12>(&two).into_repr()),
"0x27cd26f702a777dbf782534ae6bf2ec4aa6cb4617c8366f10f59bef13beb8c56");
}
#[test]
fn fmt_byte_to_int_works() {
assert_eq!(fmt_bytes_to_int([12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123]),
"122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123");
}
}