commit
c772a7f3a7
|
@ -10,6 +10,7 @@ use bolt::bidirectional;
|
|||
use std::time::Instant;
|
||||
use pairing::bls12_381::{Bls12};
|
||||
use bolt::handle_bolt_result;
|
||||
use bolt::util::hash_pubkey_to_fr;
|
||||
|
||||
macro_rules! measure_one_arg {
|
||||
($x: expr) => {
|
||||
|
@ -66,8 +67,9 @@ fn main() {
|
|||
println!(">> Time to generate proof for establish: {} ms", est_time);
|
||||
|
||||
// obtain close token for closing out channel
|
||||
let pk_h = hash_pubkey_to_fr::<Bls12>(&cust_state.pk_c);
|
||||
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof,
|
||||
b0_customer, b0_merchant, &merch_state);
|
||||
&pk_h, b0_customer, b0_merchant, &merch_state);
|
||||
let close_token= match option {
|
||||
Ok(n) => n.unwrap(),
|
||||
Err(e) => panic!("Failed - bidirectional::establish_merchant_issue_close_token(): {}", e)
|
||||
|
|
148
go/libbolt.go
148
go/libbolt.go
|
@ -30,6 +30,16 @@ type setupResp struct {
|
|||
Result string `json:"result"`
|
||||
}
|
||||
|
||||
type ChannelState struct {
|
||||
R int `json:"R"`
|
||||
TxFee int `json:"tx_fee"`
|
||||
Cp interface{} `json:"cp"`
|
||||
Name string `json:"name"`
|
||||
PayInit bool `json:"pay_init"`
|
||||
ChannelEstablished bool `json:"channel_established"`
|
||||
ThirdParty bool `json:"third_party"`
|
||||
}
|
||||
|
||||
type MerchState struct {
|
||||
KeyPair KeyPair `json:"keypair"`
|
||||
NizkParams interface{} `json:"nizkParams"`
|
||||
|
@ -142,37 +152,51 @@ type CustClose struct {
|
|||
Signature Signature `json:"signature"`
|
||||
}
|
||||
|
||||
func BidirectionalChannelSetup(name string, channelSupport bool) (string, error) {
|
||||
func BidirectionalChannelSetup(name string, channelSupport bool) (ChannelState, error) {
|
||||
resp := C.GoString(C.ffishim_bidirectional_channel_setup(C.CString(name), C.uint(btoi(channelSupport))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return ChannelState{}, err
|
||||
}
|
||||
return r.ChannelState, nil
|
||||
channelState := ChannelState{}
|
||||
err = json.Unmarshal([]byte(r.ChannelState), &channelState)
|
||||
return channelState, err
|
||||
}
|
||||
|
||||
func BidirectionalInitMerchant(channelState string, balanceMerchant int, nameMerchant string) (ChannelToken, MerchState, string, error) {
|
||||
resp := C.GoString(C.ffishim_bidirectional_init_merchant(C.CString(channelState), C.int(balanceMerchant), C.CString(nameMerchant)))
|
||||
func BidirectionalInitMerchant(channelState ChannelState, balanceMerchant int, nameMerchant string) (ChannelToken, MerchState, ChannelState, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return ChannelToken{}, MerchState{}, ChannelState{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_init_merchant(C.CString(string(serChannelState)), C.int(balanceMerchant), C.CString(nameMerchant)))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return ChannelToken{}, MerchState{}, "", err
|
||||
return ChannelToken{}, MerchState{}, ChannelState{}, err
|
||||
}
|
||||
merchState := MerchState{}
|
||||
err = json.Unmarshal([]byte(r.MerchState), &merchState)
|
||||
if err != nil {
|
||||
return ChannelToken{}, MerchState{}, "", err
|
||||
return ChannelToken{}, MerchState{}, ChannelState{}, err
|
||||
}
|
||||
err = json.Unmarshal([]byte(r.ChannelState), &channelState)
|
||||
if err != nil {
|
||||
return ChannelToken{}, MerchState{}, ChannelState{}, err
|
||||
}
|
||||
channelToken := ChannelToken{}
|
||||
err = json.Unmarshal([]byte(r.ChannelToken), &channelToken)
|
||||
return channelToken, merchState, r.ChannelState, err
|
||||
return channelToken, merchState, channelState, err
|
||||
}
|
||||
|
||||
func BidirectionalInitCustomer(channelState string, channelToken ChannelToken, balanceCustomer int, balanceMerchant int, nameCustomer string) (ChannelToken, CustState, error) {
|
||||
func BidirectionalInitCustomer(channelState ChannelState, channelToken ChannelToken, balanceCustomer int, balanceMerchant int, nameCustomer string) (ChannelToken, CustState, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return ChannelToken{}, CustState{}, err
|
||||
}
|
||||
serChannelToken, err := json.Marshal(channelToken)
|
||||
if err != nil {
|
||||
return ChannelToken{}, CustState{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_init_customer(C.CString(channelState), C.CString(string(serChannelToken)), C.int(balanceCustomer), C.int(balanceMerchant), C.CString(nameCustomer)))
|
||||
resp := C.GoString(C.ffishim_bidirectional_init_customer(C.CString(string(serChannelState)), C.CString(string(serChannelToken)), C.int(balanceCustomer), C.int(balanceMerchant), C.CString(nameCustomer)))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return ChannelToken{}, CustState{}, err
|
||||
|
@ -218,7 +242,11 @@ func BidirectionalEstablishCustomerGenerateProof(channelToken ChannelToken, cust
|
|||
return channelToken, custState, com, comProof, err
|
||||
}
|
||||
|
||||
func BidirectionalEstablishMerchantIssueCloseToken(serChannelState string, com Commitment, comProof CommitmentProof, initCustBal int, initMerchBal int, merchState MerchState) (Signature, error) {
|
||||
func BidirectionalEstablishMerchantIssueCloseToken(channelState ChannelState, com Commitment, comProof CommitmentProof, pkc string, initCustBal int, initMerchBal int, merchState MerchState) (Signature, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return Signature{}, err
|
||||
}
|
||||
serCom, err := json.Marshal(com)
|
||||
if err != nil {
|
||||
return Signature{}, err
|
||||
|
@ -231,7 +259,7 @@ func BidirectionalEstablishMerchantIssueCloseToken(serChannelState string, com C
|
|||
if err != nil {
|
||||
return Signature{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_close_token(C.CString(serChannelState), C.CString(string(serCom)), C.CString(string(serComProof)), C.int(initCustBal), C.int(initMerchBal), C.CString(string(serMerchState))))
|
||||
resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_close_token(C.CString(string(serChannelState)), C.CString(string(serCom)), C.CString(string(serComProof)), C.CString(pkc), C.int(initCustBal), C.int(initMerchBal), C.CString(string(serMerchState))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return Signature{}, err
|
||||
|
@ -241,7 +269,11 @@ func BidirectionalEstablishMerchantIssueCloseToken(serChannelState string, com C
|
|||
return closeToken, err
|
||||
}
|
||||
|
||||
func BidirectionalEstablishMerchantIssuePayToken(serChannelState string, com Commitment, merchState MerchState) (Signature, error) {
|
||||
func BidirectionalEstablishMerchantIssuePayToken(channelState ChannelState, com Commitment, merchState MerchState) (Signature, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return Signature{}, err
|
||||
}
|
||||
serCom, err := json.Marshal(com)
|
||||
if err != nil {
|
||||
return Signature{}, err
|
||||
|
@ -250,7 +282,7 @@ func BidirectionalEstablishMerchantIssuePayToken(serChannelState string, com Com
|
|||
if err != nil {
|
||||
return Signature{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_pay_token(C.CString(serChannelState), C.CString(string(serCom)), C.CString(string(serMerchState))))
|
||||
resp := C.GoString(C.ffishim_bidirectional_establish_merchant_issue_pay_token(C.CString(string(serChannelState)), C.CString(string(serCom)), C.CString(string(serMerchState))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return Signature{}, err
|
||||
|
@ -260,48 +292,68 @@ func BidirectionalEstablishMerchantIssuePayToken(serChannelState string, com Com
|
|||
return payToken, err
|
||||
}
|
||||
|
||||
func BidirectionalVerifyCloseToken(serChannelState string, custState CustState, closeToken Signature) (bool, string, CustState, error) {
|
||||
func BidirectionalVerifyCloseToken(channelState ChannelState, custState CustState, closeToken Signature) (bool, ChannelState, CustState, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return false, ChannelState{}, CustState{}, err
|
||||
}
|
||||
serCloseToken, err := json.Marshal(closeToken)
|
||||
if err != nil {
|
||||
return false, "", CustState{}, err
|
||||
return false, ChannelState{}, CustState{}, err
|
||||
}
|
||||
serCustState, err := json.Marshal(custState)
|
||||
if err != nil {
|
||||
return false, "", CustState{}, err
|
||||
return false, ChannelState{}, CustState{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_verify_close_token(C.CString(serChannelState), C.CString(string(serCustState)), C.CString(string(serCloseToken))))
|
||||
resp := C.GoString(C.ffishim_bidirectional_verify_close_token(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serCloseToken))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return false, "", CustState{}, err
|
||||
return false, ChannelState{}, CustState{}, err
|
||||
}
|
||||
err = json.Unmarshal([]byte(r.ChannelState), &channelState)
|
||||
if err != nil {
|
||||
return false, ChannelState{}, CustState{}, err
|
||||
}
|
||||
err = json.Unmarshal([]byte(r.CustState), &custState)
|
||||
return r.IsTokenValid, r.ChannelState, custState, err
|
||||
return r.IsTokenValid, channelState, custState, err
|
||||
}
|
||||
|
||||
func BidirectionalEstablishCustomerFinal(serChannelState string, custState CustState, payToken Signature) (bool, string, CustState, error) {
|
||||
func BidirectionalEstablishCustomerFinal(channelState ChannelState, custState CustState, payToken Signature) (bool, ChannelState, CustState, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return false, ChannelState{}, CustState{}, err
|
||||
}
|
||||
serPayToken, err := json.Marshal(payToken)
|
||||
if err != nil {
|
||||
return false, "", CustState{}, err
|
||||
return false, ChannelState{}, CustState{}, err
|
||||
}
|
||||
serCustState, err := json.Marshal(custState)
|
||||
if err != nil {
|
||||
return false, "", CustState{}, err
|
||||
return false, ChannelState{}, CustState{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_establish_customer_final(C.CString(serChannelState), C.CString(string(serCustState)), C.CString(string(serPayToken))))
|
||||
resp := C.GoString(C.ffishim_bidirectional_establish_customer_final(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serPayToken))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return false, "", CustState{}, err
|
||||
return false,ChannelState{}, CustState{}, err
|
||||
}
|
||||
err = json.Unmarshal([]byte(r.ChannelState), &channelState)
|
||||
if err != nil {
|
||||
return false, ChannelState{}, CustState{}, err
|
||||
}
|
||||
err = json.Unmarshal([]byte(r.CustState), &custState)
|
||||
return r.IsEstablished, r.ChannelState, custState, err
|
||||
return r.IsEstablished, channelState, custState, err
|
||||
}
|
||||
|
||||
func BidirectionalPayGeneratePaymentProof(serChannelState string, custState CustState, amount int) (string, CustState, error) {
|
||||
func BidirectionalPayGeneratePaymentProof(channelState ChannelState, custState CustState, amount int) (string, CustState, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return "", CustState{}, err
|
||||
}
|
||||
serCustState, err := json.Marshal(custState)
|
||||
if err != nil {
|
||||
return "", CustState{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_pay_generate_payment_proof(C.CString(serChannelState), C.CString(string(serCustState)), C.int(amount)))
|
||||
resp := C.GoString(C.ffishim_bidirectional_pay_generate_payment_proof(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.int(amount)))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return "", CustState{}, err
|
||||
|
@ -310,12 +362,16 @@ func BidirectionalPayGeneratePaymentProof(serChannelState string, custState Cust
|
|||
return r.Payment, custState, err
|
||||
}
|
||||
|
||||
func BidirectionalPayVerifyPaymentProof(serChannelState string, serPayProof string, merchState MerchState) (Signature, MerchState, error) {
|
||||
func BidirectionalPayVerifyPaymentProof(channelState ChannelState, serPayProof string, merchState MerchState) (Signature, MerchState, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return Signature{}, MerchState{}, err
|
||||
}
|
||||
serMerchState, err := json.Marshal(merchState)
|
||||
if err != nil {
|
||||
return Signature{}, MerchState{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_proof(C.CString(serChannelState), C.CString(serPayProof), C.CString(string(serMerchState))))
|
||||
resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_proof(C.CString(string(serChannelState)), C.CString(serPayProof), C.CString(string(serMerchState))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return Signature{}, MerchState{}, err
|
||||
|
@ -329,7 +385,11 @@ func BidirectionalPayVerifyPaymentProof(serChannelState string, serPayProof stri
|
|||
return *closeToken, merchState, err
|
||||
}
|
||||
|
||||
func BidirectionalPayGenerateRevokeToken(serChannelState string, custState CustState, newCustState CustState, closeToken Signature) (RevokeToken, CustState, error) {
|
||||
func BidirectionalPayGenerateRevokeToken(channelState ChannelState, custState CustState, newCustState CustState, closeToken Signature) (RevokeToken, CustState, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return RevokeToken{}, CustState{}, err
|
||||
}
|
||||
serCloseToken, err := json.Marshal(closeToken)
|
||||
if err != nil {
|
||||
return RevokeToken{}, CustState{}, err
|
||||
|
@ -342,7 +402,7 @@ func BidirectionalPayGenerateRevokeToken(serChannelState string, custState CustS
|
|||
if err != nil {
|
||||
return RevokeToken{}, CustState{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_pay_generate_revoke_token(C.CString(serChannelState), C.CString(string(serCustState)), C.CString(string(serNewCustState)), C.CString(string(serCloseToken))))
|
||||
resp := C.GoString(C.ffishim_bidirectional_pay_generate_revoke_token(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serNewCustState)), C.CString(string(serCloseToken))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return RevokeToken{}, CustState{}, err
|
||||
|
@ -379,7 +439,11 @@ func BidirectionalPayVerifyRevokeToken(revokeToken RevokeToken, merchState Merch
|
|||
return *payToken, merchState, err
|
||||
}
|
||||
|
||||
func BidirectionalPayVerifyPaymentToken(serChannelState string, custState CustState, payToken Signature) (CustState, bool, error) {
|
||||
func BidirectionalPayVerifyPaymentToken(channelState ChannelState, custState CustState, payToken Signature) (CustState, bool, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return CustState{}, false, err
|
||||
}
|
||||
serPayToken, err := json.Marshal(payToken)
|
||||
if err != nil {
|
||||
return CustState{}, false, err
|
||||
|
@ -388,7 +452,7 @@ func BidirectionalPayVerifyPaymentToken(serChannelState string, custState CustSt
|
|||
if err != nil {
|
||||
return CustState{}, false, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_token(C.CString(serChannelState), C.CString(string(serCustState)), C.CString(string(serPayToken))))
|
||||
resp := C.GoString(C.ffishim_bidirectional_pay_verify_payment_token(C.CString(string(serChannelState)), C.CString(string(serCustState)), C.CString(string(serPayToken))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return CustState{}, false, err
|
||||
|
@ -397,12 +461,16 @@ func BidirectionalPayVerifyPaymentToken(serChannelState string, custState CustSt
|
|||
return custState, r.IsPayValid, err
|
||||
}
|
||||
|
||||
func BidirectionalCustomerClose(serChannelState string, custState CustState) (CustClose, error) {
|
||||
func BidirectionalCustomerClose(channelState ChannelState, custState CustState) (CustClose, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return CustClose{}, err
|
||||
}
|
||||
serCustState, err := json.Marshal(custState)
|
||||
if err != nil {
|
||||
return CustClose{}, err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_customer_close(C.CString(serChannelState), C.CString(string(serCustState))))
|
||||
resp := C.GoString(C.ffishim_bidirectional_customer_close(C.CString(string(serChannelState)), C.CString(string(serCustState))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return CustClose{}, err
|
||||
|
@ -412,7 +480,11 @@ func BidirectionalCustomerClose(serChannelState string, custState CustState) (Cu
|
|||
return custClose, err
|
||||
}
|
||||
|
||||
func BidirectionalMerchantClose(serChannelState string, channelToken ChannelToken, serAddress string, custClose CustClose, merchState MerchState) (string, string, string, error) {
|
||||
func BidirectionalMerchantClose(channelState ChannelState, channelToken ChannelToken, serAddress string, custClose CustClose, merchState MerchState) (string, string, string, error) {
|
||||
serChannelState, err := json.Marshal(channelState)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
serMerchState, err := json.Marshal(merchState)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
|
@ -425,7 +497,7 @@ func BidirectionalMerchantClose(serChannelState string, channelToken ChannelToke
|
|||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
resp := C.GoString(C.ffishim_bidirectional_merchant_close(C.CString(serChannelState), C.CString(string(serChannelToken)), C.CString(serAddress), C.CString(string(serCustClose)), C.CString(string(serMerchState))))
|
||||
resp := C.GoString(C.ffishim_bidirectional_merchant_close(C.CString(string(serChannelState)), C.CString(string(serChannelToken)), C.CString(serAddress), C.CString(string(serCustClose)), C.CString(string(serMerchState))))
|
||||
r, err := processCResponse(resp)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
|
|
|
@ -14,14 +14,14 @@ func Test_ChannelSetup(t *testing.T) {
|
|||
assert.NotEqual(t, ChannelToken{}, channelToken)
|
||||
}
|
||||
|
||||
func setup(b0Cust int, b0Merch int) (string, ChannelToken, MerchState, CustState, error) {
|
||||
func setup(b0Cust int, b0Merch int) (ChannelState, ChannelToken, MerchState, CustState, error) {
|
||||
channelState, err := BidirectionalChannelSetup("Test Channel", false)
|
||||
if err != nil {
|
||||
return "", ChannelToken{}, MerchState{}, CustState{}, err
|
||||
return ChannelState{}, ChannelToken{}, MerchState{}, CustState{}, err
|
||||
}
|
||||
channelToken, merchState, channelState, err := BidirectionalInitMerchant(channelState, b0Merch, "Bob")
|
||||
if err != nil {
|
||||
return "", ChannelToken{}, MerchState{}, CustState{}, err
|
||||
return ChannelState{}, ChannelToken{}, MerchState{}, CustState{}, err
|
||||
}
|
||||
channelToken, custState, err := BidirectionalInitCustomer(channelState, channelToken, b0Cust, b0Merch, "Alice")
|
||||
return channelState, channelToken, merchState, custState, err
|
||||
|
@ -36,7 +36,7 @@ func Test_Establish(t *testing.T) {
|
|||
channelToken, custState, com, comProof, err := BidirectionalEstablishCustomerGenerateProof(channelToken, custState)
|
||||
assert.Nil(t, err)
|
||||
|
||||
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, b0Cust, b0Merch, merchState)
|
||||
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, custState.PkC, b0Cust, b0Merch, merchState)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, closeToken)
|
||||
|
||||
|
@ -61,7 +61,7 @@ func Test_Pay(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
channelToken, custState, com, comProof, err := BidirectionalEstablishCustomerGenerateProof(channelToken, custState)
|
||||
assert.Nil(t, err)
|
||||
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, b0Cust, b0Merch, merchState)
|
||||
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, custState.PkC, b0Cust, b0Merch, merchState)
|
||||
assert.Nil(t, err)
|
||||
_, channelState, custState, err = BidirectionalVerifyCloseToken(channelState, custState, closeToken)
|
||||
assert.Nil(t, err)
|
||||
|
@ -90,7 +90,7 @@ func Test_Close(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
channelToken, custState, com, comProof, err := BidirectionalEstablishCustomerGenerateProof(channelToken, custState)
|
||||
assert.Nil(t, err)
|
||||
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, b0Cust, b0Merch, merchState)
|
||||
closeToken, err := BidirectionalEstablishMerchantIssueCloseToken(channelState, com, comProof, custState.PkC, b0Cust, b0Merch, merchState)
|
||||
assert.Nil(t, err)
|
||||
_, channelState, custState, err = BidirectionalVerifyCloseToken(channelState, custState, closeToken)
|
||||
assert.Nil(t, err)
|
||||
|
|
|
@ -22,7 +22,7 @@ char* ffishim_bidirectional_init_customer(const char *ser_channel_state, const c
|
|||
|
||||
// channel establish protocol routines
|
||||
char* ffishim_bidirectional_establish_customer_generate_proof(const char *ser_channel_token, const char *ser_customer_wallet);
|
||||
char* ffishim_bidirectional_establish_merchant_issue_close_token(const char *ser_channel_state, const char *ser_com, const char *ser_com_proof, int init_cust_bal, int init_merch_bal, const char *ser_merch_state);
|
||||
char* ffishim_bidirectional_establish_merchant_issue_close_token(const char *ser_channel_state, const char *ser_com, const char *ser_com_proof, const char *ser_pk_c, int init_cust_bal, int init_merch_bal, const char *ser_merch_state);
|
||||
char* ffishim_bidirectional_establish_merchant_issue_pay_token(const char *ser_channel_state, const char *ser_com, const char *ser_merch_state);
|
||||
char* ffishim_bidirectional_verify_close_token(const char *ser_channel_state, const char *ser_customer_wallet, const char *ser_close_token);
|
||||
char* ffishim_bidirectional_establish_customer_final(const char *ser_channel_state, const char *ser_customer_wallet, const char *ser_pay_token);
|
||||
|
|
|
@ -29,7 +29,7 @@ class Libbolt(object):
|
|||
self.lib.ffishim_bidirectional_establish_customer_generate_proof.argtypes = (c_void_p, c_void_p)
|
||||
self.lib.ffishim_bidirectional_establish_customer_generate_proof.restype = c_void_p
|
||||
|
||||
self.lib.ffishim_bidirectional_establish_merchant_issue_close_token.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p, c_void_p, c_void_p)
|
||||
self.lib.ffishim_bidirectional_establish_merchant_issue_close_token.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p, c_void_p, c_void_p, c_void_p)
|
||||
self.lib.ffishim_bidirectional_establish_merchant_issue_close_token.restype = c_void_p
|
||||
|
||||
self.lib.ffishim_bidirectional_establish_merchant_issue_pay_token.argtypes = (c_void_p, c_void_p, c_void_p)
|
||||
|
@ -100,8 +100,8 @@ class Libbolt(object):
|
|||
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
|
||||
return output_dictionary['channel_token'], output_dictionary['cust_state'], output_dictionary['com'], output_dictionary['com_proof']
|
||||
|
||||
def bidirectional_establish_merchant_issue_close_token(self, channel_state, com, com_proof, init_cust, init_merch, merch_state):
|
||||
output_string = self.lib.ffishim_bidirectional_establish_merchant_issue_close_token(channel_state.encode(), com.encode(), com_proof.encode(), init_cust, init_merch, merch_state.encode())
|
||||
def bidirectional_establish_merchant_issue_close_token(self, channel_state, com, com_proof, pkc, init_cust, init_merch, merch_state):
|
||||
output_string = self.lib.ffishim_bidirectional_establish_merchant_issue_close_token(channel_state.encode(), com.encode(), com_proof.encode(), pkc.encode(), init_cust, init_merch, merch_state.encode())
|
||||
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
|
||||
return output_dictionary.get('close_token')
|
||||
|
||||
|
@ -241,7 +241,8 @@ def run_unit_test():
|
|||
print("channel token: => ", channel_token)
|
||||
print("com: ", com)
|
||||
|
||||
close_token = libbolt.bidirectional_establish_merchant_issue_close_token(channel_state, com, com_proof, b0_cust, b0_merch, merch_state)
|
||||
cust_state_dict = json.loads(cust_state)
|
||||
close_token = libbolt.bidirectional_establish_merchant_issue_close_token(channel_state, com, com_proof, cust_state_dict["pk_c"], b0_cust, b0_merch, merch_state)
|
||||
print("close token: ", close_token)
|
||||
|
||||
(is_token_valid, channel_state, cust_state) = libbolt.bidirectional_establish_customer_verify_close_token(channel_state, cust_state, close_token)
|
||||
|
|
22
py/tests.py
22
py/tests.py
|
@ -48,7 +48,8 @@ class BoltEstablishTests(unittest.TestCase):
|
|||
"""
|
||||
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token, self.cust_state)
|
||||
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
|
||||
cust_state_dict = json.loads(cust_state)
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
|
||||
self.assertTrue(close_token is not None)
|
||||
|
||||
(is_token_valid, channel_state, cust_state) = self.bolt.bidirectional_establish_customer_verify_close_token(self.channel_state, cust_state, close_token)
|
||||
|
@ -68,7 +69,8 @@ class BoltEstablishTests(unittest.TestCase):
|
|||
"""
|
||||
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token_bad, self.cust_state_bad)
|
||||
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
|
||||
cust_state_dict = json.loads(cust_state)
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
|
||||
self.assertTrue(close_token is None)
|
||||
#print("Establish protocol fail works as expected.")
|
||||
|
||||
|
@ -90,7 +92,8 @@ class BoltEstablishTests(unittest.TestCase):
|
|||
bad_com = json.dumps({"c":"852a57e24a2192e1cea19157e44f92d58369751f2012bc1f4a4312a89a63c74a92a4cb1d362b37ae0eda3b3bd1333502"})
|
||||
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token, self.cust_state)
|
||||
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
|
||||
cust_state_dict = json.loads(cust_state)
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
|
||||
self.assertTrue(close_token is not None)
|
||||
|
||||
(is_token_valid, channel_state, cust_state) = self.bolt.bidirectional_establish_customer_verify_close_token(self.channel_state, cust_state, close_token)
|
||||
|
@ -123,7 +126,8 @@ class BoltEstablishTests(unittest.TestCase):
|
|||
"""
|
||||
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token, self.cust_state)
|
||||
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
|
||||
cust_state_dict = json.loads(cust_state)
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
|
||||
self.assertTrue(close_token is not None)
|
||||
|
||||
malformed_close_token = malformed_token(close_token)
|
||||
|
@ -154,7 +158,8 @@ class BoltPayTests(unittest.TestCase):
|
|||
|
||||
(self.channel_token, self.cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(self.channel_token, self.cust_state)
|
||||
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, self.b0_cust, self.b0_merch, self.merch_state)
|
||||
cust_state_dict = json.loads(self.cust_state)
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, cust_state_dict["pk_c"], self.b0_cust, self.b0_merch, self.merch_state)
|
||||
self.assertTrue(close_token is not None)
|
||||
|
||||
(is_token_valid, self.channel_state, self.cust_state) = self.bolt.bidirectional_establish_customer_verify_close_token(self.channel_state, self.cust_state, close_token)
|
||||
|
@ -262,10 +267,10 @@ class BoltMultiChannelTests(unittest.TestCase):
|
|||
(self.channel_token_c, self.charlie_state) = self.bolt.bidirectional_init_customer(self.channel_state, self.channel_token,
|
||||
self.b0_charlie, self.b0_merch, "Charlie")
|
||||
|
||||
def _establish_channel(self, channel_token, cust_state, b0_cust, b0_merch):
|
||||
def _establish_channel(self, channel_token, cust_state, pkc, b0_cust, b0_merch):
|
||||
(channel_token, cust_state, com, com_proof) = self.bolt.bidirectional_establish_customer_generate_proof(channel_token, cust_state)
|
||||
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, b0_cust, b0_merch, self.merch_state)
|
||||
close_token = self.bolt.bidirectional_establish_merchant_issue_close_token(self.channel_state, com, com_proof, pkc, b0_cust, b0_merch, self.merch_state)
|
||||
self.assertTrue(close_token is not None)
|
||||
|
||||
(is_token_valid, self.channel_state, cust_state) = self.bolt.bidirectional_establish_customer_verify_close_token(self.channel_state, cust_state, close_token)
|
||||
|
@ -282,7 +287,8 @@ class BoltMultiChannelTests(unittest.TestCase):
|
|||
def test_multiple_channels_work(self):
|
||||
"""Establishing concurrent channels with a merchant works as expected
|
||||
"""
|
||||
channel_token_a, alice_cust_state = self._establish_channel(self.channel_token, self.alice_state, self.b0_alice, self.b0_merch)
|
||||
cust_state_dict = json.loads(self.alice_state)
|
||||
channel_token_a, alice_cust_state = self._establish_channel(self.channel_token, self.alice_state, cust_state_dict["pk_c"], self.b0_alice, self.b0_merch)
|
||||
|
||||
|
||||
class BoltIntermediaryTests(unittest.TestCase):
|
||||
|
|
18
src/ccs08.rs
18
src/ccs08.rs
|
@ -22,7 +22,7 @@ This must be computed in a trusted setup.
|
|||
#[derive(Clone, Serialize, Deserialize)]
|
||||
#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, <E as pairing::Engine>::G1: serde::Serialize, <E as pairing::Engine>::G2: serde::Serialize"))]
|
||||
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, <E as pairing::Engine>::G1: serde::Deserialize<'de>, <E as pairing::Engine>::G2: serde::Deserialize<'de>"))]
|
||||
struct ParamsUL<E: Engine> {
|
||||
pub struct ParamsUL<E: Engine> {
|
||||
pub mpk: PublicParams<E>,
|
||||
pub signatures: HashMap<String, Signature<E>>,
|
||||
pub csParams: CSMultiParams<E>,
|
||||
|
@ -44,9 +44,9 @@ This must be computed in a trusted setup.
|
|||
#[derive(Clone, Serialize, Deserialize)]
|
||||
#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, <E as pairing::Engine>::G1: serde::Serialize, <E as pairing::Engine>::G2: serde::Serialize"))]
|
||||
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, <E as pairing::Engine>::G1: serde::Deserialize<'de>, <E as pairing::Engine>::G2: serde::Deserialize<'de>"))]
|
||||
struct SecretParamsUL<E: Engine> {
|
||||
pub struct SecretParamsUL<E: Engine> {
|
||||
pub pubParams: ParamsUL<E>,
|
||||
kp: BlindKeyPair<E>,
|
||||
pub kp: BlindKeyPair<E>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -117,9 +117,9 @@ This must be computed in a trusted setup.
|
|||
#[serde(bound(serialize = "<E as ff::ScalarEngine>::Fr: serde::Serialize, <E as pairing::Engine>::G1: serde::Serialize, <E as pairing::Engine>::G2: serde::Serialize"))]
|
||||
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, <E as pairing::Engine>::G1: serde::Deserialize<'de>, <E as pairing::Engine>::G2: serde::Deserialize<'de>"))]
|
||||
pub struct RPPublicParams<E: Engine> {
|
||||
p: ParamsUL<E>,
|
||||
a: i32,
|
||||
b: i32,
|
||||
pub p: ParamsUL<E>,
|
||||
pub a: i32,
|
||||
pub b: i32,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -131,7 +131,7 @@ This must be computed in a trusted setup.
|
|||
#[serde(bound(deserialize = "<E as ff::ScalarEngine>::Fr: serde::Deserialize<'de>, <E as pairing::Engine>::G1: serde::Deserialize<'de>, <E as pairing::Engine>::G2: serde::Deserialize<'de>"))]
|
||||
pub struct RPSecretParams<E: Engine> {
|
||||
pub pubParams: RPPublicParams<E>,
|
||||
p: SecretParamsUL<E>,
|
||||
pub p: SecretParamsUL<E>,
|
||||
}
|
||||
|
||||
impl<E: Engine> SecretParamsUL<E> {
|
||||
|
@ -233,7 +233,7 @@ impl<E: Engine> ParamsUL<E> {
|
|||
self.prove_ul_response(r, C, &proofUlState, c, k, otherM)
|
||||
}
|
||||
|
||||
fn prove_ul_commitment<R: Rng>(&self, rng: &mut R, x: i32, k: usize, sOptional: Option<Vec<E::Fr>>, mOptional: Option<E::Fr>) -> ProofULState<E> {
|
||||
pub fn prove_ul_commitment<R: Rng>(&self, rng: &mut R, x: i32, k: usize, sOptional: Option<Vec<E::Fr>>, mOptional: Option<E::Fr>) -> ProofULState<E> {
|
||||
if x > self.u.pow(self.l as u32) || x < 0 {
|
||||
panic!("x is not within the range.");
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ impl<E: Engine> ParamsUL<E> {
|
|||
ProofULState { decx, proofStates, V, D, m, s }
|
||||
}
|
||||
|
||||
fn prove_ul_response(&self, r: E::Fr, C: Commitment<E>, proofUlState: &ProofULState<E>, c: E::Fr, k: usize, otherM: Vec<E::Fr>) -> ProofUL<E> {
|
||||
pub fn prove_ul_response(&self, r: E::Fr, C: Commitment<E>, proofUlState: &ProofULState<E>, c: E::Fr, k: usize, otherM: Vec<E::Fr>) -> ProofUL<E> {
|
||||
let mut sigProofs = Vec::<SignatureProof<E>>::with_capacity(self.l as usize);
|
||||
let mut zr = proofUlState.m.clone();
|
||||
let mut rc = r.clone();
|
||||
|
|
|
@ -550,8 +550,8 @@ impl<E: Engine> MerchantState<E> {
|
|||
return self.keypair.sign_blind(csprng, &cp.pub_params.mpk, pay_com);
|
||||
}
|
||||
|
||||
pub fn verify_proof<R: Rng>(&self, csprng: &mut R, channel: &ChannelState<E>, com: &Commitment<E>, com_proof: &CommitmentProof<E>, cust_balance: i32, merch_balance: i32) -> ResultBoltType<(Signature<E>, Signature<E>)> {
|
||||
let is_valid = nizk::verify_opening(&self.comParams, &com.c, &com_proof, cust_balance, merch_balance);
|
||||
pub fn verify_proof<R: Rng>(&self, csprng: &mut R, channel: &ChannelState<E>, com: &Commitment<E>, com_proof: &CommitmentProof<E>, pkc: &E::Fr, cust_balance: i32, merch_balance: i32) -> ResultBoltType<(Signature<E>, Signature<E>)> {
|
||||
let is_valid = nizk::verify_opening(&self.comParams, &com.c, &com_proof, &pkc, cust_balance, merch_balance);
|
||||
let cp = channel.cp.as_ref().unwrap();
|
||||
if is_valid {
|
||||
let close_token = self.issue_close_token(csprng, cp, com, true);
|
||||
|
@ -646,7 +646,8 @@ mod tests {
|
|||
|
||||
// first return the close token, then wait for escrow-tx confirmation
|
||||
// then send the pay-token after confirmation
|
||||
let (close_token, pay_token) = merch_state.verify_proof(rng, &channel, &cust_state.w_com, &cust_com_proof, b0_cust, b0_merch).unwrap();
|
||||
let pk_h = hash_pubkey_to_fr::<Bls12>(&cust_state.pk_c.clone());
|
||||
let (close_token, pay_token) = merch_state.verify_proof(rng, &channel, &cust_state.w_com, &cust_com_proof, &pk_h, b0_cust, b0_merch).unwrap();
|
||||
// unblind tokens and verify signatures
|
||||
assert!(cust_state.verify_close_token(&channel, &close_token));
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ pub mod ffishim {
|
|||
|
||||
use bidirectional;
|
||||
use ff::Rand;
|
||||
use pairing::bls12_381::{Bls12};
|
||||
use pairing::bls12_381::{Bls12, Fr};
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
|
@ -13,6 +13,8 @@ pub mod ffishim {
|
|||
use std::str;
|
||||
use channels::{ChannelcloseM, ResultBoltType, BoltError};
|
||||
use std::alloc::handle_alloc_error;
|
||||
use util::hash_pubkey_to_fr;
|
||||
use std::str::FromStr;
|
||||
|
||||
fn error_message(s: String) -> *mut c_char {
|
||||
let ser = ["{\'error\':\'", &s, "\'}"].concat();
|
||||
|
@ -166,7 +168,7 @@ pub mod ffishim {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn ffishim_bidirectional_establish_merchant_issue_close_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_com_proof: *mut c_char, init_cust_bal: i32, init_merch_bal: i32, ser_merch_state: *mut c_char) -> *mut c_char {
|
||||
pub extern fn ffishim_bidirectional_establish_merchant_issue_close_token(ser_channel_state: *mut c_char, ser_com: *mut c_char, ser_com_proof: *mut c_char, ser_pk_c: *mut c_char, init_cust_bal: i32, init_merch_bal: i32, ser_merch_state: *mut c_char) -> *mut c_char {
|
||||
let rng = &mut rand::thread_rng();
|
||||
// Deserialize the channel state
|
||||
let channel_state_result: ResultSerdeType<bidirectional::ChannelState<Bls12>> = deserialize_result_object(ser_channel_state);
|
||||
|
@ -184,7 +186,14 @@ pub mod ffishim {
|
|||
let merch_state_result: ResultSerdeType<bidirectional::MerchantState<Bls12>> = deserialize_result_object(ser_merch_state);
|
||||
let merch_state = handle_errors!(merch_state_result);
|
||||
|
||||
let close_token = bolt_try!(bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, init_cust_bal, init_merch_bal, &merch_state));
|
||||
// Deserialize the pk_c
|
||||
let bytes = unsafe { CStr::from_ptr(ser_pk_c).to_bytes() };
|
||||
let string: &str = str::from_utf8(bytes).unwrap();
|
||||
let pk_c_result = secp256k1::PublicKey::from_str(string);
|
||||
let pk_c = handle_errors!(pk_c_result);
|
||||
let pk_h = hash_pubkey_to_fr::<Bls12>(&pk_c);
|
||||
|
||||
let close_token = bolt_try!(bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &pk_h, init_cust_bal, init_merch_bal, &merch_state));
|
||||
|
||||
let ser = ["{\'close_token\':\'", serde_json::to_string(&close_token).unwrap().as_str(), "\'}"].concat();
|
||||
let cser = CString::new(ser).unwrap();
|
||||
|
|
103
src/lib.rs
103
src/lib.rs
|
@ -16,7 +16,8 @@
|
|||
#![feature(exclusive_range_pattern)]
|
||||
|
||||
#![cfg_attr(all(test, feature = "unstable"), feature(test))]
|
||||
#[cfg(all(test, feature = "unstable"))] extern crate test;
|
||||
#[cfg(all(test, feature = "unstable"))]
|
||||
extern crate test;
|
||||
|
||||
extern crate ff;
|
||||
extern crate pairing;
|
||||
|
@ -115,10 +116,12 @@ pub mod bidirectional {
|
|||
use util;
|
||||
use wallet;
|
||||
use pairing::Engine;
|
||||
use pairing::bls12_381::{Bls12};
|
||||
use pairing::bls12_381::Bls12;
|
||||
use sodiumoxide;
|
||||
use cl; // for blind signature
|
||||
use secp256k1; // for on-chain keys
|
||||
use cl;
|
||||
// for blind signature
|
||||
use secp256k1;
|
||||
// for on-chain keys
|
||||
use HashMap;
|
||||
use sodiumoxide::crypto::hash::sha512;
|
||||
use sha2::Sha512;
|
||||
|
@ -144,7 +147,7 @@ pub mod bidirectional {
|
|||
pub struct ChannelcloseC<E: Engine> {
|
||||
pub wpk: secp256k1::PublicKey,
|
||||
pub message: wallet::Wallet<E>,
|
||||
pub signature: cl::Signature<E>
|
||||
pub signature: cl::Signature<E>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
|
@ -168,7 +171,7 @@ pub mod bidirectional {
|
|||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct RevokeToken {
|
||||
message: util::RevokedMessage,
|
||||
pub signature: secp256k1::Signature
|
||||
pub signature: secp256k1::Signature,
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
|
@ -195,8 +198,8 @@ pub mod bidirectional {
|
|||
/// and wallet commitment.
|
||||
///
|
||||
pub fn init_customer<'a, R: Rng, E: Engine>(csprng: &mut R, channel_state: &ChannelState<E>,
|
||||
channel_token: &mut ChannelToken<E>,
|
||||
b0_cust: i32, b0_merch: i32, name: &'a str) -> CustomerState<E> {
|
||||
channel_token: &mut ChannelToken<E>,
|
||||
b0_cust: i32, b0_merch: i32, name: &'a str) -> CustomerState<E> {
|
||||
assert!(b0_cust >= 0);
|
||||
assert!(b0_merch >= 0);
|
||||
|
||||
|
@ -221,10 +224,10 @@ pub mod bidirectional {
|
|||
///
|
||||
pub fn establish_merchant_issue_close_token<R: Rng, E: Engine>(csprng: &mut R, channel_state: &ChannelState<E>,
|
||||
com: &Commitment<E>, com_proof: &CommitmentProof<E>,
|
||||
init_cust_balance: i32, init_merch_balance: i32,
|
||||
pkc: &E::Fr, init_cust_balance: i32, init_merch_balance: i32,
|
||||
merch_state: &MerchantState<E>) -> BoltResult<cl::Signature<E>> {
|
||||
// verifies proof of committed values and derives blind signature on the committed values to the customer's initial wallet
|
||||
match merch_state.verify_proof(csprng, channel_state, com, com_proof, init_cust_balance, init_merch_balance) {
|
||||
match merch_state.verify_proof(csprng, channel_state, com, com_proof, pkc, init_cust_balance, init_merch_balance) {
|
||||
Ok(n) => Ok(Some(n.0)), // just close token
|
||||
Err(err) => Err(String::from(err.to_string()))
|
||||
}
|
||||
|
@ -236,7 +239,7 @@ pub mod bidirectional {
|
|||
/// signature) over the contents of the customer's wallet.
|
||||
///
|
||||
pub fn establish_merchant_issue_pay_token<R: Rng, E: Engine>(csprng: &mut R, channel_state: &ChannelState<E>,
|
||||
com: &Commitment<E>, merch_state: &MerchantState<E>) -> cl::Signature<E> {
|
||||
com: &Commitment<E>, merch_state: &MerchantState<E>) -> cl::Signature<E> {
|
||||
let cp = channel_state.cp.as_ref().unwrap();
|
||||
let pay_token = merch_state.issue_pay_token(csprng, cp, com, false);
|
||||
return pay_token;
|
||||
|
@ -287,7 +290,7 @@ pub mod bidirectional {
|
|||
/// (i.e., partially blind signature on IOU with updated balance)
|
||||
///
|
||||
pub fn verify_payment_proof<R: Rng, E: Engine>(csprng: &mut R, channel_state: &ChannelState<E>,
|
||||
payment: &Payment<E>, merch_state: &mut MerchantState<E>) -> cl::Signature<E> {
|
||||
payment: &Payment<E>, merch_state: &mut MerchantState<E>) -> cl::Signature<E> {
|
||||
// if payment proof verifies, then returns close-token and records wpk => pay-token
|
||||
// if valid revoke_token is provided later for wpk, then release pay-token
|
||||
let tx_fee = channel_state.get_channel_fee();
|
||||
|
@ -296,7 +299,7 @@ pub mod bidirectional {
|
|||
false => payment.amount
|
||||
};
|
||||
let new_close_token = merch_state.verify_payment(csprng, &channel_state,
|
||||
&payment.proof, &payment.com, &payment.wpk, payment_amount).unwrap();
|
||||
&payment.proof, &payment.com, &payment.wpk, payment_amount).unwrap();
|
||||
// store the wpk since it has been revealed
|
||||
update_merchant_state(&mut merch_state.keys, &payment.wpk, None);
|
||||
return new_close_token;
|
||||
|
@ -352,16 +355,15 @@ pub mod bidirectional {
|
|||
/// a revocation token for the old wallet public key.
|
||||
///
|
||||
pub fn generate_revoke_token<E: Engine>(channel_state: &ChannelState<E>,
|
||||
old_cust_state: &mut CustomerState<E>,
|
||||
new_cust_state: CustomerState<E>,
|
||||
new_close_token: &cl::Signature<E>) -> RevokeToken {
|
||||
old_cust_state: &mut CustomerState<E>,
|
||||
new_cust_state: CustomerState<E>,
|
||||
new_close_token: &cl::Signature<E>) -> RevokeToken {
|
||||
// let's update the old wallet
|
||||
assert!(old_cust_state.update(new_cust_state));
|
||||
// generate the token after verifying that the close token is valid
|
||||
let (message, signature) = old_cust_state.generate_revoke_token(channel_state, new_close_token).unwrap();
|
||||
// return the revoke token (msg + sig pair)
|
||||
return RevokeToken { message, signature };
|
||||
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -391,7 +393,7 @@ pub mod bidirectional {
|
|||
panic!("Cannot close a channel that has not been established!");
|
||||
}
|
||||
|
||||
let mut wallet= cust_state.get_wallet();
|
||||
let mut wallet = cust_state.get_wallet();
|
||||
let close_token = cust_state.get_close_token();
|
||||
|
||||
let cp = channel_state.cp.as_ref().unwrap();
|
||||
|
@ -523,14 +525,14 @@ mod benches {
|
|||
mod tests {
|
||||
use super::*;
|
||||
use ff::Rand;
|
||||
use pairing::bls12_381::{Bls12};
|
||||
use pairing::bls12_381::Bls12;
|
||||
use rand::Rng;
|
||||
use channels::ChannelState;
|
||||
use util::hash_pubkey_to_fr;
|
||||
|
||||
fn setup_new_channel_helper(channel_state: &mut bidirectional::ChannelState<Bls12>,
|
||||
init_cust_bal: i32, init_merch_bal: i32)
|
||||
-> (bidirectional::ChannelToken<Bls12>, bidirectional::MerchantState<Bls12>, bidirectional::CustomerState<Bls12>, bidirectional::ChannelState<Bls12>) {
|
||||
|
||||
-> (bidirectional::ChannelToken<Bls12>, bidirectional::MerchantState<Bls12>, bidirectional::CustomerState<Bls12>, bidirectional::ChannelState<Bls12>) {
|
||||
let mut rng = &mut rand::thread_rng();
|
||||
let merch_name = "Bob";
|
||||
let cust_name = "Alice";
|
||||
|
@ -550,20 +552,20 @@ mod tests {
|
|||
}
|
||||
|
||||
fn execute_establish_protocol_helper(channel_state: &mut bidirectional::ChannelState<Bls12>,
|
||||
channel_token: &mut bidirectional::ChannelToken<Bls12>,
|
||||
cust_balance: i32,
|
||||
merch_balance: i32,
|
||||
merch_state: &mut bidirectional::MerchantState<Bls12>,
|
||||
cust_state: &mut bidirectional::CustomerState<Bls12>) {
|
||||
|
||||
channel_token: &mut bidirectional::ChannelToken<Bls12>,
|
||||
cust_balance: i32,
|
||||
merch_balance: i32,
|
||||
merch_state: &mut bidirectional::MerchantState<Bls12>,
|
||||
cust_state: &mut bidirectional::CustomerState<Bls12>) {
|
||||
let mut rng = &mut rand::thread_rng();
|
||||
|
||||
// lets establish the channel
|
||||
let (com, com_proof) = bidirectional::establish_customer_generate_proof(rng, channel_token, cust_state);
|
||||
|
||||
// obtain close token for closing out channel
|
||||
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, cust_balance, merch_balance, &merch_state);
|
||||
let close_token= match option {
|
||||
let pk_h = hash_pubkey_to_fr::<Bls12>(&cust_state.pk_c.clone());
|
||||
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &pk_h, cust_balance, merch_balance, &merch_state);
|
||||
let close_token = match option {
|
||||
Ok(n) => n.unwrap(),
|
||||
Err(e) => panic!("Failed - bidirectional::establish_merchant_issue_close_token(): {}", e)
|
||||
};
|
||||
|
@ -580,11 +582,10 @@ mod tests {
|
|||
}
|
||||
|
||||
fn execute_payment_protocol_helper(channel_state: &mut bidirectional::ChannelState<Bls12>,
|
||||
channel_token: &mut bidirectional::ChannelToken<Bls12>,
|
||||
merch_state: &mut bidirectional::MerchantState<Bls12>,
|
||||
cust_state: &mut bidirectional::CustomerState<Bls12>,
|
||||
payment_increment: i32) {
|
||||
|
||||
channel_token: &mut bidirectional::ChannelToken<Bls12>,
|
||||
merch_state: &mut bidirectional::MerchantState<Bls12>,
|
||||
cust_state: &mut bidirectional::CustomerState<Bls12>,
|
||||
payment_increment: i32) {
|
||||
let mut rng = &mut rand::thread_rng();
|
||||
|
||||
let (payment, new_cust_state) = bidirectional::generate_payment_proof(rng, channel_state, &cust_state, payment_increment);
|
||||
|
@ -599,7 +600,7 @@ mod tests {
|
|||
|
||||
// verify the pay token and update internal state
|
||||
assert!(cust_state.verify_pay_token(&channel_state, &new_pay_token.unwrap()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bidirectional_payment_basics_work() {
|
||||
|
@ -622,9 +623,10 @@ mod tests {
|
|||
let (com, com_proof) = bidirectional::establish_customer_generate_proof(rng, &mut channel_token, &mut cust_state);
|
||||
|
||||
// obtain close token for closing out channel
|
||||
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof,
|
||||
b0_customer, b0_merchant, &merch_state);
|
||||
let close_token= match option {
|
||||
let pk_h = hash_pubkey_to_fr::<Bls12>(&cust_state.pk_c.clone());
|
||||
let option = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &pk_h,
|
||||
b0_customer, b0_merchant, &merch_state);
|
||||
let close_token = match option {
|
||||
Ok(n) => n.unwrap(),
|
||||
Err(e) => panic!("Failed - bidirectional::establish_merchant_issue_close_token(): {}", e)
|
||||
};
|
||||
|
@ -662,7 +664,6 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn bidirectional_multiple_payments_work() {
|
||||
|
||||
let total_owed = 40;
|
||||
let b0_customer = 380;
|
||||
let b0_merchant = 20;
|
||||
|
@ -675,7 +676,7 @@ mod tests {
|
|||
let fee = 5;
|
||||
channel_state.set_channel_fee(fee);
|
||||
|
||||
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
|
||||
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper(&mut channel_state, b0_customer, b0_merchant);
|
||||
|
||||
// run establish protocol for customer and merchant channel
|
||||
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
|
||||
|
@ -685,7 +686,7 @@ mod tests {
|
|||
{
|
||||
// make multiple payments in a loop
|
||||
let num_payments = total_owed / payment_increment;
|
||||
for i in 0 .. num_payments {
|
||||
for i in 0..num_payments {
|
||||
execute_payment_protocol_helper(&mut channel_state, &mut channel_token, &mut merch_state, &mut cust_state, payment_increment);
|
||||
}
|
||||
|
||||
|
@ -702,7 +703,6 @@ mod tests {
|
|||
println!("{}", cust_close_msg.message);
|
||||
println!("{}", cust_close_msg.signature);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -716,7 +716,7 @@ mod tests {
|
|||
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Channel A -> B"), false);
|
||||
let mut rng = &mut rand::thread_rng();
|
||||
|
||||
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
|
||||
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper(&mut channel_state, b0_customer, b0_merchant);
|
||||
|
||||
// run establish protocol for customer and merchant channel
|
||||
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
|
||||
|
@ -744,7 +744,7 @@ mod tests {
|
|||
|
||||
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Channel A -> B"), false);
|
||||
|
||||
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
|
||||
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper(&mut channel_state, b0_customer, b0_merchant);
|
||||
|
||||
// run establish protocol for customer and merchant channel
|
||||
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
|
||||
|
@ -765,9 +765,9 @@ mod tests {
|
|||
let cur_cust_close_msg = bidirectional::customer_close(&channel_state, &cust_state);
|
||||
|
||||
let merch_close_result = bidirectional::merchant_close(&channel_state,
|
||||
&channel_token,
|
||||
&old_cust_close_msg,
|
||||
&merch_state);
|
||||
&channel_token,
|
||||
&old_cust_close_msg,
|
||||
&merch_state);
|
||||
let merch_close_msg = match merch_close_result {
|
||||
Ok(n) => n.unwrap(),
|
||||
Err(err) => panic!("Merchant close msg: {}", err)
|
||||
|
@ -789,7 +789,7 @@ mod tests {
|
|||
|
||||
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Channel A -> B"), false);
|
||||
|
||||
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper( &mut channel_state, b0_customer, b0_merchant);
|
||||
let (mut channel_token, mut merch_state, mut cust_state, mut channel_state) = setup_new_channel_helper(&mut channel_state, b0_customer, b0_merchant);
|
||||
|
||||
// run establish protocol for customer and merchant channel
|
||||
execute_establish_protocol_helper(&mut channel_state, &mut channel_token, b0_customer, b0_merchant, &mut merch_state, &mut cust_state);
|
||||
|
@ -808,9 +808,9 @@ mod tests {
|
|||
let cust_close_msg = bidirectional::customer_close(&channel_state, &cust_state);
|
||||
|
||||
let merch_close_result = bidirectional::merchant_close(&channel_state,
|
||||
&channel_token,
|
||||
&cust_close_msg,
|
||||
&merch_state);
|
||||
&channel_token,
|
||||
&cust_close_msg,
|
||||
&merch_state);
|
||||
let merch_close_msg = match merch_close_result {
|
||||
Ok(n) => n.unwrap(),
|
||||
Err(err) => panic!("Merchant close msg: {}", err)
|
||||
|
@ -942,5 +942,4 @@ mod tests {
|
|||
|
||||
let des_cw: bidirectional::CustomerState<Bls12> = serde_json::from_str(&serlalized_cw).unwrap();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
94
src/nizk.rs
94
src/nizk.rs
|
@ -7,7 +7,7 @@ use cl::{Signature, PublicParams, setup, BlindKeyPair, SignatureProof, PublicKey
|
|||
use ped92::{Commitment, CSMultiParams, CommitmentProof};
|
||||
use pairing::{Engine, CurveProjective};
|
||||
use wallet::Wallet;
|
||||
use ccs08::{RPPublicParams, RPSecretParams, RangeProof};
|
||||
use ccs08::{SecretParamsUL, ParamsUL, ProofUL};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use util;
|
||||
use std::borrow::BorrowMut;
|
||||
|
@ -28,8 +28,8 @@ pub struct NIZKProof<E: Engine> {
|
|||
pub sig: Signature<E>,
|
||||
pub sigProof: SignatureProof<E>,
|
||||
pub comProof: CommitmentProof<E>,
|
||||
pub rpBC: RangeProof<E>,
|
||||
pub rpBM: RangeProof<E>,
|
||||
pub rpBC: ProofUL<E>,
|
||||
pub rpBM: ProofUL<E>,
|
||||
}
|
||||
|
||||
/// NIZKPublicParams are public parameters to perform a NIZK Proof of Knowledge during the payment and closing protocol
|
||||
|
@ -46,8 +46,7 @@ pub struct NIZKPublicParams<E: Engine> {
|
|||
pub mpk: PublicParams<E>,
|
||||
pub pk: BlindPublicKey<E>,
|
||||
pub comParams: CSMultiParams<E>,
|
||||
pub rpParamsBC: RPPublicParams<E>,
|
||||
pub rpParamsBM: RPPublicParams<E>,
|
||||
pub rpParams: ParamsUL<E>,
|
||||
}
|
||||
|
||||
/// NIZKSecretParams are secret parameters to perform the verification of a NIZK Proof of Knowledge during the payment and closing protocol
|
||||
|
@ -63,8 +62,7 @@ pub struct NIZKPublicParams<E: Engine> {
|
|||
pub struct NIZKSecretParams<E: Engine> {
|
||||
pub pubParams: NIZKPublicParams<E>,
|
||||
pub keypair: BlindKeyPair<E>,
|
||||
pub rpParamsBC: RPSecretParams<E>,
|
||||
pub rpParamsBM: RPSecretParams<E>,
|
||||
pub rpParams: SecretParamsUL<E>,
|
||||
}
|
||||
|
||||
impl<E: Engine> NIZKSecretParams<E> {
|
||||
|
@ -74,11 +72,12 @@ impl<E: Engine> NIZKSecretParams<E> {
|
|||
let mpk = setup(rng);
|
||||
let keypair = BlindKeyPair::<E>::generate(rng, &mpk, messageLength);
|
||||
let comParams = keypair.generate_cs_multi_params(&mpk);
|
||||
let rpParamsBC = RPSecretParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone());
|
||||
let rpParamsBM = RPSecretParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone());
|
||||
let pubParams = NIZKPublicParams { mpk, pk: keypair.public.clone(), comParams, rpParamsBC: rpParamsBC.pubParams.clone(), rpParamsBM: rpParamsBM.pubParams.clone() };
|
||||
let u = 57; //TODO: optimize u?
|
||||
let l = (std::i16::MAX as f32).log(u as f32).floor() as i32;
|
||||
let rpParams = SecretParamsUL::setup_ul(rng, u, l, comParams.clone());
|
||||
let pubParams = NIZKPublicParams { mpk, pk: keypair.public.clone(), comParams, rpParams: rpParams.pubParams.clone() };
|
||||
|
||||
NIZKSecretParams{pubParams, keypair, rpParamsBC, rpParamsBM}
|
||||
NIZKSecretParams { pubParams, keypair, rpParams }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,7 +93,7 @@ impl<E: Engine> NIZKSecretParams<E> {
|
|||
let r0 = proof.sig.h != E::G1::one();
|
||||
|
||||
//compute challenge
|
||||
let challenge = NIZKPublicParams::<E>::hash(proof.sigProof.a, vec! {proof.comProof.T, proof.rpBC.p1.D, proof.rpBC.p2.D, proof.rpBM.p1.D, proof.rpBM.p2.D});
|
||||
let challenge = NIZKPublicParams::<E>::hash(proof.sigProof.a, vec! {proof.comProof.T, proof.rpBC.D, proof.rpBM.D});
|
||||
|
||||
//verify knowledge of signature
|
||||
let mut r1 = self.keypair.public.verify_proof(&self.pubParams.mpk, proof.sig, proof.sigProof.clone(), challenge);
|
||||
|
@ -103,11 +102,11 @@ impl<E: Engine> NIZKSecretParams<E> {
|
|||
r1 = r1 && proof.sigProof.zsig[1] == wpkc;
|
||||
|
||||
//verify knowledge of commitment
|
||||
let r2 = proof.comProof.verify_proof(&self.pubParams.comParams, &com.c.clone(), &challenge);
|
||||
let r2 = proof.comProof.verify_proof(&self.pubParams.comParams, &com.c.clone(), &challenge, None);
|
||||
|
||||
//verify range proofs
|
||||
let r3 = self.rpParamsBC.verify(proof.rpBC.clone(), challenge.clone(), 3);
|
||||
let r4 = self.rpParamsBM.verify(proof.rpBM.clone(), challenge.clone(), 4);
|
||||
let r3 = self.rpParams.verify_ul(&proof.rpBC.clone(), challenge.clone(), 3);
|
||||
let r4 = self.rpParams.verify_ul(&proof.rpBM.clone(), challenge.clone(), 4);
|
||||
|
||||
//verify linear relationship
|
||||
let mut r5 = proof.comProof.z[1] == proof.sigProof.zsig[0];
|
||||
|
@ -147,7 +146,7 @@ impl<E: Engine> NIZKPublicParams<E> {
|
|||
false => self.comParams.pub_bases.len()
|
||||
};
|
||||
|
||||
let (D, t, rt) = CommitmentProof::<E>::prove_commitment(rng, &self.comParams, &newWallet.as_fr_vec(), &vec! {});
|
||||
let (D, t) = CommitmentProof::<E>::prove_commitment(rng, &self.comParams, &newWallet.as_fr_vec(), None);
|
||||
|
||||
//commit signature
|
||||
let zero = E::Fr::zero();
|
||||
|
@ -158,11 +157,11 @@ impl<E: Engine> NIZKPublicParams<E> {
|
|||
let proofState = self.pk.prove_commitment(rng, &self.mpk, &paymentToken, tOptional, None);
|
||||
|
||||
//commit range proof
|
||||
let rpStateBC = self.rpParamsBC.prove_commitment(rng, newWallet.bc.clone(), newWalletCom.clone(), 3, None, None);
|
||||
let rpStateBM = self.rpParamsBM.prove_commitment(rng, newWallet.bm.clone(), newWalletCom.clone(), 4, None, None);
|
||||
let rpStateBC = self.rpParams.prove_ul_commitment(rng, newWallet.bc.clone(), 3, None, None);
|
||||
let rpStateBM = self.rpParams.prove_ul_commitment(rng, newWallet.bm.clone(), 4, None, None);
|
||||
|
||||
//Compute challenge
|
||||
let challenge = NIZKPublicParams::<E>::hash(proofState.a, vec! {D, rpStateBC.ps1.D, rpStateBC.ps2.D, rpStateBM.ps1.D, rpStateBM.ps2.D});
|
||||
let challenge = NIZKPublicParams::<E>::hash(proofState.a, vec! {D, rpStateBC.D, rpStateBM.D});
|
||||
|
||||
//Response phase
|
||||
//response for signature
|
||||
|
@ -171,7 +170,7 @@ impl<E: Engine> NIZKPublicParams<E> {
|
|||
|
||||
//response commitment
|
||||
let newWalletVec = newWallet.as_fr_vec();
|
||||
let comProof = CommitmentProof::<E>::prove_response(&newWalletVec, &rPrime, &vec! {}, D, &t, rt, &challenge);
|
||||
let comProof = CommitmentProof::<E>::prove_response(&newWalletVec, &rPrime, D, &t, &challenge);
|
||||
|
||||
//response range proof
|
||||
let mut vec01 = newWalletVec[0..2].to_vec();
|
||||
|
@ -184,8 +183,8 @@ impl<E: Engine> NIZKPublicParams<E> {
|
|||
let mut vec4 = newWalletVec[4..].to_vec();
|
||||
vec01.append(&mut vec4);
|
||||
}
|
||||
let rpBC = self.rpParamsBC.prove_response(rPrime.clone(), &rpStateBC, challenge.clone(), 3, vecWithout2.to_vec());
|
||||
let rpBM = self.rpParamsBM.prove_response(rPrime.clone(), &rpStateBM, challenge.clone(), 4, vec01.to_vec());
|
||||
let rpBC = self.rpParams.prove_ul_response(rPrime.clone(), newWalletCom.clone(), &rpStateBC, challenge.clone(), 3, vecWithout2.to_vec());
|
||||
let rpBM = self.rpParams.prove_ul_response(rPrime.clone(), newWalletCom.clone(), &rpStateBM, challenge.clone(), 4, vec01.to_vec());
|
||||
|
||||
NIZKProof { sig: proofState.blindSig, sigProof, comProof, rpBC, rpBM }
|
||||
}
|
||||
|
@ -204,40 +203,14 @@ impl<E: Engine> NIZKPublicParams<E> {
|
|||
///
|
||||
/// Verify PoK for the opening of a commitment during the establishment protocol
|
||||
///
|
||||
pub fn verify_opening<E: Engine>(com_params: &CSMultiParams<E>, com: &E::G1, proof: &CommitmentProof<E>, init_cust: i32, init_merch: i32) -> bool {
|
||||
pub fn verify_opening<E: Engine>(com_params: &CSMultiParams<E>, com: &E::G1, proof: &CommitmentProof<E>, pkc: &E::Fr, init_cust: i32, init_merch: i32) -> bool {
|
||||
let xvec: Vec<E::G1> = vec![proof.T.clone(), com.clone()];
|
||||
let challenge = util::hash_g1_to_fr::<E>(&xvec);
|
||||
|
||||
// compute the
|
||||
let com_equal = proof.verify_proof(com_params, com, &challenge);
|
||||
let com_equal = proof.verify_proof(com_params, com, &challenge, Some(vec!{None, Some(pkc.clone()), None, Some(util::convert_int_to_fr::<E>(init_cust)), Some(util::convert_int_to_fr::<E>(init_merch))}));
|
||||
|
||||
if proof.index.len() == 0 {
|
||||
println!("verify_opening - doing any partial reveals?");
|
||||
return false;
|
||||
}
|
||||
|
||||
// verify linear relationshps
|
||||
// pkc: index = 1
|
||||
let mut s1 = proof.reveal[1].clone();
|
||||
s1.mul_assign(&challenge);
|
||||
s1.add_assign(&proof.t[1]);
|
||||
let pkc_equal = (s1 == proof.z[1]);
|
||||
|
||||
// cust init balances: index = 3
|
||||
let mut s3 = proof.reveal[3].clone();
|
||||
s3.mul_assign(&challenge);
|
||||
s3.add_assign(&proof.t[3]);
|
||||
let init_c = util::convert_int_to_fr::<E>(init_cust);
|
||||
let bc_equal = (s3 == proof.z[3]) && (proof.reveal[3] == init_c);
|
||||
|
||||
// merch init balances: index = 4
|
||||
let mut s4 = proof.reveal[4].clone();
|
||||
s4.mul_assign(&challenge);
|
||||
s4.add_assign(&proof.t[4]);
|
||||
let init_m = util::convert_int_to_fr::<E>(init_merch);
|
||||
let bm_equal = (s4 == proof.z[4]) && (proof.reveal[4] == init_m);
|
||||
|
||||
return com_equal && pkc_equal && bc_equal && bm_equal;
|
||||
return com_equal;
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,7 +247,7 @@ mod tests {
|
|||
let paymentToken = secParams.keypair.unblind(&r, &blindPaymentToken);
|
||||
|
||||
let proof = secParams.pubParams.prove(rng, wallet1, wallet2,
|
||||
commitment2.clone(), rprime, &paymentToken);
|
||||
commitment2.clone(), rprime, &paymentToken);
|
||||
let fr = convert_int_to_fr::<Bls12>(*epsilon);
|
||||
assert_eq!(secParams.verify(proof, fr, &commitment2, wpk), true);
|
||||
}
|
||||
|
@ -304,7 +277,7 @@ mod tests {
|
|||
let paymentToken = secParams.keypair.unblind(&r, &blindPaymentToken);
|
||||
|
||||
let proof = secParams.pubParams.prove(rng, wallet1, wallet2,
|
||||
commitment2.clone(), rprime, &paymentToken);
|
||||
commitment2.clone(), rprime, &paymentToken);
|
||||
let fr = convert_int_to_fr::<Bls12>(*epsilon);
|
||||
assert_eq!(secParams.verify(proof, fr, &commitment2, wpk), true);
|
||||
}
|
||||
|
@ -345,7 +318,7 @@ mod tests {
|
|||
assert!(pk.verify(&secParams.pubParams.mpk, &wallet2.as_fr_vec(), &closeToken));
|
||||
|
||||
let proof = secParams.pubParams.prove(rng, wallet1, wallet2,
|
||||
commitment2.clone(), rprime, &paymentToken);
|
||||
commitment2.clone(), rprime, &paymentToken);
|
||||
|
||||
assert_eq!(secParams.verify(proof, Fr::from_str(&epsilon.to_string()).unwrap(), &commitment2, wpk), true);
|
||||
}
|
||||
|
@ -407,7 +380,7 @@ mod tests {
|
|||
let com_proof = CommitmentProof::<Bls12>::new(rng, &secParams.pubParams.comParams,
|
||||
&com.c, &wallet.as_fr_vec(), &t, &vec![1, 3, 4]);
|
||||
|
||||
assert!(verify_opening(&secParams.pubParams.comParams, &com.c, &com_proof, bc, bm));
|
||||
assert!(verify_opening(&secParams.pubParams.comParams, &com.c, &com_proof, &pkc.clone(), bc, bm));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -430,8 +403,8 @@ mod tests {
|
|||
let com1_proof = CommitmentProof::<Bls12>::new(rng, &secParams.pubParams.comParams,
|
||||
&com1.c, &wallet1.as_fr_vec(), &t, &vec![1, 3, 4]);
|
||||
|
||||
assert!(verify_opening(&secParams.pubParams.comParams, &com1.c, &com1_proof, bc, bm));
|
||||
assert!(!verify_opening(&secParams.pubParams.comParams, &com2.c, &com1_proof, bc2, bm));
|
||||
assert!(verify_opening(&secParams.pubParams.comParams, &com1.c, &com1_proof, &pkc.clone(), bc, bm));
|
||||
assert!(!verify_opening(&secParams.pubParams.comParams, &com2.c, &com1_proof, &pkc.clone(), bc2, bm));
|
||||
}
|
||||
|
||||
|
||||
|
@ -443,10 +416,11 @@ mod tests {
|
|||
let mpk = setup(&mut rng);
|
||||
let blindkeypair = BlindKeyPair::<Bls12>::generate(&mut rng, &mpk, l);
|
||||
let comParams = blindkeypair.generate_cs_multi_params(&mpk);
|
||||
let rpParamsBC = ccs08::RPSecretParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone());
|
||||
let rpParamsBM = ccs08::RPSecretParams::setup(rng, 0, std::i16::MAX as i32, comParams.clone());
|
||||
let u = 57; //TODO: optimize u?
|
||||
let l = (std::i16::MAX as f32).log(u as f32).floor() as i32;
|
||||
let rpParams = ccs08::SecretParamsUL::setup_ul(rng, u, l, comParams.clone());
|
||||
|
||||
let nizk_params = NIZKPublicParams { mpk: mpk, pk: blindkeypair.public, comParams: comParams, rpParamsBC: rpParamsBC.pubParams, rpParamsBM: rpParamsBM.pubParams };
|
||||
let nizk_params = NIZKPublicParams { mpk: mpk, pk: blindkeypair.public, comParams: comParams, rpParams: rpParams.pubParams.clone() };
|
||||
|
||||
let is_serialized = serde_json::to_vec(&nizk_params).unwrap();
|
||||
println!("NIZK Struct len: {}", is_serialized.len());
|
||||
|
|
61
src/ped92.rs
61
src/ped92.rs
|
@ -187,88 +187,85 @@ impl<E: Engine> CSMultiParams<E> {
|
|||
pub struct CommitmentProof<E: Engine> {
|
||||
pub T: E::G1,
|
||||
pub z: Vec<E::Fr>,
|
||||
pub t: Vec<E::Fr>,
|
||||
pub index: Vec<usize>,
|
||||
pub reveal: Vec<E::Fr>
|
||||
}
|
||||
|
||||
impl<E: Engine> CommitmentProof<E> {
|
||||
pub fn new<R: Rng>(csprng: &mut R, com_params: &CSMultiParams<E>, com: &E::G1, wallet: &Vec<E::Fr>, r: &E::Fr, reveal_index: &Vec<usize>) -> Self {
|
||||
let (Tvals, t, rt) = CommitmentProof::<E>::prove_commitment::<R>(csprng, com_params, wallet, reveal_index);
|
||||
let mut rt = Vec::new();
|
||||
for i in 0..wallet.len() + 1 {
|
||||
if reveal_index.contains(&i) {
|
||||
rt.push(E::Fr::zero());
|
||||
} else {
|
||||
rt.push(E::Fr::rand(csprng));
|
||||
}
|
||||
}
|
||||
|
||||
let (Tvals, t) = CommitmentProof::<E>::prove_commitment::<R>(csprng, com_params, wallet, Some(rt));
|
||||
|
||||
// compute the challenge
|
||||
let x: Vec<E::G1> = vec![Tvals, com.clone()];
|
||||
let challenge = util::hash_g1_to_fr::<E>(&x);
|
||||
|
||||
// compute the response
|
||||
CommitmentProof::<E>::prove_response(wallet, r, reveal_index, Tvals, &t, rt, &challenge)
|
||||
CommitmentProof::<E>::prove_response(wallet, r, Tvals, &t, &challenge)
|
||||
}
|
||||
|
||||
pub fn prove_commitment<R: Rng>(csprng: &mut R, com_params: &CSMultiParams<E>, wallet: &Vec<E::Fr>, reveal_index: &Vec<usize>) -> (E::G1, Vec<E::Fr>, Vec<E::Fr>) {
|
||||
pub fn prove_commitment<R: Rng>(csprng: &mut R, com_params: &CSMultiParams<E>, wallet: &Vec<E::Fr>, tOptional: Option<Vec<E::Fr>>) -> (E::G1, Vec<E::Fr>) {
|
||||
let mut Tvals = E::G1::zero();
|
||||
assert!(wallet.len() <= com_params.pub_bases.len());
|
||||
let mut t = Vec::<E::Fr>::with_capacity(wallet.len() + 1);
|
||||
let mut rt: Vec<E::Fr> = Vec::new();
|
||||
let mut t = tOptional.unwrap_or(Vec::<E::Fr>::with_capacity(wallet.len() + 1));
|
||||
// aspects of wallet being revealed
|
||||
for i in 0..wallet.len() + 1 {
|
||||
let ti = E::Fr::rand(csprng);
|
||||
t.push(ti);
|
||||
// check if we are revealing this index
|
||||
if reveal_index.contains(&i) {
|
||||
rt.push(ti);
|
||||
} else {
|
||||
rt.push(E::Fr::zero());
|
||||
if t.len() == i {
|
||||
t.push(E::Fr::rand(csprng));
|
||||
}
|
||||
let ti = t[i].clone();
|
||||
let mut gt = com_params.pub_bases[i].clone();
|
||||
gt.mul_assign(ti.into_repr());
|
||||
Tvals.add_assign(>);
|
||||
}
|
||||
(Tvals, t, rt)
|
||||
(Tvals, t)
|
||||
}
|
||||
|
||||
pub fn prove_response(wallet: &Vec<E::Fr>, r: &E::Fr, reveal_index: &Vec<usize>, Tvals: E::G1, t: &Vec<E::Fr>, rt: Vec<E::Fr>, challenge: &E::Fr) -> CommitmentProof<E> {
|
||||
pub fn prove_response(wallet: &Vec<E::Fr>, r: &E::Fr, Tvals: E::G1, t: &Vec<E::Fr>, challenge: &E::Fr) -> CommitmentProof<E> {
|
||||
let mut z: Vec<E::Fr> = Vec::new();
|
||||
let mut z0 = r.clone();
|
||||
z0.mul_assign(&challenge);
|
||||
z0.add_assign(&t[0]);
|
||||
z.push(z0);
|
||||
// t values that will be revealed
|
||||
let mut reveal_wallet: Vec<E::Fr> = Vec::new();
|
||||
reveal_wallet.push(E::Fr::zero());
|
||||
for i in 1..t.len() {
|
||||
let mut zi = wallet[i - 1].clone();
|
||||
zi.mul_assign(&challenge);
|
||||
zi.add_assign(&t[i]);
|
||||
z.push(zi);
|
||||
// check if we are revealing this index
|
||||
if reveal_index.contains(&i) {
|
||||
reveal_wallet.push(wallet[i - 1].clone());
|
||||
} else {
|
||||
reveal_wallet.push(E::Fr::zero());
|
||||
}
|
||||
}
|
||||
|
||||
CommitmentProof {
|
||||
T: Tvals, // commitment challenge
|
||||
z: z, // response values
|
||||
t: rt, // randomness for verifying partial reveals
|
||||
index: reveal_index.clone(),
|
||||
reveal: reveal_wallet.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn verify_proof(&self, com_params: &CSMultiParams<E>, com: &<E as Engine>::G1, challenge: &E::Fr) -> bool {
|
||||
pub fn verify_proof(&self, com_params: &CSMultiParams<E>, com: &<E as Engine>::G1, challenge: &E::Fr, revealOption: Option<Vec<Option<E::Fr>>>) -> bool {
|
||||
let mut comc = com.clone();
|
||||
let T = self.T.clone();
|
||||
comc.mul_assign(challenge.into_repr());
|
||||
comc.add_assign(&T);
|
||||
let mut x = E::G1::zero();
|
||||
let reveal = revealOption.unwrap_or(vec!{});
|
||||
let mut revealBool = true;
|
||||
for i in 0..self.z.len() {
|
||||
let mut base = com_params.pub_bases[i].clone();
|
||||
base.mul_assign(self.z[i].into_repr());
|
||||
x.add_assign(&base);
|
||||
|
||||
if reveal.len() > i && reveal[i].is_some() {
|
||||
let mut el = reveal[i].unwrap();
|
||||
el.mul_assign(&challenge.clone());
|
||||
revealBool = revealBool && self.z[i] == el;
|
||||
}
|
||||
}
|
||||
comc == x
|
||||
revealBool && comc == x
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,7 +367,7 @@ mod tests {
|
|||
|
||||
let xvec: Vec<G1> = vec![proof.T.clone(), com.c];
|
||||
let challenge = util::hash_g1_to_fr::<Bls12>(&xvec);
|
||||
assert_eq!(proof.verify_proof(&comParams, &com.c, &challenge), true);
|
||||
assert_eq!(proof.verify_proof(&comParams, &com.c, &challenge, None), true);
|
||||
}
|
||||
|
||||
// add tests for extend/remove commits dynamically
|
||||
|
|
Loading…
Reference in New Issue