diff --git a/src/channels.rs b/src/channels.rs index 47c7976..ce4e456 100644 --- a/src/channels.rs +++ b/src/channels.rs @@ -20,7 +20,6 @@ use rand::Rng; use std::collections::HashMap; use std::fmt::Display; use serde::{Serialize, Deserialize}; -use serialization_wrappers::WalletCommitmentAndParamsWrapper; use std::ptr::hash; use nizk::{NIZKPublicParams, Proof}; use wallet::Wallet; diff --git a/src/clproto.rs b/src/clproto.rs deleted file mode 100644 index d7fe127..0000000 --- a/src/clproto.rs +++ /dev/null @@ -1,324 +0,0 @@ -// clproto.rs -extern crate serde; - -use serialization_wrappers; -use std::fmt; -use std::str; -use rand::{thread_rng, Rng}; -use bn::{Group, Fr, G1, G2, Gt, pairing}; -use clsigs; -use commit_scheme; -use debug_elem_in_hex; -use debug_g1_in_hex; -use debug_g2_in_hex; -use debug_gt_in_hex; -use bincode::SizeLimit::Infinite; -use bincode::rustc_serialize::encode; -use clsigs::{PublicParams, SignatureD, PublicKeyD, SecretKeyD, hash_g2_to_fr, hash_gt_to_fr}; - -use serde::{Serialize, Deserialize}; - -#[derive(Clone, Serialize, Deserialize)] -pub struct ProofCV { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] - pub T: G2, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] - pub C: G2, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_fr_vec")] - pub s: Vec, - pub num_secrets: usize, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_two_vec")] - pub pub_bases: Vec -} - -/// NIZK for PoK of the opening of a commitment M = g^m0 * Z1^m1 * ... * Zl^ml -/// Arg 1 - secret values -/// Arg 2 - public bases -/// Arg 3 - commitment to include in the proof -pub fn bs_gen_nizk_proof(x: &Vec, pub_bases: &Vec, C: G2) -> ProofCV { - let rng = &mut thread_rng(); - let l = x.len(); // number of secrets - let mut t: Vec = Vec::new(); - for i in 0 .. l { - t.push(Fr::random(rng)); - } - - // compute the T - let mut T = pub_bases[0] * t[0]; - for i in 1 .. l { - T = T + (pub_bases[i] * t[i]); - } - - // hash T to get the challenge - let c = hash_g2_to_fr(&T); - // compute s values - let mut s: Vec = Vec::new(); - for i in 0 .. l { - //println!("(gen proof) i => {}", i); - let _s = (x[i] * c) + t[i]; - s.push(_s); - } - - return ProofCV { T: T, C: C, s: s, pub_bases: pub_bases.clone(), num_secrets: l }; -} - -pub fn bs_check_proof_and_gen_signature(mpk: &PublicParams, sk: &SecretKeyD, proof: &ProofCV) -> SignatureD { - if bs_verify_nizk_proof(&proof) { - return bs_compute_blind_signature(&mpk, &sk, proof.C, proof.num_secrets); - } else { - panic!("Invalid proof: could not verify the NIZK proof"); - } -} - -pub fn bs_verify_nizk_proof(proof: &ProofCV) -> bool { - // if proof is valid, then call part - let c = hash_g2_to_fr(&proof.T); - let l = proof.s.len(); // number of s values - assert!(l <= proof.pub_bases.len()); - - let mut lhs = proof.pub_bases[0] * proof.s[0]; - for i in 1 .. l { - //println!("(in verify proof) i => {}", i); - lhs = lhs + (proof.pub_bases[i] * proof.s[i]); - } - let rhs = (proof.C * c) + proof.T; - return lhs == rhs; -} - -// internal function -pub fn bs_compute_blind_signature(mpk: &PublicParams, sk: &SecretKeyD, m: G2, num_secrets: usize) -> SignatureD { - let rng = &mut thread_rng(); - let alpha = Fr::random(rng); - let a = mpk.g2 * alpha; - let mut A: Vec = Vec::new(); - let mut B: Vec = Vec::new(); - - assert!(sk.z.len() <= num_secrets); - let l = sk.z.len(); - - for i in 0 .. l { - let _A = a * sk.z[i]; - let _B = _A * sk.y; - A.push(_A); - B.push(_B); - } - - let b = a * sk.y; - let c = (a * sk.x) + (m * (alpha * sk.x * sk.y)); - let sig = SignatureD { a: a, A: A, b: b, B: B, c: c }; - return sig; -} - -// Prover first randomizes the signature -pub fn prover_generate_blinded_sig(sig: &SignatureD) -> SignatureD { - let rng = &mut thread_rng(); - let r = Fr::random(rng); - let rpr = Fr::random(rng); - - let a = sig.a * r; - let b = sig.b * r; - let c = (sig.c * r) * rpr; - let mut A: Vec = Vec::new(); - let mut B: Vec = Vec::new(); - assert!(sig.A.len() == sig.B.len()); - let l = sig.A.len(); - - for i in 0 .. l { - A.push(sig.A[i] * r); - B.push(sig.B[i] * r); - } - - let bsig = SignatureD { a: a, A: A, b: b, B: B, c: c }; - return bsig; -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct CommonParams { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_t")] - vx: Gt, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_t")] - vxy: Gt, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_t_vec")] - vxyi: Vec, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_t")] - pub vs: Gt -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct ProofVS { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_t")] - T: Gt, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_t")] - A: Gt, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_fr_vec")] - s: Vec, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_t_vec")] - pub_bases: Vec -} - -pub fn gen_common_params(mpk: &PublicParams, pk: &PublicKeyD, sig: &SignatureD) -> CommonParams { - let l = sig.B.len(); - - let vx = pairing(pk.X, sig.a); - let vxy = pairing(pk.X, sig.b); - // generate vector - let mut vxyi: Vec = Vec::new(); - for i in 0 .. l { - vxyi.push(pairing(pk.X, sig.B[i])); - } - let vs = pairing(mpk.g1, sig.c); - return CommonParams { vx: vx, vxy: vxy, vxyi: vxyi, vs: vs }; -} - -pub fn vs_gen_nizk_proof(x: &Vec, cp: &CommonParams, a: Gt) -> ProofVS { - let rng = &mut thread_rng(); - let l = x.len() + 1; - let mut t: Vec = Vec::new(); - for i in 0 .. l { - t.push(Fr::random(rng)); - } - - let mut pub_bases: Vec = Vec::new(); - pub_bases.push(cp.vx); // 1 - pub_bases.push(cp.vxy); // u_0 - for i in 0 .. cp.vxyi.len() { - pub_bases.push(cp.vxyi[i]); // u_1 ... u_l - } - - // compute the T - let mut T = pub_bases[0].pow(t[0]); // vx ^ t0 - for i in 1 .. l { - T = T * (pub_bases[i].pow(t[i])); // vxy{i} ^ t{i} - } - - // hash T to get the challenge - let c = hash_gt_to_fr(&T); - // compute s values - let mut s: Vec = Vec::new(); - let _s = c + t[0]; // for vx => s0 = (1*c + t[0]) - s.push(_s); - for i in 1 .. l { - //println!("(gen nizk proof) i => {}", i); - let _s = (x[i-1] * c) + t[i]; - s.push(_s); - } - - return ProofVS { T: T, A: a, s: s, pub_bases: pub_bases }; -} - -fn part1_verify_proof_vs(proof: &ProofVS) -> bool { - let c = hash_gt_to_fr(&proof.T); - let l = proof.s.len(); - assert!(l > 1); - - let mut lhs = proof.pub_bases[0].pow(proof.s[0]); - for i in 1 .. l { - lhs = lhs * (proof.pub_bases[i].pow(proof.s[i])); - } - let rhs = proof.A.pow(c) * proof.T; - return lhs == rhs; -} - -pub fn vs_verify_blind_sig(mpk: &PublicParams, pk: &PublicKeyD, proof: &ProofVS, sig: &SignatureD) -> bool { - let result0 = part1_verify_proof_vs(&proof); - let mut result1 = true; - let mut result3 = true; - - // TODO: optimize verification - // verify second condition - let lhs2 = pairing(pk.Y, sig.a); - let rhs2 = pairing(mpk.g1, sig.b); - let result2 = lhs2 == rhs2; - - assert_eq!(sig.A.len(), sig.B.len()); - let l = sig.A.len(); - - for i in 0 .. l { - let lhs1 = pairing(pk.Z[i], sig.a); - let rhs1 = pairing(mpk.g1, sig.A[i]); - if lhs1 != rhs1 { - result1 = false; - } - - let lhs3 = pairing(pk.Y, sig.A[i]); - let rhs3 = pairing(mpk.g1, sig.B[i]); - - if lhs3 != rhs3 { - result3 = false; - } - } - - if !result0 { - println!("ERROR: Failed to verify proof"); - } - if !result1 { - println!("ERROR: Failed to verify pairing eq 1"); - } - if !result2 { - println!("ERROR: Failed to verify pairing eq 2"); - } - if !result3 { - println!("ERROR: Failed to verify pairing eq 3"); - } - - return result0 && result1 && result2 && result3; -} - -#[cfg(test)] -mod tests { - use super::*; - use rand::{Rng, thread_rng}; - use bn::{Fr, Group}; - use clsigs; - use commit_scheme; - use debug_g2_in_hex; - - #[test] - #[ignore] - fn efficient_protocols_for_cl_signatures() { - let rng = &mut rand::thread_rng(); - - let mpk = clsigs::setup_d(); - let l = 3; - let m_keypair = clsigs::keygen_d(&mpk, l); - let mut m1 : Vec = Vec::new(); - - for i in 0 .. l+1 { - m1.push(Fr::random(rng)); - } - - let b = m_keypair.pk.Z2.len(); - let mut bases: Vec = Vec::new(); - bases.push(mpk.g2); - for i in 0 .. b { - bases.push(m_keypair.pk.Z2[i]); - } - - // generate sample commitment - let mut C = mpk.g2 * m1[0]; - for i in 0 .. b { - //println!("index: {}", i); - C = C + (m_keypair.pk.Z2[i] * m1[i+1]); - } - let msg = "Sample Commit output:"; - debug_g2_in_hex(msg, &C); - - let cm_csp = commit_scheme::setup(b, m_keypair.pk.Z2.clone(), mpk.g2.clone()); - let r = m1[0]; - let w_com = commit_scheme::commit(&cm_csp, &m1, r); - - assert!(commit_scheme::decommit(&cm_csp, &w_com, &m1)); - - let proof = bs_gen_nizk_proof(&m1, &cm_csp.pub_bases, w_com.c); - - let int_sig = bs_check_proof_and_gen_signature(&mpk, &m_keypair.sk, &proof); - - assert!(clsigs::verify_d(&mpk, &m_keypair.pk, &m1, &int_sig) == true); - - let blind_sigs = prover_generate_blinded_sig(&int_sig); - let common_params1 = gen_common_params(&mpk, &m_keypair.pk, &int_sig); - - let proof_vs = vs_gen_nizk_proof(&m1, &common_params1, common_params1.vs); - assert!(vs_verify_blind_sig(&mpk, &m_keypair.pk, &proof_vs, &blind_sigs) == true); - } -} diff --git a/src/clsigs.rs b/src/clsigs.rs deleted file mode 100644 index 174571b..0000000 --- a/src/clsigs.rs +++ /dev/null @@ -1,441 +0,0 @@ -// clsigs.rs -extern crate serde; - -use std::fmt; -use std::str; -use rand::{thread_rng, Rng}; -use bn::{Group, Fr, G1, G2, Gt, pairing}; -use debug_elem_in_hex; -use debug_g1_in_hex; -use debug_g2_in_hex; -use debug_gt_in_hex; -use concat_g2_to_vector; -use bincode::SizeLimit::Infinite; -use bincode::rustc_serialize::encode; -use sodiumoxide::crypto::hash::sha512; -use sodiumoxide::randombytes; -use serialization_wrappers; -use serde_with; - -use serde::{Serialize, Deserialize}; - -#[derive(Serialize, Deserialize)] -pub struct PublicParams { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_one")] - pub g1: G1, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] - pub g2: G2 -} - -#[derive(Copy, Clone, Serialize, Deserialize)] -pub struct PublicKey { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_one")] - X: G1, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_one")] - Y: G1 -} - -impl PublicKey { - pub fn encode(&self) -> Vec { - let mut output_buf = Vec::new(); - let x_vec: Vec = encode(&self.X, Infinite).unwrap(); - let y_vec: Vec = encode(&self.Y, Infinite).unwrap(); - output_buf.extend(x_vec); - output_buf.extend(y_vec); - return output_buf; - } -} - - -impl fmt::Display for PublicKey { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let x_vec: Vec = encode(&self.X, Infinite).unwrap(); - let y_vec: Vec = encode(&self.Y, Infinite).unwrap(); - let mut x_s = String::new(); - for x in x_vec.iter() { - x_s = format!("{}{:x}", x_s, x); - } - - let mut y_s = String::new(); - for y in y_vec.iter() { - y_s = format!("{}{:x}", y_s, y); - } - - write!(f, "PK : (X=0x{}, Y=0x{})", x_s, y_s) - } -} - -#[derive(Copy, Clone, Serialize)] -pub struct SecretKey { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")] - x: Fr, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")] - y: Fr -} - -impl SecretKey { - pub fn encode(&self) -> Vec { - let mut output_buf = Vec::new(); - let x_vec: Vec = encode(&self.x, Infinite).unwrap(); - let y_vec: Vec = encode(&self.y, Infinite).unwrap(); - output_buf.extend(x_vec); - output_buf.extend(y_vec); - return output_buf; - } -} - -#[derive(Clone, Serialize)] -pub struct KeyPair { - pub sk: SecretKey, - pub pk: PublicKey -} - -#[derive(Serialize)] -pub struct Signature { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable")] - a: G2, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable")] - b: G2, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable")] - c: G2 -} - -impl fmt::Display for Signature { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let a_vec: Vec = encode(&self.a, Infinite).unwrap(); - let b_vec: Vec = encode(&self.b, Infinite).unwrap(); - let c_vec: Vec = encode(&self.c, Infinite).unwrap(); - let mut a_s = String::new(); - for x in a_vec.iter() { - a_s = format!("{}{:x}", a_s, x); - } - - let mut b_s = String::new(); - for y in b_vec.iter() { - b_s = format!("{}{:x}", b_s, y); - } - - let mut c_s = String::new(); - for y in c_vec.iter() { - c_s = format!("{}{:x}", c_s, y); - } - - write!(f, "Signature : (\na = 0x{},\nb = 0x{},\nc = 0x{}\n)", a_s, b_s, c_s) - } -} - -// scheme A - for a single message - -pub fn setup_a() -> PublicParams { - let rng = &mut thread_rng(); - let g1 = G1::random(rng); - let g2 = G2::random(rng); - let mpk = PublicParams { g1: g1, g2: g2 }; - return mpk; -} - -pub fn keygen_a(mpk : &PublicParams) -> KeyPair { - let rng = &mut thread_rng(); - let x = Fr::random(rng); - let y = Fr::random(rng); - let sk = SecretKey { x: x, y: y }; - let pk = PublicKey { X: mpk.g1 * x, - Y: mpk.g1 * y - }; - return KeyPair { sk: sk, pk: pk } -} - -pub fn sign_a(sk: &SecretKey, m: Fr) -> Signature { - let rng = &mut thread_rng(); - let a = G2::random(rng); - - let b = a * sk.y; - let c = a * (sk.x + (m * sk.x * sk.y)); - let sig = Signature { a: a, b: b, c: c }; - return sig; -} - -pub fn verify_a(mpk: &PublicParams, pk: &PublicKey, m: Fr, sig: &Signature) -> bool { - let lhs1 = pairing(pk.Y, sig.a); - let rhs1 = pairing(mpk.g1, sig.b); - let lhs2 = pairing(pk.X, sig.a) * (pairing(pk.X, sig.b).pow(m)); - let rhs2 = pairing(mpk.g1, sig.c); - return (lhs1 == rhs1) && (lhs2 == rhs2); -} - -// scheme D - for a vector of messages -#[derive(Clone, Serialize, Deserialize)] -pub struct PublicKeyD { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_one")] - pub X: G1, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_one")] - pub Y: G1, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_one_vec")] - pub Z: Vec, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_two_vec")] - pub Z2: Vec, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_one_vec")] - pub W: Vec -} - -impl PublicKeyD { - pub fn encode(&self) -> Vec { - let mut output_buf = Vec::new(); - let x_vec: Vec = encode(&self.X, Infinite).unwrap(); - let y_vec: Vec = encode(&self.Y, Infinite).unwrap(); - - output_buf.extend(x_vec); - output_buf.extend(y_vec); - for i in 0 .. self.Z.len() { - let zi_vec: Vec = encode(&self.Z[i], Infinite).unwrap(); - output_buf.extend(zi_vec); - let z2i_vec: Vec = encode(&self.Z2[i], Infinite).unwrap(); - output_buf.extend(z2i_vec); - let w_vec: Vec = encode(&self.W[i], Infinite).unwrap(); - output_buf.extend(w_vec); - } - return output_buf; - } -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct SecretKeyD { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")] - pub x: Fr, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")] - pub y: Fr, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_fr_vec")] - pub z: Vec -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct KeyPairD { - pub sk: SecretKeyD, - pub pk: PublicKeyD -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct SignatureD { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] - pub a: G2, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_two_vec")] - pub A: Vec, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] - pub b: G2, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_two_vec")] - pub B: Vec, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] - pub c: G2 -} - -impl SignatureD { - pub fn new(_a: G2, _A: Vec, _b: G2, _B: Vec, _c: G2) -> SignatureD { - SignatureD { - a: _a, A: _A, b: _b, B: _B, c: _c - } - } - - pub fn hash(&self, prefix: &str) -> Fr { - let mut output_buf: Vec = Vec::new(); - output_buf.extend_from_slice(prefix.as_bytes()); - concat_g2_to_vector(&mut output_buf, &self.a); - concat_g2_to_vector(&mut output_buf, &self.b); - concat_g2_to_vector(&mut output_buf, &self.c); - assert_eq!(self.A.len(), self.B.len()); - for i in 0 .. self.A.len() { - concat_g2_to_vector(&mut output_buf, &self.A[i]); - concat_g2_to_vector(&mut output_buf, &self.B[i]); - } - - // println!("DEBUG: signature len => {}", output_buf.len()); - // let's hash the final output_buf - let sha2_digest = sha512::hash(output_buf.as_slice()); - - let mut hash_buf: [u8; 64] = [0; 64]; - hash_buf.copy_from_slice(&sha2_digest[0..64]); - return Fr::interpret(&hash_buf); - } -} - -pub fn setup_d() -> PublicParams { - let rng = &mut thread_rng(); - let g1 = G1::random(rng); - let g2 = G2::random(rng); - let mpk = PublicParams { g1: g1, g2: g2 }; - return mpk; -} - -pub fn keygen_d(mpk : &PublicParams, l: usize) -> KeyPairD { - let rng = &mut thread_rng(); - let x = Fr::random(rng); - let y = Fr::random(rng); - let X = mpk.g1 * x; - let Y = mpk.g1 * y; - let mut z: Vec = Vec::new(); - let mut Z: Vec = Vec::new(); - let mut Z2: Vec = Vec::new(); - let mut W: Vec = Vec::new(); - // generate the vector ck of sym keys - for i in 0 .. l { - let _z = Fr::random(rng); - let _Z = mpk.g1 * _z; - let _Z2 = mpk.g2 * _z; - let _W = Y * _z; - z.push(_z); - Z.push(_Z); - Z2.push(_Z2); - W.push(_W); - } - // plus one to Z2 - - - let sk = SecretKeyD { x: x, y: y, z: z }; - let pk = PublicKeyD { X: X, Y: Y, Z: Z, Z2: Z2, W: W }; - return KeyPairD { sk: sk, pk: pk } -} - -pub fn sign_d(mpk: &PublicParams, sk: &SecretKeyD, m: &Vec) -> SignatureD { - assert!(m.len() <= sk.z.len()+1); - let l = m.len(); - - let rng = &mut thread_rng(); - //let a = mpk.g2 * Fr::random(rng); // G2::random(rng); - let a = G2::random(rng); - let mut A: Vec = Vec::new(); - let b = a * sk.y; - let mut B: Vec = Vec::new(); - let mut c = (a * (sk.x + (m[0] * sk.x * sk.y))); - - for i in 0 .. l-1 { - let _A = a * sk.z[i]; - let _B = _A * sk.y; - A.push(_A); - B.push(_B); - c = c + (_A * (m[i+1] * sk.x * sk.y)); - } - - let sig = SignatureD { a: a, A: A, b: b, B: B, c: c }; - return sig; -} - -pub fn verify_d_unoptimized(mpk: &PublicParams, pk: &PublicKeyD, m: &Vec, sig: &SignatureD) -> bool { - let l = m.len(); - // lhs2a and rhs2a checks that sig.b was formed correctly - let lhs2a = pairing(pk.Y, sig.a); // eq2a - let rhs2a = pairing(mpk.g1, sig.b); - - let mut result1 = true; - let mut result2b = true; - // lhs3 and rhs3 checks that sig.c was formed correctly - let mut lhs3 = pairing(pk.X, sig.a) * pairing(pk.X, sig.b * m[0]); // eq3 - let rhs3 = pairing(mpk.g1, sig.c); - - for i in 0 .. l-1 { - // checks that {sig.A}_i was formed correctly - let lhs1 = pairing(pk.Z[i], sig.a); // eq1 - let rhs1 = pairing(mpk.g1, sig.A[i]); - if (lhs1 != rhs1) { - result1 = false; - } - let lhs2b = pairing(pk.Y, sig.A[i]); // eq2b - let rhs2b = pairing(mpk.g1, sig.B[i]); - if lhs2b != rhs2b { - result2b = false; - } - lhs3 = lhs3 * pairing(pk.X, sig.B[i] * m[i+1]); // eq3 - } - - return result1 && (lhs2a == rhs2a) && result2b && (lhs3 == rhs3); -} - -// optimized but does not include small exps for security -pub fn verify_d(mpk: &PublicParams, pk: &PublicKeyD, m: &Vec, sig: &SignatureD) -> bool { - let l = m.len(); - let mut Zis = G1::zero(); - let mut Ais = G2::zero(); - let mut Bis = G2::zero(); - let mut _lhs3 = G2::zero(); - for i in 0 .. l-1 { - // checks that {sig.A}_i was formed correctly - let Zis = Zis + pk.Z[i]; - let Ais = Ais + sig.A[i]; - let Bis = Bis + sig.B[i]; - _lhs3 = _lhs3 + (sig.B[i] * m[i+1]); - } - - return pairing(Zis, sig.a) * - pairing(pk.Y, Ais + sig.a).inverse() * - pairing(pk.X, sig.a + (sig.b * m[0]) + _lhs3).inverse() == - pairing(mpk.g1, Ais + -Bis + -sig.b + -sig.c); -} - -// NIZK protocol for proving knowledge of a signature -pub fn hash_g2_to_fr(x: &G2) -> Fr { - // TODO: change to serde (instead of rustc_serialize) - let x_vec: Vec = encode(&x, Infinite).unwrap(); - 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 Fr::interpret(&hash_buf); -} - -pub fn hash_gt_to_fr(x: &Gt) -> Fr { - // TODO: change to serde (instead of rustc_serialize) - let x_vec: Vec = encode(&x, Infinite).unwrap(); - 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 Fr::interpret(&hash_buf); -} - -#[cfg(test)] -mod tests { - use super::*; - use bn::{Fr, Group}; - - #[test] - #[ignore] - fn scheme_a_sign_and_verify_works() { - // test ability to sign/verify a single message - let rng = &mut thread_rng(); - - let mpk = setup_a(); - let keypair = keygen_a(&mpk); - - let mut m1 = Fr::random(rng); - let mut m2 = Fr::random(rng); - - let signature = sign_a(&keypair.sk, m1); - - assert!(verify_a(&mpk, &keypair.pk, m1, &signature) == true); - assert!(verify_a(&mpk, &keypair.pk, m2, &signature) == false); - } - - #[test] - #[ignore] - fn scheme_d_sign_and_verify_works() { - // test ability to sign/verify a vector of messages - let rng = &mut thread_rng(); - - let mpk = setup_d(); - let l = 3; - let keypair = keygen_d(&mpk, l); - - let mut m1 : Vec = Vec::new(); - let mut m2 : Vec = Vec::new(); - - for i in 0 .. l+1 { - m1.push(Fr::random(rng)); - m2.push(Fr::random(rng)); - } - - let signature = sign_d(&mpk, &keypair.sk, &m1); - - assert!(verify_d(&mpk, &keypair.pk, &m1, &signature) == true); - assert!(verify_d_unoptimized(&mpk, &keypair.pk, &m1, &signature) == true); - assert!(verify_d(&mpk, &keypair.pk, &m2, &signature) == false); - } -} - diff --git a/src/commit_scheme.rs b/src/commit_scheme.rs deleted file mode 100644 index 0234f50..0000000 --- a/src/commit_scheme.rs +++ /dev/null @@ -1,222 +0,0 @@ -// commit_schemes.rs -extern crate serde; - -use serialization_wrappers; -use std::fmt; -use rand::{thread_rng, Rng}; -use bn::{Group, Fr, G1, G2}; -use clsigs; -use debug_elem_in_hex; -use bincode::SizeLimit::Infinite; -use bincode::rustc_serialize::encode; -use sodiumoxide::crypto::hash::sha512; - -use serde::{Serialize, Deserialize}; - -#[derive(Copy, Clone, Serialize, Deserialize)] -pub struct PublicKey { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] - g: G2, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] - h: G2 -} - -#[derive(Copy, Clone, Serialize, Deserialize)] -pub struct Commitment { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] - pub c: G2, - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")] - pub r: Fr -} - -#[derive(Clone, Serialize, Deserialize)] -pub struct CSParams { - #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_two_vec")] - pub pub_bases: Vec -} - -impl fmt::Display for PublicKey { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let g_vec: Vec = encode(&self.g, Infinite).unwrap(); - let h_vec: Vec = encode(&self.h, Infinite).unwrap(); - let mut g_s = String::new(); - for x in g_vec.iter() { - g_s = format!("{}{:x}", g_s, x); - } - - let mut h_s = String::new(); - for y in h_vec.iter() { - h_s = format!("{}{:x}", h_s, y); - } - - write!(f, "PK : (g=0x{}, h=0x{})", g_s, h_s) - } -} - -impl fmt::Display for Commitment { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let c_vec: Vec = encode(&self.c, Infinite).unwrap(); - let mut c_s = String::new(); - for x in c_vec.iter() { - c_s = format!("{}{:x}", c_s, x); - } - - let d_vec: Vec = encode(&self.r, Infinite).unwrap(); - let mut d_s = String::new(); - for x in d_vec.iter() { - d_s = format!("{}{:x}", d_s, x); - } - write!(f, "Commitment : (c=0x{}, r=0x{})", c_s, d_s) - } -} - -/* -Implements the setup algorithm for the Pedersen92 commitment scheme -*/ -pub fn ped92_setup() -> PublicKey { - println!("Run Setup..."); - let rng = &mut thread_rng(); - let g = G2::random(rng); - let h = G2::random(rng); - let pk = PublicKey { g: g, h: h }; - println!("{}", pk); - return pk; -} - -/* -commit(pk, msg) -> cm where -- pk is the public key generated from setup() -- msg is the message structure for the commitment scheme -- cm is the output commitment message for the given message -*/ -pub fn ped92_commit(pk: &PublicKey, m: Fr, R: Option) -> Commitment { - let rng = &mut thread_rng(); - - let r = R.unwrap_or(Fr::random(rng)); - //let r = Fr::random(rng); - - //let m = msg.hash(); - let p = "commit -> m"; - debug_elem_in_hex(p, &m); - // c = g^m * h^r - let c = (pk.g * m) + (pk.h * r); - // return (c, r) <- d=r - let commitment = Commitment { c: c, r: r }; - - // debugging - println!("{}", commitment); - return commitment; -} - -/* -decommit(pk, cm, msg) -> bool where -- pk is the public key generated from setup() -- cm is the commitment -- m is the message to validate -- outputs T/F for whether the cm is a valid commitment to the msg -*/ -pub fn ped92_decommit(pk: &PublicKey, cm: &Commitment, m: Fr) -> bool { - let p = "decommit -> m"; - debug_elem_in_hex(p, &m); - - let dm = (pk.g * m) + (pk.h * cm.r); - return dm == cm.c; -} - - -/* -Implements the setup algorithm for the Pedersen92 commitment scheme over -a vector of messages. -*/ - -pub fn setup(len: usize, pub_bases: Vec, h: G2) -> CSParams { - let rng = &mut thread_rng(); - //let base_h = h.unwrap_or(G2::random(rng)); - let mut p: Vec = Vec::new(); - p.push(h); - - let _p = pub_bases; - for i in 0 .. _p.len() { - p.push(_p[i]); - } - return CSParams { pub_bases: p }; -} - -pub fn setup_gen_params(len: usize) -> CSParams { - let rng = &mut thread_rng(); - - let mut p: Vec = Vec::new(); - for i in 0 .. len { - p.push(G2::random(rng)); - } - return CSParams { pub_bases: p }; -} - -pub fn commit(csp: &CSParams, x: &Vec, r: Fr) -> Commitment { - let rng = &mut thread_rng(); - - //let r = R.unwrap_or(Fr::random(rng)); - // c = g1^m1 * ... * gn^mn * h^r - //println!("(commit) index: 0"); - let mut c = csp.pub_bases[0] * r; - for i in 1 .. x.len() { - //println!("(commit) index: {}", i); - c = c + (csp.pub_bases[i] * x[i]); - } - // return (c, r) <- r - let commitment = Commitment { c: c, r: r }; - - // debugging - //println!("{}", commitment); - return commitment; -} - -pub fn decommit(csp: &CSParams, cm: &Commitment, x: &Vec) -> bool { - let l = x.len(); - // pub_base[0] => h, x[0] => r - // check that cm.r == x[0] - // assert!(cm.r == x[0]); - let mut dc = csp.pub_bases[0] * cm.r; - for i in 1 .. l { - dc = dc + (csp.pub_bases[i] * x[i]); - } - return dc == cm.c && cm.r == x[0]; -} - -#[cfg(test)] -mod tests { - use super::*; - use bn::{Fr, Group}; - - #[test] - #[ignore] - fn commit_one_message_works() { - let rng = &mut thread_rng(); - let pk = ped92_setup(); - - let m1 = Fr::random(rng); - let m2 = m1 + Fr::from_str("1").unwrap(); - let r = Fr::random(rng); - let c = ped92_commit(&pk, m1, Some(r)); - - assert!(ped92_decommit(&pk, &c, m1) == true); - assert!(ped92_decommit(&pk, &c, m2) == false); - } - - #[test] - #[ignore] - fn commit_n_message_works() { - let rng = &mut thread_rng(); - let len = 3; - let csp = setup_gen_params(len); - - let mut m: Vec = Vec::new(); - for i in 0 .. len { - m.push(Fr::random(rng)); - } - let r = m[0]; - let c = commit(&csp, &m, r); - - assert!(decommit(&csp, &c, &m) == true); - } -} diff --git a/src/ffishim.rs b/src/ffishim.rs index bd60a46..efeba2e 100644 --- a/src/ffishim.rs +++ b/src/ffishim.rs @@ -13,7 +13,6 @@ pub mod ffishim { use std::str; use std::mem; - use serialization_wrappers; fn error_message(s: String) -> *mut c_char { let ser = ["{\'error\':\'", serde_json::to_string(&s).unwrap().as_str(), "\'}"].concat(); let cser = CString::new(ser).unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 712196f..a1646e6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,8 +4,8 @@ //! It builds on academic work done by Ian Miers and Matthew Green - //! https://eprint.iacr.org/2016/701. //! -//! Libbolt relies on BN curves at 128-bit security, as implemented in -//! [`bn module`](https://github.com/zcash-hackworks/bn). +//! Libbolt relies on BLS12-381 curves at 128-bit security, as implemented in a fork of +//! [`pairing module`](https://github.com/boltlabs-inc/pairing). //! #![allow(non_snake_case)] #![allow(non_camel_case_types)] @@ -19,7 +19,6 @@ #![cfg_attr(all(test, feature = "unstable"), feature(test))] #[cfg(all(test, feature = "unstable"))] extern crate test; -extern crate bn; extern crate ff; extern crate pairing; extern crate rand; @@ -27,7 +26,6 @@ extern crate rand_core; extern crate bincode; extern crate sodiumoxide; -extern crate rustc_serialize; extern crate secp256k1; extern crate time; extern crate merlin; @@ -46,7 +44,6 @@ extern crate core; use std::fmt; use std::str; -use bn::{Group, Fr, G1, G2, Gt}; use bincode::SizeLimit::Infinite; use bincode::rustc_serialize::{encode, decode}; use sodiumoxide::randombytes; @@ -64,54 +61,15 @@ use serde::de::{Deserializer, Unexpected, Error}; pub mod sym; pub mod cl; -pub mod clsigs; pub mod ccs08; -pub mod commit_scheme; pub mod ped92; pub mod channels; -pub mod clproto; -pub mod serialization_wrappers; pub mod nizk; pub mod util; pub mod wallet; pub mod ffishim; -pub fn debug_elem_in_hex(prefix: &str, r: &Fr) { - let encoded: Vec = encode(&r, Infinite).unwrap(); - print!("{} (hex) = 0x", prefix); - for e in encoded.iter() { - print!("{:x}", e); - } - print!("\n"); -} - -pub fn debug_g1_in_hex(prefix: &str, g: &G1) { - let encoded: Vec = encode(&g, Infinite).unwrap(); - print!("{} (hex) = 0x", prefix); - for e in encoded.iter() { - print!("{:x}", e); - } - print!("\n"); -} - -pub fn debug_g2_in_hex(prefix: &str, g: &G2) { - let encoded: Vec = encode(&g, Infinite).unwrap(); - print!("{} (hex) = 0x", prefix); - for e in encoded.iter() { - print!("{:x}", e); - } - print!("\n"); -} - -pub fn debug_gt_in_hex(prefix: &str, g: &Gt) { - let encoded: Vec = encode(&g, Infinite).unwrap(); - print!("{} (hex) = 0x", prefix); - for e in encoded.iter() { - print!("{:x}", e); - } - print!("\n"); -} - +////////////////////////////////// Utilities ////////////////////////////////// struct HexSlice<'a>(&'a [u8]); @@ -147,42 +105,6 @@ impl<'a> fmt::UpperHex for HexSlice<'a> { } } -/// Deserialize bool from String with custom value mapping -//fn bool_from_string<'de, D>(deserializer: D) -> Result -//where -// D: Deserializer<'de>, -//{ -// match String::deserialize(deserializer)?.as_ref() { -// "true" => Ok(true), -// "false" => Ok(false), -// other => Err(de::Error::invalid_value( -// Unexpected::Str(other), -// &"true or false", -// )), -// } -//} - -////////////////////////////////// Utilities ////////////////////////////////// - -pub fn concat_g1_to_vector(output: &mut Vec, t: &G1) { - let t_vec: Vec = encode(t, Infinite).unwrap(); - output.extend(t_vec); -} - -pub fn concat_g2_to_vector(output: &mut Vec, t: &G2) { - let t_vec: Vec = encode(t, Infinite).unwrap(); - output.extend(t_vec); -} - -pub fn hash_pub_key_to_fr(wpk: &secp256k1::PublicKey) -> Fr { - let x_slice = wpk.serialize_uncompressed(); - let sha2_digest = sha512::hash(&x_slice); - - let mut hash_buf: [u8; 64] = [0; 64]; - hash_buf.copy_from_slice(&sha2_digest[0..64]); - return Fr::interpret(&hash_buf); -} - pub type BoltResult = Result, String>; ////////////////////////////////// Utilities ////////////////////////////////// @@ -203,7 +125,6 @@ pub mod bidirectional { use sodiumoxide::crypto::hash::sha512; use sha2::Sha512; - use serialization_wrappers; use serde::{Serialize, Deserialize}; use std::sync::mpsc::channel; use util::RevokedMessage; diff --git a/src/nizk.rs b/src/nizk.rs index 26a6570..5a1ba9b 100644 --- a/src/nizk.rs +++ b/src/nizk.rs @@ -7,7 +7,6 @@ use cl::{KeyPair, Signature, PublicParams, setup, BlindKeyPair, ProofState, Sign use ped92::{CSParams, Commitment, CSMultiParams}; use pairing::{Engine, CurveProjective}; use ff::PrimeField; -use commit_scheme::commit; use wallet::Wallet; use ccs08::{RPPublicParams, RangeProof}; use serde::{Serialize, Deserialize};