Merge pull request #15 from boltlabs-inc/nizk2

Optimize NIZKs
This commit is contained in:
J. Ayo Akinyele 2019-09-13 17:18:19 -04:00 committed by GitHub
commit c772a7f3a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 278 additions and 217 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

@ -30,6 +30,16 @@ type setupResp struct {
Result string `json:"result"`
}
type ChannelState struct {
R int `json:"R"`
TxFee int `json:"tx_fee"`
Cp interface{} `json:"cp"`
Name string `json:"name"`
PayInit bool `json:"pay_init"`
ChannelEstablished bool `json:"channel_established"`
ThirdParty bool `json:"third_party"`
}
type MerchState struct {
KeyPair KeyPair `json:"keypair"`
NizkParams interface{} `json:"nizkParams"`
@ -142,37 +152,51 @@ type CustClose struct {
Signature Signature `json:"signature"`
}
func BidirectionalChannelSetup(name string, channelSupport bool) (string, error) {
func BidirectionalChannelSetup(name string, channelSupport bool) (ChannelState, error) {
resp := C.GoString(C.ffishim_bidirectional_channel_setup(C.CString(name), C.uint(btoi(channelSupport))))
r, err := processCResponse(resp)
if err != nil {
return "", err
return ChannelState{}, err
}
return r.ChannelState, nil
channelState := ChannelState{}
err = json.Unmarshal([]byte(r.ChannelState), &channelState)
return channelState, err
}
func BidirectionalInitMerchant(channelState string, balanceMerchant int, nameMerchant string) (ChannelToken, MerchState, string, error) {
resp := C.GoString(C.ffishim_bidirectional_init_merchant(C.CString(channelState), C.int(balanceMerchant), C.CString(nameMerchant)))
func BidirectionalInitMerchant(channelState ChannelState, balanceMerchant int, nameMerchant string) (ChannelToken, MerchState, ChannelState, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return ChannelToken{}, MerchState{}, ChannelState{}, err
}
resp := C.GoString(C.ffishim_bidirectional_init_merchant(C.CString(string(serChannelState)), C.int(balanceMerchant), C.CString(nameMerchant)))
r, err := processCResponse(resp)
if err != nil {
return ChannelToken{}, MerchState{}, "", err
return ChannelToken{}, MerchState{}, ChannelState{}, err
}
merchState := MerchState{}
err = json.Unmarshal([]byte(r.MerchState), &merchState)
if err != nil {
return ChannelToken{}, MerchState{}, "", err
return ChannelToken{}, MerchState{}, ChannelState{}, err
}
err = json.Unmarshal([]byte(r.ChannelState), &channelState)
if err != nil {
return ChannelToken{}, MerchState{}, ChannelState{}, err
}
channelToken := ChannelToken{}
err = json.Unmarshal([]byte(r.ChannelToken), &channelToken)
return channelToken, merchState, r.ChannelState, err
return channelToken, merchState, channelState, err
}
func BidirectionalInitCustomer(channelState string, channelToken ChannelToken, balanceCustomer int, balanceMerchant int, nameCustomer string) (ChannelToken, CustState, error) {
func BidirectionalInitCustomer(channelState ChannelState, channelToken ChannelToken, balanceCustomer int, balanceMerchant int, nameCustomer string) (ChannelToken, CustState, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return ChannelToken{}, CustState{}, err
}
serChannelToken, err := json.Marshal(channelToken)
if err != nil {
return ChannelToken{}, CustState{}, err
}
resp := C.GoString(C.ffishim_bidirectional_init_customer(C.CString(channelState), C.CString(string(serChannelToken)), C.int(balanceCustomer), C.int(balanceMerchant), C.CString(nameCustomer)))
resp := C.GoString(C.ffishim_bidirectional_init_customer(C.CString(string(serChannelState)), C.CString(string(serChannelToken)), C.int(balanceCustomer), C.int(balanceMerchant), C.CString(nameCustomer)))
r, err := processCResponse(resp)
if err != nil {
return ChannelToken{}, CustState{}, err
@ -218,7 +242,11 @@ func BidirectionalEstablishCustomerGenerateProof(channelToken ChannelToken, cust
return channelToken, custState, com, comProof, err
}
func BidirectionalEstablishMerchantIssueCloseToken(serChannelState string, 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
}
serCom, err := json.Marshal(com)
if err != nil {
return Signature{}, err
@ -231,7 +259,7 @@ func BidirectionalEstablishMerchantIssueCloseToken(serChannelState string, com C
if err != nil {
return Signature{}, err
}
resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_close_token(C.CString(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
@ -241,7 +269,11 @@ func BidirectionalEstablishMerchantIssueCloseToken(serChannelState string, com C
return closeToken, err
}
func BidirectionalEstablishMerchantIssuePayToken(serChannelState string, com Commitment, merchState MerchState) (Signature, error) {
func BidirectionalEstablishMerchantIssuePayToken(channelState ChannelState, com Commitment, merchState MerchState) (Signature, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return Signature{}, err
}
serCom, err := json.Marshal(com)
if err != nil {
return Signature{}, err
@ -250,7 +282,7 @@ func BidirectionalEstablishMerchantIssuePayToken(serChannelState string, com Com
if err != nil {
return Signature{}, err
}
resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_pay_token(C.CString(serChannelState), C.CString(string(serCom)), C.CString(string(serMerchState))))
resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_pay_token(C.CString(string(serChannelState)), C.CString(string(serCom)), C.CString(string(serMerchState))))
r, err := processCResponse(resp)
if err != nil {
return Signature{}, err
@ -260,48 +292,68 @@ func BidirectionalEstablishMerchantIssuePayToken(serChannelState string, com Com
return payToken, err
}
func BidirectionalVerifyCloseToken(serChannelState string, custState CustState, closeToken Signature) (bool, string, CustState, error) {
func BidirectionalVerifyCloseToken(channelState ChannelState, custState CustState, closeToken Signature) (bool, ChannelState, CustState, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return false, ChannelState{}, CustState{}, err
}
serCloseToken, err := json.Marshal(closeToken)
if err != nil {
return false, "", CustState{}, err
return false, ChannelState{}, CustState{}, err
}
serCustState, err := json.Marshal(custState)
if err != nil {
return false, "", CustState{}, err
return false, ChannelState{}, CustState{}, err
}
resp := C.GoString(C.ffishim_bidirectional_verify_close_token(C.CString(serChannelState), C.CString(string(serCustState)), C.CString(string(serCloseToken))))
resp := C.GoString(C.ffishim_bidirectional_verify_close_token(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serCloseToken))))
r, err := processCResponse(resp)
if err != nil {
return false, "", CustState{}, err
return false, ChannelState{}, CustState{}, err
}
err = json.Unmarshal([]byte(r.ChannelState), &channelState)
if err != nil {
return false, ChannelState{}, CustState{}, err
}
err = json.Unmarshal([]byte(r.CustState), &custState)
return r.IsTokenValid, r.ChannelState, custState, err
return r.IsTokenValid, channelState, custState, err
}
func BidirectionalEstablishCustomerFinal(serChannelState string, custState CustState, payToken Signature) (bool, string, CustState, error) {
func BidirectionalEstablishCustomerFinal(channelState ChannelState, custState CustState, payToken Signature) (bool, ChannelState, CustState, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return false, ChannelState{}, CustState{}, err
}
serPayToken, err := json.Marshal(payToken)
if err != nil {
return false, "", CustState{}, err
return false, ChannelState{}, CustState{}, err
}
serCustState, err := json.Marshal(custState)
if err != nil {
return false, "", CustState{}, err
return false, ChannelState{}, CustState{}, err
}
resp := C.GoString(C.ffishim_bidirectional_establish_customer_final(C.CString(serChannelState), C.CString(string(serCustState)), C.CString(string(serPayToken))))
resp := C.GoString(C.ffishim_bidirectional_establish_customer_final(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serPayToken))))
r, err := processCResponse(resp)
if err != nil {
return false, "", CustState{}, err
return false,ChannelState{}, CustState{}, err
}
err = json.Unmarshal([]byte(r.ChannelState), &channelState)
if err != nil {
return false, ChannelState{}, CustState{}, err
}
err = json.Unmarshal([]byte(r.CustState), &custState)
return r.IsEstablished, r.ChannelState, custState, err
return r.IsEstablished, channelState, custState, err
}
func BidirectionalPayGeneratePaymentProof(serChannelState string, custState CustState, amount int) (string, CustState, error) {
func BidirectionalPayGeneratePaymentProof(channelState ChannelState, custState CustState, amount int) (string, CustState, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return "", CustState{}, err
}
serCustState, err := json.Marshal(custState)
if err != nil {
return "", CustState{}, err
}
resp := C.GoString(C.ffishim_bidirectional_pay_generate_payment_proof(C.CString(serChannelState), C.CString(string(serCustState)), C.int(amount)))
resp := C.GoString(C.ffishim_bidirectional_pay_generate_payment_proof(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.int(amount)))
r, err := processCResponse(resp)
if err != nil {
return "", CustState{}, err
@ -310,12 +362,16 @@ func BidirectionalPayGeneratePaymentProof(serChannelState string, custState Cust
return r.Payment, custState, err
}
func BidirectionalPayVerifyPaymentProof(serChannelState string, serPayProof string, merchState MerchState) (Signature, MerchState, error) {
func BidirectionalPayVerifyPaymentProof(channelState ChannelState, serPayProof string, merchState MerchState) (Signature, MerchState, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return Signature{}, MerchState{}, err
}
serMerchState, err := json.Marshal(merchState)
if err != nil {
return Signature{}, MerchState{}, err
}
resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_proof(C.CString(serChannelState), C.CString(serPayProof), C.CString(string(serMerchState))))
resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_proof(C.CString(string(serChannelState)), C.CString(serPayProof), C.CString(string(serMerchState))))
r, err := processCResponse(resp)
if err != nil {
return Signature{}, MerchState{}, err
@ -329,7 +385,11 @@ func BidirectionalPayVerifyPaymentProof(serChannelState string, serPayProof stri
return *closeToken, merchState, err
}
func BidirectionalPayGenerateRevokeToken(serChannelState string, custState CustState, newCustState CustState, closeToken Signature) (RevokeToken, CustState, error) {
func BidirectionalPayGenerateRevokeToken(channelState ChannelState, custState CustState, newCustState CustState, closeToken Signature) (RevokeToken, CustState, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return RevokeToken{}, CustState{}, err
}
serCloseToken, err := json.Marshal(closeToken)
if err != nil {
return RevokeToken{}, CustState{}, err
@ -342,7 +402,7 @@ func BidirectionalPayGenerateRevokeToken(serChannelState string, custState CustS
if err != nil {
return RevokeToken{}, CustState{}, err
}
resp := C.GoString(C.ffishim_bidirectional_pay_generate_revoke_token(C.CString(serChannelState), C.CString(string(serCustState)), C.CString(string(serNewCustState)), C.CString(string(serCloseToken))))
resp := C.GoString(C.ffishim_bidirectional_pay_generate_revoke_token(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serNewCustState)), C.CString(string(serCloseToken))))
r, err := processCResponse(resp)
if err != nil {
return RevokeToken{}, CustState{}, err
@ -379,7 +439,11 @@ func BidirectionalPayVerifyRevokeToken(revokeToken RevokeToken, merchState Merch
return *payToken, merchState, err
}
func BidirectionalPayVerifyPaymentToken(serChannelState string, custState CustState, payToken Signature) (CustState, bool, error) {
func BidirectionalPayVerifyPaymentToken(channelState ChannelState, custState CustState, payToken Signature) (CustState, bool, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return CustState{}, false, err
}
serPayToken, err := json.Marshal(payToken)
if err != nil {
return CustState{}, false, err
@ -388,7 +452,7 @@ func BidirectionalPayVerifyPaymentToken(serChannelState string, custState CustSt
if err != nil {
return CustState{}, false, err
}
resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_token(C.CString(serChannelState), C.CString(string(serCustState)), C.CString(string(serPayToken))))
resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_token(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serPayToken))))
r, err := processCResponse(resp)
if err != nil {
return CustState{}, false, err
@ -397,12 +461,16 @@ func BidirectionalPayVerifyPaymentToken(serChannelState string, custState CustSt
return custState, r.IsPayValid, err
}
func BidirectionalCustomerClose(serChannelState string, custState CustState) (CustClose, error) {
func BidirectionalCustomerClose(channelState ChannelState, custState CustState) (CustClose, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return CustClose{}, err
}
serCustState, err := json.Marshal(custState)
if err != nil {
return CustClose{}, err
}
resp := C.GoString(C.ffishim_bidirectional_customer_close(C.CString(serChannelState), C.CString(string(serCustState))))
resp := C.GoString(C.ffishim_bidirectional_customer_close(C.CString(string(serChannelState)), C.CString(string(serCustState))))
r, err := processCResponse(resp)
if err != nil {
return CustClose{}, err
@ -412,7 +480,11 @@ func BidirectionalCustomerClose(serChannelState string, custState CustState) (Cu
return custClose, err
}
func BidirectionalMerchantClose(serChannelState string, channelToken ChannelToken, serAddress string, custClose CustClose, merchState MerchState) (string, string, string, error) {
func BidirectionalMerchantClose(channelState ChannelState, channelToken ChannelToken, serAddress string, custClose CustClose, merchState MerchState) (string, string, string, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
return "", "", "", err
}
serMerchState, err := json.Marshal(merchState)
if err != nil {
return "", "", "", err
@ -425,7 +497,7 @@ func BidirectionalMerchantClose(serChannelState string, channelToken ChannelToke
if err != nil {
return "", "", "", err
}
resp := C.GoString(C.ffishim_bidirectional_merchant_close(C.CString(serChannelState), C.CString(string(serChannelToken)), C.CString(serAddress), C.CString(string(serCustClose)), C.CString(string(serMerchState))))
resp := C.GoString(C.ffishim_bidirectional_merchant_close(C.CString(string(serChannelState)), C.CString(string(serChannelToken)), C.CString(serAddress), C.CString(string(serCustClose)), C.CString(string(serMerchState))))
r, err := processCResponse(resp)
if err != nil {
return "", "", "", err

View File

@ -14,14 +14,14 @@ func Test_ChannelSetup(t *testing.T) {
assert.NotEqual(t, ChannelToken{}, channelToken)
}
func setup(b0Cust int, b0Merch int) (string, ChannelToken, MerchState, CustState, error) {
func setup(b0Cust int, b0Merch int) (ChannelState, ChannelToken, MerchState, CustState, error) {
channelState, err := BidirectionalChannelSetup("Test Channel", false)
if err != nil {
return "", ChannelToken{}, MerchState{}, CustState{}, err
return ChannelState{}, ChannelToken{}, MerchState{}, CustState{}, err
}
channelToken, merchState, channelState, err := BidirectionalInitMerchant(channelState, b0Merch, "Bob")
if err != nil {
return "", ChannelToken{}, MerchState{}, CustState{}, err
return ChannelState{}, ChannelToken{}, MerchState{}, CustState{}, err
}
channelToken, custState, err := BidirectionalInitCustomer(channelState, channelToken, b0Cust, b0Merch, "Alice")
return channelState, channelToken, merchState, custState, err
@ -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

@ -22,7 +22,7 @@ This must be computed in a trusted setup.
#[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 struct ParamsUL<E: Engine> {
pub mpk: PublicParams<E>,
pub signatures: HashMap<String, Signature<E>>,
pub csParams: CSMultiParams<E>,
@ -44,9 +44,9 @@ This must be computed in a trusted setup.
#[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 SecretParamsUL<E: Engine> {
pub struct SecretParamsUL<E: Engine> {
pub pubParams: ParamsUL<E>,
kp: BlindKeyPair<E>,
pub kp: BlindKeyPair<E>,
}
#[derive(Clone)]
@ -117,9 +117,9 @@ This must be computed in a trusted setup.
#[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,
b: i32,
pub p: ParamsUL<E>,
pub a: i32,
pub b: i32,
}
/**
@ -131,7 +131,7 @@ This must be computed in a trusted setup.
#[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 RPSecretParams<E: Engine> {
pub pubParams: RPPublicParams<E>,
p: SecretParamsUL<E>,
pub p: SecretParamsUL<E>,
}
impl<E: Engine> SecretParamsUL<E> {
@ -233,7 +233,7 @@ impl<E: Engine> ParamsUL<E> {
self.prove_ul_response(r, C, &proofUlState, c, k, otherM)
}
fn prove_ul_commitment<R: Rng>(&self, rng: &mut R, x: i32, k: usize, sOptional: Option<Vec<E::Fr>>, mOptional: Option<E::Fr>) -> ProofULState<E> {
pub fn prove_ul_commitment<R: Rng>(&self, rng: &mut R, x: i32, k: usize, sOptional: Option<Vec<E::Fr>>, mOptional: Option<E::Fr>) -> ProofULState<E> {
if x > self.u.pow(self.l as u32) || x < 0 {
panic!("x is not within the range.");
}
@ -286,7 +286,7 @@ impl<E: Engine> ParamsUL<E> {
ProofULState { decx, proofStates, V, D, m, s }
}
fn prove_ul_response(&self, r: E::Fr, C: Commitment<E>, proofUlState: &ProofULState<E>, c: E::Fr, k: usize, otherM: Vec<E::Fr>) -> ProofUL<E> {
pub fn prove_ul_response(&self, r: E::Fr, C: Commitment<E>, proofUlState: &ProofULState<E>, c: E::Fr, k: usize, otherM: Vec<E::Fr>) -> ProofUL<E> {
let mut sigProofs = Vec::<SignatureProof<E>>::with_capacity(self.l as usize);
let mut zr = proofUlState.m.clone();
let mut rc = r.clone();

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

@ -7,7 +7,7 @@ use cl::{Signature, PublicParams, setup, BlindKeyPair, SignatureProof, PublicKey
use ped92::{Commitment, CSMultiParams, CommitmentProof};
use pairing::{Engine, CurveProjective};
use wallet::Wallet;
use ccs08::{RPPublicParams, RPSecretParams, RangeProof};
use ccs08::{SecretParamsUL, ParamsUL, ProofUL};
use serde::{Serialize, Deserialize};
use util;
use std::borrow::BorrowMut;
@ -28,8 +28,8 @@ pub struct NIZKProof<E: Engine> {
pub sig: Signature<E>,
pub sigProof: SignatureProof<E>,
pub comProof: CommitmentProof<E>,
pub rpBC: RangeProof<E>,
pub rpBM: RangeProof<E>,
pub rpBC: ProofUL<E>,
pub rpBM: ProofUL<E>,
}
/// NIZKPublicParams are public parameters to perform a NIZK Proof of Knowledge during the payment and closing protocol
@ -46,8 +46,7 @@ pub struct NIZKPublicParams<E: Engine> {
pub mpk: PublicParams<E>,
pub pk: BlindPublicKey<E>,
pub comParams: CSMultiParams<E>,
pub rpParamsBC: RPPublicParams<E>,
pub rpParamsBM: RPPublicParams<E>,
pub rpParams: ParamsUL<E>,
}
/// NIZKSecretParams are secret parameters to perform the verification of a NIZK Proof of Knowledge during the payment and closing protocol
@ -63,8 +62,7 @@ pub struct NIZKPublicParams<E: Engine> {
pub struct NIZKSecretParams<E: Engine> {
pub pubParams: NIZKPublicParams<E>,
pub keypair: BlindKeyPair<E>,
pub rpParamsBC: RPSecretParams<E>,
pub rpParamsBM: RPSecretParams<E>,
pub rpParams: SecretParamsUL<E>,
}
impl<E: Engine> NIZKSecretParams<E> {
@ -74,11 +72,12 @@ impl<E: Engine> NIZKSecretParams<E> {
let mpk = setup(rng);
let keypair = BlindKeyPair::<E>::generate(rng, &mpk, messageLength);
let comParams = keypair.generate_cs_multi_params(&mpk);
let rpParamsBC = RPSecretParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone());
let rpParamsBM = RPSecretParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone());
let pubParams = NIZKPublicParams { mpk, pk: keypair.public.clone(), comParams, rpParamsBC: rpParamsBC.pubParams.clone(), rpParamsBM: rpParamsBM.pubParams.clone() };
let u = 57; //TODO: optimize u?
let l = (std::i16::MAX as f32).log(u as f32).floor() as i32;
let rpParams = SecretParamsUL::setup_ul(rng, u, l, comParams.clone());
let pubParams = NIZKPublicParams { mpk, pk: keypair.public.clone(), comParams, rpParams: rpParams.pubParams.clone() };
NIZKSecretParams{pubParams, keypair, rpParamsBC, rpParamsBM}
NIZKSecretParams { pubParams, keypair, rpParams }
}
/**
@ -94,7 +93,7 @@ impl<E: Engine> NIZKSecretParams<E> {
let r0 = proof.sig.h != E::G1::one();
//compute challenge
let challenge = NIZKPublicParams::<E>::hash(proof.sigProof.a, vec! {proof.comProof.T, proof.rpBC.p1.D, proof.rpBC.p2.D, proof.rpBM.p1.D, proof.rpBM.p2.D});
let challenge = NIZKPublicParams::<E>::hash(proof.sigProof.a, vec! {proof.comProof.T, proof.rpBC.D, proof.rpBM.D});
//verify knowledge of signature
let mut r1 = self.keypair.public.verify_proof(&self.pubParams.mpk, proof.sig, proof.sigProof.clone(), challenge);
@ -103,11 +102,11 @@ 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.rpParamsBC.verify(proof.rpBC.clone(), challenge.clone(), 3);
let r4 = self.rpParamsBM.verify(proof.rpBM.clone(), challenge.clone(), 4);
let r3 = self.rpParams.verify_ul(&proof.rpBC.clone(), challenge.clone(), 3);
let r4 = self.rpParams.verify_ul(&proof.rpBM.clone(), challenge.clone(), 4);
//verify linear relationship
let mut r5 = proof.comProof.z[1] == proof.sigProof.zsig[0];
@ -147,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();
@ -158,11 +157,11 @@ impl<E: Engine> NIZKPublicParams<E> {
let proofState = self.pk.prove_commitment(rng, &self.mpk, &paymentToken, tOptional, None);
//commit range proof
let rpStateBC = self.rpParamsBC.prove_commitment(rng, newWallet.bc.clone(), newWalletCom.clone(), 3, None, None);
let rpStateBM = self.rpParamsBM.prove_commitment(rng, newWallet.bm.clone(), newWalletCom.clone(), 4, None, None);
let rpStateBC = self.rpParams.prove_ul_commitment(rng, newWallet.bc.clone(), 3, None, None);
let rpStateBM = self.rpParams.prove_ul_commitment(rng, newWallet.bm.clone(), 4, None, None);
//Compute challenge
let challenge = NIZKPublicParams::<E>::hash(proofState.a, vec! {D, rpStateBC.ps1.D, rpStateBC.ps2.D, rpStateBM.ps1.D, rpStateBM.ps2.D});
let challenge = NIZKPublicParams::<E>::hash(proofState.a, vec! {D, rpStateBC.D, rpStateBM.D});
//Response phase
//response for signature
@ -171,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();
@ -184,8 +183,8 @@ impl<E: Engine> NIZKPublicParams<E> {
let mut vec4 = newWalletVec[4..].to_vec();
vec01.append(&mut vec4);
}
let rpBC = self.rpParamsBC.prove_response(rPrime.clone(), &rpStateBC, challenge.clone(), 3, vecWithout2.to_vec());
let rpBM = self.rpParamsBM.prove_response(rPrime.clone(), &rpStateBM, challenge.clone(), 4, vec01.to_vec());
let rpBC = self.rpParams.prove_ul_response(rPrime.clone(), newWalletCom.clone(), &rpStateBC, challenge.clone(), 3, vecWithout2.to_vec());
let rpBM = self.rpParams.prove_ul_response(rPrime.clone(), newWalletCom.clone(), &rpStateBM, challenge.clone(), 4, vec01.to_vec());
NIZKProof { sig: proofState.blindSig, sigProof, comProof, rpBC, rpBM }
}
@ -204,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;
}
@ -274,7 +247,7 @@ mod tests {
let paymentToken = secParams.keypair.unblind(&r, &blindPaymentToken);
let proof = secParams.pubParams.prove(rng, wallet1, wallet2,
commitment2.clone(), rprime, &paymentToken);
commitment2.clone(), rprime, &paymentToken);
let fr = convert_int_to_fr::<Bls12>(*epsilon);
assert_eq!(secParams.verify(proof, fr, &commitment2, wpk), true);
}
@ -304,7 +277,7 @@ mod tests {
let paymentToken = secParams.keypair.unblind(&r, &blindPaymentToken);
let proof = secParams.pubParams.prove(rng, wallet1, wallet2,
commitment2.clone(), rprime, &paymentToken);
commitment2.clone(), rprime, &paymentToken);
let fr = convert_int_to_fr::<Bls12>(*epsilon);
assert_eq!(secParams.verify(proof, fr, &commitment2, wpk), true);
}
@ -345,7 +318,7 @@ mod tests {
assert!(pk.verify(&secParams.pubParams.mpk, &wallet2.as_fr_vec(), &closeToken));
let proof = secParams.pubParams.prove(rng, wallet1, wallet2,
commitment2.clone(), rprime, &paymentToken);
commitment2.clone(), rprime, &paymentToken);
assert_eq!(secParams.verify(proof, Fr::from_str(&epsilon.to_string()).unwrap(), &commitment2, wpk), true);
}
@ -407,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]
@ -430,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));
}
@ -443,10 +416,11 @@ mod tests {
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::RPSecretParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone());
let rpParamsBM = ccs08::RPSecretParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone());
let u = 57; //TODO: optimize u?
let l = (std::i16::MAX as f32).log(u as f32).floor() as i32;
let rpParams = ccs08::SecretParamsUL::setup_ul(rng, u, l, comParams.clone());
let nizk_params = NIZKPublicParams { mpk: mpk, pk: blindkeypair.public, comParams: comParams, rpParamsBC: rpParamsBC.pubParams, rpParamsBM: rpParamsBM.pubParams };
let nizk_params = NIZKPublicParams { mpk: mpk, pk: blindkeypair.public, comParams: comParams, rpParams: rpParams.pubParams.clone() };
let is_serialized = serde_json::to_vec(&nizk_params).unwrap();
println!("NIZK Struct len: {}", is_serialized.len());

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