diff --git a/src/ccs08.rs b/src/ccs08.rs index 69d33a8..2b822fd 100644 --- a/src/ccs08.rs +++ b/src/ccs08.rs @@ -22,7 +22,9 @@ use util::fmt_bytes_to_int; paramsUL contains elements generated by the verifier, which are necessary for the prover. This must be computed in a trusted setup. */ -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] +#[serde(bound(serialize = "::Fr: serde::Serialize, ::G1: serde::Serialize, ::G2: serde::Serialize"))] +#[serde(bound(deserialize = "::Fr: serde::Deserialize<'de>, ::G1: serde::Deserialize<'de>, ::G2: serde::Deserialize<'de>"))] struct ParamsUL { pub mpk: PublicParams, pub signatures: HashMap>, @@ -82,7 +84,9 @@ pub struct RangeProof { params contains elements generated by the verifier, which are necessary for the prover. This must be computed in a trusted setup. */ -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] +#[serde(bound(serialize = "::Fr: serde::Serialize, ::G1: serde::Serialize, ::G2: serde::Serialize"))] +#[serde(bound(deserialize = "::Fr: serde::Deserialize<'de>, ::G1: serde::Deserialize<'de>, ::G2: serde::Deserialize<'de>"))] pub struct RPPublicParams { p: ParamsUL, a: i32, diff --git a/src/channels.rs b/src/channels.rs index e051631..78db54a 100644 --- a/src/channels.rs +++ b/src/channels.rs @@ -31,7 +31,15 @@ pub struct PubKeyMap { pub revoke_token: Option } -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] +#[serde(bound(serialize = "::Fr: serde::Serialize, \ +::G1: serde::Serialize, \ +::G2: serde::Serialize" +))] +#[serde(bound(deserialize = "::Fr: serde::Deserialize<'de>, \ +::G1: serde::Deserialize<'de>, \ +::G2: serde::Deserialize<'de>" +))] pub struct ChannelParams { pub pub_params: NIZKPublicParams, l: usize, // messages for commitment @@ -39,7 +47,15 @@ pub struct ChannelParams { } -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] +#[serde(bound(serialize = "::Fr: serde::Serialize, \ +::G1: serde::Serialize, \ +::G2: serde::Serialize" +))] +#[serde(bound(deserialize = "::Fr: serde::Deserialize<'de>, \ +::G1: serde::Deserialize<'de>, \ +::G2: serde::Deserialize<'de>" +))] pub struct ChannelState { R: i32, tx_fee: i32, @@ -50,7 +66,15 @@ pub struct ChannelState { pub third_party: bool } -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] +#[serde(bound(serialize = "::Fr: serde::Serialize, \ +::G1: serde::Serialize, \ +::G2: serde::Serialize" +))] +#[serde(bound(deserialize = "::Fr: serde::Deserialize<'de>, \ +::G1: serde::Deserialize<'de>, \ +::G2: serde::Deserialize<'de>" +))] pub struct ChannelToken { pub pk_c: Option, // pk_c pub blind_pk_m: cl::BlindPublicKey, // PK_m diff --git a/src/cl.rs b/src/cl.rs index c9fa32e..346682d 100644 --- a/src/cl.rs +++ b/src/cl.rs @@ -9,8 +9,11 @@ use ff::{PrimeField, ScalarEngine}; use rand::Rng; use ped92::{Commitment, CSMultiParams}; use std::fmt::LowerHex; -use serde::{Serialize, Deserialize, Serializer, Deserializer}; +use serde::{Serialize, Deserialize}; +use serde::ser::{Serializer, SerializeStruct, SerializeSeq}; use util; +use ccs08; +use bincode::serde::serialize; #[derive(Clone, Serialize, Deserialize, Debug)] pub struct PublicParams { @@ -124,17 +127,38 @@ impl PartialEq for Signature { } } -// #[serde(serialize_with = "secret_key_serialize_struct", deserialize_with = "")] - #[derive(Clone)] pub struct KeyPair { pub secret: SecretKey, pub public: PublicKey, } +//#[derive(Clone, Serialize, Deserialize)] +//#[serde(bound(serialize = "::Fr: serde::Serialize, \ +//::G1: serde::Serialize, \ +//::G2: serde::Serialize" +//))] +//#[serde(bound(deserialize = "::Fr: serde::Deserialize<'de>, \ +//::G1: serde::Deserialize<'de>, \ +//::G2: serde::Deserialize<'de>" +//))] +//pub struct TestStruct { +// pub mpk: PublicParams, +// pub keypair: BlindKeyPair, +// pub comParams: CSMultiParams, +// pub rpParamsBC: ccs08::RPPublicParams, +// pub rpParamsBM: ccs08::RPPublicParams +//} - -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] +#[serde(bound(serialize = "::Fr: serde::Serialize, \ +::G1: serde::Serialize, \ +::G2: serde::Serialize" +))] +#[serde(bound(deserialize = "::Fr: serde::Deserialize<'de>, \ +::G1: serde::Deserialize<'de>, \ +::G2: serde::Deserialize<'de>" +))] pub struct BlindKeyPair { pub secret: SecretKey, pub public: BlindPublicKey, @@ -150,7 +174,7 @@ pub struct ProofState { pub blindSig: Signature, } -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize, Debug)] pub struct SignatureProof { pub zx: E::Fr, pub zsig: Vec, @@ -373,18 +397,6 @@ impl KeyPair { } } -//impl Serialize for KeyPair { -// -// fn serialize(&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 /// @@ -408,23 +420,6 @@ impl BlindKeyPair { PublicKey::from_secret(mpk, &self.secret) } -// pub fn export_pubkey(&self) -> Vec { -// return serde_json::to_vec(&self.public).unwrap(); -// } -// -// pub fn export_seckey(&self) -> Vec { -// return serde_json::to_vec(&self.secret).unwrap(); -// } -// -// pub fn import_pubkey(&mut self, bytes: &Vec) { -// // TODO: validate the public key -// self.public = serde_json::from_slice(&bytes).unwrap(); -// } -// -// pub fn import_seckey(&mut self, bytes: &Vec) { -// self.secret = serde_json::from_slice(&bytes).unwrap(); -// } - /// sign a vector of messages pub fn sign(&self, csprng: &mut R, message: &Vec) -> Signature { self.secret.sign(csprng, message) @@ -730,20 +725,5 @@ mod tests { 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::::generate(&mut rng, &mpk, l); -// let blindkeypair = BlindKeyPair::::generate(&mut rng, &mpk, l); -// -// // focusing on high-level structures -// let keypair_serialized = serde_json::to_string(&keypair).unwrap(); -// print("Keypair: {}", keypair_serialized); -// -// } } diff --git a/src/lib.rs b/src/lib.rs index 6cf4b2c..0bd80d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -217,19 +217,6 @@ pub mod bidirectional { pub signature: cl::Signature } -// #[derive(Clone, Serialize, Deserialize)] -// pub struct BalanceProof { -// third_party: bool, -// balance_increment: i32, -// #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] -// w_com_pr_pr: G2, -// #[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_g_two")] -// old_bal_com: G2, -// vcom: Option, -// proof_vcom: Option, -// proof_vrange: Option -// } - #[derive(Clone)] pub struct Payment { proof: Proof, @@ -518,67 +505,95 @@ pub mod bidirectional { // } } -//#[no_mangle] -//pub mod ffishim { -// extern crate libc; -// -// use bidirectional; -// use ff::Rand; -// use pairing::bls12_381::{Bls12}; -// -// use serde::{Serialize, Deserialize}; -// -// use libc::{c_char}; -// use std::ffi::{CStr, CString}; -// use std::str; -// use std::mem; -// -// 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 -// 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 mod ffishim { + extern crate libc; + + use bidirectional; + use ff::Rand; + use pairing::bls12_381::{Bls12}; + + use serde::{Serialize, Deserialize}; + + use libc::{c_uchar, c_char}; // c_char + use std::ffi::{CStr, CString}; + use std::str; + use std::mem; + + 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 + 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_channel_setup(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 mut channel_state = bidirectional::ChannelState::::new(name.to_string(), tps); + let mut rng = &mut rand::thread_rng(); + + channel_state.setup(&mut rng); + let ser = ["{\'state\':\'", serde_json::to_string(&channel_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + // #[no_mangle] -// pub extern fn ffishim_free_string(pointer: *mut c_char) { -// unsafe{ -// if pointer.is_null() { return } -// CString::from_raw(pointer) -// }; -// } +// pub extern fn ffishim_bidirectional_channel_load(ser_channel_state: *mut c_char) -> *mut c_char { // -// #[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 des_channel_state: bidirectional::ChannelState = deserialize_object(ser_channel_state); // -// let mut tps = false; -// if third_party_support > 1 { -// tps = true; -// } -// let channel_state = bidirectional::ChannelState::::new(name.to_string(), tps); -// let ser = ["{\'state\':\'", serde_json::to_string(&channel_state).unwrap().as_str(), "\'}"].concat(); +// let keypair = bidirectional::keygen(&deserialized_pp); +// let ser = ["{\'state\':\'",serde_json::to_string(&keypair).unwrap().as_str(), "\'}"].concat(); // let cser = CString::new(ser).unwrap(); // cser.into_raw() // } + +// #[no_mangle] +// pub extern fn ffishim_bidirectional_init_merchant(serialized_pp: *mut c_char, balance_merchant: i32, serialized_merchant_keypair: *mut c_char) -> *mut c_char { +// // Deserialize the pp +// let deserialized_pp: bidirectional::PublicParams = deserialize_object(serialized_pp); // -//} +// // Deserialize the merchant keypair +// let deserialized_merchant_keypair: cl::KeyPairD = deserialize_object(serialized_merchant_keypair); +// +// let init_merchant_data = bidirectional::init_merchant(&deserialized_pp, balance_merchant, &deserialized_merchant_keypair); +// let ser = ["{\'merchant_data\':\'", serde_json::to_string(&init_merchant_data).unwrap().as_str(), "\'}"].concat(); +// let cser = CString::new(ser).unwrap(); +// cser.into_raw() +// } + +} // use serialization_wrappers; @@ -1081,34 +1096,27 @@ mod tests { use ff::Rand; use pairing::bls12_381::{Bls12}; -// fn setup_new_channel_helper(channel: &mut bidirectional::ChannelState, -// init_cust_bal: i32, init_merch_bal: i32) -// -> (bidirectional::MerchantWallet, -// bidirectional::CustomerWallet) { -// -// let b0_cust = init_cust_bal; -// let b0_merch = init_merch_bal; -// -// // generate long-lived keypair for merchant -- used to identify -// // merchant to all customers -// let merch_keys = bidirectional::keygen(&pp); -// -// // customer generates an ephemeral keypair for use on a single channel -// let cust_keys = bidirectional::keygen(&pp); -// -// // each party executes the init algorithm on the agreed initial challenge balance -// // in order to derive the channel tokens -// // initialize on the merchant side with balance: b0_merch -// let merch_data = bidirectional::init_merchant(&pp, b0_merch, &merch_keys); -// -// // retrieve commitment setup params (using merchant long lived pk params) -// let cm_csp = bidirectional::generate_commit_setup(&pp, &merch_keys.pk); -// // initialize on the customer side with balance: b0_cust -// let cust_data = bidirectional::init_customer(&pp, channel, -// b0_cust, b0_merch, -// &cm_csp, &cust_keys); -// return (merch_keys, merch_data, cust_keys, cust_data); -// } + fn setup_new_channel_helper(channel_state: &mut bidirectional::ChannelState, + init_cust_bal: i32, init_merch_bal: i32) + -> (bidirectional::ChannelToken, bidirectional::MerchantWallet, bidirectional::CustomerWallet) { + + let mut rng = &mut rand::thread_rng(); + let merch_name = "Bob"; + let cust_name = "Alice"; + + let b0_cust = init_cust_bal; + let b0_merch = init_merch_bal; + + // each party executes the init algorithm on the agreed initial challenge balance + // in order to derive the channel tokens + // initialize on the merchant side with balance: b0_merch + let (mut channel_token, merch_wallet) = bidirectional::init_merchant(rng, channel_state, merch_name); + + // initialize on the customer side with balance: b0_cust + let cust_wallet = bidirectional::init_customer(rng, channel_state, &mut channel_token, b0_cust, b0_merch, cust_name); + + return (channel_token, merch_wallet, cust_wallet); + } // fn setup_new_channel_existing_merchant_helper(pp: &bidirectional::PublicParams, channel: &mut bidirectional::ChannelState, // init_cust_bal: i32, init_merch_bal: i32, merch_keys: &cl::KeyPairD) @@ -1390,10 +1398,16 @@ mod tests { // } #[test] - #[ignore] fn serialization_tests() { - // TODO: finish me - assert!(true); + let mut channel_state = bidirectional::ChannelState::::new(String::from("Channel A -> B"), false); + let mut rng = &mut rand::thread_rng(); + channel_state.setup(&mut rng); + + let serialized = serde_json::to_string(&channel_state).unwrap(); + println!("new channel state len: {}", &serialized.len()); + + let chan_state: bidirectional::ChannelState = serde_json::from_str(&serialized).unwrap(); + } } diff --git a/src/nizk.rs b/src/nizk.rs index 93ada86..e6b8272 100644 --- a/src/nizk.rs +++ b/src/nizk.rs @@ -23,7 +23,15 @@ pub struct Proof { pub rpBM: RangeProof, } -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] +#[serde(bound(serialize = "::Fr: serde::Serialize, \ +::G1: serde::Serialize, \ +::G2: serde::Serialize" +))] +#[serde(bound(deserialize = "::Fr: serde::Deserialize<'de>, \ +::G1: serde::Deserialize<'de>, \ +::G2: serde::Deserialize<'de>" +))] pub struct NIZKPublicParams { pub mpk: PublicParams, pub keypair: BlindKeyPair, @@ -300,4 +308,24 @@ mod tests { let proof = pubParams.prove(rng, r, wallet1.clone(), wallet5, commitment2.clone(), rprime, &paymentToken); assert_eq!(pubParams.verify(proof, Fr::from_str(&epsilon.to_string()).unwrap(), &commitment2, wpk), false); } + + #[test] + fn test_nizk_serialization() { + let mut rng = &mut rand::thread_rng(); + + let l = 5; + let mpk = setup(&mut rng); + let blindkeypair = BlindKeyPair::::generate(&mut rng, &mpk, l); + let comParams = blindkeypair.generate_cs_multi_params(&mpk); + let rpParamsBC = ccs08::RPPublicParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone()); + let rpParamsBM = ccs08::RPPublicParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone()); + + let nizk_params = NIZKPublicParams { mpk: mpk, keypair: blindkeypair, comParams: comParams, rpParamsBC: rpParamsBC, rpParamsBM: rpParamsBM }; + + let is_serialized = serde_json::to_vec(&nizk_params).unwrap(); + println!("NIZK Struct len: {}", is_serialized.len()); + + // deserialize + } + } diff --git a/src/ped92.rs b/src/ped92.rs index 00833ba..ef8f468 100644 --- a/src/ped92.rs +++ b/src/ped92.rs @@ -24,7 +24,9 @@ impl PartialEq for Commitment { } -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] +#[serde(bound(serialize = "::G1: serde::Serialize"))] +#[serde(bound(deserialize = "::G1: serde::Deserialize<'de>"))] pub struct CSMultiParams { pub pub_bases: Vec }