From aff41dce685e9629f183e134cf24ec294f5fbbae Mon Sep 17 00:00:00 2001 From: "J. Ayo Akinyele" Date: Sat, 23 Nov 2019 00:14:09 -0500 Subject: [PATCH] add BN support to ffishim and py/go api --- examples/bolt_test_bn256.rs | 2 +- go/libbolt.go | 40 +-- include/libbolt.h | 48 ++-- py/libbolt.py | 120 ++++----- py/libbolt_bn256.py | 369 ++++++++++++++++++++++++++ src/ffishim.rs | 158 +++++------ src/ffishim_bn256.rs | 511 ++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 8 files changed, 1056 insertions(+), 193 deletions(-) create mode 100644 py/libbolt_bn256.py create mode 100644 src/ffishim_bn256.rs diff --git a/examples/bolt_test_bn256.rs b/examples/bolt_test_bn256.rs index 8658d1b..107e6ae 100644 --- a/examples/bolt_test_bn256.rs +++ b/examples/bolt_test_bn256.rs @@ -76,7 +76,7 @@ fn main() { assert!(cust_state.verify_close_token(&channel_state, &close_token)); - // wait for funding tx to be confirmed, etc + // wait for funding tx to be confirmed, etc // obtain payment token for pay protocol let pay_token = bidirectional::establish_merchant_issue_pay_token(rng, &channel_state, &com, &merch_state); diff --git a/go/libbolt.go b/go/libbolt.go index 95e5065..8bb53f3 100644 --- a/go/libbolt.go +++ b/go/libbolt.go @@ -233,7 +233,7 @@ type ZkChannelParams struct { } func BidirectionalChannelSetup(name string, channelSupport bool) (ChannelState, error) { - resp := C.GoString(C.ffishim_bidirectional_channel_setup(C.CString(name), C.uint(btoi(channelSupport)))) + resp := C.GoString(C.ffishim_bls12_channel_setup(C.CString(name), C.uint(btoi(channelSupport)))) r, err := processCResponse(resp) if err != nil { return ChannelState{}, err @@ -248,7 +248,7 @@ func BidirectionalInitMerchant(channelState ChannelState, nameMerchant string) ( if err != nil { return ChannelToken{}, MerchState{}, ChannelState{}, err } - resp := C.GoString(C.ffishim_bidirectional_init_merchant(C.CString(string(serChannelState)), C.CString(nameMerchant))) + resp := C.GoString(C.ffishim_bls12_init_merchant(C.CString(string(serChannelState)), C.CString(nameMerchant))) r, err := processCResponse(resp) if err != nil { return ChannelToken{}, MerchState{}, ChannelState{}, err @@ -272,7 +272,7 @@ func BidirectionalInitCustomer(channelToken ChannelToken, balanceCustomer int, b if err != nil { return ChannelToken{}, CustState{}, err } - resp := C.GoString(C.ffishim_bidirectional_init_customer(C.CString(string(serChannelToken)), C.longlong(balanceCustomer), C.longlong(balanceMerchant), C.CString(nameCustomer))) + resp := C.GoString(C.ffishim_bls12_init_customer(C.CString(string(serChannelToken)), C.longlong(balanceCustomer), C.longlong(balanceMerchant), C.CString(nameCustomer))) r, err := processCResponse(resp) if err != nil { return ChannelToken{}, CustState{}, err @@ -295,7 +295,7 @@ func BidirectionalEstablishCustomerGenerateProof(channelToken ChannelToken, cust if err != nil { return ChannelToken{}, CustState{}, Commitment{}, CommitmentProof{}, err } - resp := C.GoString(C.ffishim_bidirectional_establish_customer_generate_proof(C.CString(string(serChannelToken)), C.CString(string(serCustState)))) + resp := C.GoString(C.ffishim_bls12_establish_customer_generate_proof(C.CString(string(serChannelToken)), C.CString(string(serCustState)))) r, err := processCResponse(resp) if err != nil { return ChannelToken{}, CustState{}, Commitment{}, CommitmentProof{}, err @@ -325,7 +325,7 @@ func BidirectionalGenerateChannelID(channelToken ChannelToken) (error) { if err != nil { return err } - resp := C.GoString(C.ffishim_bidirectional_generate_channel_id(C.CString(string(serChannelToken)))) + resp := C.GoString(C.ffishim_bls12_generate_channel_id(C.CString(string(serChannelToken)))) r, err := processCResponse(resp) if err != nil { return err @@ -357,7 +357,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.CString(string(serChannelId)), C.longlong(initCustBal), C.longlong(initMerchBal), C.CString(string(serMerchState)))) + resp := C.GoString(C.ffishim_bls12_establish_merchant_issue_close_token(C.CString(string(serChannelState)), C.CString(string(serCom)), C.CString(string(serComProof)), C.CString(string(serChannelId)), C.longlong(initCustBal), C.longlong(initMerchBal), C.CString(string(serMerchState)))) r, err := processCResponse(resp) if err != nil { return Signature{}, err @@ -380,7 +380,7 @@ func BidirectionalEstablishMerchantIssuePayToken(channelState ChannelState, com if err != nil { return Signature{}, err } - resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_pay_token(C.CString(string(serChannelState)), C.CString(string(serCom)), C.CString(string(serMerchState)))) + resp := C.GoString(C.ffishim_bls12_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 @@ -403,7 +403,7 @@ func BidirectionalVerifyCloseToken(channelState ChannelState, custState CustStat if err != nil { return false, ChannelState{}, CustState{}, err } - resp := C.GoString(C.ffishim_bidirectional_verify_close_token(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serCloseToken)))) + resp := C.GoString(C.ffishim_bls12_verify_close_token(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serCloseToken)))) r, err := processCResponse(resp) if err != nil { return false, ChannelState{}, CustState{}, err @@ -429,7 +429,7 @@ func BidirectionalEstablishCustomerFinal(channelState ChannelState, custState Cu if err != nil { return false, ChannelState{}, CustState{}, err } - resp := C.GoString(C.ffishim_bidirectional_establish_customer_final(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serPayToken)))) + resp := C.GoString(C.ffishim_bls12_establish_customer_final(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serPayToken)))) r, err := processCResponse(resp) if err != nil { return false, ChannelState{}, CustState{}, err @@ -451,7 +451,7 @@ func BidirectionalPayGeneratePaymentProof(channelState ChannelState, custState C if err != nil { return Payment{}, CustState{}, err } - resp := C.GoString(C.ffishim_bidirectional_pay_generate_payment_proof(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.longlong(amount))) + resp := C.GoString(C.ffishim_bls12_pay_generate_payment_proof(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.longlong(amount))) r, err := processCResponse(resp) if err != nil { return Payment{}, CustState{}, err @@ -478,7 +478,7 @@ func BidirectionalPayVerifyPaymentProof(channelState ChannelState, payProof Paym if err != nil { return Signature{}, MerchState{}, err } - resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_proof(C.CString(string(serChannelState)), C.CString(string(serPayProof)), C.CString(string(serMerchState)))) + resp := C.GoString(C.ffishim_bls12_pay_verify_payment_proof(C.CString(string(serChannelState)), C.CString(string(serPayProof)), C.CString(string(serMerchState)))) r, err := processCResponse(resp) if err != nil { return Signature{}, MerchState{}, err @@ -509,7 +509,7 @@ func BidirectionalPayVerifyMultiplePaymentProofs(channelState ChannelState, send if err != nil { return Signature{}, Signature{}, MerchState{}, err } - resp := C.GoString(C.ffishim_bidirectional_pay_verify_multiple_payment_proofs(C.CString(string(serChannelState)), C.CString(string(serSenderPayProof)), C.CString(string(serReceiverPayProof)), C.CString(string(serMerchState)))) + resp := C.GoString(C.ffishim_bls12_pay_verify_multiple_payment_proofs(C.CString(string(serChannelState)), C.CString(string(serSenderPayProof)), C.CString(string(serReceiverPayProof)), C.CString(string(serMerchState)))) r, err := processCResponse(resp) if err != nil { return Signature{}, Signature{}, MerchState{}, err @@ -545,7 +545,7 @@ func BidirectionalPayGenerateRevokeToken(channelState ChannelState, custState Cu if err != nil { return RevokeToken{}, CustState{}, err } - 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)))) + resp := C.GoString(C.ffishim_bls12_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 @@ -568,7 +568,7 @@ func BidirectionalPayVerifyRevokeToken(revokeToken RevokeToken, merchState Merch if err != nil { return Signature{}, MerchState{}, err } - resp := C.GoString(C.ffishim_bidirectional_pay_verify_revoke_token(C.CString(string(serRevokeToken)), C.CString(string(serMerchState)))) + resp := C.GoString(C.ffishim_bls12_pay_verify_revoke_token(C.CString(string(serRevokeToken)), C.CString(string(serMerchState)))) r, err := processCResponse(resp) if err != nil { return Signature{}, MerchState{}, err @@ -595,7 +595,7 @@ func BidirectionalPayVerifyMultipleRevokeTokens(senderRevokeToken RevokeToken, r if err != nil { return Signature{}, Signature{}, MerchState{}, err } - resp := C.GoString(C.ffishim_bidirectional_pay_verify_multiple_revoke_tokens(C.CString(string(serSenderRevokeToken)), C.CString(string(serReceiverRevokeToken)), C.CString(string(serMerchState)))) + resp := C.GoString(C.ffishim_bls12_pay_verify_multiple_revoke_tokens(C.CString(string(serSenderRevokeToken)), C.CString(string(serReceiverRevokeToken)), C.CString(string(serMerchState)))) r, err := processCResponse(resp) if err != nil { return Signature{}, Signature{}, MerchState{}, err @@ -627,7 +627,7 @@ func BidirectionalPayVerifyPaymentToken(channelState ChannelState, custState Cus if err != nil { return CustState{}, false, err } - resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_token(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serPayToken)))) + resp := C.GoString(C.ffishim_bls12_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 @@ -645,7 +645,7 @@ func BidirectionalCustomerClose(channelState ChannelState, custState CustState) if err != nil { return CustClose{}, err } - resp := C.GoString(C.ffishim_bidirectional_customer_close(C.CString(string(serChannelState)), C.CString(string(serCustState)))) + resp := C.GoString(C.ffishim_bls12_customer_close(C.CString(string(serChannelState)), C.CString(string(serCustState)))) r, err := processCResponse(resp) if err != nil { return CustClose{}, err @@ -672,7 +672,7 @@ func BidirectionalMerchantClose(channelState ChannelState, channelToken ChannelT if err != nil { return "", "", "", err } - 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)))) + resp := C.GoString(C.ffishim_bls12_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 @@ -685,7 +685,7 @@ func BidirectionalWtpVerifyCustCloseMessage(channelToken ChannelToken, serWpk st if err != nil { return "", err } - resp := C.GoString(C.ffishim_bidirectional_wtp_verify_cust_close_message(C.CString(string(serChannelToken)), C.CString(serWpk), C.CString(serCloseMsg), C.CString(string(serCloseToken)))) + resp := C.GoString(C.ffishim_bls12_wtp_verify_cust_close_message(C.CString(string(serChannelToken)), C.CString(serWpk), C.CString(serCloseMsg), C.CString(string(serCloseToken)))) r, err := processCResponse(resp) if err != nil { return "", err @@ -698,7 +698,7 @@ func BidirectionalWtpVerifyMerchCloseMessage(channelToken ChannelToken, serWpk s if err != nil { return "", err } - resp := C.GoString(C.ffishim_bidirectional_wtp_verify_merch_close_message(C.CString(string(serChannelToken)), C.CString(serWpk), C.CString(serMerchClose))) + resp := C.GoString(C.ffishim_bls12_wtp_verify_merch_close_message(C.CString(string(serChannelToken)), C.CString(serWpk), C.CString(serMerchClose))) r, err := processCResponse(resp) if err != nil { return "", err diff --git a/include/libbolt.h b/include/libbolt.h index f36d6bb..2bb3190 100644 --- a/include/libbolt.h +++ b/include/libbolt.h @@ -16,36 +16,36 @@ extern "C" { #endif // channel init -char* ffishim_bidirectional_channel_setup(const char *channel_name, unsigned int third_party_support); -char* ffishim_bidirectional_init_merchant(const char *ser_channel_state, const char *name_ptr); -char* ffishim_bidirectional_init_customer(const char *ser_channel_token, long long int balance_customer, long long int balance_merchant, const char *name_ptr); +char* ffishim_bls12_channel_setup(const char *channel_name, unsigned int third_party_support); +char* ffishim_bls12_init_merchant(const char *ser_channel_state, const char *name_ptr); +char* ffishim_bls12_init_customer(const char *ser_channel_token, long long int balance_customer, long long int balance_merchant, const char *name_ptr); // channel establish protocol routines -char* ffishim_bidirectional_establish_customer_generate_proof(const char *ser_channel_token, const char *ser_customer_wallet); -char* ffishim_bidirectional_generate_channel_id(const char *ser_channel_token); -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, long long int init_cust_bal, long long 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); +char* ffishim_bls12_establish_customer_generate_proof(const char *ser_channel_token, const char *ser_customer_wallet); +char* ffishim_bls12_generate_channel_id(const char *ser_channel_token); +char* ffishim_bls12_establish_merchant_issue_close_token(const char *ser_channel_state, const char *ser_com, const char *ser_com_proof, const char *ser_pk_c, long long int init_cust_bal, long long int init_merch_bal, const char *ser_merch_state); +char* ffishim_bls12_establish_merchant_issue_pay_token(const char *ser_channel_state, const char *ser_com, const char *ser_merch_state); +char* ffishim_bls12_verify_close_token(const char *ser_channel_state, const char *ser_customer_wallet, const char *ser_close_token); +char* ffishim_bls12_establish_customer_final(const char *ser_channel_state, const char *ser_customer_wallet, const char *ser_pay_token); // channel pay protocol routines -char* ffishim_bidirectional_pay_generate_payment_proof(const char *ser_channel_state, const char *ser_customer_wallet, long long int amount); -char* ffishim_bidirectional_pay_verify_payment_proof(const char *ser_channel_state, const char *ser_pay_proof, const char *ser_merch_state); -char* ffishim_bidirectional_pay_verify_multiple_payment_proofs(const char *ser_channel_state, const char *ser_sender_pay_proof, const char *ser_receiver_pay_proof, const char *ser_merch_state); -char* ffishim_bidirectional_pay_generate_revoke_token(const char *ser_channel_state, const char *ser_cust_state, const char *ser_new_cust_state, const char *ser_close_token); -char* ffishim_bidirectional_pay_verify_revoke_token(const char *ser_revoke_token, const char *ser_merch_state); -char* ffishim_bidirectional_pay_verify_multiple_revoke_tokens(const char *ser_sender_revoke_token, const char *ser_receiver_revoke_token, const char *ser_merch_state); -char* ffishim_bidirectional_pay_verify_payment_token(const char *ser_channel_state, const char *ser_cust_state, const char *ser_pay_token); +char* ffishim_bls12_pay_generate_payment_proof(const char *ser_channel_state, const char *ser_customer_wallet, long long int amount); +char* ffishim_bls12_pay_verify_payment_proof(const char *ser_channel_state, const char *ser_pay_proof, const char *ser_merch_state); +char* ffishim_bls12_pay_verify_multiple_payment_proofs(const char *ser_channel_state, const char *ser_sender_pay_proof, const char *ser_receiver_pay_proof, const char *ser_merch_state); +char* ffishim_bls12_pay_generate_revoke_token(const char *ser_channel_state, const char *ser_cust_state, const char *ser_new_cust_state, const char *ser_close_token); +char* ffishim_bls12_pay_verify_revoke_token(const char *ser_revoke_token, const char *ser_merch_state); +char* ffishim_bls12_pay_verify_multiple_revoke_tokens(const char *ser_sender_revoke_token, const char *ser_receiver_revoke_token, const char *ser_merch_state); +char* ffishim_bls12_pay_verify_payment_token(const char *ser_channel_state, const char *ser_cust_state, const char *ser_pay_token); // closing routines for both sides -char* ffishim_bidirectional_customer_close(const char *ser_channel_state, const char *ser_cust_state); -char* ffishim_bidirectional_merchant_close(const char *ser_channel_state, const char *ser_channel_token, const char *ser_address, const char *ser_cust_close, const char *ser_merch_state); +char* ffishim_bls12_customer_close(const char *ser_channel_state, const char *ser_cust_state); +char* ffishim_bls12_merchant_close(const char *ser_channel_state, const char *ser_channel_token, const char *ser_address, const char *ser_cust_close, const char *ser_merch_state); // WTP logic for on-chain validation of closing messages -char* ffishim_bidirectional_wtp_verify_cust_close_message(const char *ser_channel_token, const char *ser_wpk, const char *ser_close_msg, const char *ser_close_token); -char* ffishim_bidirectional_wtp_verify_merch_close_message(const char *ser_channel_token, const char *ser_wpk, const char *ser_merch_close); +char* ffishim_bls12_wtp_verify_cust_close_message(const char *ser_channel_token, const char *ser_wpk, const char *ser_close_msg, const char *ser_close_token); +char* ffishim_bls12_wtp_verify_merch_close_message(const char *ser_channel_token, const char *ser_wpk, const char *ser_merch_close); -char* ffishim_bidirectional_wtp_check_wpk(const char *wpk); +char* ffishim_bls12_wtp_check_wpk(const char *wpk); #ifdef __cplusplus @@ -65,7 +65,7 @@ char* ffishim_bidirectional_wtp_check_wpk(const char *wpk); int wtp_check_wpk(const char *wpk) { - const char *ret = ffishim_bidirectional_wtp_check_wpk(wpk); + const char *ret = ffishim_bls12_wtp_check_wpk(wpk); printf("RESULT: %s\n", ret); return 0; } @@ -79,7 +79,7 @@ char* ffishim_bidirectional_wtp_check_wpk(const char *wpk); int wtp_verify_cust_close_message(const char *channel_token, const char *wpk, const char *cust_close, const char *close_token) { // Call rust - const char *return_json = ffishim_bidirectional_wtp_verify_cust_close_message(channel_token, wpk, cust_close, close_token); + const char *return_json = ffishim_bls12_wtp_verify_cust_close_message(channel_token, wpk, cust_close, close_token); Document d; d.Parse(return_json); @@ -103,7 +103,7 @@ char* ffishim_bidirectional_wtp_check_wpk(const char *wpk); int wtp_verify_merch_close_message(const char *channel_token, const char *wpk, const char *merch_close) { // Call into Rust - const char* return_json = string_replace_all(ffishim_bidirectional_wtp_verify_merch_close_message(channel_token, wpk, merch_close), '\'', '\"'); + const char* return_json = string_replace_all(ffishim_bls12_wtp_verify_merch_close_message(channel_token, wpk, merch_close), '\'', '\"'); Document d; d.Parse(return_json); diff --git a/py/libbolt.py b/py/libbolt.py index 54aed1a..e09e2e3 100644 --- a/py/libbolt.py +++ b/py/libbolt.py @@ -15,123 +15,123 @@ class Libbolt(object): self.load_library_params() def load_library_params(self): - self.lib.ffishim_bidirectional_channel_setup.argtypes = (c_void_p, c_uint8) - self.lib.ffishim_bidirectional_channel_setup.restype = c_void_p + self.lib.ffishim_bls12_channel_setup.argtypes = (c_void_p, c_uint8) + self.lib.ffishim_bls12_channel_setup.restype = c_void_p # ESTABLISH PROTOCOL - self.lib.ffishim_bidirectional_init_merchant.argtypes = (c_void_p, c_void_p) - self.lib.ffishim_bidirectional_init_merchant.restype = c_void_p + self.lib.ffishim_bls12_init_merchant.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bls12_init_merchant.restype = c_void_p - self.lib.ffishim_bidirectional_init_customer.argtypes = (c_void_p, ctypes.c_int32, ctypes.c_int32, c_void_p) - self.lib.ffishim_bidirectional_init_customer.restype = c_void_p + self.lib.ffishim_bls12_init_customer.argtypes = (c_void_p, ctypes.c_int32, ctypes.c_int32, c_void_p) + self.lib.ffishim_bls12_init_customer.restype = c_void_p - 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_bls12_establish_customer_generate_proof.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bls12_establish_customer_generate_proof.restype = c_void_p - self.lib.ffishim_bidirectional_generate_channel_id.argtypes = (c_void_p, ) - self.lib.ffishim_bidirectional_generate_channel_id.restype = c_void_p + self.lib.ffishim_bls12_generate_channel_id.argtypes = (c_void_p, ) + self.lib.ffishim_bls12_generate_channel_id.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, c_void_p) - self.lib.ffishim_bidirectional_establish_merchant_issue_close_token.restype = c_void_p + self.lib.ffishim_bls12_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_bls12_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) - self.lib.ffishim_bidirectional_establish_merchant_issue_pay_token.restype = c_void_p + self.lib.ffishim_bls12_establish_merchant_issue_pay_token.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_establish_merchant_issue_pay_token.restype = c_void_p - self.lib.ffishim_bidirectional_verify_close_token.argtypes = (c_void_p, c_void_p, c_void_p) - self.lib.ffishim_bidirectional_verify_close_token.restype = c_void_p + self.lib.ffishim_bls12_verify_close_token.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_verify_close_token.restype = c_void_p - self.lib.ffishim_bidirectional_establish_customer_final.argtypes = (c_void_p, c_void_p, c_void_p) - self.lib.ffishim_bidirectional_establish_customer_final.restype = c_void_p + self.lib.ffishim_bls12_establish_customer_final.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_establish_customer_final.restype = c_void_p # PAY PROTOCOL - self.lib.ffishim_bidirectional_pay_generate_payment_proof.argtypes = (c_void_p, c_void_p, ctypes.c_int32) - self.lib.ffishim_bidirectional_pay_generate_payment_proof.restype = c_void_p + self.lib.ffishim_bls12_pay_generate_payment_proof.argtypes = (c_void_p, c_void_p, ctypes.c_int32) + self.lib.ffishim_bls12_pay_generate_payment_proof.restype = c_void_p - self.lib.ffishim_bidirectional_pay_verify_payment_proof.argtypes = (c_void_p, c_void_p, c_void_p) - self.lib.ffishim_bidirectional_pay_verify_payment_proof.restype = c_void_p + self.lib.ffishim_bls12_pay_verify_payment_proof.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_pay_verify_payment_proof.restype = c_void_p - self.lib.ffishim_bidirectional_pay_verify_multiple_payment_proofs.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p) - self.lib.ffishim_bidirectional_pay_verify_multiple_payment_proofs.restype = c_void_p + self.lib.ffishim_bls12_pay_verify_multiple_payment_proofs.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_pay_verify_multiple_payment_proofs.restype = c_void_p - self.lib.ffishim_bidirectional_pay_generate_revoke_token.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p) - self.lib.ffishim_bidirectional_pay_generate_revoke_token.restype = c_void_p + self.lib.ffishim_bls12_pay_generate_revoke_token.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_pay_generate_revoke_token.restype = c_void_p - self.lib.ffishim_bidirectional_pay_verify_revoke_token.argtypes = (c_void_p, c_void_p) - self.lib.ffishim_bidirectional_pay_verify_revoke_token.restype = c_void_p + self.lib.ffishim_bls12_pay_verify_revoke_token.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bls12_pay_verify_revoke_token.restype = c_void_p - self.lib.ffishim_bidirectional_pay_verify_multiple_revoke_tokens.argtypes = (c_void_p, c_void_p, c_void_p) - self.lib.ffishim_bidirectional_pay_verify_multiple_revoke_tokens.restype = c_void_p + self.lib.ffishim_bls12_pay_verify_multiple_revoke_tokens.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_pay_verify_multiple_revoke_tokens.restype = c_void_p - self.lib.ffishim_bidirectional_pay_verify_payment_token.argtypes = (c_void_p, c_void_p) - self.lib.ffishim_bidirectional_pay_verify_payment_token.restype = c_void_p + self.lib.ffishim_bls12_pay_verify_payment_token.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bls12_pay_verify_payment_token.restype = c_void_p # CLOSE - self.lib.ffishim_bidirectional_customer_close.argtypes = (c_void_p, c_void_p) - self.lib.ffishim_bidirectional_customer_close.restype = c_void_p + self.lib.ffishim_bls12_customer_close.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bls12_customer_close.restype = c_void_p - self.lib.ffishim_bidirectional_merchant_close.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p, c_void_p) - self.lib.ffishim_bidirectional_merchant_close.restype = c_void_p + self.lib.ffishim_bls12_merchant_close.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_merchant_close.restype = c_void_p # ON-CHAIN BOLT LOGIC / WTPs - self.lib.ffishim_bidirectional_wtp_verify_cust_close_message.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p) - self.lib.ffishim_bidirectional_wtp_verify_cust_close_message.restype = c_void_p + self.lib.ffishim_bls12_wtp_verify_cust_close_message.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_wtp_verify_cust_close_message.restype = c_void_p - self.lib.ffishim_bidirectional_wtp_verify_merch_close_message.argtypes = (c_void_p, c_void_p, c_void_p) - self.lib.ffishim_bidirectional_wtp_verify_merch_close_message.restype = c_void_p + self.lib.ffishim_bls12_wtp_verify_merch_close_message.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bls12_wtp_verify_merch_close_message.restype = c_void_p self.lib.ffishim_free_string.argtypes = (c_void_p, ) def channel_setup(self, name, third_party_support=0): - output_string = self.lib.ffishim_bidirectional_channel_setup(name.encode(), third_party_support) + output_string = self.lib.ffishim_bls12_channel_setup(name.encode(), third_party_support) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return output_dictionary.get('channel_state') # INIT PROTOCOL def bidirectional_init_merchant(self, channel_state, name): - output_string = self.lib.ffishim_bidirectional_init_merchant(channel_state.encode(), name.encode()) + output_string = self.lib.ffishim_bls12_init_merchant(channel_state.encode(), name.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return output_dictionary.get('channel_token'), output_dictionary.get('merch_state'), output_dictionary.get('channel_state') def bidirectional_init_customer(self, channel_token, b0_cust, b0_merch, name): - output_string = self.lib.ffishim_bidirectional_init_customer(channel_token.encode(), b0_cust, b0_merch, name.encode()) + output_string = self.lib.ffishim_bls12_init_customer(channel_token.encode(), b0_cust, b0_merch, name.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return (output_dictionary.get('channel_token'), output_dictionary.get('cust_state')) # ESTABLISH PROTOCOL def bidirectional_generate_channel_id(self, channel_token): - output_string = self.lib.ffishim_bidirectional_generate_channel_id(channel_token.encode()) + output_string = self.lib.ffishim_bls12_generate_channel_id(channel_token.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return output_dictionary.get('channel_id') def bidirectional_establish_customer_generate_proof(self, channel_token, cust_state): - output_string = self.lib.ffishim_bidirectional_establish_customer_generate_proof(channel_token.encode(), cust_state.encode()) + output_string = self.lib.ffishim_bls12_establish_customer_generate_proof(channel_token.encode(), cust_state.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return output_dictionary.get('channel_token'), output_dictionary.get('cust_state'), output_dictionary.get('com'), output_dictionary.get('com_proof') def bidirectional_establish_merchant_issue_close_token(self, channel_state, com, com_proof, channel_id, 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(), json.dumps(channel_id).encode(), init_cust, init_merch, merch_state.encode()) + output_string = self.lib.ffishim_bls12_establish_merchant_issue_close_token(channel_state.encode(), com.encode(), com_proof.encode(), json.dumps(channel_id).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') def bidirectional_establish_merchant_issue_pay_token(self, channel_state, com, merch_state): - output_string = self.lib.ffishim_bidirectional_establish_merchant_issue_pay_token(channel_state.encode(), com.encode(), merch_state.encode()) + output_string = self.lib.ffishim_bls12_establish_merchant_issue_pay_token(channel_state.encode(), com.encode(), merch_state.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return output_dictionary.get('pay_token') def bidirectional_establish_customer_verify_close_token(self, channel_state, cust_state, close_token): - output_string = self.lib.ffishim_bidirectional_verify_close_token(channel_state.encode(), cust_state.encode(), close_token.encode()) + output_string = self.lib.ffishim_bls12_verify_close_token(channel_state.encode(), cust_state.encode(), close_token.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) is_token_valid = self._convert_boolean(output_dictionary.get('is_token_valid')) return is_token_valid, output_dictionary.get('channel_state'), output_dictionary.get('cust_state') def bidirectional_establish_customer_final(self, channel_state, cust_state, pay_token): - output_string = self.lib.ffishim_bidirectional_establish_customer_final(channel_state.encode(), cust_state.encode(), pay_token.encode()) + output_string = self.lib.ffishim_bls12_establish_customer_final(channel_state.encode(), cust_state.encode(), pay_token.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) is_established = self._convert_boolean(output_dictionary.get('is_established')) return is_established, output_dictionary.get('channel_state'), output_dictionary.get('cust_state') @@ -140,44 +140,44 @@ class Libbolt(object): # generate payment proof and new cust state def bidirectional_pay_generate_payment_proof(self, channel_state, cust_state, amount): - output_string = self.lib.ffishim_bidirectional_pay_generate_payment_proof(channel_state.encode(), cust_state.encode(), amount) + output_string = self.lib.ffishim_bls12_pay_generate_payment_proof(channel_state.encode(), cust_state.encode(), amount) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return output_dictionary.get('payment'), output_dictionary.get('cust_state') # verify payment proof def bidirectional_pay_verify_payment_proof(self, channel_state, pay_proof, merch_state): - output_string = self.lib.ffishim_bidirectional_pay_verify_payment_proof(channel_state.encode(), pay_proof.encode(), merch_state.encode()) + output_string = self.lib.ffishim_bls12_pay_verify_payment_proof(channel_state.encode(), pay_proof.encode(), 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'), output_dictionary.get('merch_state')) # verify multiple payment proof def bidirectional_pay_verify_multiple_payment_proofs(self, channel_state, sender_pay_proof, receiver_pay_proof, merch_state): - output_string = self.lib.ffishim_bidirectional_pay_verify_multiple_payment_proofs(channel_state.encode(), sender_pay_proof.encode(), receiver_pay_proof.encode(), merch_state.encode()) + output_string = self.lib.ffishim_bls12_pay_verify_multiple_payment_proofs(channel_state.encode(), sender_pay_proof.encode(), receiver_pay_proof.encode(), merch_state.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return (output_dictionary.get('sender_close_token'), output_dictionary.get('receiver_cond_close_token'), output_dictionary.get('merch_state')) # generate revoke token def bidirectional_pay_generate_revoke_token(self, channel_state, cust_state, new_cust_state, close_token): - output_string = self.lib.ffishim_bidirectional_pay_generate_revoke_token(channel_state.encode(), cust_state.encode(), + output_string = self.lib.ffishim_bls12_pay_generate_revoke_token(channel_state.encode(), cust_state.encode(), new_cust_state.encode(), close_token.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return output_dictionary.get('revoke_token'), output_dictionary.get('cust_state') # verify revoke token def bidirectional_pay_verify_revoke_token(self, revoke_token, merch_state): - output_string = self.lib.ffishim_bidirectional_pay_verify_revoke_token(revoke_token.encode(), merch_state.encode()) + output_string = self.lib.ffishim_bls12_pay_verify_revoke_token(revoke_token.encode(), merch_state.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return (output_dictionary.get('pay_token'), output_dictionary.get('merch_state')) # verify multiple revoke tokens def bidirectional_pay_verify_multiple_revoke_tokens(self, sender_revoke_token, receiver_revoke_token, merch_state): - output_string = self.lib.ffishim_bidirectional_pay_verify_multiple_revoke_tokens(sender_revoke_token.encode(), receiver_revoke_token.encode(), merch_state.encode()) + output_string = self.lib.ffishim_bls12_pay_verify_multiple_revoke_tokens(sender_revoke_token.encode(), receiver_revoke_token.encode(), merch_state.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return (output_dictionary.get('sender_pay_token'), output_dictionary.get('receiver_pay_token'), output_dictionary.get('merch_state')) # verify payment token def bidirectional_pay_verify_payment_token(self, channel_state, cust_state, pay_token): - output_string = self.lib.ffishim_bidirectional_pay_verify_payment_token(channel_state.encode(), cust_state.encode(), pay_token.encode()) + output_string = self.lib.ffishim_bls12_pay_verify_payment_token(channel_state.encode(), cust_state.encode(), pay_token.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) is_pay_valid = self._convert_boolean(output_dictionary.get('is_pay_valid')) return (output_dictionary.get('cust_state'), is_pay_valid) @@ -185,12 +185,12 @@ class Libbolt(object): # CLOSE def bidirectional_customer_close(self, channel_state, cust_state): - output_string = self.lib.ffishim_bidirectional_customer_close(channel_state.encode(), cust_state.encode()) + output_string = self.lib.ffishim_bls12_customer_close(channel_state.encode(), cust_state.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return output_dictionary.get('cust_close') def bidirectional_merchant_close(self, channel_state, channel_token, address, cust_close, merch_state): - output_string = self.lib.ffishim_bidirectional_merchant_close(channel_state.encode(), channel_token.encode(), + output_string = self.lib.ffishim_bls12_merchant_close(channel_state.encode(), channel_token.encode(), address.encode(), cust_close.encode(), merch_state.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) return (output_dictionary.get('wpk'), output_dictionary.get('merch_close'), output_dictionary.get('error')) @@ -206,7 +206,7 @@ class Libbolt(object): return json.dumps(cust_close_dict.get("signature")) def wtp_verify_cust_close_message(self, channel_token, wpk, cust_close_wallet, close_token): - output_string = self.lib.ffishim_bidirectional_wtp_verify_cust_close_message(channel_token.encode(), + output_string = self.lib.ffishim_bls12_wtp_verify_cust_close_message(channel_token.encode(), wpk.encode(), cust_close_wallet.encode(), close_token.encode()) @@ -214,7 +214,7 @@ class Libbolt(object): return output_dictionary.get('result') def wtp_verify_merch_close_message(self, channel_token, wpk, merch_close): - output_string = self.lib.ffishim_bidirectional_wtp_verify_merch_close_message(channel_token.encode(), + output_string = self.lib.ffishim_bls12_wtp_verify_merch_close_message(channel_token.encode(), wpk.encode(), merch_close.encode()) output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) diff --git a/py/libbolt_bn256.py b/py/libbolt_bn256.py new file mode 100644 index 0000000..17b685d --- /dev/null +++ b/py/libbolt_bn256.py @@ -0,0 +1,369 @@ +from ctypes import cdll +from sys import platform + +import sys, ctypes +from ctypes import c_void_p, c_uint8 + +import ast +import json + +class Libbolt(object): + """Libbolt Py/C low-level API""" + + def __init__(self, path): + self.lib = cdll.LoadLibrary(path) + self.load_library_params() + + def load_library_params(self): + self.lib.ffishim_bn256_channel_setup.argtypes = (c_void_p, c_uint8) + self.lib.ffishim_bn256_channel_setup.restype = c_void_p + + # ESTABLISH PROTOCOL + + self.lib.ffishim_bn256_init_merchant.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bn256_init_merchant.restype = c_void_p + + self.lib.ffishim_bn256_init_customer.argtypes = (c_void_p, ctypes.c_int32, ctypes.c_int32, c_void_p) + self.lib.ffishim_bn256_init_customer.restype = c_void_p + + self.lib.ffishim_bn256_establish_customer_generate_proof.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bn256_establish_customer_generate_proof.restype = c_void_p + + self.lib.ffishim_bn256_generate_channel_id.argtypes = (c_void_p, ) + self.lib.ffishim_bn256_generate_channel_id.restype = c_void_p + + self.lib.ffishim_bn256_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_bn256_establish_merchant_issue_close_token.restype = c_void_p + + self.lib.ffishim_bn256_establish_merchant_issue_pay_token.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_establish_merchant_issue_pay_token.restype = c_void_p + + self.lib.ffishim_bn256_verify_close_token.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_verify_close_token.restype = c_void_p + + self.lib.ffishim_bn256_establish_customer_final.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_establish_customer_final.restype = c_void_p + + # PAY PROTOCOL + + self.lib.ffishim_bn256_pay_generate_payment_proof.argtypes = (c_void_p, c_void_p, ctypes.c_int32) + self.lib.ffishim_bn256_pay_generate_payment_proof.restype = c_void_p + + self.lib.ffishim_bn256_pay_verify_payment_proof.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_pay_verify_payment_proof.restype = c_void_p + + self.lib.ffishim_bn256_pay_verify_multiple_payment_proofs.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_pay_verify_multiple_payment_proofs.restype = c_void_p + + self.lib.ffishim_bn256_pay_generate_revoke_token.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_pay_generate_revoke_token.restype = c_void_p + + self.lib.ffishim_bn256_pay_verify_revoke_token.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bn256_pay_verify_revoke_token.restype = c_void_p + + self.lib.ffishim_bn256_pay_verify_multiple_revoke_tokens.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_pay_verify_multiple_revoke_tokens.restype = c_void_p + + self.lib.ffishim_bn256_pay_verify_payment_token.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bn256_pay_verify_payment_token.restype = c_void_p + + # CLOSE + + self.lib.ffishim_bn256_customer_close.argtypes = (c_void_p, c_void_p) + self.lib.ffishim_bn256_customer_close.restype = c_void_p + + self.lib.ffishim_bn256_merchant_close.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_merchant_close.restype = c_void_p + + # ON-CHAIN BOLT LOGIC / WTPs + + self.lib.ffishim_bn256_wtp_verify_cust_close_message.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_wtp_verify_cust_close_message.restype = c_void_p + + self.lib.ffishim_bn256_wtp_verify_merch_close_message.argtypes = (c_void_p, c_void_p, c_void_p) + self.lib.ffishim_bn256_wtp_verify_merch_close_message.restype = c_void_p + + self.lib.ffishim_free_string.argtypes = (c_void_p, ) + + def channel_setup(self, name, third_party_support=0): + output_string = self.lib.ffishim_bn256_channel_setup(name.encode(), third_party_support) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('channel_state') + + # INIT PROTOCOL + + def bidirectional_init_merchant(self, channel_state, name): + output_string = self.lib.ffishim_bn256_init_merchant(channel_state.encode(), name.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('channel_token'), output_dictionary.get('merch_state'), output_dictionary.get('channel_state') + + def bidirectional_init_customer(self, channel_token, b0_cust, b0_merch, name): + output_string = self.lib.ffishim_bn256_init_customer(channel_token.encode(), b0_cust, b0_merch, name.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return (output_dictionary.get('channel_token'), output_dictionary.get('cust_state')) + + # ESTABLISH PROTOCOL + + def bidirectional_generate_channel_id(self, channel_token): + output_string = self.lib.ffishim_bn256_generate_channel_id(channel_token.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('channel_id') + + def bidirectional_establish_customer_generate_proof(self, channel_token, cust_state): + output_string = self.lib.ffishim_bn256_establish_customer_generate_proof(channel_token.encode(), cust_state.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('channel_token'), output_dictionary.get('cust_state'), output_dictionary.get('com'), output_dictionary.get('com_proof') + + def bidirectional_establish_merchant_issue_close_token(self, channel_state, com, com_proof, channel_id, init_cust, init_merch, merch_state): + output_string = self.lib.ffishim_bn256_establish_merchant_issue_close_token(channel_state.encode(), com.encode(), com_proof.encode(), json.dumps(channel_id).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') + + def bidirectional_establish_merchant_issue_pay_token(self, channel_state, com, merch_state): + output_string = self.lib.ffishim_bn256_establish_merchant_issue_pay_token(channel_state.encode(), com.encode(), merch_state.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('pay_token') + + def bidirectional_establish_customer_verify_close_token(self, channel_state, cust_state, close_token): + output_string = self.lib.ffishim_bn256_verify_close_token(channel_state.encode(), cust_state.encode(), close_token.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + is_token_valid = self._convert_boolean(output_dictionary.get('is_token_valid')) + return is_token_valid, output_dictionary.get('channel_state'), output_dictionary.get('cust_state') + + def bidirectional_establish_customer_final(self, channel_state, cust_state, pay_token): + output_string = self.lib.ffishim_bn256_establish_customer_final(channel_state.encode(), cust_state.encode(), pay_token.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + is_established = self._convert_boolean(output_dictionary.get('is_established')) + return is_established, output_dictionary.get('channel_state'), output_dictionary.get('cust_state') + + # PAY PROTOCOL + + # generate payment proof and new cust state + def bidirectional_pay_generate_payment_proof(self, channel_state, cust_state, amount): + output_string = self.lib.ffishim_bn256_pay_generate_payment_proof(channel_state.encode(), cust_state.encode(), amount) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('payment'), output_dictionary.get('cust_state') + + # verify payment proof + def bidirectional_pay_verify_payment_proof(self, channel_state, pay_proof, merch_state): + output_string = self.lib.ffishim_bn256_pay_verify_payment_proof(channel_state.encode(), pay_proof.encode(), 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'), output_dictionary.get('merch_state')) + + # verify multiple payment proof + def bidirectional_pay_verify_multiple_payment_proofs(self, channel_state, sender_pay_proof, receiver_pay_proof, merch_state): + output_string = self.lib.ffishim_bn256_pay_verify_multiple_payment_proofs(channel_state.encode(), sender_pay_proof.encode(), receiver_pay_proof.encode(), merch_state.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return (output_dictionary.get('sender_close_token'), output_dictionary.get('receiver_cond_close_token'), output_dictionary.get('merch_state')) + + # generate revoke token + def bidirectional_pay_generate_revoke_token(self, channel_state, cust_state, new_cust_state, close_token): + output_string = self.lib.ffishim_bn256_pay_generate_revoke_token(channel_state.encode(), cust_state.encode(), + new_cust_state.encode(), close_token.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('revoke_token'), output_dictionary.get('cust_state') + + # verify revoke token + def bidirectional_pay_verify_revoke_token(self, revoke_token, merch_state): + output_string = self.lib.ffishim_bn256_pay_verify_revoke_token(revoke_token.encode(), merch_state.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return (output_dictionary.get('pay_token'), output_dictionary.get('merch_state')) + + # verify multiple revoke tokens + def bidirectional_pay_verify_multiple_revoke_tokens(self, sender_revoke_token, receiver_revoke_token, merch_state): + output_string = self.lib.ffishim_bn256_pay_verify_multiple_revoke_tokens(sender_revoke_token.encode(), receiver_revoke_token.encode(), merch_state.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return (output_dictionary.get('sender_pay_token'), output_dictionary.get('receiver_pay_token'), output_dictionary.get('merch_state')) + + # verify payment token + def bidirectional_pay_verify_payment_token(self, channel_state, cust_state, pay_token): + output_string = self.lib.ffishim_bn256_pay_verify_payment_token(channel_state.encode(), cust_state.encode(), pay_token.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + is_pay_valid = self._convert_boolean(output_dictionary.get('is_pay_valid')) + return (output_dictionary.get('cust_state'), is_pay_valid) + + # CLOSE + + def bidirectional_customer_close(self, channel_state, cust_state): + output_string = self.lib.ffishim_bn256_customer_close(channel_state.encode(), cust_state.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('cust_close') + + def bidirectional_merchant_close(self, channel_state, channel_token, address, cust_close, merch_state): + output_string = self.lib.ffishim_bn256_merchant_close(channel_state.encode(), channel_token.encode(), + address.encode(), cust_close.encode(), merch_state.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return (output_dictionary.get('wpk'), output_dictionary.get('merch_close'), output_dictionary.get('error')) + + # WTP logic + + def wtp_get_wallet(self, cust_state): + cust_state_dict = self._interperate_json_string_as_dictionary(cust_state) + return json.dumps(cust_state_dict.get("wpk")), json.dumps(cust_state_dict.get("wallet")) + + def wtp_get_close_token(self, cust_close): + cust_close_dict = self._interperate_json_string_as_dictionary(cust_close) + return json.dumps(cust_close_dict.get("signature")) + + def wtp_verify_cust_close_message(self, channel_token, wpk, cust_close_wallet, close_token): + output_string = self.lib.ffishim_bn256_wtp_verify_cust_close_message(channel_token.encode(), + wpk.encode(), + cust_close_wallet.encode(), + close_token.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('result') + + def wtp_verify_merch_close_message(self, channel_token, wpk, merch_close): + output_string = self.lib.ffishim_bn256_wtp_verify_merch_close_message(channel_token.encode(), + wpk.encode(), + merch_close.encode()) + output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8')) + return output_dictionary.get('result') + + def _interperate_json_string_as_dictionary(self, json_string): + return ast.literal_eval(json_string) + + def _convert_boolean(self, bool_str): + if bool_str == "true": + return True + if bool_str == "false": + return False + return bool_str + +if platform == 'darwin': + prefix = 'lib' + ext = 'dylib' +elif platform == 'win32': + prefix = '' + ext = 'dll' +else: + prefix = 'lib' + ext = 'so' + +DEBUG = 'debug' +RELEASE = 'release' +mode = RELEASE # debug or release + +def run_unit_test(): + libbolt = Libbolt('target/{}/{}bolt.{}'.format(mode, prefix, ext)) + + b0_cust = 100 + b0_merch = 10 + + channel_state = libbolt.channel_setup("My New Channel A") + + print("channel state new: ", len(channel_state)) + + (channel_token, merch_state, channel_state) = libbolt.bidirectional_init_merchant(channel_state, "Bob") + + print("merch_state: ", len(merch_state)) + #print("channel_token: ", type(_channel_token)) + + (channel_token, cust_state) = libbolt.bidirectional_init_customer(channel_token, b0_cust, b0_merch, "Alice") + print("cust_state: ", len(cust_state)) + + (channel_token, cust_state, com, com_proof) = libbolt.bidirectional_establish_customer_generate_proof(channel_token, cust_state) + print("channel token len: => ", len(channel_token)) + print("channel token: => ", channel_token) + print("com: ", com) + + cust_state_dict = json.loads(cust_state) + channel_id = libbolt.bidirectional_generate_channel_id(channel_token) + print("channel ID: ", channel_id) + #print("wallet chan ID: ", cust_state_dict["wallet"]["channelId"]) + + close_token = libbolt.bidirectional_establish_merchant_issue_close_token(channel_state, com, com_proof, cust_state_dict["wallet"]["channelId"], 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) + + pay_token = libbolt.bidirectional_establish_merchant_issue_pay_token(channel_state, com, merch_state) + print("pay token: ", pay_token) + + (is_channel_established, channel_state, cust_state) = libbolt.bidirectional_establish_customer_final(channel_state, cust_state, pay_token) + if is_channel_established: + print("updated cust_state: ", cust_state) + else: + print("channel still not established. did you verify close token?") + + # Pay protocol + print("Pay protocol...") + + # make a payment + amount = 5 + (payment_proof, new_cust_state) = libbolt.bidirectional_pay_generate_payment_proof(channel_state, cust_state, amount) + print("Pay proof: ", len(payment_proof)) + print("new cust wallet: ", new_cust_state) + print("<========================================>") + revoked_wpk, _ = libbolt.wtp_get_wallet(new_cust_state) + + (new_close_token, merch_state) = libbolt.bidirectional_pay_verify_payment_proof(channel_state, payment_proof, merch_state) + print("Close token: ", new_close_token) + print("<========================================>") + + (revoke_token, cust_state) = libbolt.bidirectional_pay_generate_revoke_token(channel_state, cust_state, new_cust_state, new_close_token) + print("Revoke token: ", revoke_token) + + (pay_token, merch_state) = libbolt.bidirectional_pay_verify_revoke_token(revoke_token, merch_state) + print("Pay token: ", pay_token) + + (cust_state, is_pay_valid) = libbolt.bidirectional_pay_verify_payment_token(channel_state, cust_state, pay_token) + print("Pay token is valid: ", is_pay_valid) + + old_cust_close = libbolt.bidirectional_customer_close(channel_state, cust_state) + + # make a payment + amount = 10 + (payment_proof2, new_cust_state2) = libbolt.bidirectional_pay_generate_payment_proof(channel_state, cust_state, amount) + print("Pay proof 2: ", len(payment_proof2)) + print("new cust wallet 2: ", new_cust_state2) + print("<========================================>") + + (new_close_token2, merch_state) = libbolt.bidirectional_pay_verify_payment_proof(channel_state, payment_proof2, merch_state) + print("Close token 2: ", new_close_token2) + print("<========================================>") + + (revoke_token2, cust_state) = libbolt.bidirectional_pay_generate_revoke_token(channel_state, cust_state, new_cust_state2, new_close_token2) + print("Revoke token 2: ", revoke_token) + + (pay_token2, merch_state) = libbolt.bidirectional_pay_verify_revoke_token(revoke_token2, merch_state) + print("Pay token 2: ", pay_token2) + + (cust_state, is_pay_valid) = libbolt.bidirectional_pay_verify_payment_token(channel_state, cust_state, pay_token2) + print("Pay token is valid: ", is_pay_valid) + + print("<========================================>") + print("<========================================>") + + cust_close = libbolt.bidirectional_customer_close(channel_state, cust_state) + print("Cust close msg: ", cust_close) + print("<========================================>") + + # normal case: no action b/c cust close is valid + address = "11" * 32 + merch_close = libbolt.bidirectional_merchant_close(channel_state, channel_token, address, cust_close, merch_state) + print("Customer initiated - Merch close msg: ", merch_close) + print("<========================================>") + + # common case: merchant catches customer double spending + address = "11" * 32 + merch_wpk, merch_close_msg, _ = libbolt.bidirectional_merchant_close(channel_state, channel_token, address, old_cust_close, merch_state) + print("Double spend - Merch close msg: ", merch_close_msg) + merch_close_valid = libbolt.wtp_verify_merch_close_message(channel_token, merch_wpk, merch_close_msg) + print("Merchant close msg valid: ", merch_close_valid) + print("<========================================>") + + print("<========================================>") + wpk, cust_close_wallet = libbolt.wtp_get_wallet(cust_state) + print("wpk = ", wpk) + print("close-msg wallet = ", cust_close_wallet) + cust_close_token = libbolt.wtp_get_close_token(cust_close) + print("close token: ", cust_close_token) + print("Valid channel opening: ", libbolt.wtp_verify_cust_close_message(channel_token, wpk, cust_close_wallet, cust_close_token)) + # TODO: merch close when cust_close represents correct channel state + + print("Invalid channel opening: ", libbolt.wtp_verify_cust_close_message(channel_token, revoked_wpk, cust_close_wallet, cust_close_token)) + print("<========================================>") + +if __name__ == "__main__": + run_unit_test() diff --git a/src/ffishim.rs b/src/ffishim.rs index e89d990..a9bf19a 100644 --- a/src/ffishim.rs +++ b/src/ffishim.rs @@ -11,7 +11,6 @@ pub mod ffishim { use libc::c_char; use std::ffi::{CStr, CString}; use std::str; -// use channels::{ChannelcloseM, ResultBoltType, BoltError}; fn error_message(s: String) -> *mut c_char { let ser = ["{\'error\':\'", &s, "\'}"].concat(); @@ -34,24 +33,7 @@ pub mod ffishim { } pub type ResultSerdeType = Result; - -// fn deserialize_object<'a, T>(serialized: *mut c_char) -> T -// where -// T: Deserialize<'a>, -// { -// let bytes = unsafe { CStr::from_ptr(serialized).to_bytes() }; -// let string: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8 -// serde_json::from_str(&string).unwrap() -// } -// -// fn deserialize_optional_object<'a, T>(serialized: *mut c_char) -> Option -// where -// T: Deserialize<'a>, -// { -// let bytes = unsafe { CStr::from_ptr(serialized).to_bytes() }; -// let string: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8 -// Some(serde_json::from_str(&string).unwrap()) -// } + type CURVE = Bls12; fn deserialize_result_object<'a, T>(serialized: *mut c_char) -> ResultSerdeType where @@ -71,7 +53,7 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_wtp_check_wpk(ser_wpk: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_wtp_check_wpk(ser_wpk: *mut c_char) -> *mut c_char { let wpk_result: ResultSerdeType = deserialize_result_object(ser_wpk); let _wpk = handle_errors!(wpk_result); @@ -82,7 +64,7 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_channel_setup(channel_name: *const c_char, third_party_support: u32) -> *mut c_char { + pub extern fn ffishim_bls12_channel_setup(channel_name: *const c_char, third_party_support: u32) -> *mut c_char { let bytes = unsafe { CStr::from_ptr(channel_name).to_bytes() }; let name: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8 @@ -90,7 +72,7 @@ pub mod ffishim { if third_party_support > 1 { tps = true; } - let channel_state = bidirectional::ChannelState::::new(name.to_string(), tps); + let channel_state = bidirectional::ChannelState::::new(name.to_string(), tps); let ser = ["{\'channel_state\':\'", serde_json::to_string(&channel_state).unwrap().as_str(), "\'}"].concat(); let cser = CString::new(ser).unwrap(); @@ -100,9 +82,9 @@ pub mod ffishim { // INIT #[no_mangle] - pub extern fn ffishim_bidirectional_init_merchant(ser_channel_state: *mut c_char, name_ptr: *const c_char) -> *mut c_char { + pub extern fn ffishim_bls12_init_merchant(ser_channel_state: *mut c_char, name_ptr: *const c_char) -> *mut c_char { let rng = &mut rand::thread_rng(); - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let mut channel_state = handle_errors!(channel_state_result); let bytes = unsafe { CStr::from_ptr(name_ptr).to_bytes() }; @@ -117,10 +99,10 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_init_customer(ser_channel_token: *mut c_char, balance_customer: i64, balance_merchant: i64, name_ptr: *const c_char) -> *mut c_char { + pub extern fn ffishim_bls12_init_customer(ser_channel_token: *mut c_char, balance_customer: i64, balance_merchant: i64, name_ptr: *const c_char) -> *mut c_char { let rng = &mut rand::thread_rng(); // Deserialize the channel token - let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); let mut channel_token = handle_errors!(channel_token_result); // Deserialize the name @@ -137,14 +119,14 @@ pub mod ffishim { // ESTABLISH #[no_mangle] - pub extern fn ffishim_bidirectional_establish_customer_generate_proof(ser_channel_token: *mut c_char, ser_customer_state: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_establish_customer_generate_proof(ser_channel_token: *mut c_char, ser_customer_state: *mut c_char) -> *mut c_char { let rng = &mut rand::thread_rng(); // Deserialize the channel token - let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); let mut channel_token = handle_errors!(channel_token_result); // Deserialize the cust state - let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); let mut cust_state = handle_errors!(cust_state_result); let (com, com_proof) = bidirectional::establish_customer_generate_proof(rng, &mut channel_token, &mut cust_state); @@ -159,9 +141,9 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_generate_channel_id(ser_channel_token: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_generate_channel_id(ser_channel_token: *mut c_char) -> *mut c_char { // Deserialize the channel token - let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); let channel_token = handle_errors!(channel_token_result); let id = channel_token.compute_channel_id(); @@ -171,26 +153,26 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_establish_merchant_issue_close_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_com_proof: *mut c_char, ser_channel_id: *mut c_char, init_cust_bal: i64, init_merch_bal: i64, ser_merch_state: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_establish_merchant_issue_close_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_com_proof: *mut c_char, ser_channel_id: *mut c_char, init_cust_bal: i64, init_merch_bal: i64, ser_merch_state: *mut c_char) -> *mut c_char { let rng = &mut rand::thread_rng(); // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let channel_state = handle_errors!(channel_state_result); // Deserialize the com proof - let com_result: ResultSerdeType> = deserialize_result_object(ser_com); + let com_result: ResultSerdeType> = deserialize_result_object(ser_com); let com = handle_errors!(com_result); // Deserialize the com proof - let com_proof_result: ResultSerdeType> = deserialize_result_object(ser_com_proof); + let com_proof_result: ResultSerdeType> = deserialize_result_object(ser_com_proof); let com_proof = handle_errors!(com_proof_result); // Deserialize the merchant state - let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); let merch_state = handle_errors!(merch_state_result); // Deserialize the pk_c - let channel_id_result: ResultSerdeType<::Fr> = deserialize_result_object(ser_channel_id); + let channel_id_result: ResultSerdeType<::Fr> = deserialize_result_object(ser_channel_id); let channel_id_fr = handle_errors!(channel_id_result); let close_token = bolt_try!(bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &channel_id_fr, init_cust_bal, init_merch_bal, &merch_state)); @@ -201,18 +183,18 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_establish_merchant_issue_pay_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_establish_merchant_issue_pay_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { let rng = &mut rand::thread_rng(); // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let channel_state = handle_errors!(channel_state_result); // Deserialize the commitment - let com_result: ResultSerdeType> = deserialize_result_object(ser_com); + let com_result: ResultSerdeType> = deserialize_result_object(ser_com); let com = handle_errors!(com_result); // Deserialize the merchant state - let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); let merch_state = handle_errors!(merch_state_result); let pay_token = bidirectional::establish_merchant_issue_pay_token(rng, &channel_state, &com, &merch_state); @@ -223,17 +205,17 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_verify_close_token(ser_channel_state: *mut c_char, ser_customer_state: *mut c_char, ser_close_token: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_verify_close_token(ser_channel_state: *mut c_char, ser_customer_state: *mut c_char, ser_close_token: *mut c_char) -> *mut c_char { // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let mut channel_state = handle_errors!(channel_state_result); // Deserialize the cust state - let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); let mut cust_state = handle_errors!(cust_state_result); // Deserialize the close token - let close_result: ResultSerdeType> = deserialize_result_object(ser_close_token); + let close_result: ResultSerdeType> = deserialize_result_object(ser_close_token); let close_token = handle_errors!(close_result); let is_close_token_valid = cust_state.verify_close_token(&mut channel_state, &close_token); @@ -247,17 +229,17 @@ pub mod ffishim { #[no_mangle] - pub extern fn ffishim_bidirectional_establish_customer_final(ser_channel_state: *mut c_char, ser_customer_state: *mut c_char, ser_pay_token: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_establish_customer_final(ser_channel_state: *mut c_char, ser_customer_state: *mut c_char, ser_pay_token: *mut c_char) -> *mut c_char { // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let mut channel_state = handle_errors!(channel_state_result); // Deserialize the cust state - let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); let mut cust_state = handle_errors!(cust_state_result); // Deserialize the custdata - let pay_token_result: ResultSerdeType> = deserialize_result_object(ser_pay_token); + let pay_token_result: ResultSerdeType> = deserialize_result_object(ser_pay_token); let pay_token = handle_errors!(pay_token_result); let is_channel_established = bidirectional::establish_customer_final(&mut channel_state, &mut cust_state, &pay_token); @@ -272,14 +254,14 @@ pub mod ffishim { // PAY #[no_mangle] - pub extern fn ffishim_bidirectional_pay_generate_payment_proof(ser_channel_state: *mut c_char, ser_customer_state: *mut c_char, amount: i64) -> *mut c_char { + pub extern fn ffishim_bls12_pay_generate_payment_proof(ser_channel_state: *mut c_char, ser_customer_state: *mut c_char, amount: i64) -> *mut c_char { let rng = &mut rand::thread_rng(); // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let channel_state = handle_errors!(channel_state_result); // Deserialize the cust state - let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); let cust_state = handle_errors!(cust_state_result); // Generate the payment proof @@ -292,18 +274,18 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_pay_verify_payment_proof(ser_channel_state: *mut c_char, ser_pay_proof: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_pay_verify_payment_proof(ser_channel_state: *mut c_char, ser_pay_proof: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { let rng = &mut rand::thread_rng(); // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let channel_state = handle_errors!(channel_state_result); // Deserialize the payment proof - let payment_result: ResultSerdeType> = deserialize_result_object(ser_pay_proof); + let payment_result: ResultSerdeType> = deserialize_result_object(ser_pay_proof); let payment = handle_errors!(payment_result); // Deserialize the merch state - let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); let mut merch_state = handle_errors!(merch_state_result); let close_token = bidirectional::verify_payment_proof(rng, &channel_state, &payment, &mut merch_state); @@ -314,21 +296,21 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_pay_verify_multiple_payment_proofs(ser_channel_state: *mut c_char, ser_sender_pay_proof: *mut c_char, ser_receiver_pay_proof: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_pay_verify_multiple_payment_proofs(ser_channel_state: *mut c_char, ser_sender_pay_proof: *mut c_char, ser_receiver_pay_proof: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { let rng = &mut rand::thread_rng(); // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let channel_state = handle_errors!(channel_state_result); // Deserialize the payment proofs - let sender_payment_result: ResultSerdeType> = deserialize_result_object(ser_sender_pay_proof); + let sender_payment_result: ResultSerdeType> = deserialize_result_object(ser_sender_pay_proof); let sender_payment = handle_errors!(sender_payment_result); - let receiver_payment_result: ResultSerdeType> = deserialize_result_object(ser_receiver_pay_proof); + let receiver_payment_result: ResultSerdeType> = deserialize_result_object(ser_receiver_pay_proof); let receiver_payment = handle_errors!(receiver_payment_result); // Deserialize the merch state - let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); let mut merch_state = handle_errors!(merch_state_result); let close_token_result = bidirectional::verify_multiple_payment_proofs(rng, &channel_state, &sender_payment, &receiver_payment, &mut merch_state); @@ -341,21 +323,21 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_pay_generate_revoke_token(ser_channel_state: *mut c_char, ser_cust_state: *mut c_char, ser_new_cust_state: *mut c_char, ser_close_token: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_pay_generate_revoke_token(ser_channel_state: *mut c_char, ser_cust_state: *mut c_char, ser_new_cust_state: *mut c_char, ser_close_token: *mut c_char) -> *mut c_char { // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let channel_state = handle_errors!(channel_state_result); // Deserialize the cust state - let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_cust_state); + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_cust_state); let mut cust_state = handle_errors!(cust_state_result); // Deserialize the cust state - let new_cust_state_result: ResultSerdeType> = deserialize_result_object(ser_new_cust_state); + let new_cust_state_result: ResultSerdeType> = deserialize_result_object(ser_new_cust_state); let new_cust_state = handle_errors!(new_cust_state_result); // Deserialize the close token - let close_token_result: ResultSerdeType> = deserialize_result_object(ser_close_token); + let close_token_result: ResultSerdeType> = deserialize_result_object(ser_close_token); let close_token = handle_errors!(close_token_result); let revoke_token = bidirectional::generate_revoke_token(&channel_state, &mut cust_state, new_cust_state, &close_token); @@ -366,13 +348,13 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_pay_verify_revoke_token(ser_revoke_token: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_pay_verify_revoke_token(ser_revoke_token: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { // Deserialize the revoke token let revoke_token_result: ResultSerdeType = deserialize_result_object(ser_revoke_token); let revoke_token = handle_errors!(revoke_token_result); // Deserialize the cust state - let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); let mut merch_state = handle_errors!(merch_state_result); // send revoke token and get pay-token in response @@ -386,7 +368,7 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_pay_verify_multiple_revoke_tokens(ser_sender_revoke_token: *mut c_char, ser_receiver_revoke_token: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_pay_verify_multiple_revoke_tokens(ser_sender_revoke_token: *mut c_char, ser_receiver_revoke_token: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { // Deserialize the revoke tokens let sender_revoke_token_result: ResultSerdeType = deserialize_result_object(ser_sender_revoke_token); let sender_revoke_token = handle_errors!(sender_revoke_token_result); @@ -395,7 +377,7 @@ pub mod ffishim { let receiver_revoke_token = handle_errors!(receiver_revoke_token_result); // Deserialize the cust state - let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); let mut merch_state = handle_errors!(merch_state_result); // send revoke token and get pay-token in response @@ -411,17 +393,17 @@ pub mod ffishim { #[no_mangle] - pub extern fn ffishim_bidirectional_pay_verify_payment_token(ser_channel_state: *mut c_char, ser_cust_state: *mut c_char, ser_pay_token: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_pay_verify_payment_token(ser_channel_state: *mut c_char, ser_cust_state: *mut c_char, ser_pay_token: *mut c_char) -> *mut c_char { // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let channel_state = handle_errors!(channel_state_result); // Deserialize the cust state - let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_cust_state); + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_cust_state); let mut cust_state = handle_errors!(cust_state_result); // Deserialize the pay token - let pay_token_result: ResultSerdeType> = deserialize_result_object(ser_pay_token); + let pay_token_result: ResultSerdeType> = deserialize_result_object(ser_pay_token); let pay_token = handle_errors!(pay_token_result); // verify the pay token and update internal state @@ -435,13 +417,13 @@ pub mod ffishim { // CLOSE #[no_mangle] - pub extern fn ffishim_bidirectional_customer_close(ser_channel_state: *mut c_char, ser_cust_state: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_customer_close(ser_channel_state: *mut c_char, ser_cust_state: *mut c_char) -> *mut c_char { // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let channel_state = handle_errors!(channel_state_result); // Deserialize the cust state - let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_cust_state); + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_cust_state); let cust_state = handle_errors!(cust_state_result); let cust_close = bidirectional::customer_close(&channel_state, &cust_state); @@ -451,21 +433,21 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_merchant_close(ser_channel_state: *mut c_char, ser_channel_token: *mut c_char, ser_address: *const c_char, ser_cust_close: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_merchant_close(ser_channel_state: *mut c_char, ser_channel_token: *mut c_char, ser_address: *const c_char, ser_cust_close: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { // Deserialize the channel state - let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); let channel_state = handle_errors!(channel_state_result); // Deserialize the channel token - let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); let channel_token = handle_errors!(channel_token_result); // Deserialize the customer close structure - let cust_close_result: ResultSerdeType> = deserialize_result_object(ser_cust_close); + let cust_close_result: ResultSerdeType> = deserialize_result_object(ser_cust_close); let cust_close = handle_errors!(cust_close_result); // Deserialize the merch state - let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); let merch_state = handle_errors!(merch_state_result); // Deserialize the destination address as a string @@ -487,9 +469,9 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_wtp_verify_cust_close_message(ser_channel_token: *mut c_char, ser_wpk: *mut c_char, ser_close_msg: *mut c_char, ser_close_token: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_wtp_verify_cust_close_message(ser_channel_token: *mut c_char, ser_wpk: *mut c_char, ser_close_msg: *mut c_char, ser_close_token: *mut c_char) -> *mut c_char { // Deserialize the channel token - let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); let channel_token = handle_errors!(channel_token_result); // Deserialize the wpk @@ -497,11 +479,11 @@ pub mod ffishim { let wpk = handle_errors!(wpk_result); // Deserialize the close wallet - let close_msg_result: ResultSerdeType> = deserialize_result_object(ser_close_msg); + let close_msg_result: ResultSerdeType> = deserialize_result_object(ser_close_msg); let close_msg = handle_errors!(close_msg_result); // Deserialize the close token - let close_token_result: ResultSerdeType> = deserialize_result_object(ser_close_token); + let close_token_result: ResultSerdeType> = deserialize_result_object(ser_close_token); let close_token = handle_errors!(close_token_result); // check the signatures @@ -512,9 +494,9 @@ pub mod ffishim { } #[no_mangle] - pub extern fn ffishim_bidirectional_wtp_verify_merch_close_message(ser_channel_token: *mut c_char, ser_wpk: *mut c_char, ser_merch_close: *mut c_char) -> *mut c_char { + pub extern fn ffishim_bls12_wtp_verify_merch_close_message(ser_channel_token: *mut c_char, ser_wpk: *mut c_char, ser_merch_close: *mut c_char) -> *mut c_char { // Deserialize the channel token - let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); let channel_token = handle_errors!(channel_token_result); // Deserialize the wpk diff --git a/src/ffishim_bn256.rs b/src/ffishim_bn256.rs new file mode 100644 index 0000000..fb969c1 --- /dev/null +++ b/src/ffishim_bn256.rs @@ -0,0 +1,511 @@ +#[no_mangle] +pub mod ffishim_bn256 { + extern crate libc; + + use bidirectional; + use ff::ScalarEngine; + use pairing::bn256::Bn256; + + use serde::Deserialize; + + use libc::c_char; + use std::ffi::{CStr, CString}; + use std::str; + + fn error_message(s: String) -> *mut c_char { + let ser = ["{\'error\':\'", &s, "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + macro_rules! bolt_try { + ($e:expr) => (match $e { + Ok(val) => val.unwrap(), + Err(err) => return error_message(err), + }); + } + + macro_rules! handle_errors { + ($e:expr) => (match $e { + Ok(val) => val, + Err(err) => return error_message(err.to_string()), + }); + } + + pub type ResultSerdeType = Result; + type CURVE = Bn256; + + fn deserialize_result_object<'a, T>(serialized: *mut c_char) -> ResultSerdeType + where + T: Deserialize<'a>, + { + let bytes = unsafe { CStr::from_ptr(serialized).to_bytes() }; + let string: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8 + serde_json::from_str(&string) + } + + #[no_mangle] + pub extern fn ffishim_bn256_wtp_check_wpk(ser_wpk: *mut c_char) -> *mut c_char { + let wpk_result: ResultSerdeType = deserialize_result_object(ser_wpk); + let _wpk = handle_errors!(wpk_result); + + let res = true; + let ser = ["{\'result\':\'", serde_json::to_string(&res).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_channel_setup(channel_name: *const c_char, third_party_support: u32) -> *mut c_char { + let bytes = unsafe { CStr::from_ptr(channel_name).to_bytes() }; + let name: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8 + + let mut tps = false; + if third_party_support > 1 { + tps = true; + } + let channel_state = bidirectional::ChannelState::::new(name.to_string(), tps); + + let ser = ["{\'channel_state\':\'", serde_json::to_string(&channel_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + // INIT + + #[no_mangle] + pub extern fn ffishim_bn256_init_merchant(ser_channel_state: *mut c_char, name_ptr: *const c_char) -> *mut c_char { + let rng = &mut rand::thread_rng(); + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let mut channel_state = handle_errors!(channel_state_result); + + let bytes = unsafe { CStr::from_ptr(name_ptr).to_bytes() }; + let name: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8 + + let (channel_token, merch_state, channel_state) = bidirectional::init_merchant(rng, &mut channel_state, name); + + let ser = ["{\'channel_token\':\'", serde_json::to_string(&channel_token).unwrap().as_str(), "\', \'merch_state\':\'", serde_json::to_string(&merch_state).unwrap().as_str(), "\', \'channel_state\':\'", serde_json::to_string(&channel_state).unwrap().as_str(), "\'}"].concat(); + + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_init_customer(ser_channel_token: *mut c_char, balance_customer: i64, balance_merchant: i64, name_ptr: *const c_char) -> *mut c_char { + let rng = &mut rand::thread_rng(); + // Deserialize the channel token + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let mut channel_token = handle_errors!(channel_token_result); + + // Deserialize the name + let bytes = unsafe { CStr::from_ptr(name_ptr).to_bytes() }; + let name: &str = str::from_utf8(bytes).unwrap(); // make sure the bytes are UTF-8 + + // We change the channel state + let cust_state = bidirectional::init_customer(rng, &mut channel_token, balance_customer, balance_merchant, name); + let ser = ["{\'cust_state\':\'", serde_json::to_string(&cust_state).unwrap().as_str(), "\', \'channel_token\':\'", serde_json::to_string(&channel_token).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + // ESTABLISH + + #[no_mangle] + pub extern fn ffishim_bn256_establish_customer_generate_proof(ser_channel_token: *mut c_char, ser_customer_state: *mut c_char) -> *mut c_char { + let rng = &mut rand::thread_rng(); + // Deserialize the channel token + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let mut channel_token = handle_errors!(channel_token_result); + + // Deserialize the cust state + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); + let mut cust_state = handle_errors!(cust_state_result); + + let (com, com_proof) = bidirectional::establish_customer_generate_proof(rng, &mut channel_token, &mut cust_state); + + let ser = ["{\'cust_state\':\'", serde_json::to_string(&cust_state).unwrap().as_str(), + "\', \'channel_token\':\'", serde_json::to_string(&channel_token).unwrap().as_str(), + "\', \'com\':\'", serde_json::to_string(&com).unwrap().as_str(), + "\', \'com_proof\':\'", serde_json::to_string(&com_proof).unwrap().as_str(), + "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_generate_channel_id(ser_channel_token: *mut c_char) -> *mut c_char { + // Deserialize the channel token + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token = handle_errors!(channel_token_result); + + let id = channel_token.compute_channel_id(); + let ser = ["{\'channel_id\':\'", serde_json::to_string(&id).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_establish_merchant_issue_close_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_com_proof: *mut c_char, ser_channel_id: *mut c_char, init_cust_bal: i64, init_merch_bal: i64, ser_merch_state: *mut c_char) -> *mut c_char { + let rng = &mut rand::thread_rng(); + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state = handle_errors!(channel_state_result); + + // Deserialize the com proof + let com_result: ResultSerdeType> = deserialize_result_object(ser_com); + let com = handle_errors!(com_result); + + // Deserialize the com proof + let com_proof_result: ResultSerdeType> = deserialize_result_object(ser_com_proof); + let com_proof = handle_errors!(com_proof_result); + + // Deserialize the merchant state + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state = handle_errors!(merch_state_result); + + // Deserialize the pk_c + let channel_id_result: ResultSerdeType<::Fr> = deserialize_result_object(ser_channel_id); + let channel_id_fr = handle_errors!(channel_id_result); + + let close_token = bolt_try!(bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &channel_id_fr, 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(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_establish_merchant_issue_pay_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + let rng = &mut rand::thread_rng(); + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state = handle_errors!(channel_state_result); + + // Deserialize the commitment + let com_result: ResultSerdeType> = deserialize_result_object(ser_com); + let com = handle_errors!(com_result); + + // Deserialize the merchant state + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state = handle_errors!(merch_state_result); + + let pay_token = bidirectional::establish_merchant_issue_pay_token(rng, &channel_state, &com, &merch_state); + + let ser = ["{\'pay_token\':\'", serde_json::to_string(&pay_token).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_verify_close_token(ser_channel_state: *mut c_char, ser_customer_state: *mut c_char, ser_close_token: *mut c_char) -> *mut c_char { + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let mut channel_state = handle_errors!(channel_state_result); + + // Deserialize the cust state + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); + let mut cust_state = handle_errors!(cust_state_result); + + // Deserialize the close token + let close_result: ResultSerdeType> = deserialize_result_object(ser_close_token); + let close_token = handle_errors!(close_result); + + let is_close_token_valid = cust_state.verify_close_token(&mut channel_state, &close_token); + + let ser = ["{\'cust_state\':\'", serde_json::to_string(&cust_state).unwrap().as_str(), + "\', \'is_token_valid\':\'", serde_json::to_string(&is_close_token_valid).unwrap().as_str(), + "\', \'channel_state\':\'", serde_json::to_string(&channel_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + + #[no_mangle] + pub extern fn ffishim_bn256_establish_customer_final(ser_channel_state: *mut c_char, ser_customer_state: *mut c_char, ser_pay_token: *mut c_char) -> *mut c_char { + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let mut channel_state = handle_errors!(channel_state_result); + + // Deserialize the cust state + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); + let mut cust_state = handle_errors!(cust_state_result); + + // Deserialize the custdata + let pay_token_result: ResultSerdeType> = deserialize_result_object(ser_pay_token); + let pay_token = handle_errors!(pay_token_result); + + let is_channel_established = bidirectional::establish_customer_final(&mut channel_state, &mut cust_state, &pay_token); + + let ser = ["{\'cust_state\':\'", serde_json::to_string(&cust_state).unwrap().as_str(), + "\', \'is_established\':\'", serde_json::to_string(&is_channel_established).unwrap().as_str(), + "\', \'channel_state\':\'", serde_json::to_string(&channel_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + // PAY + + #[no_mangle] + pub extern fn ffishim_bn256_pay_generate_payment_proof(ser_channel_state: *mut c_char, ser_customer_state: *mut c_char, amount: i64) -> *mut c_char { + let rng = &mut rand::thread_rng(); + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state = handle_errors!(channel_state_result); + + // Deserialize the cust state + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_customer_state); + let cust_state = handle_errors!(cust_state_result); + + // Generate the payment proof + let (payment, new_cust_state) = bidirectional::generate_payment_proof(rng, &channel_state, &cust_state, amount); + // Serialize the results and return to caller + let ser = ["{\'payment\':\'", serde_json::to_string(&payment).unwrap().as_str(), + "\', \'cust_state\':\'", serde_json::to_string(&new_cust_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_pay_verify_payment_proof(ser_channel_state: *mut c_char, ser_pay_proof: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + let rng = &mut rand::thread_rng(); + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state = handle_errors!(channel_state_result); + + // Deserialize the payment proof + let payment_result: ResultSerdeType> = deserialize_result_object(ser_pay_proof); + let payment = handle_errors!(payment_result); + + // Deserialize the merch state + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let mut merch_state = handle_errors!(merch_state_result); + + let close_token = bidirectional::verify_payment_proof(rng, &channel_state, &payment, &mut merch_state); + let ser = ["{\'close_token\':\'", serde_json::to_string(&close_token).unwrap().as_str(), + "\', \'merch_state\':\'", serde_json::to_string(&merch_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_pay_verify_multiple_payment_proofs(ser_channel_state: *mut c_char, ser_sender_pay_proof: *mut c_char, ser_receiver_pay_proof: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + let rng = &mut rand::thread_rng(); + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state = handle_errors!(channel_state_result); + + // Deserialize the payment proofs + let sender_payment_result: ResultSerdeType> = deserialize_result_object(ser_sender_pay_proof); + let sender_payment = handle_errors!(sender_payment_result); + + let receiver_payment_result: ResultSerdeType> = deserialize_result_object(ser_receiver_pay_proof); + let receiver_payment = handle_errors!(receiver_payment_result); + + // Deserialize the merch state + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let mut merch_state = handle_errors!(merch_state_result); + + let close_token_result = bidirectional::verify_multiple_payment_proofs(rng, &channel_state, &sender_payment, &receiver_payment, &mut merch_state); + let (sender_close_token, receiver_cond_close_token) = handle_errors!(close_token_result).unwrap(); + let ser = ["{\'sender_close_token\':\'", serde_json::to_string(&sender_close_token).unwrap().as_str(), + "\', \'receiver_cond_close_token\':\'", serde_json::to_string(&receiver_cond_close_token).unwrap().as_str(), + "\', \'merch_state\':\'", serde_json::to_string(&merch_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_pay_generate_revoke_token(ser_channel_state: *mut c_char, ser_cust_state: *mut c_char, ser_new_cust_state: *mut c_char, ser_close_token: *mut c_char) -> *mut c_char { + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state = handle_errors!(channel_state_result); + + // Deserialize the cust state + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_cust_state); + let mut cust_state = handle_errors!(cust_state_result); + + // Deserialize the cust state + let new_cust_state_result: ResultSerdeType> = deserialize_result_object(ser_new_cust_state); + let new_cust_state = handle_errors!(new_cust_state_result); + + // Deserialize the close token + let close_token_result: ResultSerdeType> = deserialize_result_object(ser_close_token); + let close_token = handle_errors!(close_token_result); + + let revoke_token = bidirectional::generate_revoke_token(&channel_state, &mut cust_state, new_cust_state, &close_token); + let ser = ["{\'revoke_token\':\'", serde_json::to_string(&revoke_token).unwrap().as_str(), + "\', \'cust_state\':\'", serde_json::to_string(&cust_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_pay_verify_revoke_token(ser_revoke_token: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + // Deserialize the revoke token + let revoke_token_result: ResultSerdeType = deserialize_result_object(ser_revoke_token); + let revoke_token = handle_errors!(revoke_token_result); + + // Deserialize the cust state + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let mut merch_state = handle_errors!(merch_state_result); + + // send revoke token and get pay-token in response + let pay_token_result = bidirectional::verify_revoke_token(&revoke_token, &mut merch_state); + let pay_token = handle_errors!(pay_token_result); + + let ser = ["{\'pay_token\':\'", serde_json::to_string(&pay_token.unwrap()).unwrap().as_str(), + "\', \'merch_state\':\'", serde_json::to_string(&merch_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_pay_verify_multiple_revoke_tokens(ser_sender_revoke_token: *mut c_char, ser_receiver_revoke_token: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + // Deserialize the revoke tokens + let sender_revoke_token_result: ResultSerdeType = deserialize_result_object(ser_sender_revoke_token); + let sender_revoke_token = handle_errors!(sender_revoke_token_result); + + let receiver_revoke_token_result: ResultSerdeType = deserialize_result_object(ser_receiver_revoke_token); + let receiver_revoke_token = handle_errors!(receiver_revoke_token_result); + + // Deserialize the cust state + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let mut merch_state = handle_errors!(merch_state_result); + + // send revoke token and get pay-token in response + let pay_token_result = bidirectional::verify_multiple_revoke_tokens(&sender_revoke_token, &receiver_revoke_token, &mut merch_state); + let (sender_pay_token, receiver_pay_token) = handle_errors!(pay_token_result).unwrap(); + + let ser = ["{\'sender_pay_token\':\'", serde_json::to_string(&sender_pay_token).unwrap().as_str(), + "\', \'receiver_pay_token\':\'", serde_json::to_string(&receiver_pay_token).unwrap().as_str(), + "\', \'merch_state\':\'", serde_json::to_string(&merch_state).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + + #[no_mangle] + pub extern fn ffishim_bn256_pay_verify_payment_token(ser_channel_state: *mut c_char, ser_cust_state: *mut c_char, ser_pay_token: *mut c_char) -> *mut c_char { + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state = handle_errors!(channel_state_result); + + // Deserialize the cust state + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_cust_state); + let mut cust_state = handle_errors!(cust_state_result); + + // Deserialize the pay token + let pay_token_result: ResultSerdeType> = deserialize_result_object(ser_pay_token); + let pay_token = handle_errors!(pay_token_result); + + // verify the pay token and update internal state + let is_pay_valid = cust_state.verify_pay_token(&channel_state, &pay_token); + let ser = ["{\'cust_state\':\'", serde_json::to_string(&cust_state).unwrap().as_str(), + "\', \'is_pay_valid\':\'", serde_json::to_string(&is_pay_valid).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + // CLOSE + + #[no_mangle] + pub extern fn ffishim_bn256_customer_close(ser_channel_state: *mut c_char, ser_cust_state: *mut c_char) -> *mut c_char { + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state = handle_errors!(channel_state_result); + + // Deserialize the cust state + let cust_state_result: ResultSerdeType> = deserialize_result_object(ser_cust_state); + let cust_state = handle_errors!(cust_state_result); + + let cust_close = bidirectional::customer_close(&channel_state, &cust_state); + let ser = ["{\'cust_close\':\'", serde_json::to_string(&cust_close).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_merchant_close(ser_channel_state: *mut c_char, ser_channel_token: *mut c_char, ser_address: *const c_char, ser_cust_close: *mut c_char, ser_merch_state: *mut c_char) -> *mut c_char { + // Deserialize the channel state + let channel_state_result: ResultSerdeType> = deserialize_result_object(ser_channel_state); + let channel_state = handle_errors!(channel_state_result); + + // Deserialize the channel token + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token = handle_errors!(channel_token_result); + + // Deserialize the customer close structure + let cust_close_result: ResultSerdeType> = deserialize_result_object(ser_cust_close); + let cust_close = handle_errors!(cust_close_result); + + // Deserialize the merch state + let merch_state_result: ResultSerdeType> = deserialize_result_object(ser_merch_state); + let merch_state = handle_errors!(merch_state_result); + + // Deserialize the destination address as a string + let ser_addr_bytes = unsafe { CStr::from_ptr(ser_address).to_bytes() }; + let address: &str = str::from_utf8(ser_addr_bytes).unwrap(); // make sure the bytes are UTF-8 + + let option = bidirectional::merchant_close(&channel_state, &channel_token, &cust_close, &merch_state); + let keys = match option { + Ok(n) => n.unwrap(), + Err(err) => return error_message(err), + }; + + let merch_close: bidirectional::ChannelcloseM = merch_state.sign_revoke_message(address.to_string(), &keys.revoke_token); + + let ser = ["{\'wpk\':\'", serde_json::to_string(&keys.wpk).unwrap().as_str(), + "\', \'merch_close\':\'", serde_json::to_string(&merch_close).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_wtp_verify_cust_close_message(ser_channel_token: *mut c_char, ser_wpk: *mut c_char, ser_close_msg: *mut c_char, ser_close_token: *mut c_char) -> *mut c_char { + // Deserialize the channel token + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token = handle_errors!(channel_token_result); + + // Deserialize the wpk + let wpk_result: ResultSerdeType = deserialize_result_object(ser_wpk); + let wpk = handle_errors!(wpk_result); + + // Deserialize the close wallet + let close_msg_result: ResultSerdeType> = deserialize_result_object(ser_close_msg); + let close_msg = handle_errors!(close_msg_result); + + // Deserialize the close token + let close_token_result: ResultSerdeType> = deserialize_result_object(ser_close_token); + let close_token = handle_errors!(close_token_result); + + // check the signatures + let token_valid = bidirectional::wtp_verify_cust_close_message(&channel_token, &wpk, &close_msg, &close_token); + let ser = ["{\"result\":\"", serde_json::to_string(&token_valid).unwrap().as_str(), "\"}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } + + #[no_mangle] + pub extern fn ffishim_bn256_wtp_verify_merch_close_message(ser_channel_token: *mut c_char, ser_wpk: *mut c_char, ser_merch_close: *mut c_char) -> *mut c_char { + // Deserialize the channel token + let channel_token_result: ResultSerdeType> = deserialize_result_object(ser_channel_token); + let channel_token = handle_errors!(channel_token_result); + + // Deserialize the wpk + let wpk_result: ResultSerdeType = deserialize_result_object(ser_wpk); + let wpk = handle_errors!(wpk_result); + + // Deserialize the merch close + //let revoke_token: secp256k1::Signature = deserialize_object(ser_revoke_token); + let merch_close_result: ResultSerdeType = deserialize_result_object(ser_merch_close); + let merch_close = handle_errors!(merch_close_result); + + let revoke_token_valid = bidirectional::wtp_verify_revoke_message(&wpk, &merch_close.revoke.unwrap()); + let merch_close_valid = bidirectional::wtp_verify_merch_close_message(&channel_token, &merch_close); + let token_valid = revoke_token_valid && merch_close_valid; + + let ser = ["{\'result\':\'", serde_json::to_string(&token_valid).unwrap().as_str(), "\'}"].concat(); + let cser = CString::new(ser).unwrap(); + cser.into_raw() + } +} diff --git a/src/lib.rs b/src/lib.rs index 7b13510..d9d7438 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,6 +43,7 @@ pub mod nizk; pub mod util; pub mod wallet; pub mod ffishim; +pub mod ffishim_bn256; use std::fmt; use std::str;