Merge pull request #8 from boltlabs-inc/master

Syncing ZF repo
This commit is contained in:
J. Ayo Akinyele 2019-12-10 16:38:53 -05:00 committed by GitHub
commit 595cd87b90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1789 additions and 264 deletions

View File

@ -10,19 +10,19 @@ repository = "https://github.com/ZcashFoundation/libbolt"
license = "MIT License"
[dependencies]
rand = "0.6"
rand_core = "0.4.0"
ff = { git = "https://github.com/boltlabs-inc/ff", branch = "master" }
pairing = { git = "https://github.com/boltlabs-inc/pairing", branch = "master", features = ["serde"] }
rand = "0.7"
ff_bl = { git = "https://github.com/boltlabs-inc/ff", branch = "master" }
pairing_bl = { git = "https://github.com/boltlabs-inc/pairing", branch = "master", features = ["serde"] }
libc = "*"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_with = "1.0"
serde_bytes = "0.11.2"
time = "*"
secp256k1 = { version = "0.15.0", features = ["rand", "serde"] }
secp256k1 = { version = "0.16.0", features = ["serde"] }
sha2 = { version = "0.8", default-features = false }
hex = "0.3.2"
[lib]
crate-type = ["lib", "cdylib"]
crate-type = ["lib", "cdylib", "staticlib"]

View File

@ -4,23 +4,25 @@ all:
export RUSTFLAGS=-Awarnings
cargo +nightly build
cargo +nightly test
cargo +nightly run --example bolt_test
cargo +nightly run --example bolt_test_bls12
cargo +nightly run --example bolt_test_bn256
debug:
export RUST_BACKTRACE=1
cargo +nightly build
cargo +nightly run --example bolt_test
cargo +nightly run --example bolt_test_bls12
release:
cargo +nightly build --release
cargo +nightly run --release --example bolt_test
cargo +nightly run --release --example bolt_test_bls12
cargo +nightly run --release --example bolt_test_bn256
bench:
cargo +nightly bench
test:
# runs the unit test suite
cargo +nightly test --release #-- --nocapture
cargo +nightly test --release -- --nocapture
update:
cargo +nightly update

View File

@ -40,9 +40,7 @@ We will switch to the stable release channel once libbolt (and dependencies) are
# Build & Install
Please ensure you have installed the libsodium library for your platform. See install instructions [here](https://download.libsodium.org/doc/installation/index.html).
To build the library and execute basic examples, run `make`
To build the library in debug, execute tests and basic examples, run `make`
# Tests

View File

@ -1,14 +1,13 @@
extern crate rand;
extern crate rand_core;
extern crate bolt;
extern crate ff;
extern crate pairing;
extern crate ff_bl as ff;
extern crate pairing_bl as pairing;
extern crate time;
extern crate secp256k1;
use bolt::bidirectional;
use std::time::Instant;
use pairing::bls12_381::{Bls12};
use pairing::bls12_381::Bls12;
use bolt::handle_bolt_result;
macro_rules! measure_one_arg {

121
examples/bolt_test_bn256.rs Normal file
View File

@ -0,0 +1,121 @@
extern crate rand;
extern crate bolt;
extern crate ff_bl as ff;
extern crate pairing_bl as pairing;
extern crate time;
extern crate secp256k1;
use bolt::bidirectional;
use std::time::Instant;
use pairing::bn256::Bn256;
use bolt::handle_bolt_result;
macro_rules! measure_one_arg {
($x: expr) => {
{
let s = Instant::now();
let res = $x;
let e = s.elapsed();
(res, e.as_millis())
};
}
}
macro_rules! measure_two_arg {
($x: expr) => {
{
let s = Instant::now();
let (res1, res2) = $x;
let e = s.elapsed();
(res1, res2, e.as_millis())
};
}
}
//macro_rules! measure_ret_mut {
// ($x: expr) => {
// {
// let s = Instant::now();
// let mut handle = $x;
// let e = s.elapsed();
// (handle, s.as_millis())
// };
// }
//}
fn main() {
println!("******************************************");
let mut channel_state = bidirectional::ChannelState::<Bn256>::new(String::from("Channel A -> B"), false);
let rng = &mut rand::thread_rng();
let b0_customer = 150;
let b0_merchant = 10;
let pay_inc = 20;
let pay_inc2 = 10;
let (mut channel_token, mut merch_state, mut channel_state) = bidirectional::init_merchant(rng, &mut channel_state, "Merchant Bob");
let mut cust_state = bidirectional::init_customer(rng, &mut channel_token, b0_customer, b0_merchant, "Alice");
println!("{}", cust_state);
// lets establish the channel
let (com, com_proof, est_time) = measure_two_arg!(bidirectional::establish_customer_generate_proof(rng, &mut channel_token, &mut cust_state));
println!(">> Time to generate proof for establish: {} ms", est_time);
// obtain close token for closing out channel
let channel_id = channel_token.compute_channel_id();
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof,
&channel_id, b0_customer, b0_merchant, &merch_state);
let close_token= match option {
Ok(n) => n.unwrap(),
Err(e) => panic!("Failed - bidirectional::establish_merchant_issue_close_token(): {}", e)
};
assert!(cust_state.verify_close_token(&channel_state, &close_token));
// 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);
//assert!(cust_state.verify_pay_token(&channel_state, &pay_token));
assert!(bidirectional::establish_customer_final(&mut channel_state, &mut cust_state, &pay_token));
println!("Channel established!");
let (payment, new_cust_state, pay_time) = measure_two_arg!(bidirectional::generate_payment_proof(rng, &channel_state, &cust_state, pay_inc));
println!(">> Time to generate payment proof: {} ms", pay_time);
let (new_close_token, verify_time) = measure_one_arg!(bidirectional::verify_payment_proof(rng, &channel_state, &payment, &mut merch_state));
println!(">> Time to verify payment proof: {} ms", verify_time);
let revoke_token = bidirectional::generate_revoke_token(&channel_state, &mut cust_state, new_cust_state, &new_close_token);
// send revoke token and get pay-token in response
let new_pay_token_result = bidirectional::verify_revoke_token(&revoke_token, &mut merch_state);
let new_pay_token = handle_bolt_result!(new_pay_token_result);
// verify the pay token and update internal state
assert!(cust_state.verify_pay_token(&channel_state, &new_pay_token.unwrap()));
println!("******************************************");
let (payment2, new_cust_state2, pay_time2) = measure_two_arg!(bidirectional::generate_payment_proof(rng, &channel_state, &cust_state, pay_inc2));
println!(">> Time to generate payment proof 2: {} ms", pay_time2);
let (new_close_token2, verify_time2) = measure_one_arg!(bidirectional::verify_payment_proof(rng, &channel_state, &payment2, &mut merch_state));
println!(">> Time to verify payment proof 2: {} ms", verify_time2);
let revoke_token2 = bidirectional::generate_revoke_token(&channel_state, &mut cust_state, new_cust_state2, &new_close_token2);
// send revoke token and get pay-token in response
let new_pay_token_result2 = bidirectional::verify_revoke_token(&revoke_token2, &mut merch_state);
let new_pay_token2 = handle_bolt_result!(new_pay_token_result2);
// verify the pay token and update internal state
assert!(cust_state.verify_pay_token(&channel_state, &new_pay_token2.unwrap()));
println!("Final Cust state: {}", cust_state);
}

View File

@ -7,6 +7,7 @@ import "C"
import (
"encoding/json"
"strings"
"fmt"
)
type setupResp struct {
@ -232,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
@ -247,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
@ -271,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
@ -294,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
@ -317,6 +318,24 @@ func BidirectionalEstablishCustomerGenerateProof(channelToken ChannelToken, cust
return channelToken, custState, com, comProof, err
}
func BidirectionalGenerateChannelID(channelToken ChannelToken) (error) {
serChannelToken, err := json.Marshal(channelToken)
if err != nil {
return err
}
resp := C.GoString(C.ffishim_bls12_generate_channel_id(C.CString(string(serChannelToken))))
r, err := processCResponse(resp)
if err != nil {
return err
}
fmt.Println("channel id: ", r)
return err
}
func BidirectionalEstablishMerchantIssueCloseToken(channelState ChannelState, com Commitment, comProof CommitmentProof, channelId []string, initCustBal int, initMerchBal int, merchState MerchState) (Signature, error) {
serChannelState, err := json.Marshal(channelState)
if err != nil {
@ -338,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
@ -361,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
@ -384,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
@ -410,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
@ -432,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
@ -459,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
@ -490,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
@ -526,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
@ -549,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
@ -576,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
@ -608,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
@ -626,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
@ -653,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
@ -666,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
@ -679,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

View File

@ -16,35 +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_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
@ -64,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;
}
@ -78,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);
@ -102,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);

View File

@ -15,115 +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_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_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_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_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_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_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_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_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_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_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')
@ -132,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)
@ -177,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'))
@ -198,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())
@ -206,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'))
@ -222,6 +230,27 @@ class Libbolt(object):
return False
return bool_str
def get_compact_channel_token(self, channel_token_str):
ct = self._interperate_json_string_as_dictionary(channel_token_str)
s = ct["pk_c"]
s += ct["pk_m"]
s += ct["cl_pk_m"]["X"]
s += "".join(ct["cl_pk_m"]["Y"])
s += ct["mpk"]["g1"]
s += ct["mpk"]["g2"]
s += "".join(ct["comParams"]["pub_bases"])
return s
def get_compact_signing_keys(self, cust_state_str):
cust_state_str = cust_state_str.replace("null", "None")
cust_state = self._interperate_json_string_as_dictionary(cust_state_str)
name = cust_state.get("name")
(pk, sk) = cust_state.get("pk_c"), cust_state.get("sk_c")
return name, pk, sk
if platform == 'darwin':
prefix = 'lib'
ext = 'dylib'
@ -255,10 +284,20 @@ def run_unit_test():
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)
#libbolt.get_compact_channel_token(channel_token)
print("cust state: ", cust_state)
#libbolt.get_compact_signing_keys(cust_state)
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)

