minor updates to channel establish routines for cust/merch

This commit is contained in:
J. Ayo Akinyele 2019-07-23 09:54:53 -04:00
parent e7160f0f68
commit 2848ced5d1
4 changed files with 69 additions and 28 deletions

View File

@ -14,12 +14,15 @@ use pairing::{Engine, CurveProjective};
use pairing::bls12_381::{Bls12};
use cl::{BlindKeyPair, KeyPair, Signature, PublicParams, setup};
use ped92::{CSParams, Commitment, CSMultiParams};
use util::{hash_pubkey_to_fr, convert_int_to_fr, CommitmentProof};
use util::{hash_pubkey_to_fr, convert_int_to_fr, hash_to_fr, CommitmentProof};
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;
use wallet::Wallet;
#[derive(Clone, Serialize, Deserialize)]
struct PubKeyMap {
@ -30,7 +33,7 @@ struct PubKeyMap {
//#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone)]
pub struct ChannelParams<E: Engine> {
pub cl_mpk: cl::PublicParams<E>,
pub pub_params: NIZKPublicParams<E>,
l: usize, // messages for commitment
range_proof_bits: usize,
extra_verify: bool // extra verification for certain points in the establish/pay protocol
@ -98,12 +101,12 @@ impl<E: Engine> ChannelState<E> {
/// setup - generate public parameters for bidirectional payment channels
///
pub fn setup<R: Rng>(&mut self, csprng: &mut R) {
let cl_mpk = cl::setup(csprng);
let pubParams = NIZKPublicParams::<E>::setup(csprng);
let l = 4;
let n = 32; // bitsize: 32-bit (0, 2^32-1)
let num_rand_values = 1;
let cp = ChannelParams { cl_mpk: cl_mpk, l: l, range_proof_bits: n, extra_verify: true };
let cp = ChannelParams { pub_params: pubParams, l: l, range_proof_bits: n, extra_verify: true };
self.cp = Some(cp);
}
@ -112,7 +115,7 @@ impl<E: Engine> ChannelState<E> {
///
pub fn keygen<R: Rng>(&mut self, csprng: &mut R, id: String) -> cl::BlindKeyPair<E> {
let cp = self.cp.as_ref();
let keypair = BlindKeyPair::<E>::generate(csprng, &cp.unwrap().cl_mpk, cp.unwrap().l);
let keypair = BlindKeyPair::<E>::generate(csprng, &cp.unwrap().pub_params.mpk, cp.unwrap().l);
println!("Generating keypair for '{}'", id);
// print the keypair as well
return keypair;
@ -143,7 +146,7 @@ pub struct CustomerWallet<E: Engine> {
pub wpk: secp256k1::PublicKey, // keypair bound to the wallet
wsk: secp256k1::SecretKey,
r: E::Fr, // randomness used to form the commitment
w_vec: Vec<E::Fr>, // vector of field elements that represent wallet
wallet: Wallet<E>, // vector of field elements that represent wallet
pub w_com: Commitment<E>, // commitment to the current state of the wallet
}
@ -168,9 +171,9 @@ impl<E: Engine> CustomerWallet<E> {
// randomness for commitment
let r = E::Fr::rand(csprng);
// initialize wallet vector
let wallet: Vec<E::Fr> = vec! {pk_h, wpk_h, cust_b0, merch_b0};
let wallet = Wallet { pkc: pk_h, wpk: wpk_h, bc: cust_bal, bm: merch_bal };
let w_com = channel_token.comParams.commit(&wallet, &r);
let w_com = channel_token.comParams.commit(&wallet.as_fr_vec(), &r);
channel_token.set_customer_pk(&pk_c);
@ -186,13 +189,35 @@ impl<E: Engine> CustomerWallet<E> {
wsk: wsk,
r: r,
w_com: w_com,
w_vec: wallet
wallet: wallet
}
}
// generate nizk proof of knowledge of commitment opening
pub fn generate_proof<R: Rng>(&mut self, csprng: &mut R, channel_token: &ChannelToken<E>) -> CommitmentProof<E> {
return CommitmentProof::<E>::new(csprng, &channel_token.comParams, &self.w_com.c, &self.w_vec, &self.r);
return CommitmentProof::<E>::new(csprng, &channel_token.comParams, &self.w_com.c, &self.wallet.as_fr_vec(), &self.r);
}
pub fn verify_tokens(&self, channel: &ChannelState<E>, close_token: &Signature<E>, pay_token: &Signature<E>) -> bool {
// unblind and verify signature
let cp = channel.cp.as_ref().unwrap();
let mpk = cp.pub_params.mpk.clone();
let wallet = self.wallet.as_fr_vec();
// add a prefix to the wallet for close-message
let close_wallet = self.wallet.with_msg(String::from("close"));
let is_pay_valid = cp.pub_params.keypair.verify(&mpk, &wallet, &self.r, &pay_token);
// TODO: will need to support an extra base to verify the close-msg wallet
//let is_close_valid = cp.pub_params.keypair.verify(&mpk, &close_wallet, &self.r, &close_token);
if is_pay_valid {
let unblind_pay_token = cp.pub_params.keypair.unblind(&self.r, &pay_token);
let pk = cp.pub_params.keypair.get_public_key(&mpk);
return pk.verify(&mpk, &wallet, &unblind_pay_token);
}
//let unblind_close_token = cp.pub_params.keypair.unblind(&self.r, &close_token);
panic!("Channel establish - Verification failed for pay token!") ;
}
}
@ -210,19 +235,17 @@ pub struct MerchantWallet<E: Engine> {
impl<E: Engine> MerchantWallet<E> {
pub fn new<R: Rng>(csprng: &mut R, channel: &mut ChannelState<E>, id: String) -> Self {
// generate keys here
let kp = channel.keygen(csprng, id);
let mut tx_kp = secp256k1::Secp256k1::new();
tx_kp.randomize(csprng);
let (wsk, wpk) = tx_kp.generate_keypair(csprng);
let cp = channel.cp.as_ref().unwrap(); // if not set, then panic!
let com_params = kp.generate_cs_multi_params(&cp.cl_mpk);
MerchantWallet {
keypair: kp,
keypair: cp.pub_params.keypair.clone(),
balance: 0,
pk: wpk,
sk: wsk,
comParams: com_params
comParams: cp.pub_params.comParams.clone()
}
}
@ -236,13 +259,17 @@ impl<E: Engine> MerchantWallet<E> {
}
}
pub fn verify_proof<R: Rng>(&self, csprng: &mut R, channel: &ChannelState<E>, com: &Commitment<E>, com_proof: &CommitmentProof<E>) -> Signature<E> {
pub fn verify_proof<R: Rng>(&self, csprng: &mut R, channel: &ChannelState<E>, com: &Commitment<E>, com_proof: &CommitmentProof<E>) -> (Signature<E>, Signature<E>) {
let is_valid = util::verify(&self.comParams, &com.c, &com_proof);
let cp = channel.cp.as_ref().unwrap();
if is_valid {
println!("Commitment PoK is valid!");
let pay_token = self.keypair.sign_blind(csprng, &cp.cl_mpk, com.clone());
return pay_token;
let x = hash_to_fr::<E>(String::from("close").into_bytes() );
let close_com = self.comParams.extend_commit(com, &x);
let close_token = self.keypair.sign_blind(csprng, &cp.pub_params.mpk, close_com);
let pay_token = self.keypair.sign_blind(csprng, &cp.pub_params.mpk, com.clone());
return (close_token, pay_token);
}
panic!("Failed to verify PoK of commitment opening");
}
@ -318,7 +345,10 @@ mod tests {
let cust_com_proof = cust_wallet.generate_proof(rng, &mut channel_token);
// should return a blind signature or close token
let pay_token = merch_wallet.verify_proof(rng, &channel, &cust_wallet.w_com, &cust_com_proof);
let (close_token, pay_token) = merch_wallet.verify_proof(rng, &channel, &cust_wallet.w_com, &cust_com_proof);
// unblind tokens and verify signatures
assert!(cust_wallet.verify_tokens(&channel, &close_token, &pay_token));
println!("Done!");
}

View File

@ -60,9 +60,7 @@ use ff::{Rand, Field};
use serde::{Serialize, Deserialize};
pub mod prf;
pub mod sym;
pub mod ote;
pub mod cl;
pub mod clsigs;
pub mod ccs08;
@ -2043,13 +2041,6 @@ mod benches {
mod tests {
use super::*;
#[test]
#[ignore]
fn unidirectional_payment_basics_work() {
// TODO: finish me
assert!(true);
}
fn setup_new_channel_helper(pp: &bidirectional::PublicParams, channel: &mut bidirectional::ChannelState,
init_cust_bal: i32, init_merch_bal: i32)
-> (clsigs::KeyPairD, bidirectional::InitMerchantData,

View File

@ -16,7 +16,7 @@ pub struct Commitment<E: Engine> {
#[derive(Clone)]
pub struct CSMultiParams<E: Engine> {
pub pub_bases: Vec<E::G1>,
pub pub_bases: Vec<E::G1>
}
//impl<E: Engine> fmt::Display for CSParams<E> {
@ -111,6 +111,8 @@ impl<E: Engine> CSMultiParams<E> {
for i in 0..len + 1 {
p.push(E::G1::rand(rng));
}
// extra base used when extending a commitment
// p.push(E::G1::rand(rng));
CSMultiParams { pub_bases: p }
}
@ -126,6 +128,16 @@ impl<E: Engine> CSMultiParams<E> {
Commitment { c }
}
pub fn extend_commit(&self, com: &Commitment<E>, x: &E::Fr) -> Commitment<E> {
// c = com * gn+1 ^ x
let len = self.pub_bases.len();
let mut c = self.pub_bases[len-1].clone();
c.mul_assign(x.clone());
c.add_assign(&com.c);
return Commitment { c };
}
pub fn decommit(&self, cm: &Commitment<E>, x: &Vec<E::Fr>, r: &E::Fr) -> bool {
let l = x.len();
// pub_base[0] => h, x[0] => r

View File

@ -3,6 +3,7 @@ extern crate pairing;
use super::*;
use pairing::{Engine, CurveProjective};
use ff::PrimeField;
use util::hash_to_fr;
#[derive(Clone)]
pub struct Wallet<E: Engine> {
@ -16,4 +17,11 @@ impl<E: Engine> Wallet<E> {
pub fn as_fr_vec(&self) -> Vec<E::Fr> {
vec!(self.pkc, self.wpk, E::Fr::from_str(&self.bc.to_string()).unwrap(), E::Fr::from_str(&self.bm.to_string()).unwrap())
}
pub fn with_msg(&self, msg: String) -> Vec<E::Fr> {
let m = hash_to_fr::<E>(msg.into_bytes() );
let mut new_vec = self.as_fr_vec();
new_vec.push(m);
return new_vec;
}
}