512 lines
27 KiB
Rust
512 lines
27 KiB
Rust
|
#[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()
|
||
|
}
|
||
|
}
|