Additional verification to establish prior to issuing close token

This commit is contained in:
J. Ayo Akinyele 2019-08-27 09:56:02 -04:00
parent 3c0f087ff6
commit c947a446ea
6 changed files with 51 additions and 46 deletions

View File

@ -69,7 +69,8 @@ fn main() {
println!(">> Time to generate proof for establish: {} ms", est_time);
// obtain close token for closing out channel
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &merch_state);
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof,
b0_customer, b0_merchant, &merch_state);
let close_token= match option {
Ok(n) => n.unwrap(),
Err(e) => panic!("Failed - bidirectional::establish_merchant_issue_close_token(): {}", e)

View File

@ -29,7 +29,7 @@ class Libbolt(object):
self.lib.ffishim_bidirectional_establish_customer_generate_proof.argtypes = (c_void_p, c_void_p)
self.lib.ffishim_bidirectional_establish_customer_generate_proof.restype = c_void_p
self.lib.ffishim_bidirectional_establish_merchant_issue_close_token.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p)
self.lib.ffishim_bidirectional_establish_merchant_issue_close_token.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p, c_void_p, c_void_p)
self.lib.ffishim_bidirectional_establish_merchant_issue_close_token.restype = c_void_p
self.lib.ffishim_bidirectional_establish_merchant_issue_pay_token.argtypes = (c_void_p, c_void_p, c_void_p)
@ -100,8 +100,8 @@ class Libbolt(object):
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['channel_token'], output_dictionary['cust_state'], output_dictionary['com'], output_dictionary['com_proof']
def bidirectional_establish_merchant_issue_close_token(self, channel_state, com, com_proof, merch_state):
output_string = self.lib.ffishim_bidirectional_establish_merchant_issue_close_token(channel_state.encode(), com.encode(), com_proof.encode(), merch_state.encode())
def bidirectional_establish_merchant_issue_close_token(self, channel_state, com, com_proof, init_cust, init_merch, merch_state):
output_string = self.lib.ffishim_bidirectional_establish_merchant_issue_close_token(channel_state.encode(), com.encode(), com_proof.encode(), init_cust, init_merch, merch_state.encode())
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
return output_dictionary['close_token']
@ -229,7 +229,7 @@ def run_unit_test():
(channel_token, cust_state, com, com_proof) = libbolt.bidirectional_establish_customer_generate_proof(channel_token, cust_state)
print("com: ", com)
close_token = libbolt.bidirectional_establish_merchant_issue_close_token(channel_state, com, com_proof, merch_state)
close_token = libbolt.bidirectional_establish_merchant_issue_close_token(channel_state, com, com_proof, b0_cust, b0_merch, merch_state)
print("close token: ", close_token)
(is_token_valid, channel_state, cust_state) = libbolt.bidirectional_establish_customer_verify_close_token(channel_state, cust_state, close_token)

View File

