wip ffishim and adding tests for libbolt

This commit is contained in:
J. Ayo Akinyele 2019-07-30 00:53:58 -04:00
parent be2dc562cd
commit 9cf6d734b4
6 changed files with 207 additions and 155 deletions

View File

@ -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 = "<E as ff::ScalarEngine>::Fr: serde::Serialize, <E as pairing::Engine>::G1: serde::Serialize, <E as pairing::Engine>::G2: serde::Serialize"))]
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, <E as pairing::Engine>::G1: serde::Deserialize<'de>, <E as pairing::Engine>::G2: serde::Deserialize<'de>"))]
struct ParamsUL<E: Engine> {
pub mpk: PublicParams<E>,
pub signatures: HashMap<String, Signature<E>>,
@ -82,7 +84,9 @@ pub struct RangeProof<E: Engine> {
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 = "<E as ff::ScalarEngine>::Fr: serde::Serialize, <E as pairing::Engine>::G1: serde::Serialize, <E as pairing::Engine>::G2: serde::Serialize"))]
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, <E as pairing::Engine>::G1: serde::Deserialize<'de>, <E as pairing::Engine>::G2: serde::Deserialize<'de>"))]
pub struct RPPublicParams<E: Engine> {
p: ParamsUL<E>,
a: i32,

View File

@ -31,7 +31,15 @@ pub struct PubKeyMap {
pub revoke_token: Option<secp256k1::Signature>
}
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, \
<E as pairing::Engine>::G1: serde::Serialize, \
<E as pairing::Engine>::G2: serde::Serialize"
))]
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, \
<E as pairing::Engine>::G1: serde::Deserialize<'de>, \
<E as pairing::Engine>::G2: serde::Deserialize<'de>"
))]
pub struct ChannelParams<E: Engine> {
pub pub_params: NIZKPublicParams<E>,
l: usize, // messages for commitment
@ -39,7 +47,15 @@ pub struct ChannelParams<E: Engine> {
}
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, \
<E as pairing::Engine>::G1: serde::Serialize, \
<E as pairing::Engine>::G2: serde::Serialize"
))]
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, \
<E as pairing::Engine>::G1: serde::Deserialize<'de>, \
<E as pairing::Engine>::G2: serde::Deserialize<'de>"
))]
pub struct ChannelState<E: Engine> {
R: i32,
tx_fee: i32,
@ -50,7 +66,15 @@ pub struct ChannelState<E: Engine> {
pub third_party: bool
}
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, \
<E as pairing::Engine>::G1: serde::Serialize, \
<E as pairing::Engine>::G2: serde::Serialize"
))]
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, \
<E as pairing::Engine>::G1: serde::Deserialize<'de>, \
<E as pairing::Engine>::G2: serde::Deserialize<'de>"
))]
pub struct ChannelToken<E: Engine> {
pub pk_c: Option<secp256k1::PublicKey>, // pk_c
pub blind_pk_m: cl::BlindPublicKey<E>, // PK_m

View File

@ -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<E: Engine> {
@ -124,17 +127,38 @@ 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, Serialize, Deserialize)]
//#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, \
//<E as pairing::Engine>::G1: serde::Serialize, \
//<E as pairing::Engine>::G2: serde::Serialize"
//))]
//#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, \
//<E as pairing::Engine>::G1: serde::Deserialize<'de>, \
//<E as pairing::Engine>::G2: serde::Deserialize<'de>"
//))]
//pub struct TestStruct<E: Engine> {
// pub mpk: PublicParams<E>,
// pub keypair: BlindKeyPair<E>,
// pub comParams: CSMultiParams<E>,
// pub rpParamsBC: ccs08::RPPublicParams<E>,
// pub rpParamsBM: ccs08::RPPublicParams<E>
//}
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, \
<E as pairing::Engine>::G1: serde::Serialize, \
<E as pairing::Engine>::G2: serde::Serialize"
))]
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, \
<E as pairing::Engine>::G1: serde::Deserialize<'de>, \
<E as pairing::Engine>::G2: serde::Deserialize<'de>"
))]
pub struct BlindKeyPair<E: Engine> {
pub secret: SecretKey<E>,
pub public: BlindPublicKey<E>,
@ -150,7 +174,7 @@ pub struct ProofState<E: Engine> {
pub blindSig: Signature<E>,
}
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct SignatureProof<E: Engine> {
pub zx: E::Fr,
pub zsig: Vec<E::Fr>,
@ -373,18 +397,6 @@ 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
///
@ -408,23 +420,6 @@ 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)
@ -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::<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

@ -217,19 +217,6 @@ pub mod bidirectional {
pub signature: cl::Signature<E>
}
// #[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<commit_scheme::Commitment>,
// proof_vcom: Option<clproto::ProofCV>,
// proof_vrange: Option<ProofVB>
// }
#[derive(Clone)]
pub struct Payment<E: Engine> {
proof: Proof<E>,
@ -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<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 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<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_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::<Bls12>::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<Bls12> = deserialize_object(ser_channel_state);
//
// 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 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<Bls12>,
init_cust_bal: i32, init_merch_bal: i32)
-> (bidirectional::ChannelToken<Bls12>, bidirectional::MerchantWallet<Bls12>, bidirectional::CustomerWallet<Bls12>) {
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::<Bls12>::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<Bls12> = serde_json::from_str(&serialized).unwrap();
}
}

View File

@ -23,7 +23,15 @@ pub struct Proof<E: Engine> {
pub rpBM: RangeProof<E>,
}
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, \
<E as pairing::Engine>::G1: serde::Serialize, \
<E as pairing::Engine>::G2: serde::Serialize"
))]
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, \
<E as pairing::Engine>::G1: serde::Deserialize<'de>, \
<E as pairing::Engine>::G2: serde::Deserialize<'de>"
))]
pub struct NIZKPublicParams<E: Engine> {
pub mpk: PublicParams<E>,
pub keypair: BlindKeyPair<E>,
@ -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::<Bls12>::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
}
}

View File

@ -24,7 +24,9 @@ impl<E: Engine> PartialEq for Commitment<E> {
}
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
#[serde(bound(serialize = "<E as pairing::Engine>::G1: serde::Serialize"))]
#[serde(bound(deserialize = "<E as pairing::Engine>::G1: serde::Deserialize<'de>"))]
pub struct CSMultiParams<E: Engine> {
pub pub_bases: Vec<E::G1>
}