Adding serde support to cl structs

This commit is contained in:
J. Ayo Akinyele 2019-07-29 17:13:40 -04:00
parent 1c91cf03fe
commit be2dc562cd
7 changed files with 226 additions and 103 deletions

View File

@ -15,7 +15,7 @@ rand_core = "0.4.0"
rand_xorshift = "0.1"
bn = { git = "https://github.com/ZcashFoundation/bn", branch = "master" }
ff = { git = "https://github.com/boltlabs-inc/ff", branch = "master" }
pairing = { git = "https://github.com/boltlabs-inc/pairing", branch = "master" }
pairing = { git = "https://github.com/boltlabs-inc/pairing", branch = "master", features = ["serde"] }
bincode = "0.6.1"
sodiumoxide = "0.0.16"
libc = "*"

View File

@ -1,8 +1,8 @@
/*
* Implement for Bolt protocols:
* - initializing channel state and generating cust/merch wallets (almost done)
* - establish protocol (WIP)
* - pay protocol (WIP)
* - initializing channel state and generating cust/merch wallets
* - establish protocol
* - pay protocol
* - channel close algorithms (WIP)
*/
@ -31,7 +31,6 @@ pub struct PubKeyMap {
pub revoke_token: Option<secp256k1::Signature>
}
//#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone)]
pub struct ChannelParams<E: Engine> {
pub pub_params: NIZKPublicParams<E>,
@ -40,7 +39,6 @@ pub struct ChannelParams<E: Engine> {
}
//#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone)]
pub struct ChannelState<E: Engine> {
R: i32,

140
src/cl.rs
View File

@ -5,18 +5,27 @@ extern crate rand;
use super::*;
use pairing::{CurveAffine, CurveProjective, Engine};
use ff::PrimeField;
use ff::{PrimeField, ScalarEngine};
use rand::Rng;
use ped92::{Commitment, CSMultiParams};
use std::fmt::LowerHex;
use serde::{Serialize, Deserialize, Serializer, Deserializer};
use util;
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct PublicParams<E: Engine> {
pub g1: E::G1,
pub g2: E::G2,
}
#[derive(Clone, Serialize, Deserialize)]
impl<E: Engine> PartialEq for PublicParams<E> {
fn eq(&self, other: &PublicParams<E>) -> bool {
self.g1 == other.g1 && self.g2 == other.g2
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct SecretKey<E: Engine> {
pub x: E::Fr,
pub y: Vec<E::Fr>,
@ -36,8 +45,14 @@ impl<E: Engine> fmt::Display for SecretKey<E> {
}
}
impl<E: Engine> PartialEq for SecretKey<E> {
fn eq(&self, other: &SecretKey<E>) -> bool {
self.x == other.x && util::is_vec_fr_equal::<E>(&self.y, &other.y)
}
}
#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct PublicKey<E: Engine> {
pub X: E::G2,
pub Y: Vec<E::G2>,
@ -57,8 +72,14 @@ impl<E: Engine> fmt::Display for PublicKey<E> {
}
}
//#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone)]
impl<E: Engine> PartialEq for PublicKey<E> {
fn eq(&self, other: &PublicKey<E>) -> bool {
self.X == other.X && util::is_vec_g2_equal::<E>(&self.Y, &other.Y)
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct BlindPublicKey<E: Engine> {
pub X1: E::G1,
pub X2: E::G2,
@ -83,8 +104,15 @@ impl<E: Engine> fmt::Display for BlindPublicKey<E> {
}
}
impl<E: Engine> PartialEq for BlindPublicKey<E> {
fn eq(&self, other: &BlindPublicKey<E>) -> bool {
self.X1 == other.X1 && self.X2 == other.X2 &&
util::is_vec_g1_equal::<E>(&self.Y1, &other.Y1) &&
util::is_vec_g2_equal::<E>(&self.Y2, &other.Y2)
}
}
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Signature<E: Engine> {
pub h: E::G1,
pub H: E::G1,
@ -96,12 +124,16 @@ impl<E: Engine> PartialEq for Signature<E> {
}
}
// #[serde(serialize_with = "secret_key_serialize_struct", deserialize_with = "")]
#[derive(Clone)]
pub struct KeyPair<E: Engine> {
pub secret: SecretKey<E>,
pub public: PublicKey<E>,
}
#[derive(Clone)]
pub struct BlindKeyPair<E: Engine> {
pub secret: SecretKey<E>,
@ -341,6 +373,18 @@ impl<E: Engine> KeyPair<E> {
}
}
//impl Serialize for KeyPair {
//
// fn serialize<S: Serializer, E: Engine>(&self, serializer: &mut S) -> Result<(), S::Error>
// where
// {
//// let mut state = serializer.serialize_struct("KeyPair", 2)?;
//// state.serialize_field("public", &self.public)?;
//// state.serialize_field("secret", &self.secret)?;
// Ok(serializer.serialize_struct(&self.public))
// }
//}
///
/// BlindingKeyPair - implements the blinding signature scheme in PS - Section 3.1.1
///
@ -364,6 +408,23 @@ impl<E: Engine> BlindKeyPair<E> {
PublicKey::from_secret(mpk, &self.secret)
}
// pub fn export_pubkey(&self) -> Vec<u8> {
// return serde_json::to_vec(&self.public).unwrap();
// }
//
// pub fn export_seckey(&self) -> Vec<u8> {
// return serde_json::to_vec(&self.secret).unwrap();
// }
//
// pub fn import_pubkey(&mut self, bytes: &Vec<u8>) {
// // TODO: validate the public key
// self.public = serde_json::from_slice(&bytes).unwrap();
// }
//
// pub fn import_seckey(&mut self, bytes: &Vec<u8>) {
// self.secret = serde_json::from_slice(&bytes).unwrap();
// }
/// sign a vector of messages
pub fn sign<R: Rng>(&self, csprng: &mut R, message: &Vec<E::Fr>) -> Signature<E> {
self.secret.sign(csprng, message)
@ -473,7 +534,7 @@ mod tests {
use super::*;
use ff::Rand;
use pairing::bls12_381::{Bls12, Fr};
use pairing::bls12_381::{Bls12, Fr, G1, G2};
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use ped92::CSMultiParams;
@ -621,5 +682,68 @@ mod tests {
assert_eq!(keypair.public.verify_proof(&mpk, proof_state.blindSig, proof, challenge), true);
}
#[test]
fn test_cl_basic_serialize() {
let mut rng = &mut rand::thread_rng();
let l = 5;
let mpk = setup(&mut rng);
let keypair = KeyPair::<Bls12>::generate(&mut rng, &mpk, l);
let blindkeypair = BlindKeyPair::<Bls12>::generate(&mut rng, &mpk, l);
let serialized = serde_json::to_vec(&mpk).unwrap();
//println!("serialized = {:?}", serialized.len());
let mpk_des: PublicParams<Bls12> = serde_json::from_slice(&serialized).unwrap();
//println!("{}", mpk_des);
//println!("SK => {}", &keypair.secret);
let sk_serialized = serde_json::to_vec(&keypair.secret).unwrap();
//println!("sk_serialized = {:?}", sk_serialized.len());
let sk_des: SecretKey<Bls12> = serde_json::from_slice(&sk_serialized).unwrap();
//println!("{}", sk_des);
assert_eq!(sk_des, keypair.secret);
//println!("PK => {}", &keypair.public);
let pk_serialized = serde_json::to_vec(&keypair.public).unwrap();
//println!("pk_serialized = {:?}", pk_serialized.len());
let pk_des: PublicKey<Bls12> = serde_json::from_slice(&pk_serialized).unwrap();
//assert_eq!(pk_des, keypair.public);
//println!("{}", &blindkeypair.public);
let bpk_ser = serde_json::to_vec(&blindkeypair.public).unwrap();
//println!("blind pk_ser = {:?}", bpk_ser.len());
let bpk_des: BlindPublicKey<Bls12> = serde_json::from_slice(&bpk_ser).unwrap();
assert_eq!(bpk_des, blindkeypair.public);
let unblind_pk = blindkeypair.get_public_key(&mpk);
//println!("{}", &unblind_pk);
let upk_serialized = serde_json::to_vec(&unblind_pk).unwrap();
//println!("upk_serialized = {:?}", upk_serialized.len());
let upk_des: PublicKey<Bls12> = serde_json::from_slice(&upk_serialized).unwrap();
assert_eq!(upk_des, unblind_pk);
assert_ne!(upk_des, keypair.public);
}
// #[test]
// fn test_cl_high_level() {
// let mut rng = &mut rand::thread_rng();
//
// let l = 3;
// let mpk = setup(&mut rng);
// let keypair = KeyPair::<Bls12>::generate(&mut rng, &mpk, l);
// let blindkeypair = BlindKeyPair::<Bls12>::generate(&mut rng, &mpk, l);
//
// // focusing on high-level structures
// let keypair_serialized = serde_json::to_string(&keypair).unwrap();
// print("Keypair: {}", keypair_serialized);
//
// }
}

View File

@ -205,73 +205,6 @@ pub mod bidirectional {
use util::RevokedMessage;
// #[derive(Clone, Serialize, Deserialize)]
// pub struct ChannelToken {
// w_com: commit_scheme::Commitment,
// pk: cl::PublicKey,
// csp: commit_scheme::CSParams,
// third_party_pay: bool
// }
//
// // proof of wallet signature, blind signature on wallet and common params for NIZK
// #[derive(Clone, Serialize, Deserialize)]
// pub struct CustomerWalletProof {
// proof_cv: clproto::ProofCV, // proof of knowledge of committed values
// proof_vs: clproto::ProofVS, // proof of knowledge of valid signature
//
// #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")]
// bal_com: G2, // old balance commitment
// blind_sig: cl::Signature, // a blind signature
// common_params: clproto::CommonParams, // common params for NIZK
// }
//
// #[derive(Clone, Serialize, Deserialize)]
// pub struct CustomerWallet {
// sk: cl::SecretKey, // the secret key for the signature scheme (Is it possible to make this a generic field?)
// #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")]
// cid: Fr, // channel Id
// wpk: secp256k1::PublicKey, // signature verification key
// wsk: secp256k1::SecretKey, // signature signing key
// #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")]
// h_wpk: Fr,
// #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")]
// r: Fr, // random coins for commitment scheme
// pub balance: i32, // the balance for the user
// merchant_balance: i32,
// signature: Option<cl::Signature>,
// // proof of signature on wallet contents in zero-knowledge
// proof: Option<CustomerWalletProof>,
// refund_token: Option<cl::Signature>
// }
//
// #[derive(Clone, Serialize, Deserialize)]
// pub struct MerchSecretKey {
// sk: cl::SecretKey, // merchant signing key
// pub balance: i32
// }
//
// #[derive(Clone, Serialize, Deserialize)]
// pub struct InitCustomerData {
// pub channel_token: ChannelToken,
// pub csk: CustomerWallet,
// #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_two_vec")]
// pub bases: Vec<G2>,
// }
//
// #[derive(Clone, Serialize, Deserialize)]
// pub struct InitMerchantData {
// pub channel_token: cl::PublicKey,
// pub csk: MerchSecretKey,
// #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable_vec", deserialize_with = "serialization_wrappers::deserialize_g_two_vec")]
// pub bases: Vec<G2>
// }
//
// // part of channel state
// #[derive(Clone)]
// pub struct PubKeyMap {
// wpk: secp256k1::PublicKey,
// revoke_token: Option<secp256k1::Signature>
// }
//
#[derive(Clone)]
pub struct ChannelclosureC<E: Engine> {
pub message: wallet::Wallet<E>,
@ -284,7 +217,6 @@ pub mod bidirectional {
pub signature: cl::Signature<E>
}
// #[derive(Clone, Serialize, Deserialize)]
// pub struct BalanceProof {
// third_party: bool,
@ -296,19 +228,6 @@ pub mod bidirectional {
// vcom: Option<commit_scheme::Commitment>,
// proof_vcom: Option<clproto::ProofCV>,
// proof_vrange: Option<ProofVB>
// }
//
// #[derive(Clone, Serialize, Deserialize)]
// pub struct PaymentProof {
// proof2a: clproto::ProofCV, // PoK of committed values in new wallet
// //proof2b: clproto::ProofCV, // PoK of committed values in old wallet (minus wpk)
// proof2c: clproto::ProofVS, // PoK of old wallet signature (that includes wpk)
// proof3: ProofVB, // range proof that balance - balance_inc is between (0, val_max)
// #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")]
// old_com_base: G2,
// wpk: secp256k1::PublicKey, // verification key for old wallet
// wallet_sig: cl::Signature, // blinded signature for old wallet
// pub bal_proof: BalanceProof
// }
#[derive(Clone)]
@ -513,7 +432,7 @@ pub mod bidirectional {
// for customer => on input a wallet w, it outputs a customer channel closure message
///
/// customer_refund - takes as input the public params, channel state, merchant's verification
/// customer_refund - takes as input the channel state, merchant's verification
/// key, and customer wallet. Generates a channel closure message for customer.
///
pub fn customer_refund<E: Engine>(channel_state: &ChannelState<E>, cust_wallet: &CustomerWallet<E>) -> bool { // ChannelclosureC
@ -604,9 +523,8 @@ pub mod bidirectional {
// extern crate libc;
//
// use bidirectional;
// use clsigs;
// use commit_scheme;
// use clproto;
// use ff::Rand;
// use pairing::bls12_381::{Bls12};
//
// use serde::{Serialize, Deserialize};
//
@ -615,8 +533,54 @@ pub mod bidirectional {
// use std::str;
// use std::mem;
//
// use bn::Fr;
// use serialization_wrappers;
//
// fn deserialize_object<'a, T>(serialized: *mut c_char) -> T
// where
// T: Deserialize<'a>,
// { // TODO make this a result with nice error handling
// let bytes = unsafe { CStr::from_ptr(serialized).to_bytes() };
// let string: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8
// serde_json::from_str(&string).unwrap()
// }
//
// fn deserialize_optional_object<'a, T>(serialized: *mut c_char) -> Option<T>
// where
// T: Deserialize<'a>,
// { // TODO make this a result with nice error handling
// let bytes = unsafe { CStr::from_ptr(serialized).to_bytes() };
// let string: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8
// Some(serde_json::from_str(&string).unwrap())
// }
//
//
//
// #[no_mangle]
// pub extern fn ffishim_free_string(pointer: *mut c_char) {
// unsafe{
// if pointer.is_null() { return }
// CString::from_raw(pointer)
// };
// }
//
// #[no_mangle]
// pub extern fn ffishim_bidirectional_channelstate_new(channel_name: *const c_char, third_party_support: u32) -> *mut c_char {
// let bytes = unsafe { CStr::from_ptr(channel_name).to_bytes() };
// let name: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8
//
// let mut tps = false;
// if third_party_support > 1 {
// tps = true;
// }
// let channel_state = bidirectional::ChannelState::<Bls12>::new(name.to_string(), tps);
// let ser = ["{\'state\':\'", serde_json::to_string(&channel_state).unwrap().as_str(), "\'}"].concat();
// let cser = CString::new(ser).unwrap();
// cser.into_raw()
// }
//
//}
// use serialization_wrappers;
//
// fn deserialize_object<'a, T>(serialized: *mut c_char) -> T
@ -1117,10 +1081,10 @@ mod tests {
use ff::Rand;
use pairing::bls12_381::{Bls12};
// fn setup_new_channel_helper(pp: &bidirectional::PublicParams, channel: &mut bidirectional::ChannelState,
// fn setup_new_channel_helper(channel: &mut bidirectional::ChannelState,
// init_cust_bal: i32, init_merch_bal: i32)
// -> (cl::KeyPairD, bidirectional::InitMerchantData,
// cl::KeyPairD, bidirectional::InitCustomerData) {
// -> (bidirectional::MerchantWallet,
// bidirectional::CustomerWallet) {
//
// let b0_cust = init_cust_bal;
// let b0_merch = init_merch_bal;

View File

@ -11,6 +11,7 @@ use util::hash_g2_to_fr;
use commit_scheme::commit;
use wallet::Wallet;
use ccs08::{RPPublicParams, RangeProof};
use serde::{Serialize, Deserialize};
#[derive(Clone)]
pub struct Proof<E: Engine> {

View File

@ -3,6 +3,8 @@ use rand::{thread_rng, Rng};
use pairing::{Engine, CurveProjective};
use ff::{Rand, Field};
use std::fmt;
use util::is_vec_g1_equal;
use serde::{Serialize, Deserialize};
#[derive(Clone)]
pub struct CSParams<E: Engine> {
@ -15,6 +17,11 @@ pub struct Commitment<E: Engine> {
pub c: E::G1,
}
impl<E: Engine> PartialEq for Commitment<E> {
fn eq(&self, other: &Commitment<E>) -> bool {
self.c == other.c
}
}
#[derive(Clone)]
@ -22,6 +29,13 @@ pub struct CSMultiParams<E: Engine> {
pub pub_bases: Vec<E::G1>
}
impl<E: Engine> PartialEq for CSMultiParams<E> {
fn eq(&self, other: &CSMultiParams<E>) -> bool {
is_vec_g1_equal::<E>(&self.pub_bases, &other.pub_bases)
}
}
impl<E: Engine> fmt::Display for CSMultiParams<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

View File

@ -7,6 +7,28 @@ use ped92::CSMultiParams;
use secp256k1::{Signature, PublicKey};
use cl::Signature as clSignature;
pub fn is_vec_fr_equal<E: Engine>(a: &Vec<E::Fr>, b: &Vec<E::Fr>) -> bool {
(a.len() == b.len()) &&
a.iter()
.zip(b)
.all(|(a, b)| a == b)
}
pub fn is_vec_g1_equal<E: Engine>(a: &Vec<E::G1>, b: &Vec<E::G1>) -> bool {
(a.len() == b.len()) &&
a.iter()
.zip(b)
.all(|(a, b)| a == b)
}
pub fn is_vec_g2_equal<E: Engine>(a: &Vec<E::G2>, b: &Vec<E::G2>) -> bool {
(a.len() == b.len()) &&
a.iter()
.zip(b)
.all(|(a, b)| a == b)
}
pub fn hash_g1_to_fr<E: Engine>(x: &Vec<E::G1>) -> E::Fr {
let mut x_vec: Vec<u8> = Vec::new();
for i in x.iter() {