@ -415,22 +415,6 @@ impl<E: Engine> CustomerState<E> {
}
// pub name: String,
// pub pk_c: secp256k1::PublicKey,
// sk_c: secp256k1::SecretKey,
// pub cust_balance: i32, //
// pub merch_balance: i32,
// pub wpk: secp256k1::PublicKey, // keypair bound to the wallet
// wsk: secp256k1::SecretKey,
// old_kp: Option<WalletKeyPair>, // old wallet key pair
// t: 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> fmt::Display for CustomerState<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut content = String::new();
@ -445,7 +429,16 @@ impl<E: Engine> fmt::Display for CustomerState<E> {
content = format!("{}revoked: wpk = {}\nrevoked: wsk = {}\n", content, &old_kp.wpk, &old_kp.wsk);
}
content = format!("{}t = {}\n", content, &self.t);
content = format!("{}wallet = {}\n", content, &self.wallet);
content = format!("{}w_com = {}\n", content, &self.w_com);
let close_token = self.close_tokens.get(&self.index);
let pay_token = self.pay_tokens.get(&self.index);
if (!close_token.is_none()) {
content = format!("{}close_token = {}\n", content, &self.close_tokens.get(&self.index).unwrap());
}
if (!pay_token.is_none()) {
content = format!("{}pay_token = {}\n", content, &self.pay_tokens.get(&self.index).unwrap());
}
write!(f, "CustomerState : (\n{}\n)", &content)
}
}
@ -471,7 +464,7 @@ pub struct ChannelcloseM {
))]
pub struct MerchantState<E: Engine> {
keypair: cl::BlindKeyPair<E>,
pub balance: i32,
pub init_balance: i32,
pk: secp256k1::PublicKey, // pk_m
sk: secp256k1::SecretKey, // sk_m
comParams: CSMultiParams<E>,
@ -489,7 +482,7 @@ impl<E: Engine> MerchantState<E> {
MerchantState {
keypair: cp.pub_params.keypair.clone(),
balance: 0,
init_balance: 0,
pk: wpk,
sk: wsk,
comParams: cp.pub_params.comParams.clone(),
@ -514,7 +507,7 @@ impl<E: Engine> MerchantState<E> {
pub fn init_balance(&mut self, balance: i32) {
// set by the escrow/funding transactionf for the channel
self.balance = balance;
self.init_balance = balance;
}
pub fn issue_close_token<R: Rng>(&self, csprng: &mut R, cp: &ChannelParams<E>, com: &Commitment<E>, extend_close: bool) -> Signature<E> {
@ -539,11 +532,13 @@ impl<E: Engine> MerchantState<E> {
return self.keypair.sign_blind(csprng, &cp.pub_params.mpk, pay_com);
}
pub fn verify_proof<R: Rng>(&self, csprng: &mut R, channel: &ChannelState<E>, com: &Commitment<E>, com_proof: &CommitmentProof<E>) -> ResultBoltSig<(Signature<E>, Signature<E>)> {
let is_valid = nizk::verify_opening(&self.comParams, &com.c, &com_proof);
pub fn verify_proof<R: Rng>(&self, csprng: &mut R, channel: &ChannelState<E>, com: &Commitment<E>, com_proof: &CommitmentProof<E>, cust_balance: i32, merch_balance: i32) -> ResultBoltSig<(Signature<E>, Signature<E>)> {
if (merch_balance != self.init_balance) {
return Err(BoltError::new("verify_proof - initial balance of merchant inconsistent with specified balance"));
}
let is_valid = nizk::verify_opening(&self.comParams, &com.c, &com_proof, cust_balance, merch_balance);
let cp = channel.cp.as_ref().unwrap();
if is_valid {
// println!("Commitment PoK is valid!");
let close_token = self.issue_close_token(csprng, cp, com, true);
let pay_token = self.issue_pay_token(csprng, cp, com, false);
return Ok((close_token, pay_token));
@ -566,7 +561,7 @@ impl<E: Engine> MerchantState<E> {
let cp = channel.cp.as_ref().unwrap();
let pay_proof = proof.clone();
let prev_wpk = hash_pubkey_to_fr::<E>(&wpk);
let epsilon = util::convert_int_to_fr::<E>(amount); // E::Fr::from_str(&amount.to_string()).unwrap();
let epsilon = util::convert_int_to_fr::<E>(amount);
if cp.pub_params.verify(pay_proof, epsilon, com, prev_wpk) {
// 1 - proceed with generating close and pay token
@ -627,6 +622,7 @@ mod tests {
// in order to derive the channel tokens
// initialize on the merchant side with balance: b0_merch
let mut merch_state = MerchantState::<Bls12>::new(rng, &mut channel, String::from("Merchant B"));
merch_state.init_balance(b0_merch);
// initialize the merchant wallet with the balance
let mut channel_token = merch_state.init(rng, &mut channel);
@ -640,7 +636,7 @@ mod tests {
// first return the close token, then wait for escrow-tx confirmation
// then send the pay-token after confirmation
let (close_token, pay_token) = merch_state.verify_proof(rng, &channel, &cust_state.w_com, &cust_com_proof).unwrap();
let (close_token, pay_token) = merch_state.verify_proof(rng, &channel, &cust_state.w_com, &cust_com_proof, b0_cust, b0_merch).unwrap();
// unblind tokens and verify signatures
assert!(cust_state.verify_close_token(&channel, &close_token));

View File

@ -132,7 +132,8 @@ pub mod ffishim {
}
#[no_mangle]
pub extern fn ffishim_bidirectional_establish_merchant_issue_close_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_com_proof: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char {
pub extern fn ffishim_bidirectional_establish_merchant_issue_close_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_com_proof: *mut c_char,
init_cust_bal: i32, init_merch_bal: i32, ser_merch_state: *mut c_char) -> *mut c_char {
let rng = &mut rand::thread_rng();
// Deserialize the channel state
let channel_state: bidirectional::ChannelState<Bls12> = deserialize_object(ser_channel_state);
@ -146,7 +147,7 @@ pub mod ffishim {
// Deserialize the merchant wallet
let merch_state: bidirectional::MerchantState<Bls12> = deserialize_object(ser_merch_state);
let close_token = bolt_try!(bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &merch_state));
let close_token = bolt_try!(bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, init_cust_bal, init_merch_bal, &merch_state));
let ser = ["{\'close_token\':\'", serde_json::to_string(&close_token).unwrap().as_str(), "\'}"].concat();
let cser = CString::new(ser).unwrap();

View File

@ -218,9 +218,11 @@ pub mod bidirectional {
/// signature) over the contents of the customer's wallet.
///
pub fn establish_merchant_issue_close_token<R: Rng, E: Engine>(csprng: &mut R, channel_state: &ChannelState<E>,
com: &Commitment<E>, com_proof: &CommitmentProof<E>, merch_state: &MerchantState<E>) -> BoltResult<cl::Signature<E>> {
com: &Commitment<E>, com_proof: &CommitmentProof<E>,
init_cust_balance: i32, init_merch_balance: i32,
merch_state: &MerchantState<E>) -> BoltResult<cl::Signature<E>> {
// verifies proof of committed values and derives blind signature on the committed values to the customer's initial wallet
match merch_state.verify_proof(csprng, channel_state, com, com_proof) {
match merch_state.verify_proof(csprng, channel_state, com, com_proof, init_cust_balance, merch_state.init_balance) {
Ok(n) => Ok(Some(n.0)), // just close token
Err(err) => Err(String::from(err.to_string()))
}
@ -537,6 +539,8 @@ mod tests {
fn execute_establish_protocol_helper(channel_state: &mut bidirectional::ChannelState<Bls12>,
channel_token: &mut bidirectional::ChannelToken<Bls12>,
cust_balance: i32,
merch_balance: i32,
merch_state: &mut bidirectional::MerchantState<Bls12>,
cust_state: &mut bidirectional::CustomerState<Bls12>) {
@ -546,7 +550,7 @@ mod tests {
let (com, com_proof) = bidirectional::establish_customer_generate_proof(rng, channel_token, cust_state);
// obtain close token for closing out channel
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &merch_state);
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, cust_balance, merch_balance, &merch_state);
let close_token= match option {
Ok(n) => n.unwrap(),
Err(e) => panic!("Failed - bidirectional::establish_merchant_issue_close_token(): {}", e)
@ -609,7 +613,8 @@ mod tests {
let (com, com_proof) = bidirectional::establish_customer_generate_proof(rng, &mut channel_token, &mut cust_state);
// obtain close token for closing out channel
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &merch_state);
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof,
b0_customer, b0_merchant, &merch_state);
let close_token= match option {
Ok(n) => n.unwrap(),
Err(e) => panic!("Failed - bidirectional::establish_merchant_issue_close_token(): {}", e)
@ -661,7 +666,7 @@ mod tests {
let (mut channel_token, mut merch_state, mut cust_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
// run establish protocol for customer and merchant channel
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state);
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
assert!(channel_state.channel_established);
@ -703,7 +708,7 @@ mod tests {
let (mut channel_token, mut merch_state, mut cust_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
// run establish protocol for customer and merchant channel
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state);
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
assert!(channel_state.channel_established);
{
@ -733,7 +738,7 @@ mod tests {
let (mut channel_token, mut merch_state, mut cust_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
// run establish protocol for customer and merchant channel
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state);
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
assert!(channel_state.channel_established);
@ -780,7 +785,7 @@ mod tests {
let (mut channel_token, mut merch_state, mut cust_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
// run establish protocol for customer and merchant channel
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state);
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
assert!(channel_state.channel_established);

View File

@ -264,7 +264,7 @@ impl<E: Engine> CommitmentProof<E> {
///
/// Verify PoK for the opening of a commitment
///
pub fn verify_opening<E: Engine>(com_params: &CSMultiParams<E>, com: &E::G1, proof: &CommitmentProof<E>) -> bool {
pub fn verify_opening<E: Engine>(com_params: &CSMultiParams<E>, com: &E::G1, proof: &CommitmentProof<E>, init_cust: i32, init_merch: i32) -> bool {
let mut comc = com.clone();
let T = proof.T.clone();
@ -299,13 +299,15 @@ pub fn verify_opening<E: Engine>(com_params: &CSMultiParams<E>, com: &E::G1, pro
let mut s3 = proof.reveal[3].clone();
s3.mul_assign(&challenge);
s3.add_assign(&proof.t[3]);
let bc_equal = (s3 == proof.z[3]);
let init_c = util::convert_int_to_fr::<E>(init_cust);
let bc_equal = (s3 == proof.z[3]) && (proof.reveal[3] == init_c);
// merch init balances: index = 4
let mut s4 = proof.reveal[4].clone();
s4.mul_assign(&challenge);
s4.add_assign(&proof.t[4]);
let bm_equal = (s4 == proof.z[4]);
let init_m = util::convert_int_to_fr::<E>(init_merch);
let bm_equal = (s4 == proof.z[4]) && (proof.reveal[4] == init_m);
return comc == x && pkc_equal && bc_equal && bm_equal;
}
@ -476,7 +478,7 @@ mod tests {
let com_proof = CommitmentProof::<Bls12>::new(rng, &pubParams.comParams,
&com.c, &wallet.as_fr_vec(), &t, &vec![1, 3, 4]);
assert!(verify_opening(&pubParams.comParams, &com.c, &com_proof));
assert!(verify_opening(&pubParams.comParams, &com.c, &com_proof, bc, bm));
}
#[test]
@ -499,8 +501,8 @@ mod tests {
let com1_proof = CommitmentProof::<Bls12>::new(rng, &pubParams.comParams,
&com1.c, &wallet1.as_fr_vec(), &t, &vec![1, 3, 4]);
assert!(verify_opening(&pubParams.comParams, &com1.c, &com1_proof));
assert!(!verify_opening(&pubParams.comParams, &com2.c, &com1_proof));
assert!(verify_opening(&pubParams.comParams, &com1.c, &com1_proof, bc, bm));
assert!(!verify_opening(&pubParams.comParams, &com2.c, &com1_proof, bc2, bm));
}