369
py/libbolt_bn256.py Normal file
View File

@ -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()

View File

@ -4,11 +4,9 @@ Efficient Protocols for Set Membership and Range Proofs
Jan Camenisch, Rafik Chaabouni, and abhi shelat
Asiacrypt 2008
*/
extern crate pairing;
extern crate rand;
use rand::Rng;
use super::*;
use rand::Rng;
use cl::{Signature, PublicParams, setup, BlindKeyPair, ProofState, SignatureProof, BlindPublicKey};
use ped92::{Commitment, CSMultiParams};
use pairing::{Engine, CurveProjective};

View File

@ -1,14 +1,3 @@
/*
* Implement for Bolt protocols:
* - initializing channel state and generating cust/merch wallets
* - establish protocol
* - pay protocol
* - channel close algorithms (WIP)
*/
extern crate pairing;
extern crate rand;
use super::*;
use pairing::Engine;
use cl::{BlindKeyPair, Signature};
@ -134,8 +123,6 @@ impl<E: Engine> ChannelToken<E> {
// add a method to compute hash on chain: SHA256 + RIPEMD160?
}
// add methods to check if channel token is initialized
// (only if
///
/// Channel state for generating/loading channel parameters and generating keypairs
@ -223,13 +210,20 @@ impl<E: Engine> CustomerState<E> {
<E as pairing::Engine>::G2: serde::Serialize,
<E as ff::ScalarEngine>::Fr: serde::Serialize
{
let mut kp = secp256k1::Secp256k1::new();
kp.randomize(csprng);
let secp = secp256k1::Secp256k1::new();
// generate the keypair for the channel
let (sk_c, pk_c) = kp.generate_keypair(csprng);
let mut seckey = [0u8; 32];
csprng.fill_bytes(&mut seckey);
// generate the signing keypair for the channel
let sk_c = secp256k1::SecretKey::from_slice(&seckey).unwrap();
let pk_c = secp256k1::PublicKey::from_secret_key(&secp, &sk_c);
let mut seckey1 = [0u8; 32];
csprng.fill_bytes(&mut seckey1);
// generate the keypair for the initial wallet
let (wsk, wpk) = kp.generate_keypair(csprng);
let wsk = secp256k1::SecretKey::from_slice(&seckey1).unwrap();
let wpk = secp256k1::PublicKey::from_secret_key(&secp, &wsk);
// hash the wallet pub key
let wpk_h = hash_pubkey_to_fr::<E>(&wpk);
channel_token.set_customer_pk(&pk_c);
@ -346,9 +340,14 @@ impl<E: Engine> CustomerState<E> {
// for channel pay
pub fn generate_payment<R: Rng>(&self, csprng: &mut R, channel: &ChannelState<E>, amount: i64) -> (NIZKProof<E>, Commitment<E>, secp256k1::PublicKey, CustomerState<E>) {
// 1 - chooose new wpk/wsk pair
let mut kp = secp256k1::Secp256k1::new();
kp.randomize(csprng);
let (new_wsk, new_wpk) = kp.generate_keypair(csprng);
let secp = secp256k1::Secp256k1::new();
let mut seckey = [0u8; 32];
csprng.fill_bytes(&mut seckey);
let new_wsk = secp256k1::SecretKey::from_slice(&seckey).unwrap();
let new_wpk = secp256k1::PublicKey::from_secret_key(&secp, &new_wsk);
// compute hash of the pubkey
let wpk_h = hash_pubkey_to_fr::<E>(&new_wpk);
// 2 - form new wallet and commitment
@ -489,9 +488,14 @@ impl<E: Engine> MerchantState<E> {
pub fn new<R: Rng>(csprng: &mut R, channel: &mut ChannelState<E>, id: String) -> (Self, ChannelState<E>) {
let l = 5;
// generate keys here
let mut tx_kp = secp256k1::Secp256k1::new();
tx_kp.randomize(csprng);
let (wsk, wpk) = tx_kp.generate_keypair(csprng);
let secp = secp256k1::Secp256k1::new();
// tx_kp.randomize(csprng);
// let (wsk, wpk) = tx_kp.generate_keypair(csprng);
let mut seckey = [0u8; 32];
csprng.fill_bytes(&mut seckey);
let wsk = secp256k1::SecretKey::from_slice(&seckey).unwrap();
let wpk = secp256k1::PublicKey::from_secret_key(&secp, &wsk);
let mut ch = channel.clone();
let nizkParams = NIZKSecretParams::<E>::setup(csprng, l);
ch.cp = Some(ChannelParams::<E> { pub_params: nizkParams.pubParams.clone(), l, extra_verify: true });
@ -611,9 +615,10 @@ impl<E: Engine> MerchantState<E> {
mod tests {
use super::*;
use pairing::bls12_381::Bls12;
use pairing::bn256::Bn256;
#[test]
fn channel_util_works() {
fn channel_util_works_with_Bls12() {
let mut channel = ChannelState::<Bls12>::new(String::from("Channel A <-> B"), false);
let rng = &mut rand::thread_rng();
@ -689,4 +694,66 @@ mod tests {
let _channelId = channel_token.compute_channel_id();
}
#[test]
fn channel_util_works_with_Bn256() {
let mut channel = ChannelState::<Bn256>::new(String::from("Channel A <-> B"), false);
let rng = &mut rand::thread_rng();
let b0_cust = 100;
let b0_merch = 20;
// each party executes the init algorithm on the agreed initial challenge balance
// in order to derive the channel tokens
// initialize on the merchant side with balance: b0_merch
let (mut merch_state, mut channel) = MerchantState::<Bn256>::new(rng, &mut channel, String::from("Merchant B"));
// initialize the merchant wallet with the balance
let mut channel_token = merch_state.init(&mut channel);
// retrieve commitment setup params (using merchant long lived pk params)
// initialize on the customer side with balance: b0_cust
let mut cust_state = CustomerState::<Bn256>::new(rng, &mut channel_token, b0_cust, b0_merch, String::from("Alice"));
// lets establish the channel
let cust_com_proof = cust_state.generate_proof(rng, &mut channel_token);
// first return the close token, then wait for escrow-tx confirmation
// then send the pay-token after confirmation
let channelId = channel_token.compute_channel_id();
assert_eq!(channelId, cust_state.get_wallet().channelId);
let (close_token, pay_token) = merch_state.verify_proof(rng, &channel, &cust_state.w_com, &cust_com_proof, &channelId, b0_cust, b0_merch).unwrap();
// unblind tokens and verify signatures
assert!(cust_state.verify_close_token(&channel, &close_token));
assert!(cust_state.verify_pay_token(&channel, &pay_token));
// pay protocol tests
let amount = 10;
let (pay_proof, new_com, old_wpk, new_cw) = cust_state.generate_payment(rng, &channel, amount);
// new pay_token is not sent until revoke_token is obtained from the customer
let new_close_token = merch_state.verify_payment(rng, &channel, &pay_proof, &new_com, &old_wpk, amount).unwrap();
//println!("1 - Updated close Token : {}", new_close_token);
// unblind tokens and verify signatures
// assuming the pay_proof checks out, can go ahead and update internal state of cust_state
assert!(cust_state.update(new_cw));
//println!("2 - updated customer wallet!");
assert!(cust_state.verify_close_token(&channel, &new_close_token));
//println!("3 - verified the close token!");
// invalidate the previous state only if close token checks out
let (revoke_msg, revoke_sig) = cust_state.generate_revoke_token(&channel, &new_close_token).unwrap();
//println!("4 - Generated revoke token successfully.");
//println!("5 - Revoke token => {}", revoke_token);
let new_pay_token = merch_state.verify_revoke_token(&revoke_sig, &revoke_msg, &old_wpk).unwrap();
assert!(cust_state.verify_pay_token(&channel, &new_pay_token));
//println!("Validated revoke token!");
}
}

106
src/cl.rs
View File

@ -1,8 +1,5 @@
// cl.rs
// CL Sigs - Pointcheval Sanders ('06)
extern crate pairing;
extern crate rand;
use super::*;
use pairing::{CurveProjective, Engine};
use ff::PrimeField;
@ -12,6 +9,7 @@ use serde::{Serialize, Deserialize};
use util;
#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(bound(deserialize = "<E as pairing::Engine>::G1: serde::Deserialize<'de>, <E as pairing::Engine>::G2: serde::Deserialize<'de>"))]
pub struct PublicParams<E: Engine> {
pub g1: E::G1,
pub g2: E::G2,
@ -23,6 +21,18 @@ impl<E: Engine> PartialEq for PublicParams<E> {
}
}
impl<E: Engine> PublicParams<E> {
pub fn from_slice<'de>(ser_g1: &'de [u8], ser_g2: &'de [u8]) -> Self
where <E as pairing::Engine>::G1: serde::Deserialize<'de>,
<E as pairing::Engine>::G2: serde::Deserialize<'de>
{
// TODO: handle malformed input errors
let g1: E::G1 = serde_json::from_slice(ser_g1).unwrap();
let g2: E::G2 = serde_json::from_slice(ser_g2).unwrap();
PublicParams { g1, g2 }
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct SecretKey<E: Engine> {
@ -51,6 +61,7 @@ impl<E: Engine> PartialEq for SecretKey<E> {
#[derive(Clone, Serialize, Deserialize, Debug)]
#[serde(bound(deserialize = "<E as pairing::Engine>::G2: serde::Deserialize<'de>"))]
pub struct PublicKey<E: Engine> {
pub X: E::G2,
pub Y: Vec<E::G2>,
@ -75,6 +86,23 @@ impl<E: Engine> PartialEq for PublicKey<E> {
}
}
impl<E: Engine> PublicKey<E> {
pub fn from_slice<'de>(ser_x: &'de [u8], ser_y: &'de [u8], y_len: usize, num_elems: usize) -> Self
where <E as pairing::Engine>::G2: serde::Deserialize<'de>
{
let X: E::G2 = serde_json::from_slice(ser_x).unwrap();
let mut Y: Vec<E::G2> = Vec::new();
let mut start_pos = 0;
let mut end_pos = y_len;
for _ in 0 .. num_elems {
let y = serde_json::from_slice(&ser_y[start_pos .. end_pos]).unwrap();
start_pos = end_pos;
end_pos += y_len;
Y.push(y);
}
PublicKey { X, Y }
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct BlindPublicKey<E: Engine> {
@ -120,6 +148,19 @@ impl<E: Engine> PartialEq for Signature<E> {
}
}
impl<E: Engine> Signature<E> {
pub fn from_slice<'de>(ser_h: &'de [u8], ser_H: &'de [u8]) -> Self
where <E as pairing::Engine>::G1: serde::Deserialize<'de>
{
// TODO: handle malformed input errors
let h: E::G1 = serde_json::from_slice(ser_h).unwrap();
let H: E::G1 = serde_json::from_slice(ser_H).unwrap();
Signature { h, H }
}
}
#[derive(Clone)]
pub struct KeyPair<E: Engine> {
pub secret: SecretKey<E>,
@ -682,10 +723,10 @@ mod tests {
let blindkeypair = BlindKeyPair::<Bls12>::generate(&mut rng, &mpk, l);
let serialized = serde_json::to_vec(&mpk).unwrap();
//println!("serialized = {:?}", serialized.len());
println!("mpk serialized len = {:?}", serialized.len());
let _mpk_des: PublicParams<Bls12> = serde_json::from_slice(&serialized).unwrap();
//println!("{}", mpk_des);
//println!("{}", _mpk_des);
//println!("SK => {}", &keypair.secret);
let sk_serialized = serde_json::to_vec(&keypair.secret).unwrap();
@ -697,7 +738,7 @@ mod tests {
//println!("PK => {}", &keypair.public);
let pk_serialized = serde_json::to_vec(&keypair.public).unwrap();
//println!("pk_serialized = {:?}", pk_serialized.len());
println!("cl pk_serialized len = {:?}", pk_serialized.len());
let _pk_des: PublicKey<Bls12> = serde_json::from_slice(&pk_serialized).unwrap();
//assert_eq!(pk_des, keypair.public);
@ -719,5 +760,58 @@ mod tests {
assert_eq!(upk_des, unblind_pk);
assert_ne!(upk_des, keypair.public);
}
#[test]
fn test_compact_public_params_deserialize() {
let bin_g1= vec![132, 83, 99, 124, 75, 72, 15, 109, 12, 94, 84, 103, 1, 58, 160, 232, 190, 23, 119, 195, 112, 161, 152, 141, 178, 29, 141, 61, 227, 246, 215, 157, 140, 190, 100, 18, 248, 141, 57, 222, 12, 209, 191, 158, 143, 155, 87, 255];
let bin_g2 = vec![147, 63, 33, 190, 248, 155, 91, 211, 249, 169, 1, 147, 101, 104, 219, 88, 204, 131, 38, 167, 25, 191, 86, 67, 139, 188, 171, 101, 154, 32, 234, 92, 3, 66, 235, 159, 7, 47, 16, 83, 3, 201, 13, 227, 179, 184, 101, 102, 21, 88, 153, 208, 93, 0, 57, 108, 250, 231, 74, 192, 82, 111, 13, 211, 12, 51, 224, 198, 121, 15, 63, 129, 25, 218, 193, 47, 182, 248, 112, 185, 163, 23, 175, 169, 76, 214, 36, 184, 142, 222, 48, 212, 157, 35, 115, 181];
let ser_g1 = util::encode_as_hexstring(&bin_g1);
let ser_g2 = util::encode_as_hexstring(&bin_g2);
let str_g1 = ser_g1.as_bytes();
let str_g2 = ser_g2.as_bytes();
let rec_mpk = PublicParams::<Bls12>::from_slice(&str_g1, &str_g2);
println!("g1: {}", rec_mpk.g1);
println!("g2: {}", rec_mpk.g2);
let rec_g1_str = serde_json::to_string(&rec_mpk.g1).unwrap();
assert_eq!(rec_g1_str, "\"8453637c4b480f6d0c5e5467013aa0e8be1777c370a1988db21d8d3de3f6d79d8cbe6412f88d39de0cd1bf9e8f9b57ff\"");
let rec_g2_str = serde_json::to_string(&rec_mpk.g2).unwrap();
assert_eq!(rec_g2_str, "\"933f21bef89b5bd3f9a901936568db58cc8326a719bf56438bbcab659a20ea5c0342eb9f072f105303c90de3b3b86566155899d05d00396cfae74ac0526f0dd30c33e0c6790f3f8119dac12fb6f870b9a317afa94cd624b88ede30d49d2373b5\"");
}
#[test]
fn test_compact_cl_public_key_deserialize() {
let bin_g2_x = vec![147, 63, 33, 190, 248, 155, 91, 211, 249, 169, 1, 147, 101, 104, 219, 88, 204, 131, 38, 167, 25, 191, 86, 67, 139, 188, 171, 101, 154, 32, 234, 92, 3, 66, 235, 159, 7, 47, 16, 83, 3, 201, 13, 227, 179, 184, 101, 102, 21, 88, 153, 208, 93, 0, 57, 108, 250, 231, 74, 192, 82, 111, 13, 211, 12, 51, 224, 198, 121, 15, 63, 129, 25, 218, 193, 47, 182, 248, 112, 185, 163, 23, 175, 169, 76, 214, 36, 184, 142, 222, 48, 212, 157, 35, 115, 181];
let bin_g2_y1 = vec![143, 76, 112, 7, 35, 99, 254, 7, 255, 225, 69, 13, 99, 32, 92, 186, 234, 175, 230, 0, 202, 144, 1, 216, 187, 248, 152, 76, 229, 74, 156, 94, 4, 16, 132, 119, 157, 172, 231, 164, 207, 88, 41, 6, 234, 78, 73, 58, 19, 104, 236, 127, 5, 231, 248, 150, 53, 197, 85, 194, 110, 93, 1, 73, 24, 96, 149, 133, 109, 194, 16, 190, 244, 184, 254, 192, 52, 21, 205, 109, 18, 83, 189, 175, 208, 147, 74, 32, 181, 126, 224, 136, 250, 126, 224, 186];
let bin_g2_y2 = vec![150, 132, 45, 236, 146, 135, 127, 242, 61, 55, 73, 100, 151, 12, 51, 134, 151, 42, 138, 227, 105, 54, 121, 7, 0, 27, 205, 139, 186, 69, 139, 143, 41, 132, 35, 33, 168, 35, 31, 52, 65, 5, 73, 153, 203, 25, 178, 196, 4, 9, 218, 130, 22, 64, 98, 152, 225, 212, 27, 202, 245, 234, 138, 34, 82, 102, 40, 72, 211, 248, 16, 221, 54, 154, 186, 95, 246, 132, 54, 0, 128, 170, 111, 94, 155, 166, 27, 225, 51, 31, 107, 223, 139, 0, 209, 236];
let ser_g2_x = util::encode_as_hexstring(&bin_g2_x);
let ser_g2_y1 = util::encode_as_hexstring(&bin_g2_y1);
let ser_g2_y2 = util::encode_as_hexstring(&bin_g2_y2);
let str_g2_x = ser_g2_x.as_bytes();
let str_g2_y1 = ser_g2_y1.as_bytes();
let str_g2_y2 = ser_g2_y2.as_bytes();
let mut vec = Vec::new();
vec.extend(str_g2_y1);
vec.extend(str_g2_y2);
let rec_cl_pk = PublicKey::<Bls12>::from_slice(&str_g2_x, &vec.as_slice(), ser_g2_y1.len(), 2);
let rec_x_str = serde_json::to_string(&rec_cl_pk.X).unwrap();
assert_eq!(rec_x_str, "\"933f21bef89b5bd3f9a901936568db58cc8326a719bf56438bbcab659a20ea5c0342eb9f072f105303c90de3b3b86566155899d05d00396cfae74ac0526f0dd30c33e0c6790f3f8119dac12fb6f870b9a317afa94cd624b88ede30d49d2373b5\"");
let rec_y1_str = serde_json::to_string(&rec_cl_pk.Y[0]).unwrap();
assert_eq!(rec_y1_str, "\"8f4c70072363fe07ffe1450d63205cbaeaafe600ca9001d8bbf8984ce54a9c5e041084779dace7a4cf582906ea4e493a1368ec7f05e7f89635c555c26e5d0149186095856dc210bef4b8fec03415cd6d1253bdafd0934a20b57ee088fa7ee0ba\"");
let rec_y2_str = serde_json::to_string(&rec_cl_pk.Y[1]).unwrap();
assert_eq!(rec_y2_str, "\"96842dec92877ff23d374964970c3386972a8ae369367907001bcd8bba458b8f29842321a8231f3441054999cb19b2c40409da8216406298e1d41bcaf5ea8a2252662848d3f810dd369aba5ff684360080aa6f5e9ba61be1331f6bdf8b00d1ec\"");
}
}

View File

@ -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<T> = Result<T, serde_json::error::Error>;
// 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<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
// Some(serde_json::from_str(&string).unwrap())
// }
type CURVE = Bls12;
fn deserialize_result_object<'a, T>(serialized: *mut c_char) -> ResultSerdeType<T>
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<secp256k1::PublicKey> = 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::<Bls12>::new(name.to_string(), tps);
let channel_state = bidirectional::ChannelState::<CURVE>::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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = 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<bidirectional::ChannelToken<Bls12>> = deserialize_result_object(ser_channel_token);
let channel_token_result: ResultSerdeType<bidirectional::ChannelToken<CURVE>> = deserialize_result_object(ser_channel_token);
let mut channel_token = handle_errors!(channel_token_result);
// Deserialize the name
@ -136,15 +118,15 @@ pub mod ffishim {
// ESTABLISH
#[no_mangle] // bidirectional::establish_customer_generate_proof(rng, &mut channel_token, &mut cust_state);
pub extern fn ffishim_bidirectional_establish_customer_generate_proof(ser_channel_token: *mut c_char, ser_customer_state: *mut c_char) -> *mut c_char {
#[no_mangle]
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<bidirectional::ChannelToken<Bls12>> = deserialize_result_object(ser_channel_token);
let channel_token_result: ResultSerdeType<bidirectional::ChannelToken<CURVE>> = deserialize_result_object(ser_channel_token);
let mut channel_token = handle_errors!(channel_token_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<Bls12>> = deserialize_result_object(ser_customer_state);
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = 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,26 +141,38 @@ 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_generate_channel_id(ser_channel_token: *mut c_char) -> *mut c_char {
// Deserialize the channel token
let channel_token_result: ResultSerdeType<bidirectional::ChannelToken<CURVE>> = 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_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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the com proof
let com_result: ResultSerdeType<bidirectional::Commitment<Bls12>> = deserialize_result_object(ser_com);
let com_result: ResultSerdeType<bidirectional::Commitment<CURVE>> = deserialize_result_object(ser_com);
let com = handle_errors!(com_result);
// Deserialize the com proof
let com_proof_result: ResultSerdeType<bidirectional::CommitmentProof<Bls12>> = deserialize_result_object(ser_com_proof);
let com_proof_result: ResultSerdeType<bidirectional::CommitmentProof<CURVE>> = deserialize_result_object(ser_com_proof);
let com_proof = handle_errors!(com_proof_result);
// Deserialize the merchant state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<Bls12>> = deserialize_result_object(ser_merch_state);
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = deserialize_result_object(ser_merch_state);
let merch_state = handle_errors!(merch_state_result);
// Deserialize the pk_c
let channel_id_result: ResultSerdeType<<Bls12 as ScalarEngine>::Fr> = deserialize_result_object(ser_channel_id);
let channel_id_result: ResultSerdeType<<CURVE as ScalarEngine>::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));
@ -189,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the commitment
let com_result: ResultSerdeType<bidirectional::Commitment<Bls12>> = deserialize_result_object(ser_com);
let com_result: ResultSerdeType<bidirectional::Commitment<CURVE>> = deserialize_result_object(ser_com);
let com = handle_errors!(com_result);
// Deserialize the merchant state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<Bls12>> = deserialize_result_object(ser_merch_state);
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = 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);
@ -211,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let mut channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<Bls12>> = deserialize_result_object(ser_customer_state);
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = deserialize_result_object(ser_customer_state);
let mut cust_state = handle_errors!(cust_state_result);
// Deserialize the close token
let close_result: ResultSerdeType<bidirectional::Signature<Bls12>> = deserialize_result_object(ser_close_token);
let close_result: ResultSerdeType<bidirectional::Signature<CURVE>> = 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);
@ -235,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let mut channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<Bls12>> = deserialize_result_object(ser_customer_state);
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = deserialize_result_object(ser_customer_state);
let mut cust_state = handle_errors!(cust_state_result);
// Deserialize the custdata
let pay_token_result: ResultSerdeType<bidirectional::Signature<Bls12>> = deserialize_result_object(ser_pay_token);
let pay_token_result: ResultSerdeType<bidirectional::Signature<CURVE>> = 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);
@ -260,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<Bls12>> = deserialize_result_object(ser_customer_state);
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = deserialize_result_object(ser_customer_state);
let cust_state = handle_errors!(cust_state_result);
// Generate the payment proof
@ -280,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the payment proof
let payment_result: ResultSerdeType<bidirectional::Payment<Bls12>> = deserialize_result_object(ser_pay_proof);
let payment_result: ResultSerdeType<bidirectional::Payment<CURVE>> = deserialize_result_object(ser_pay_proof);
let payment = handle_errors!(payment_result);
// Deserialize the merch state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<Bls12>> = deserialize_result_object(ser_merch_state);
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = 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);
@ -302,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the payment proofs
let sender_payment_result: ResultSerdeType<bidirectional::Payment<Bls12>> = deserialize_result_object(ser_sender_pay_proof);
let sender_payment_result: ResultSerdeType<bidirectional::Payment<CURVE>> = deserialize_result_object(ser_sender_pay_proof);
let sender_payment = handle_errors!(sender_payment_result);
let receiver_payment_result: ResultSerdeType<bidirectional::Payment<Bls12>> = deserialize_result_object(ser_receiver_pay_proof);
let receiver_payment_result: ResultSerdeType<bidirectional::Payment<CURVE>> = deserialize_result_object(ser_receiver_pay_proof);
let receiver_payment = handle_errors!(receiver_payment_result);
// Deserialize the merch state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<Bls12>> = deserialize_result_object(ser_merch_state);
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = 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);
@ -329,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<Bls12>> = deserialize_result_object(ser_cust_state);
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = 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<bidirectional::CustomerState<Bls12>> = deserialize_result_object(ser_new_cust_state);
let new_cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = 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<bidirectional::Signature<Bls12>> = deserialize_result_object(ser_close_token);
let close_token_result: ResultSerdeType<bidirectional::Signature<CURVE>> = 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);
@ -354,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<bidirectional::RevokeToken> = deserialize_result_object(ser_revoke_token);
let revoke_token = handle_errors!(revoke_token_result);
// Deserialize the cust state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<Bls12>> = deserialize_result_object(ser_merch_state);
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = deserialize_result_object(ser_merch_state);
let mut merch_state = handle_errors!(merch_state_result);
// send revoke token and get pay-token in response
@ -374,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<bidirectional::RevokeToken> = deserialize_result_object(ser_sender_revoke_token);
let sender_revoke_token = handle_errors!(sender_revoke_token_result);
@ -383,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<bidirectional::MerchantState<Bls12>> = deserialize_result_object(ser_merch_state);
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = deserialize_result_object(ser_merch_state);
let mut merch_state = handle_errors!(merch_state_result);
// send revoke token and get pay-token in response
@ -399,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<Bls12>> = deserialize_result_object(ser_cust_state);
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = deserialize_result_object(ser_cust_state);
let mut cust_state = handle_errors!(cust_state_result);
// Deserialize the pay token
let pay_token_result: ResultSerdeType<bidirectional::Signature<Bls12>> = deserialize_result_object(ser_pay_token);
let pay_token_result: ResultSerdeType<bidirectional::Signature<CURVE>> = deserialize_result_object(ser_pay_token);
let pay_token = handle_errors!(pay_token_result);
// verify the pay token and update internal state
@ -423,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<Bls12>> = deserialize_result_object(ser_cust_state);
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = deserialize_result_object(ser_cust_state);
let cust_state = handle_errors!(cust_state_result);
let cust_close = bidirectional::customer_close(&channel_state, &cust_state);
@ -439,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<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the channel token
let channel_token_result: ResultSerdeType<bidirectional::ChannelToken<Bls12>> = deserialize_result_object(ser_channel_token);
let channel_token_result: ResultSerdeType<bidirectional::ChannelToken<CURVE>> = deserialize_result_object(ser_channel_token);
let channel_token = handle_errors!(channel_token_result);
// Deserialize the customer close structure
let cust_close_result: ResultSerdeType<bidirectional::ChannelcloseC<Bls12>> = deserialize_result_object(ser_cust_close);
let cust_close_result: ResultSerdeType<bidirectional::ChannelcloseC<CURVE>> = deserialize_result_object(ser_cust_close);
let cust_close = handle_errors!(cust_close_result);
// Deserialize the merch state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<Bls12>> = deserialize_result_object(ser_merch_state);
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = deserialize_result_object(ser_merch_state);
let merch_state = handle_errors!(merch_state_result);
// Deserialize the destination address as a string
@ -475,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<bidirectional::ChannelToken<Bls12>> = deserialize_result_object(ser_channel_token);
let channel_token_result: ResultSerdeType<bidirectional::ChannelToken<CURVE>> = deserialize_result_object(ser_channel_token);
let channel_token = handle_errors!(channel_token_result);
// Deserialize the wpk
@ -485,11 +479,11 @@ pub mod ffishim {
let wpk = handle_errors!(wpk_result);
// Deserialize the close wallet
let close_msg_result: ResultSerdeType<bidirectional::Wallet<Bls12>> = deserialize_result_object(ser_close_msg);
let close_msg_result: ResultSerdeType<bidirectional::Wallet<CURVE>> = deserialize_result_object(ser_close_msg);
let close_msg = handle_errors!(close_msg_result);
// Deserialize the close token
let close_token_result: ResultSerdeType<bidirectional::Signature<Bls12>> = deserialize_result_object(ser_close_token);
let close_token_result: ResultSerdeType<bidirectional::Signature<CURVE>> = deserialize_result_object(ser_close_token);
let close_token = handle_errors!(close_token_result);
// check the signatures
@ -500,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<bidirectional::ChannelToken<Bls12>> = deserialize_result_object(ser_channel_token);
let channel_token_result: ResultSerdeType<bidirectional::ChannelToken<CURVE>> = deserialize_result_object(ser_channel_token);
let channel_token = handle_errors!(channel_token_result);
// Deserialize the wpk

511
src/ffishim_bn256.rs Normal file
View File

@ -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<T> = Result<T, serde_json::error::Error>;
type CURVE = Bn256;
fn deserialize_result_object<'a, T>(serialized: *mut c_char) -> ResultSerdeType<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)
}
#[no_mangle]
pub extern fn ffishim_bn256_wtp_check_wpk(ser_wpk: *mut c_char) -> *mut c_char {
let wpk_result: ResultSerdeType<secp256k1::PublicKey> = 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::<CURVE>::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<bidirectional::ChannelState<CURVE>> = 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<bidirectional::ChannelToken<CURVE>> = 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<bidirectional::ChannelToken<CURVE>> = deserialize_result_object(ser_channel_token);
let mut channel_token = handle_errors!(channel_token_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = 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<bidirectional::ChannelToken<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the com proof
let com_result: ResultSerdeType<bidirectional::Commitment<CURVE>> = deserialize_result_object(ser_com);
let com = handle_errors!(com_result);
// Deserialize the com proof
let com_proof_result: ResultSerdeType<bidirectional::CommitmentProof<CURVE>> = deserialize_result_object(ser_com_proof);
let com_proof = handle_errors!(com_proof_result);
// Deserialize the merchant state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = deserialize_result_object(ser_merch_state);
let merch_state = handle_errors!(merch_state_result);
// Deserialize the pk_c
let channel_id_result: ResultSerdeType<<CURVE as ScalarEngine>::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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the commitment
let com_result: ResultSerdeType<bidirectional::Commitment<CURVE>> = deserialize_result_object(ser_com);
let com = handle_errors!(com_result);
// Deserialize the merchant state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let mut channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = deserialize_result_object(ser_customer_state);
let mut cust_state = handle_errors!(cust_state_result);
// Deserialize the close token
let close_result: ResultSerdeType<bidirectional::Signature<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let mut channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = deserialize_result_object(ser_customer_state);
let mut cust_state = handle_errors!(cust_state_result);
// Deserialize the custdata
let pay_token_result: ResultSerdeType<bidirectional::Signature<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the payment proof
let payment_result: ResultSerdeType<bidirectional::Payment<CURVE>> = deserialize_result_object(ser_pay_proof);
let payment = handle_errors!(payment_result);
// Deserialize the merch state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the payment proofs
let sender_payment_result: ResultSerdeType<bidirectional::Payment<CURVE>> = deserialize_result_object(ser_sender_pay_proof);
let sender_payment = handle_errors!(sender_payment_result);
let receiver_payment_result: ResultSerdeType<bidirectional::Payment<CURVE>> = deserialize_result_object(ser_receiver_pay_proof);
let receiver_payment = handle_errors!(receiver_payment_result);
// Deserialize the merch state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = 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<bidirectional::CustomerState<CURVE>> = 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<bidirectional::Signature<CURVE>> = 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<bidirectional::RevokeToken> = deserialize_result_object(ser_revoke_token);
let revoke_token = handle_errors!(revoke_token_result);
// Deserialize the cust state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = 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<bidirectional::RevokeToken> = deserialize_result_object(ser_sender_revoke_token);
let sender_revoke_token = handle_errors!(sender_revoke_token_result);
let receiver_revoke_token_result: ResultSerdeType<bidirectional::RevokeToken> = 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<bidirectional::MerchantState<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = deserialize_result_object(ser_cust_state);
let mut cust_state = handle_errors!(cust_state_result);
// Deserialize the pay token
let pay_token_result: ResultSerdeType<bidirectional::Signature<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the cust state
let cust_state_result: ResultSerdeType<bidirectional::CustomerState<CURVE>> = 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<bidirectional::ChannelState<CURVE>> = deserialize_result_object(ser_channel_state);
let channel_state = handle_errors!(channel_state_result);
// Deserialize the channel token
let channel_token_result: ResultSerdeType<bidirectional::ChannelToken<CURVE>> = deserialize_result_object(ser_channel_token);
let channel_token = handle_errors!(channel_token_result);
// Deserialize the customer close structure
let cust_close_result: ResultSerdeType<bidirectional::ChannelcloseC<CURVE>> = deserialize_result_object(ser_cust_close);
let cust_close = handle_errors!(cust_close_result);
// Deserialize the merch state
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<CURVE>> = 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<bidirectional::ChannelToken<CURVE>> = deserialize_result_object(ser_channel_token);
let channel_token = handle_errors!(channel_token_result);
// Deserialize the wpk
let wpk_result: ResultSerdeType<secp256k1::PublicKey> = deserialize_result_object(ser_wpk);
let wpk = handle_errors!(wpk_result);
// Deserialize the close wallet
let close_msg_result: ResultSerdeType<bidirectional::Wallet<CURVE>> = deserialize_result_object(ser_close_msg);
let close_msg = handle_errors!(close_msg_result);
// Deserialize the close token
let close_token_result: ResultSerdeType<bidirectional::Signature<CURVE>> = 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<bidirectional::ChannelToken<CURVE>> = deserialize_result_object(ser_channel_token);
let channel_token = handle_errors!(channel_token_result);
// Deserialize the wpk
let wpk_result: ResultSerdeType<secp256k1::PublicKey> = 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<bidirectional::ChannelcloseM> = 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()
}
}

View File

@ -13,16 +13,15 @@
#![allow(non_upper_case_globals)]
#![allow(unused_results)]
#![allow(missing_docs)]
#![feature(exclusive_range_pattern)]
#![cfg_attr(all(test, feature = "unstable"), feature(test))]
#[cfg(all(test, feature = "unstable"))]
extern crate test;
extern crate ff;
extern crate pairing;
extern crate ff_bl as ff;
extern crate pairing_bl as pairing;
extern crate rand;
extern crate rand_core;
// extern crate rand_core;
extern crate secp256k1;
extern crate time;
@ -32,9 +31,11 @@ extern crate serde;
extern crate serde_with;
extern crate libc;
extern crate hex;
#[cfg(test)]
extern crate core;
extern crate serde_json;
pub mod cl;
pub mod ccs08;
@ -44,6 +45,7 @@ pub mod nizk;
pub mod util;
pub mod wallet;
pub mod ffishim;
pub mod ffishim_bn256;
use std::fmt;
use std::str;
@ -159,10 +161,6 @@ pub mod bidirectional {
pub signature: secp256k1::Signature,
}
pub fn init() {
//sodiumoxide::init();
}
///
/// init_merchant - takes as input the public params, merchant balance and keypair.
/// Generates merchant data which consists of channel token and merchant state.
@ -507,6 +505,180 @@ pub mod bidirectional {
}
}
pub mod wtp_utils {
// Useful routines that simplify the Bolt WTP implementation for Zcash
use pairing::bls12_381::Bls12;
use ::{util, BoltResult};
use cl;
use ped92::CSMultiParams;
pub use cl::Signature;
pub use channels::ChannelToken;
pub use wallet::Wallet;
use channels::ChannelcloseM;
const BLS12_381_CHANNEL_TOKEN_LEN: usize = 1074;
const BLS12_381_G1_LEN: usize = 48;
const BLS12_381_G2_LEN: usize = 96;
const SECP256K1_PK_LEN: usize = 33;
const ADDRESS_LEN: usize = 33;
pub fn reconstruct_secp_public_key(pk_bytes: &[u8; SECP256K1_PK_LEN]) -> secp256k1::PublicKey {
return secp256k1::PublicKey::from_slice(pk_bytes).unwrap();
}
pub fn reconstruct_secp_signature(sig_bytes: &[u8]) -> secp256k1::Signature {
return secp256k1::Signature::from_der(sig_bytes).unwrap();
}
pub fn reconstruct_close_wallet_bls12(channel_token: &ChannelToken<Bls12>, wpk: &secp256k1::PublicKey, cust_bal: u32, merch_bal: u32) -> Wallet<Bls12> {
let channelId = channel_token.compute_channel_id();
let wpk_h = util::hash_pubkey_to_fr::<Bls12>(&wpk);
let close = util::hash_to_fr::<Bls12>(String::from("close").into_bytes());
return Wallet {
channelId, wpk: wpk_h, bc: cust_bal as i64, bm: merch_bal as i64, close: Some(close)
}
}
pub fn reconstruct_signature_bls12(sig: &Vec<u8>) -> BoltResult<cl::Signature<Bls12>> {
if (sig.len() != BLS12_381_G1_LEN * 2) {
return Err(String::from("signature has invalid length"));
}
let mut cur_index = 0;
let mut end_index = BLS12_381_G1_LEN;
let ser_cl_h = sig[cur_index .. end_index].to_vec();
let str_cl_h = util::encode_as_hexstring(&ser_cl_h);
let h = str_cl_h.as_bytes();
cur_index = end_index;
end_index += BLS12_381_G1_LEN;
let ser_cl_H = sig[cur_index .. end_index].to_vec();
let str_cl_H = util::encode_as_hexstring(&ser_cl_H);
let H = str_cl_H.as_bytes();
let cl_sig = cl::Signature::<Bls12>::from_slice(&h, &H);
Ok(Some(cl_sig))
}
pub fn reconstruct_channel_token_bls12(channel_token: &Vec<u8>) -> BoltResult<ChannelToken<Bls12>>
{
// parse pkc, pkm, pkM, mpk and comParams
if channel_token.len() != BLS12_381_CHANNEL_TOKEN_LEN {
return Err(String::from("could not reconstruct the channel token!"));
}
let num_y_elems = 5;
let num_com_params= 6;
let mut cur_index = 0;
let mut end_index = SECP256K1_PK_LEN;
let pkc = secp256k1::PublicKey::from_slice(&channel_token[cur_index .. end_index]).unwrap();
cur_index = end_index;
end_index += SECP256K1_PK_LEN;
let pkm = secp256k1::PublicKey::from_slice(&channel_token[cur_index .. end_index]).unwrap();
cur_index = end_index;
end_index += BLS12_381_G2_LEN; // pk_M => (X, Y)
let ser_cl_x = channel_token[cur_index .. end_index].to_vec();
let str_cl_x = util::encode_as_hexstring(&ser_cl_x);
let X = str_cl_x.as_bytes();
let mut Y = Vec::new();
for _ in 0 .. num_y_elems {
cur_index = end_index;
end_index += BLS12_381_G2_LEN;
let cl_y = channel_token[cur_index .. end_index].to_vec();
let ser_cl_y = util::encode_as_hexstring(&cl_y);
let str_cl_y = ser_cl_y.as_bytes();
Y.extend(str_cl_y);
}
let cl_pk= cl::PublicKey::<Bls12>::from_slice(&X, &Y.as_slice(), str_cl_x.len(), num_y_elems);
cur_index = end_index;
end_index += BLS12_381_G1_LEN;
let g1 = channel_token[cur_index .. end_index].to_vec();
let ser_mpk_g1 = util::encode_as_hexstring(&g1);
cur_index = end_index;
end_index += BLS12_381_G2_LEN;
let g2 = channel_token[cur_index .. end_index].to_vec();
let ser_mpk_g2 = util::encode_as_hexstring(&g2);
let ser_g1 = ser_mpk_g1.as_bytes();
let ser_g2 = ser_mpk_g2.as_bytes();
let mpk = cl::PublicParams::<Bls12>::from_slice(&ser_g1, &ser_g2);
let mut comparams = Vec::new();
for _ in 0 .. num_com_params {
cur_index = end_index;
end_index += BLS12_381_G1_LEN;
let com = channel_token[cur_index .. end_index].to_vec();
let ser_com = util::encode_as_hexstring(&com);
let str_com = ser_com.as_bytes();
comparams.extend(str_com);
}
let com_params = CSMultiParams::<Bls12>::from_slice(&comparams.as_slice(), ser_mpk_g1.len(), num_com_params);
Ok(Some(ChannelToken {
pk_c: Some(pkc), pk_m: pkm, cl_pk_m: cl_pk, mpk: mpk, comParams: com_params
}))
}
///
/// Used in open-channel WTP for validating that a close_token is a valid signature
///
pub fn wtp_verify_cust_close_message(channel_token: &ChannelToken<Bls12>, wpk: &secp256k1::PublicKey,
close_msg: &Wallet<Bls12>, close_token: &cl::Signature<Bls12>) -> bool {
// close_msg => <pkc> || <wpk> || <balance-cust> || <balance-merch> || CLOSE
// close_token = regular CL signature on close_msg
// channel_token => <pk_c, CL_PK_m, pk_m, mpk, comParams>
// (1) check that channel token and close msg are consistent (e.g., close_msg.channelId == H(channel_token.pk_c) &&
let chan_token_cid = channel_token.compute_channel_id(); // util::hash_pubkey_to_fr::<Bls12>(&pk_c);
let chan_token_wpk = util::hash_pubkey_to_fr::<Bls12>(&wpk);
let cid_thesame = (close_msg.channelId == chan_token_cid);
// (2) check that wpk matches what's in the close msg
let wpk_thesame = (close_msg.wpk == chan_token_wpk);
return cid_thesame && wpk_thesame && channel_token.cl_pk_m.verify(&channel_token.mpk, &close_msg.as_fr_vec(), &close_token);
}
pub fn wtp_generate_secp_signature(seckey: &[u8; 32], msg: &[u8; 32]) -> Vec<u8> {
let secp = secp256k1::Secp256k1::signing_only();
let msg = secp256k1::Message::from_slice(msg).unwrap();
let seckey = secp256k1::SecretKey::from_slice(seckey).unwrap();
let sig = secp.sign(&msg, &seckey);
// get serialized signature
let ser_sig = sig.serialize_der();
return ser_sig.to_vec();
}
pub fn wtp_verify_secp_signature(pubkey: &secp256k1::PublicKey, hash: &Vec<u8>, sig: &secp256k1::Signature) -> bool {
let secp = secp256k1::Secp256k1::verification_only();
let msg = secp256k1::Message::from_slice(hash.as_slice()).unwrap();
return secp.verify(&msg, &sig, &pubkey).is_ok()
}
pub fn reconstruct_secp_channel_close_m(address: &[u8; ADDRESS_LEN], ser_revoke_token: &Vec<u8>, ser_sig: &Vec<u8>) -> ChannelcloseM {
let revoke_token = secp256k1::Signature::from_der(&ser_revoke_token.as_slice()).unwrap();
let sig = secp256k1::Signature::from_der(&ser_sig.as_slice()).unwrap();
ChannelcloseM {
address: hex::encode(&address.to_vec()),
revoke: Some(revoke_token),
signature: sig,
}
}
}
#[cfg(all(test, feature = "unstable"))]
mod benches {
use rand::{Rng, thread_rng};
@ -523,6 +695,7 @@ mod tests {
use super::*;
use pairing::bls12_381::Bls12;
use rand::Rng;
use sha2::Digest;
fn setup_new_channel_helper(channel_state: &mut bidirectional::ChannelState<Bls12>,
init_cust_bal: i64, init_merch_bal: i64)
@ -899,4 +1072,91 @@ mod tests {
let _des_cw: bidirectional::CustomerState<Bls12> = serde_json::from_str(&serialized_cw).unwrap();
}
#[test]
fn test_reconstruct_channel_token() {
let _ser_channel_token = "024c252c7e36d0c30ae7c67dabea2168f41b36b85c14d3e180b423fa1a5df0e7ac027df0457901953b9b776f4999d5a1e78\
049c0afa4f741d0d3bb7d9711a0f8c0038f4c70072363fe07ffe1450d63205cbaeaafe600ca9001d8bbf8984ce54a9c5e041084779dace7a4cf582906ea4e\
493a1368ec7f05e7f89635c555c26e5d0149186095856dc210bef4b8fec03415cd6d1253bdafd0934a20b57ee088fa7ee0bab0668b1aa84c30e856dd685ce\
e2a95844cb68504e82fd9dd874cbf6f7ee58155245e97c52625b53f4ca969f48b33c59f0009adc70d1472a303a35ace0d96149c8cdb96f29b6f476b8f4a10\
bd430c4658d4e0b5873fcb946a76aa861c6c4c601ab8fb0b9c88d2e8861de2f0dae2bb2a8492db2978ce8f2e509328efbf12384ae2db5c17021d222724a3b\
c4b621bf4f32601d555ff2cfc2171adeb2f1bd42c484c1c0a1e5d7d2853c102080680cefc925808b6e3d71b29a93f7e8f5c2eeeeef944b3740feddb24ec2c\
17e3db22ee6a7af77e32a9d186bdcc150dd59b0cd92b92b6656cb588dec9d1d07be5e2a319bf37f1120b7c656f78dc6c4064f8d63f590f70cdc0c1746fde6\
035eeb9aa90b69ea666ad71b27078ab61573aec60bab80a4e6a8e4d8ce02204f5b7e0131bf24d5df1428e9e571891c6feb1c0a52ba789136b244f13f510c4\
f1f0eb4b0a7e675f105f8102c672461da340ebcae1eddd49a009bcf3b199eb2006fab6cf0ccf102b5c6dd45722dc0c27d4b9697f627f1bcbe44f6d96842de\
c92877ff23d374964970c3386972a8ae369367907001bcd8bba458b8f29842321a8231f3441054999cb19b2c40409da8216406298e1d41bcaf5ea8a225266\
2848d3f810dd369aba5ff684360080aa6f5e9ba61be1331f6bdf8b00d1ec8453637c4b480f6d0c5e5467013aa0e8be1777c370a1988db21d8d3de3f6d79d8\
cbe6412f88d39de0cd1bf9e8f9b57ff933f21bef89b5bd3f9a901936568db58cc8326a719bf56438bbcab659a20ea5c0342eb9f072f105303c90de3b3b865\
66155899d05d00396cfae74ac0526f0dd30c33e0c6790f3f8119dac12fb6f870b9a317afa94cd624b88ede30d49d2373b58453637c4b480f6d0c5e5467013\
aa0e8be1777c370a1988db21d8d3de3f6d79d8cbe6412f88d39de0cd1bf9e8f9b57ffa397625c859a63e2c6e42486c4f76f306d484cce151f8614f87506e9\
9c871521dd244bfeb380481aed8df823a507c7a3ad367c1797fc6efa089f929729e7d48bfa9c60860fbb212918bb91d8c6aa523046bdf208c95fa5a0fb86a\
1e46f92e0e5893e136b74d38e106fa990590598932a4e2458034cea22337c6f365bcb5cab59ceea03d7a9f7821ea432e262877ef0128cb73d8733c3961762\
26acb6b3de132c803be39a4e803cbc5a4670cb6169583fa899146fab0227dc2ae167393f96f3b8b31e015af1c305de3a07f52408e9c52495c2458ea05c7a3\
71dc14f3b1d6a646ed7cc0ca9417d8bde6efc1ac300d8e28f";
let ser_channel_token = hex::decode(_ser_channel_token).unwrap();
let option_ct = wtp_utils::reconstruct_channel_token_bls12(&ser_channel_token);
let channel_token = match option_ct {
Ok(n) => n.unwrap(),
Err(e) => panic!("Error reconstructing compact rep of channel token: {}", e)
};
let channelId = channel_token.compute_channel_id();
let original_channelId = "[\"0744645c9cbbf4e47f456fa05e2c6888a59f688641d25b2607610ce03b4ae20c\"]";
let computed_channelId = serde_json::to_string(&channelId).unwrap();
println!("channel ID: {}", channelId);
println!("pkc: {:?}", channel_token.pk_c.unwrap());
println!("pkm: {:?}", channel_token.pk_m);
assert_eq!(original_channelId, computed_channelId);
// reconstruct signature
let _ser_signature = "93f26490b4576c38dfb8dceae547f4b49aeb945ecc9cccc528c39068c78177bda68aaf45743f09c48ad99b6007fe415b\
aee9eafd51cfdb0dc567a5d152bc37861727e85088b417cf3ff57c108d0156eee56aff810f1e5f9e76cd6a3590d6db5e";
let ser_signature = hex::decode(_ser_signature).unwrap();
let option_sig = wtp_utils::reconstruct_signature_bls12(&ser_signature);
let sig = match option_sig {
Ok(n) => n.unwrap(),
Err(e) => panic!("Error reconstructing compact rep of signature: {}", e)
};
}
#[test]
fn test_reconstruct_secp_sig() {
let _ser_sig = "3044022064650285b55624f1f64b2c75e76589fa4b1033dabaa7ff50ff026e1dc038279202204ca696e0a829687c87171e8e5dab17069be248ff2595fd9607f3346dadcb579f";
let ser_sig = hex::decode(_ser_sig).unwrap();
let signature = wtp_utils::reconstruct_secp_signature(ser_sig.as_slice());
assert_eq!(format!("{:?}", signature), _ser_sig);
let sk = hex::decode("81361b9bc2f67524dcc59b980dc8b06aadb77db54f6968d2af76ecdb612e07e4").unwrap();
let msg = "hello world!";
let mut sha256 = sha2::Sha256::new();
sha256.input(msg);
let mut hash = [0u8; 32];
hash.copy_from_slice(&sha256.result());
let mut seckey = [0u8; 32];
seckey.copy_from_slice(sk.as_slice());
let sig = wtp_utils::wtp_generate_secp_signature(&seckey, &hash);
}
#[test]
fn test_reconstruct_channel_close_m() {
let mut address = [0u8; 33];
let address_slice = hex::decode("0a1111111111111111111111111111111111111111111111111111111111111111").unwrap();
address.copy_from_slice(address_slice.as_slice());
let channelClose = wtp_utils::reconstruct_secp_channel_close_m(&address,
&hex::decode("3044022041932b376fe2c5e9e9ad0a3804e2290c3bc40617ea4f7b913be858dbcc3760b50220429d6eb1aabbd4135db4e0776c0b768af844b0af44f2f8f9da5a65e8541b4e9f").unwrap(),
&hex::decode("3045022100e76653c5f8cb4c2f39efc7c5450d4f68ef3d84d482305534f5dfc310095a3124022003c4651ce1305cffe5e483ab99925cc4c9c5df2b5449bb18a51d52b21d789716").unwrap());
assert_eq!(channelClose.address, "0a1111111111111111111111111111111111111111111111111111111111111111");
assert_eq!(format!("{:?}", channelClose.revoke.unwrap()), "3044022041932b376fe2c5e9e9ad0a3804e2290c3bc40617ea4f7b913be858dbcc3760b50220429d6eb1aabbd4135db4e0776c0b768af844b0af44f2f8f9da5a65e8541b4e9f");
assert_eq!(format!("{:?}", channelClose.signature), "3045022100e76653c5f8cb4c2f39efc7c5450d4f68ef3d84d482305534f5dfc310095a3124022003c4651ce1305cffe5e483ab99925cc4c9c5df2b5449bb18a51d52b21d789716");
}
}

View File

@ -1,6 +1,3 @@
extern crate pairing;
extern crate rand;
use super::*;
use rand::Rng;
use cl::{Signature, PublicParams, setup, BlindKeyPair, SignatureProof, BlindPublicKey};

View File

@ -1,5 +1,5 @@
// ped92.rs
use rand::Rng;
use rand::{Rng, AsByteSliceMut};
use pairing::{Engine, CurveProjective};
use ff::{Rand, Field, PrimeField};
use std::fmt;
@ -40,6 +40,24 @@ impl<E: Engine> PartialEq for CSMultiParams<E> {
}
}
impl<E: Engine> CSMultiParams<E> {
pub fn from_slice<'de>(ser_gs: &'de [u8], g_len: usize, num_elems: usize) -> Self
where <E as pairing::Engine>::G1: serde::Deserialize<'de>
{
let mut pub_bases: Vec<E::G1> = Vec::new();
let mut start_pos = 0;
let mut end_pos = g_len;
for _ in 0 .. num_elems {
let g: E::G1 = serde_json::from_slice(&ser_gs[start_pos .. end_pos]).unwrap();
start_pos = end_pos;
end_pos += g_len;
pub_bases.push(g);
}
return CSMultiParams { pub_bases};
}
}
impl<E: Engine> fmt::Display for CSMultiParams<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@ -369,5 +387,39 @@ mod tests {
assert_eq!(proof.verify_proof(&comParams, &com.c, &challenge, None), true);
}
// add tests for extend/remove commits dynamically
#[test]
fn test_cs_multiparam_serialization() {
let mut vec: Vec<u8> = Vec::new();
let bin_g1= vec![132, 83, 99, 124, 75, 72, 15, 109, 12, 94, 84, 103, 1, 58, 160, 232, 190, 23, 119, 195, 112, 161, 152, 141, 178, 29, 141, 61, 227, 246, 215, 157, 140, 190, 100, 18, 248, 141, 57, 222, 12, 209, 191, 158, 143, 155, 87, 255];
let bin_g2 = vec![140, 16, 244, 244, 135, 28, 18, 94, 46, 64, 233, 195, 218, 147, 238, 170, 46, 164, 50, 92, 234, 117, 61, 158, 64, 226, 153, 38, 127, 168, 49, 125, 177, 183, 74, 164, 138, 128, 168, 84, 137, 67, 21, 179, 124, 88, 194, 239];
let bin_g3 = vec![147, 174, 242, 238, 231, 127, 9, 120, 16, 9, 191, 238, 60, 57, 106, 34, 198, 62, 28, 183, 77, 170, 27, 116, 36, 75, 242, 26, 242, 23, 213, 31, 186, 21, 141, 219, 59, 104, 247, 118, 56, 95, 183, 124, 103, 83, 93, 154];
let ser_g1 = util::encode_as_hexstring(&bin_g1);
let ser_g2 = util::encode_as_hexstring(&bin_g2);
let ser_g3 = util::encode_as_hexstring(&bin_g3);
let str_g1 = ser_g1.as_bytes();
let str_g2 = ser_g2.as_bytes();
let str_g3 = ser_g3.as_bytes();
vec.extend(str_g1);
vec.extend(str_g2);
vec.extend(str_g3);
let rec_csparams = CSMultiParams::<Bls12>::from_slice(&vec.as_slice(), str_g1.len(), 3);
println!("CS params: {:?}", rec_csparams.pub_bases);
let ser_cs = serde_json::to_string(&rec_csparams).unwrap();
println!("Serialized: {:}", ser_cs);
let rec_g1_str = serde_json::to_string(&rec_csparams.pub_bases[0]).unwrap();
assert_eq!(rec_g1_str, "\"8453637c4b480f6d0c5e5467013aa0e8be1777c370a1988db21d8d3de3f6d79d8cbe6412f88d39de0cd1bf9e8f9b57ff\"");
let rec_g2_str = serde_json::to_string(&rec_csparams.pub_bases[1]).unwrap();
assert_eq!(rec_g2_str, "\"8c10f4f4871c125e2e40e9c3da93eeaa2ea4325cea753d9e40e299267fa8317db1b74aa48a80a854894315b37c58c2ef\"");
let rec_g3_str = serde_json::to_string(&rec_csparams.pub_bases[2]).unwrap();
assert_eq!(rec_g3_str, "\"93aef2eee77f09781009bfee3c396a22c63e1cb74daa1b74244bf21af217d51fba158ddb3b68f776385fb77c67535d9a\"");
}
}

View File

@ -24,6 +24,12 @@ pub fn is_vec_g2_equal<E: Engine>(a: &Vec<E::G2>, b: &Vec<E::G2>) -> bool {
.all(|(a, b)| a == b)
}
pub fn encode_as_hexstring(bytes: &Vec<u8>) -> String {
let mut ser_hex = hex::encode(bytes);
ser_hex.insert(0, '"');
ser_hex.push('"');
return ser_hex;
}
pub fn hash_g1_to_fr<E: Engine>(x: &Vec<E::G1>) -> E::Fr {
let mut x_vec: Vec<u8> = Vec::new();
@ -39,7 +45,7 @@ pub fn hash_g2_to_fr<E: Engine>(x: &E::G2) -> E::Fr {
hash_to_fr::<E>(x_vec)
}
pub fn fmt_bytes_to_int(bytearray: [u8; 64]) -> String {
pub fn fmt_bytes_to_int(bytearray: [u8; 32]) -> String {
let mut result: String = "".to_string();
for byte in bytearray.iter() {
// Decide if you want upper- or lowercase results,
@ -55,12 +61,13 @@ pub fn fmt_bytes_to_int(bytearray: [u8; 64]) -> String {
return s;
}
pub fn compute_the_hash<E: Engine>(bytes: &Vec<u8>) -> E::Fr {
let mut hasher = sha2::Sha512::new();
let mut hasher = sha2::Sha256::new();
hasher.input(&bytes.as_slice());
let sha2_digest = hasher.result();
let mut hash_buf: [u8; 64] = [0; 64];
hash_buf.copy_from_slice(&sha2_digest[0..64]);
let mut hash_buf: [u8; 32] = [0; 32];
hash_buf.copy_from_slice(&sha2_digest);
let hexresult = fmt_bytes_to_int(hash_buf);
return E::Fr::from_str(&hexresult).unwrap();
}
@ -89,10 +96,9 @@ pub fn convert_int_to_fr<E: Engine>(value: i64) -> E::Fr {
pub fn compute_pub_key_fingerprint(wpk: &secp256k1::PublicKey) -> String {
let x_slice = wpk.serialize();
let mut hasher = sha2::Sha512::new();
let mut hasher = sha2::Sha256::new();
hasher.input(&x_slice.to_vec());
let sha2_digest = hasher.result();
// let sha2_digest = sha512::hash(&x_slice);
let h = format!("{:x}", HexSlice::new(&sha2_digest[0..16]));
return h;
}
@ -105,12 +111,12 @@ pub fn hash_buffer_to_fr<'a, E: Engine>(prefix: &'a str, buf: &[u8; 64]) -> E::F
}
pub fn hash_to_slice(input_buf: &Vec<u8>) -> [u8; 32] {
let mut hasher = sha2::Sha512::new();
let mut hasher = sha2::Sha256::new();
hasher.input(&input_buf.as_slice());
let sha2_digest = hasher.result();
let mut hash_buf: [u8; 32] = [0; 32];
hash_buf.copy_from_slice(&sha2_digest[0..32]);
hash_buf.copy_from_slice(&sha2_digest);
return hash_buf;
}
@ -158,7 +164,7 @@ mod tests {
let mut two = G2::one();
two.double();
assert_eq!(format!("{}", hash_g2_to_fr::<Bls12>(&two).into_repr()),
"0x27cd26f702a777dbf782534ae6bf2ec4aa6cb4617c8366f10f59bef13beb8c56");
"0x6550a1431236024424ac8e7f65781f244b70a38e5b3c275000a2b91089706868");
}
#[test]
@ -168,13 +174,13 @@ mod tests {
let mut x_vec: Vec<u8> = Vec::new();
x_vec.extend(format!("{}", two).bytes());
assert_eq!(format!("{}", hash_to_fr::<Bls12>(x_vec).into_repr()),
"0x27cd26f702a777dbf782534ae6bf2ec4aa6cb4617c8366f10f59bef13beb8c56");
"0x6550a1431236024424ac8e7f65781f244b70a38e5b3c275000a2b91089706868");
}
#[test]
fn fmt_byte_to_int_works() {
assert_eq!(fmt_bytes_to_int([12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123]),
"122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123134312235231231343122352312313431223523123");
assert_eq!(fmt_bytes_to_int([12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235]), // , 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123, 13, 43, 12, 235, 23, 123]),
"122352312313431223523123134312235231231343122352312313431223523123134312235");
}
#[test]

View File

@ -1,5 +1,3 @@
extern crate pairing;
use super::*;
use pairing::Engine;
use ff::PrimeField;