nizk: optimize commitment proof partial reveal

This commit is contained in:
Gijs Van Laer 2019-09-13 16:16:35 -04:00
parent 54a15061ae
commit c14ed7bad9
11 changed files with 133 additions and 144 deletions

View File

@ -10,6 +10,7 @@ use bolt::bidirectional;
use std::time::Instant;
use pairing::bls12_381::{Bls12};
use bolt::handle_bolt_result;
use bolt::util::hash_pubkey_to_fr;
macro_rules! measure_one_arg {
($x: expr) => {
@ -66,8 +67,9 @@ fn main() {
println!(">> Time to generate proof for establish: {} ms", est_time);
// obtain close token for closing out channel
let pk_h = hash_pubkey_to_fr::<Bls12>(&cust_state.pk_c);
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof,
b0_customer, b0_merchant, &merch_state);
&pk_h, 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

@ -242,7 +242,7 @@ func BidirectionalEstablishCustomerGenerateProof(channelToken ChannelToken, cust
return channelToken, custState, com, comProof, err
}
func BidirectionalEstablishMerchantIssueCloseToken(channelState ChannelState, com Commitment, comProof CommitmentProof, initCustBal int, initMerchBal int, merchState MerchState) (Signature, error) {
func BidirectionalEstablishMerchantIssueCloseToken(channelState ChannelState, com Commitment, comProof CommitmentProof, pkc string, initCustBal int, initMerchBal int, merchState MerchState) (Signature, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return Signature{}, err
@ -259,7 +259,7 @@ func BidirectionalEstablishMerchantIssueCloseToken(channelState ChannelState, co
if err != nil {
return Signature{}, err
}
resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_close_token(C.CString(string(serChannelState)), C.CString(string(serCom)), C.CString(string(serComProof)), C.int(initCustBal), C.int(initMerchBal), C.CString(string(serMerchState))))
resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_close_token(C.CString(string(serChannelState)), C.CString(string(serCom)), C.CString(string(serComProof)), C.CString(pkc), C.int(initCustBal), C.int(initMerchBal), C.CString(string(serMerchState))))
r, err := processCResponse(resp)
if err != nil {
return Signature{}, err

View File

@ -36,7 +36,7 @@ func Test_Establish(t *testing.T) {
channelToken, custState, com, comProof, err := BidirectionalEstablishCustomerGenerateProof(channelToken, custState)
assert.Nil(t, err)
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, b0Cust, b0Merch, merchState)
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, custState.PkC, b0Cust, b0Merch, merchState)
assert.Nil(t, err)
assert.NotNil(t, closeToken)
@ -61,7 +61,7 @@ func Test_Pay(t *testing.T) {
assert.Nil(t, err)
channelToken, custState, com, comProof, err := BidirectionalEstablishCustomerGenerateProof(channelToken, custState)
assert.Nil(t, err)
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, b0Cust, b0Merch, merchState)
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, custState.PkC, b0Cust, b0Merch, merchState)
assert.Nil(t, err)
_, channelState, custState, err = BidirectionalVerifyCloseToken(channelState, custState, closeToken)
assert.Nil(t, err)
@ -90,7 +90,7 @@ func Test_Close(t *testing.T) {
assert.Nil(t, err)
channelToken, custState, com, comProof, err := BidirectionalEstablishCustomerGenerateProof(channelToken, custState)
assert.Nil(t, err)
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, b0Cust, b0Merch, merchState)
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, custState.PkC, b0Cust, b0Merch, merchState)
assert.Nil(t, err)
_, channelState, custState, err = BidirectionalVerifyCloseToken(channelState, custState, closeToken)
assert.Nil(t, err)

View File

@ -22,7 +22,7 @@ char* ffishim_bidirectional_init_customer(const char *ser_channel_state, const c
// channel establish protocol routines
char* ffishim_bidirectional_establish_customer_generate_proof(const char *ser_channel_token, const char *ser_customer_wallet);
char* ffishim_bidirectional_establish_merchant_issue_close_token(const char *ser_channel_state, const char *ser_com, const char *ser_com_proof, int init_cust_bal, int init_merch_bal, const char *ser_merch_state);
char* ffishim_bidirectional_establish_merchant_issue_close_token(const char *ser_channel_state, const char *ser_com, const char *ser_com_proof, const char *ser_pk_c, int init_cust_bal, int init_merch_bal, const char *ser_merch_state);
char* ffishim_bidirectional_establish_merchant_issue_pay_token(const char *ser_channel_state, const char *ser_com, const char *ser_merch_state);
char* ffishim_bidirectional_verify_close_token(const char *ser_channel_state, const char *ser_customer_wallet, const char *ser_close_token);
char* ffishim_bidirectional_establish_customer_final(const char *ser_channel_state, const char *ser_customer_wallet, const char *ser_pay_token);

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, 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, 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, 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())
def bidirectional_establish_merchant_issue_close_token(self, channel_state, com, com_proof, pkc, 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(), pkc.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.get('close_token')
@ -241,7 +241,8 @@ def run_unit_test():
print("channel token: => ", channel_token)
print("com: ", com)
close_token = libbolt.bidirectional_establish_merchant_issue_close_token(channel_state, com, com_proof, b0_cust, b0_merch, merch_state)
cust_state_dict = json.loads(cust_state)
close_token = libbolt.bidirectional_establish_merchant_issue_close_token(channel_state, com, com_proof, cust_state_dict["pk_c"], 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

@ -48,7 +48,8 @@ class BoltEstablishTests(unittest.TestCase):
"""
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token, self.cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
cust_state_dict = json.loads(cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
self.assertTrue(close_token is not None)
(is_token_valid, channel_state, cust_state) = self.bolt.bidirectional_establish_customer_verify_close_token(self.channel_state, cust_state, close_token)
@ -68,7 +69,8 @@ class BoltEstablishTests(unittest.TestCase):
"""
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token_bad, self.cust_state_bad)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
cust_state_dict = json.loads(cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
self.assertTrue(close_token is None)
#print("Establish protocol fail works as expected.")
@ -90,7 +92,8 @@ class BoltEstablishTests(unittest.TestCase):
bad_com = json.dumps({"c":"852a57e24a2192e1cea19157e44f92d58369751f2012bc1f4a4312a89a63c74a92a4cb1d362b37ae0eda3b3bd1333502"})
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token, self.cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
cust_state_dict = json.loads(cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
self.assertTrue(close_token is not None)
(is_token_valid, channel_state, cust_state) = self.bolt.bidirectional_establish_customer_verify_close_token(self.channel_state, cust_state, close_token)
@ -123,7 +126,8 @@ class BoltEstablishTests(unittest.TestCase):
"""
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token, self.cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
cust_state_dict = json.loads(cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
self.assertTrue(close_token is not None)
malformed_close_token = malformed_token(close_token)
@ -154,7 +158,8 @@ class BoltPayTests(unittest.TestCase):
(self.channel_token, self.cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token, self.cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
cust_state_dict = json.loads(self.cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
self.assertTrue(close_token is not None)
(is_token_valid, self.channel_state, self.cust_state) = self.bolt.bidirectional_establish_customer_verify_close_token(self.channel_state, self.cust_state, close_token)
@ -262,10 +267,10 @@ class BoltMultiChannelTests(unittest.TestCase):
(self.channel_token_c, self.charlie_state) = self.bolt.bidirectional_init_customer(self.channel_state, self.channel_token,
self.b0_charlie, self.b0_merch, "Charlie")
def _establish_channel(self, channel_token, cust_state, b0_cust, b0_merch):
def _establish_channel(self, channel_token, cust_state, pkc, b0_cust, b0_merch):
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(channel_token, cust_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, b0_cust, b0_merch, self.merch_state)
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, pkc, b0_cust, b0_merch, self.merch_state)
self.assertTrue(close_token is not None)
(is_token_valid, self.channel_state, cust_state) = self.bolt.bidirectional_establish_customer_verify_close_token(self.channel_state, cust_state, close_token)
@ -282,7 +287,8 @@ class BoltMultiChannelTests(unittest.TestCase):
def test_multiple_channels_work(self):
"""Establishing concurrent channels with a merchant works as expected
"""
channel_token_a, alice_cust_state = self._establish_channel(self.channel_token, self.alice_state, self.b0_alice, self.b0_merch)
cust_state_dict = json.loads(self.alice_state)
channel_token_a, alice_cust_state = self._establish_channel(self.channel_token, self.alice_state, cust_state_dict["pk_c"], self.b0_alice, self.b0_merch)
class BoltIntermediaryTests(unittest.TestCase):

View File

@ -550,8 +550,8 @@ 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>, cust_balance: i32, merch_balance: i32) -> ResultBoltType<(Signature<E>, Signature<E>)> {
let is_valid = nizk::verify_opening(&self.comParams, &com.c, &com_proof, cust_balance, merch_balance);
pub fn verify_proof<R: Rng>(&self, csprng: &mut R, channel: &ChannelState<E>, com: &Commitment<E>, com_proof: &CommitmentProof<E>, pkc: &E::Fr, cust_balance: i32, merch_balance: i32) -> ResultBoltType<(Signature<E>, Signature<E>)> {
let is_valid = nizk::verify_opening(&self.comParams, &com.c, &com_proof, &pkc, cust_balance, merch_balance);
let cp = channel.cp.as_ref().unwrap();
if is_valid {
let close_token = self.issue_close_token(csprng, cp, com, true);
@ -646,7 +646,8 @@ 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, b0_cust, b0_merch).unwrap();
let pk_h = hash_pubkey_to_fr::<Bls12>(&cust_state.pk_c.clone());
let (close_token, pay_token) = merch_state.verify_proof(rng, &channel, &cust_state.w_com, &cust_com_proof, &pk_h, b0_cust, b0_merch).unwrap();
// unblind tokens and verify signatures
assert!(cust_state.verify_close_token(&channel, &close_token));

View File

@ -4,7 +4,7 @@ pub mod ffishim {
use bidirectional;
use ff::Rand;
use pairing::bls12_381::{Bls12};
use pairing::bls12_381::{Bls12, Fr};
use serde::Deserialize;
@ -13,6 +13,8 @@ pub mod ffishim {
use std::str;
use channels::{ChannelcloseM, ResultBoltType, BoltError};
use std::alloc::handle_alloc_error;
use util::hash_pubkey_to_fr;
use std::str::FromStr;
fn error_message(s: String) -> *mut c_char {
let ser = ["{\'error\':\'", &s, "\'}"].concat();
@ -166,7 +168,7 @@ 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, init_cust_bal: i32, init_merch_bal: i32, 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, ser_pk_c: *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_result: ResultSerdeType<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
@ -184,7 +186,14 @@ pub mod ffishim {
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<Bls12>> = deserialize_result_object(ser_merch_state);
let merch_state = handle_errors!(merch_state_result);
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));
// Deserialize the pk_c
let bytes = unsafe { CStr::from_ptr(ser_pk_c).to_bytes() };
let string: &str = str::from_utf8(bytes).unwrap();
let pk_c_result = secp256k1::PublicKey::from_str(string);
let pk_c = handle_errors!(pk_c_result);
let pk_h = hash_pubkey_to_fr::<Bls12>(&pk_c);
let close_token = bolt_try!(bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &pk_h, 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

@ -16,7 +16,8 @@
#![feature(exclusive_range_pattern)]
#![cfg_attr(all(test, feature = "unstable"), feature(test))]
#[cfg(all(test, feature = "unstable"))] extern crate test;
#[cfg(all(test, feature = "unstable"))]
extern crate test;
extern crate ff;
extern crate pairing;
@ -115,10 +116,12 @@ pub mod bidirectional {
use util;
use wallet;
use pairing::Engine;
use pairing::bls12_381::{Bls12};
use pairing::bls12_381::Bls12;
use sodiumoxide;
use cl; // for blind signature
use secp256k1; // for on-chain keys
use cl;
// for blind signature
use secp256k1;
// for on-chain keys
use HashMap;
use sodiumoxide::crypto::hash::sha512;
use sha2::Sha512;
@ -144,7 +147,7 @@ pub mod bidirectional {
pub struct ChannelcloseC<E: Engine> {
pub wpk: secp256k1::PublicKey,
pub message: wallet::Wallet<E>,
pub signature: cl::Signature<E>
pub signature: cl::Signature<E>,
}
#[derive(Clone, Serialize, Deserialize)]
@ -168,7 +171,7 @@ pub mod bidirectional {
#[derive(Clone, Serialize, Deserialize)]
pub struct RevokeToken {
message: util::RevokedMessage,
pub signature: secp256k1::Signature
pub signature: secp256k1::Signature,
}
pub fn init() {
@ -195,8 +198,8 @@ pub mod bidirectional {
/// and wallet commitment.
///
pub fn init_customer<'a, R: Rng, E: Engine>(csprng: &mut R, channel_state: &ChannelState<E>,
channel_token: &mut ChannelToken<E>,
b0_cust: i32, b0_merch: i32, name: &'a str) -> CustomerState<E> {
channel_token: &mut ChannelToken<E>,
b0_cust: i32, b0_merch: i32, name: &'a str) -> CustomerState<E> {
assert!(b0_cust >= 0);
assert!(b0_merch >= 0);
@ -221,10 +224,10 @@ pub mod bidirectional {
///
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>,
init_cust_balance: i32, init_merch_balance: i32,
pkc: &E::Fr, 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, init_cust_balance, init_merch_balance) {
match merch_state.verify_proof(csprng, channel_state, com, com_proof, pkc, init_cust_balance, init_merch_balance) {
Ok(n) => Ok(Some(n.0)), // just close token
Err(err) => Err(String::from(err.to_string()))
}
@ -236,7 +239,7 @@ pub mod bidirectional {
/// signature) over the contents of the customer's wallet.
///
pub fn establish_merchant_issue_pay_token<R: Rng, E: Engine>(csprng: &mut R, channel_state: &ChannelState<E>,
com: &Commitment<E>, merch_state: &MerchantState<E>) -> cl::Signature<E> {
com: &Commitment<E>, merch_state: &MerchantState<E>) -> cl::Signature<E> {
let cp = channel_state.cp.as_ref().unwrap();
let pay_token = merch_state.issue_pay_token(csprng, cp, com, false);
return pay_token;
@ -287,7 +290,7 @@ pub mod bidirectional {
/// (i.e., partially blind signature on IOU with updated balance)
///
pub fn verify_payment_proof<R: Rng, E: Engine>(csprng: &mut R, channel_state: &ChannelState<E>,
payment: &Payment<E>, merch_state: &mut MerchantState<E>) -> cl::Signature<E> {
payment: &Payment<E>, merch_state: &mut MerchantState<E>) -> cl::Signature<E> {
// if payment proof verifies, then returns close-token and records wpk => pay-token
// if valid revoke_token is provided later for wpk, then release pay-token
let tx_fee = channel_state.get_channel_fee();
@ -296,7 +299,7 @@ pub mod bidirectional {
false => payment.amount
};
let new_close_token = merch_state.verify_payment(csprng, &channel_state,
&payment.proof, &payment.com, &payment.wpk, payment_amount).unwrap();
&payment.proof, &payment.com, &payment.wpk, payment_amount).unwrap();
// store the wpk since it has been revealed
update_merchant_state(&mut merch_state.keys, &payment.wpk, None);
return new_close_token;
@ -352,16 +355,15 @@ pub mod bidirectional {
/// a revocation token for the old wallet public key.
///
pub fn generate_revoke_token<E: Engine>(channel_state: &ChannelState<E>,
old_cust_state: &mut CustomerState<E>,
new_cust_state: CustomerState<E>,
new_close_token: &cl::Signature<E>) -> RevokeToken {
old_cust_state: &mut CustomerState<E>,
new_cust_state: CustomerState<E>,
new_close_token: &cl::Signature<E>) -> RevokeToken {
// let's update the old wallet
assert!(old_cust_state.update(new_cust_state));
// generate the token after verifying that the close token is valid
let (message, signature) = old_cust_state.generate_revoke_token(channel_state, new_close_token).unwrap();
// return the revoke token (msg + sig pair)
return RevokeToken { message, signature };
}
///
@ -391,7 +393,7 @@ pub mod bidirectional {
panic!("Cannot close a channel that has not been established!");
}
let mut wallet= cust_state.get_wallet();
let mut wallet = cust_state.get_wallet();
let close_token = cust_state.get_close_token();
let cp = channel_state.cp.as_ref().unwrap();
@ -523,14 +525,14 @@ mod benches {
mod tests {
use super::*;
use ff::Rand;
use pairing::bls12_381::{Bls12};
use pairing::bls12_381::Bls12;
use rand::Rng;
use channels::ChannelState;
use util::hash_pubkey_to_fr;
fn setup_new_channel_helper(channel_state: &mut bidirectional::ChannelState<Bls12>,
init_cust_bal: i32, init_merch_bal: i32)
-> (bidirectional::ChannelToken<Bls12>, bidirectional::MerchantState<Bls12>, bidirectional::CustomerState<Bls12>, bidirectional::ChannelState<Bls12>) {
-> (bidirectional::ChannelToken<Bls12>, bidirectional::MerchantState<Bls12>, bidirectional::CustomerState<Bls12>, bidirectional::ChannelState<Bls12>) {
let mut rng = &mut rand::thread_rng();
let merch_name = "Bob";
let cust_name = "Alice";
@ -550,20 +552,20 @@ 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>) {
channel_token: &mut bidirectional::ChannelToken<Bls12>,
cust_balance: i32,
merch_balance: i32,
merch_state: &mut bidirectional::MerchantState<Bls12>,
cust_state: &mut bidirectional::CustomerState<Bls12>) {
let mut rng = &mut rand::thread_rng();
// lets establish the channel
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, cust_balance, merch_balance, &merch_state);
let close_token= match option {
let pk_h = hash_pubkey_to_fr::<Bls12>(&cust_state.pk_c.clone());
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &pk_h, 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)
};
@ -580,11 +582,10 @@ mod tests {
}
fn execute_payment_protocol_helper(channel_state: &mut bidirectional::ChannelState<Bls12>,
channel_token: &mut bidirectional::ChannelToken<Bls12>,
merch_state: &mut bidirectional::MerchantState<Bls12>,
cust_state: &mut bidirectional::CustomerState<Bls12>,
payment_increment: i32) {
channel_token: &mut bidirectional::ChannelToken<Bls12>,
merch_state: &mut bidirectional::MerchantState<Bls12>,
cust_state: &mut bidirectional::CustomerState<Bls12>,
payment_increment: i32) {
let mut rng = &mut rand::thread_rng();
let (payment, new_cust_state) = bidirectional::generate_payment_proof(rng, channel_state, &cust_state, payment_increment);
@ -599,7 +600,7 @@ mod tests {
// verify the pay token and update internal state
assert!(cust_state.verify_pay_token(&channel_state, &new_pay_token.unwrap()));
}
}
#[test]
fn bidirectional_payment_basics_work() {
@ -622,9 +623,10 @@ 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,
b0_customer, b0_merchant, &merch_state);
let close_token= match option {
let pk_h = hash_pubkey_to_fr::<Bls12>(&cust_state.pk_c.clone());
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &pk_h,
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)
};
@ -662,7 +664,6 @@ mod tests {
#[test]
fn bidirectional_multiple_payments_work() {
let total_owed = 40;
let b0_customer = 380;
let b0_merchant = 20;
@ -675,7 +676,7 @@ mod tests {
let fee = 5;
channel_state.set_channel_fee(fee);
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
let (mut channel_token, mut merch_state, mut cust_state, mut channel_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, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
@ -685,7 +686,7 @@ mod tests {
{
// make multiple payments in a loop
let num_payments = total_owed / payment_increment;
for i in 0 .. num_payments {
for i in 0..num_payments {
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, payment_increment);
}
@ -702,7 +703,6 @@ mod tests {
println!("{}", cust_close_msg.message);
println!("{}", cust_close_msg.signature);
}
}
#[test]
@ -716,7 +716,7 @@ mod tests {
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Channel A -> B"), false);
let mut rng = &mut rand::thread_rng();
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
let (mut channel_token, mut merch_state, mut cust_state, mut channel_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, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
@ -744,7 +744,7 @@ mod tests {
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Channel A -> B"), false);
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
let (mut channel_token, mut merch_state, mut cust_state, mut channel_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, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
@ -765,9 +765,9 @@ mod tests {
let cur_cust_close_msg = bidirectional::customer_close(&channel_state, &cust_state);
let merch_close_result = bidirectional::merchant_close(&channel_state,
&channel_token,
&old_cust_close_msg,
&merch_state);
&channel_token,
&old_cust_close_msg,
&merch_state);
let merch_close_msg = match merch_close_result {
Ok(n) => n.unwrap(),
Err(err) => panic!("Merchant close msg: {}", err)
@ -789,7 +789,7 @@ mod tests {
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Channel A -> B"), false);
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
let (mut channel_token, mut merch_state, mut cust_state, mut channel_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, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
@ -808,9 +808,9 @@ mod tests {
let cust_close_msg = bidirectional::customer_close(&channel_state, &cust_state);
let merch_close_result = bidirectional::merchant_close(&channel_state,
&channel_token,
&cust_close_msg,
&merch_state);
&channel_token,
&cust_close_msg,
&merch_state);
let merch_close_msg = match merch_close_result {
Ok(n) => n.unwrap(),
Err(err) => panic!("Merchant close msg: {}", err)
@ -942,5 +942,4 @@ mod tests {
let des_cw: bidirectional::CustomerState<Bls12> = serde_json::from_str(&serlalized_cw).unwrap();
}
}

View File

@ -102,7 +102,7 @@ impl<E: Engine> NIZKSecretParams<E> {
r1 = r1 && proof.sigProof.zsig[1] == wpkc;
//verify knowledge of commitment
let r2 = proof.comProof.verify_proof(&self.pubParams.comParams, &com.c.clone(), &challenge);
let r2 = proof.comProof.verify_proof(&self.pubParams.comParams, &com.c.clone(), &challenge, None);
//verify range proofs
let r3 = self.rpParams.verify_ul(&proof.rpBC.clone(), challenge.clone(), 3);
@ -146,7 +146,7 @@ impl<E: Engine> NIZKPublicParams<E> {
false => self.comParams.pub_bases.len()
};
let (D, t, rt) = CommitmentProof::<E>::prove_commitment(rng, &self.comParams, &newWallet.as_fr_vec(), &vec! {});
let (D, t) = CommitmentProof::<E>::prove_commitment(rng, &self.comParams, &newWallet.as_fr_vec(), None);
//commit signature
let zero = E::Fr::zero();
@ -170,7 +170,7 @@ impl<E: Engine> NIZKPublicParams<E> {
//response commitment
let newWalletVec = newWallet.as_fr_vec();
let comProof = CommitmentProof::<E>::prove_response(&newWalletVec, &rPrime, &vec! {}, D, &t, rt, &challenge);
let comProof = CommitmentProof::<E>::prove_response(&newWalletVec, &rPrime, D, &t, &challenge);
//response range proof
let mut vec01 = newWalletVec[0..2].to_vec();
@ -203,40 +203,14 @@ impl<E: Engine> NIZKPublicParams<E> {
///
/// Verify PoK for the opening of a commitment during the establishment protocol
///
pub fn verify_opening<E: Engine>(com_params: &CSMultiParams<E>, com: &E::G1, proof: &CommitmentProof<E>, init_cust: i32, init_merch: i32) -> bool {
pub fn verify_opening<E: Engine>(com_params: &CSMultiParams<E>, com: &E::G1, proof: &CommitmentProof<E>, pkc: &E::Fr, init_cust: i32, init_merch: i32) -> bool {
let xvec: Vec<E::G1> = vec![proof.T.clone(), com.clone()];
let challenge = util::hash_g1_to_fr::<E>(&xvec);
// compute the
let com_equal = proof.verify_proof(com_params, com, &challenge);
let com_equal = proof.verify_proof(com_params, com, &challenge, Some(vec!{None, Some(pkc.clone()), None, Some(util::convert_int_to_fr::<E>(init_cust)), Some(util::convert_int_to_fr::<E>(init_merch))}));
if proof.index.len() == 0 {
println!("verify_opening - doing any partial reveals?");
return false;
}
// verify linear relationshps
// pkc: index = 1
let mut s1 = proof.reveal[1].clone();
s1.mul_assign(&challenge);
s1.add_assign(&proof.t[1]);
let pkc_equal = (s1 == proof.z[1]);
// cust init balances: index = 3
let mut s3 = proof.reveal[3].clone();
s3.mul_assign(&challenge);
s3.add_assign(&proof.t[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 init_m = util::convert_int_to_fr::<E>(init_merch);
let bm_equal = (s4 == proof.z[4]) && (proof.reveal[4] == init_m);
return com_equal && pkc_equal && bc_equal && bm_equal;
return com_equal;
}
@ -406,7 +380,7 @@ mod tests {
let com_proof = CommitmentProof::<Bls12>::new(rng, &secParams.pubParams.comParams,
&com.c, &wallet.as_fr_vec(), &t, &vec![1, 3, 4]);
assert!(verify_opening(&secParams.pubParams.comParams, &com.c, &com_proof, bc, bm));
assert!(verify_opening(&secParams.pubParams.comParams, &com.c, &com_proof, &pkc.clone(), bc, bm));
}
#[test]
@ -429,8 +403,8 @@ mod tests {
let com1_proof = CommitmentProof::<Bls12>::new(rng, &secParams.pubParams.comParams,
&com1.c, &wallet1.as_fr_vec(), &t, &vec![1, 3, 4]);
assert!(verify_opening(&secParams.pubParams.comParams, &com1.c, &com1_proof, bc, bm));
assert!(!verify_opening(&secParams.pubParams.comParams, &com2.c, &com1_proof, bc2, bm));
assert!(verify_opening(&secParams.pubParams.comParams, &com1.c, &com1_proof, &pkc.clone(), bc, bm));
assert!(!verify_opening(&secParams.pubParams.comParams, &com2.c, &com1_proof, &pkc.clone(), bc2, bm));
}

View File

@ -187,88 +187,85 @@ impl<E: Engine> CSMultiParams<E> {
pub struct CommitmentProof<E: Engine> {
pub T: E::G1,
pub z: Vec<E::Fr>,
pub t: Vec<E::Fr>,
pub index: Vec<usize>,
pub reveal: Vec<E::Fr>
}
impl<E: Engine> CommitmentProof<E> {
pub fn new<R: Rng>(csprng: &mut R, com_params: &CSMultiParams<E>, com: &E::G1, wallet: &Vec<E::Fr>, r: &E::Fr, reveal_index: &Vec<usize>) -> Self {
let (Tvals, t, rt) = CommitmentProof::<E>::prove_commitment::<R>(csprng, com_params, wallet, reveal_index);
let mut rt = Vec::new();
for i in 0..wallet.len() + 1 {
if reveal_index.contains(&i) {
rt.push(E::Fr::zero());
} else {
rt.push(E::Fr::rand(csprng));
}
}
let (Tvals, t) = CommitmentProof::<E>::prove_commitment::<R>(csprng, com_params, wallet, Some(rt));
// compute the challenge
let x: Vec<E::G1> = vec![Tvals, com.clone()];
let challenge = util::hash_g1_to_fr::<E>(&x);
// compute the response
CommitmentProof::<E>::prove_response(wallet, r, reveal_index, Tvals, &t, rt, &challenge)
CommitmentProof::<E>::prove_response(wallet, r, Tvals, &t, &challenge)
}
pub fn prove_commitment<R: Rng>(csprng: &mut R, com_params: &CSMultiParams<E>, wallet: &Vec<E::Fr>, reveal_index: &Vec<usize>) -> (E::G1, Vec<E::Fr>, Vec<E::Fr>) {
pub fn prove_commitment<R: Rng>(csprng: &mut R, com_params: &CSMultiParams<E>, wallet: &Vec<E::Fr>, tOptional: Option<Vec<E::Fr>>) -> (E::G1, Vec<E::Fr>) {
let mut Tvals = E::G1::zero();
assert!(wallet.len() <= com_params.pub_bases.len());
let mut t = Vec::<E::Fr>::with_capacity(wallet.len() + 1);
let mut rt: Vec<E::Fr> = Vec::new();
let mut t = tOptional.unwrap_or(Vec::<E::Fr>::with_capacity(wallet.len() + 1));
// aspects of wallet being revealed
for i in 0..wallet.len() + 1 {
let ti = E::Fr::rand(csprng);
t.push(ti);
// check if we are revealing this index
if reveal_index.contains(&i) {
rt.push(ti);
} else {
rt.push(E::Fr::zero());
if t.len() == i {
t.push(E::Fr::rand(csprng));
}
let ti = t[i].clone();
let mut gt = com_params.pub_bases[i].clone();
gt.mul_assign(ti.into_repr());
Tvals.add_assign(&gt);
}
(Tvals, t, rt)
(Tvals, t)
}
pub fn prove_response(wallet: &Vec<E::Fr>, r: &E::Fr, reveal_index: &Vec<usize>, Tvals: E::G1, t: &Vec<E::Fr>, rt: Vec<E::Fr>, challenge: &E::Fr) -> CommitmentProof<E> {
pub fn prove_response(wallet: &Vec<E::Fr>, r: &E::Fr, Tvals: E::G1, t: &Vec<E::Fr>, challenge: &E::Fr) -> CommitmentProof<E> {
let mut z: Vec<E::Fr> = Vec::new();
let mut z0 = r.clone();
z0.mul_assign(&challenge);
z0.add_assign(&t[0]);
z.push(z0);
// t values that will be revealed
let mut reveal_wallet: Vec<E::Fr> = Vec::new();
reveal_wallet.push(E::Fr::zero());
for i in 1..t.len() {
let mut zi = wallet[i - 1].clone();
zi.mul_assign(&challenge);
zi.add_assign(&t[i]);
z.push(zi);
// check if we are revealing this index
if reveal_index.contains(&i) {
reveal_wallet.push(wallet[i - 1].clone());
} else {
reveal_wallet.push(E::Fr::zero());
}
}
CommitmentProof {
T: Tvals, // commitment challenge
z: z, // response values
t: rt, // randomness for verifying partial reveals
index: reveal_index.clone(),
reveal: reveal_wallet.clone()
}
}
pub fn verify_proof(&self, com_params: &CSMultiParams<E>, com: &<E as Engine>::G1, challenge: &E::Fr) -> bool {
pub fn verify_proof(&self, com_params: &CSMultiParams<E>, com: &<E as Engine>::G1, challenge: &E::Fr, revealOption: Option<Vec<Option<E::Fr>>>) -> bool {
let mut comc = com.clone();
let T = self.T.clone();
comc.mul_assign(challenge.into_repr());
comc.add_assign(&T);
let mut x = E::G1::zero();
let reveal = revealOption.unwrap_or(vec!{});
let mut revealBool = true;
for i in 0..self.z.len() {
let mut base = com_params.pub_bases[i].clone();
base.mul_assign(self.z[i].into_repr());
x.add_assign(&base);
if reveal.len() > i && reveal[i].is_some() {
let mut el = reveal[i].unwrap();
el.mul_assign(&challenge.clone());
revealBool = revealBool && self.z[i] == el;
}
}
comc == x
revealBool && comc == x
}
}
@ -370,7 +367,7 @@ mod tests {
let xvec: Vec<G1> = vec![proof.T.clone(), com.c];
let challenge = util::hash_g1_to_fr::<Bls12>(&xvec);
assert_eq!(proof.verify_proof(&comParams, &com.c, &challenge), true);
assert_eq!(proof.verify_proof(&comParams, &com.c, &challenge, None), true);
}
// add tests for extend/remove commits dynamically