adding payment api to customer wallet
This commit is contained in:
parent
783dcea35b
commit
1b1ba22699
|
@ -243,9 +243,6 @@ To contribute code improvements, please checkout the repository, make your chang
|
|||
|
||||
Here are some TODOs (not in any particular order):
|
||||
|
||||
* Serialization support for libbolt structures such as `CustomerWallet`, `PaymentProof`, and so on.
|
||||
* Support for other curves (e.g., pairing library from Zcash)
|
||||
* Finish unidirectional channel construction
|
||||
* Fix warnings
|
||||
* Add more unit tests for other dispute resolution scenarios and pay protocol (to ensure appopriate aborts), third-party test cases, etc.
|
||||
|
||||
|
|
114
src/channels.rs
114
src/channels.rs
|
@ -21,7 +21,7 @@ use std::fmt::Display;
|
|||
use serde::{Serialize, Deserialize};
|
||||
use serialization_wrappers::WalletCommitmentAndParamsWrapper;
|
||||
use std::ptr::hash;
|
||||
use nizk::NIZKPublicParams;
|
||||
use nizk::{NIZKPublicParams, Proof};
|
||||
use wallet::Wallet;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
|
@ -100,7 +100,7 @@ impl<E: Engine> ChannelState<E> {
|
|||
/// setup - generate public parameters for bidirectional payment channels
|
||||
///
|
||||
pub fn setup<R: Rng>(&mut self, csprng: &mut R) {
|
||||
let l = 5;
|
||||
let l = 4;
|
||||
let pubParams = NIZKPublicParams::<E>::setup(csprng, l);
|
||||
let num_rand_values = 1;
|
||||
|
||||
|
@ -146,6 +146,9 @@ pub struct CustomerWallet<E: Engine> {
|
|||
r: E::Fr, // randomness used to form the commitment
|
||||
wallet: Wallet<E>, // vector of field elements that represent wallet
|
||||
pub w_com: Commitment<E>, // commitment to the current state of the wallet
|
||||
index: i32,
|
||||
close_tokens: HashMap<i32, Signature<E>>,
|
||||
pay_tokens: HashMap<i32, Signature<E>>
|
||||
}
|
||||
|
||||
impl<E: Engine> CustomerWallet<E> {
|
||||
|
@ -177,6 +180,9 @@ impl<E: Engine> CustomerWallet<E> {
|
|||
|
||||
assert!(channel_token.is_init());
|
||||
|
||||
let mut ct_db= HashMap::new();
|
||||
let mut pt_db= HashMap::new();
|
||||
|
||||
println!("Customer wallet formed -> now returning the structure to the caller.");
|
||||
return CustomerWallet {
|
||||
pk_c: pk_c,
|
||||
|
@ -187,7 +193,10 @@ impl<E: Engine> CustomerWallet<E> {
|
|||
wsk: wsk,
|
||||
r: r,
|
||||
w_com: w_com,
|
||||
wallet: wallet
|
||||
wallet: wallet,
|
||||
index: 1,
|
||||
close_tokens: ct_db,
|
||||
pay_tokens: pt_db
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,9 +205,9 @@ impl<E: Engine> CustomerWallet<E> {
|
|||
return CommitmentProof::<E>::new(csprng, &channel_token.comParams, &self.w_com.c, &self.wallet.as_fr_vec(), &self.r);
|
||||
}
|
||||
|
||||
pub fn verify_close_token(&self, channel: &ChannelState<E>, close_token: &Signature<E>) -> bool {
|
||||
pub fn verify_close_token(&mut self, channel: &ChannelState<E>, close_token: &Signature<E>) -> bool {
|
||||
// add a prefix to the wallet for close-message
|
||||
let close_wallet = self.wallet.with_msg(String::from("close"));
|
||||
let close_wallet = self.wallet.with_close(String::from("close"));
|
||||
let cp = channel.cp.as_ref().unwrap();
|
||||
let mpk = cp.pub_params.mpk.clone();
|
||||
|
||||
|
@ -207,13 +216,18 @@ impl<E: Engine> CustomerWallet<E> {
|
|||
println!("verify_close_token - Blinded close token is valid!!");
|
||||
let pk = cp.pub_params.keypair.get_public_key(&mpk);
|
||||
let unblind_close_token = cp.pub_params.keypair.unblind(&self.r, &close_token);
|
||||
return pk.verify(&mpk, &close_wallet, &unblind_close_token);
|
||||
let is_valid = pk.verify(&mpk, &close_wallet, &unblind_close_token);
|
||||
if is_valid {
|
||||
// record the unblinded close token
|
||||
self.close_tokens.insert( self.index - 1, unblind_close_token);
|
||||
}
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
panic!("Channel establish - Verification failed for close token!");
|
||||
}
|
||||
|
||||
pub fn verify_pay_token(&self, channel: &ChannelState<E>, pay_token: &Signature<E>) -> bool {
|
||||
pub fn verify_pay_token(&mut self, channel: &ChannelState<E>, pay_token: &Signature<E>) -> bool {
|
||||
// unblind and verify signature
|
||||
let cp = channel.cp.as_ref().unwrap();
|
||||
let mpk = cp.pub_params.mpk.clone();
|
||||
|
@ -224,19 +238,80 @@ impl<E: Engine> CustomerWallet<E> {
|
|||
println!("verify_pay_token - Blinded pay token is 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 is_valid = pk.verify(&mpk, &wallet, &unblind_pay_token);
|
||||
if is_valid {
|
||||
self.pay_tokens.insert(self.index - 1, unblind_pay_token);
|
||||
}
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
panic!("verify_pay_token - Channel establish - Verification failed for pay token!") ;
|
||||
}
|
||||
|
||||
// for channel pay
|
||||
pub fn generate_payment<R: Rng>(&mut self, csprng: &mut R, channel: &ChannelState<E>, amount: i32) -> (Proof<E>, Commitment<E>, secp256k1::PublicKey, CustomerWallet<E>) {
|
||||
// 1 - chooose new wpk/wsk pair
|
||||
let mut kp = secp256k1::Secp256k1::new();
|
||||
kp.randomize(csprng);
|
||||
let (new_wsk, new_wpk) = kp.generate_keypair(csprng);
|
||||
let wpk_h = hash_pubkey_to_fr::<E>(&new_wpk);
|
||||
|
||||
// // for channel pay
|
||||
// pub fn update_wallet(&self, channel: &ChannelState<E>, pay_token: &Signature<E>, amount: i32) -> (CommitmentProof<E>, secp256k1::PublicKey) {
|
||||
//
|
||||
// }
|
||||
// 2 - form new wallet and commitment
|
||||
let new_cust_bal= self.cust_balance - amount;
|
||||
let new_merch_bal = self.merch_balance + amount;
|
||||
let new_r = E::Fr::rand(csprng);
|
||||
|
||||
let cp = channel.cp.as_ref().unwrap();
|
||||
let new_wallet = Wallet { pkc: self.wallet.pkc.clone(), wpk: wpk_h, bc: new_cust_bal, bm: new_merch_bal, close: None };
|
||||
let new_wcom = cp.pub_params.comParams.commit(&new_wallet.as_fr_vec(), &new_r);
|
||||
|
||||
// 3 - generate new blinded and randomized pay token
|
||||
let i = self.index - 1;
|
||||
let mut prev_pay_token = self.pay_tokens.get(&i).unwrap();
|
||||
|
||||
println!("generate_payment - before generating proof!");
|
||||
println!("OLD {}", &self.wallet);
|
||||
println!("NEW {}", &new_wallet);
|
||||
println!("{}", &prev_pay_token);
|
||||
|
||||
let pay_proof = cp.pub_params.prove(csprng, self.r.clone(), self.wallet.clone(), new_wallet.clone(),
|
||||
new_wcom.clone(), new_r, &prev_pay_token);
|
||||
println!("generate_payment - after generating proof!");
|
||||
|
||||
// TODO: update internal state accordingly
|
||||
let new_cw = CustomerWallet {
|
||||
pk_c: self.pk_c.clone(),
|
||||
sk_c: self.sk_c.clone(),
|
||||
cust_balance: new_cust_bal,
|
||||
merch_balance: new_merch_bal,
|
||||
wpk: new_wpk,
|
||||
wsk: new_wsk,
|
||||
r: new_r,
|
||||
w_com: new_wcom.clone(),
|
||||
wallet: new_wallet.clone(),
|
||||
index: self.index + 1, // increment index here
|
||||
close_tokens: self.close_tokens.clone(),
|
||||
pay_tokens: self.pay_tokens.clone()
|
||||
};
|
||||
|
||||
println!("returning results...");
|
||||
// return new_wcom,
|
||||
return (pay_proof, new_wcom, self.wpk, new_cw);
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> fmt::Display for CustomerWallet<E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut content = String::new();
|
||||
content = format!("pk = {}\n", &self.pk_c);
|
||||
content = format!("{}sk = {}\n", content, &self.sk_c);
|
||||
content = format!("{}cust-bal = {}\n", content, &self.cust_balance);
|
||||
content = format!("{}merch-bal = {}\n", content, &self.merch_balance);
|
||||
write!(f, "CustomerWallet : (\n{}\n)", &content)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Merchant wallet (NEW)
|
||||
///
|
||||
|
@ -320,12 +395,6 @@ impl<E: Engine> MerchantWallet<E> {
|
|||
//
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// customer obtains the close signature for wallet
|
||||
//fn verify_proof() -> cl::Signature<E> {
|
||||
//
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//trait MerchantEstablishChannel<E: Engine> {
|
||||
|
@ -380,10 +449,13 @@ mod tests {
|
|||
|
||||
println!("Done!");
|
||||
|
||||
// // pay protocol tests
|
||||
// pay protocol tests
|
||||
// let amount = 10;
|
||||
// let (new_cust_com_proof, wpk) = cust_wallet.update_wallet(&channel, amount);
|
||||
|
||||
// let (pay_proof, new_com, old_wpk, new_cw) = cust_wallet.generate_payment(rng, &channel, amount);
|
||||
//
|
||||
// println!("{}", new_com);
|
||||
// println!("wpk => {}", old_wpk);
|
||||
// println!("{}", new_cw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -249,6 +249,7 @@ impl<E: Engine> BlindPublicKey<E> {
|
|||
pub fn verify(&self, mpk: &PublicParams<E>, message: &Vec<E::Fr>, signature: &Signature<E>) -> bool {
|
||||
let mut L = E::G2::zero();
|
||||
let mut l = self.Y2.len();
|
||||
println!("verify - m.len = {}, l = {}", message.len(), l);
|
||||
assert!(message.len() <= l + 1);
|
||||
let mut last_elem = l;
|
||||
|
||||
|
|
54
src/ped92.rs
54
src/ped92.rs
|
@ -2,6 +2,7 @@
|
|||
use rand::{thread_rng, Rng};
|
||||
use pairing::{Engine, CurveProjective};
|
||||
use ff::Rand;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CSParams<E: Engine> {
|
||||
|
@ -14,45 +15,32 @@ pub struct Commitment<E: Engine> {
|
|||
pub c: E::G1,
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CSMultiParams<E: Engine> {
|
||||
pub pub_bases: Vec<E::G1>
|
||||
}
|
||||
|
||||
//impl<E: Engine> fmt::Display for CSParams<E> {
|
||||
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// let g_vec: Vec<u8> = encode(&self.g, Infinite).unwrap();
|
||||
// let h_vec: Vec<u8> = 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, "CSP : (g=0x{}, h=0x{})", g_s, h_s)
|
||||
// }
|
||||
//}
|
||||
impl<E: Engine> fmt::Display for CSMultiParams<E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
||||
//impl<E: Engine> fmt::Display for Commitment<E> {
|
||||
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// let c_vec: Vec<u8> = 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<u8> = 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)
|
||||
// }
|
||||
//}
|
||||
let mut y_str = String::new();
|
||||
let mut i = 0;
|
||||
for y in self.pub_bases.iter() {
|
||||
y_str = format!("{}\n{} => {}", y_str, i, y);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
write!(f, "CSMultiParams : (\n{}\n)", y_str)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> fmt::Display for Commitment<E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Commitment : (c={})", &self.c)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> CSParams<E> {
|
||||
/*
|
||||
|
|
|
@ -4,6 +4,7 @@ use super::*;
|
|||
use pairing::{Engine, CurveProjective};
|
||||
use ff::PrimeField;
|
||||
use util::hash_to_fr;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Wallet<E: Engine> {
|
||||
|
@ -23,10 +24,21 @@ impl<E: Engine> Wallet<E> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn with_msg(&self, msg: String) -> Vec<E::Fr> {
|
||||
pub fn with_close(&mut 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;
|
||||
self.close = Some(m.clone());
|
||||
return self.as_fr_vec();
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Engine> fmt::Display for Wallet<E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.close.is_some() {
|
||||
let close_str = self.close.unwrap();
|
||||
write!(f, "Wallet : (\npkc={}\nwpk={}\nbc={}\nbm={}\nclose={}\n)", &self.pkc, &self.wpk, &self.bc, &self.bm, close_str)
|
||||
} else {
|
||||
write!(f, "Wallet : (\npkc={}\nwpk={}\nbc={}\nbm={}\nclose=None\n)", &self.pkc, &self.wpk, &self.bc, &self.bm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue