ceckpoint on libbolt resolve alg
This commit is contained in:
parent
623cb0c873
commit
09c70f7266
108
bin/bolt.rs
108
bin/bolt.rs
|
@ -6,6 +6,7 @@ extern crate bincode;
|
|||
extern crate serde_derive;
|
||||
extern crate serde;
|
||||
extern crate time;
|
||||
extern crate secp256k1;
|
||||
|
||||
use std::fmt;
|
||||
use bn::{Group, Fr, G1, G2, pairing};
|
||||
|
@ -374,6 +375,31 @@ fn main() {
|
|||
println!("{} seconds for verifying valid signatures.", start1.to(end1));
|
||||
println!("{} seconds for verifying invalid signatures.", end1.to(end2));
|
||||
|
||||
let mut schnorr = secp256k1::Secp256k1::new();
|
||||
schnorr.randomize(rng);
|
||||
let (wsk, wpk) = schnorr.generate_keypair(rng).unwrap();
|
||||
|
||||
let balance = 100;
|
||||
let r = Fr::random(rng);
|
||||
let cid = Fr::random(rng);
|
||||
let rm1 = libbolt::RefundMessage::new("refundUnsigned", cid, wpk, balance, Some(&r), None).hash();
|
||||
|
||||
println!("RefundMessage => ");
|
||||
for i in 0 .. rm1.len() {
|
||||
let p = format!("rm1[{}] = ", i);
|
||||
libbolt::debug_elem_in_hex(&p, &rm1[i]);
|
||||
}
|
||||
|
||||
let rm2 = libbolt::RefundMessage::new("refundToken", cid, wpk, balance+15, None, Some(&signature)).hash();
|
||||
println!("RefundMessage (token) => ");
|
||||
for i in 0 .. rm2.len() {
|
||||
let p = format!("rm2[{}] = ", i);
|
||||
libbolt::debug_elem_in_hex(&p, &rm2[i]);
|
||||
}
|
||||
|
||||
assert!(clsigs::verifyD(&mpk, &keypair.pk, &m1, &signature) == true);
|
||||
println!("All good in the hood!");
|
||||
|
||||
|
||||
// println!("******************************************");
|
||||
// let b = keypair.pk.Z2.len();
|
||||
|
@ -432,45 +458,45 @@ fn main() {
|
|||
|
||||
println!("******************************************");
|
||||
|
||||
println!("[1] libbolt - setup bidirecitonal scheme params");
|
||||
let pp = bidirectional::setup();
|
||||
|
||||
// generate long-lived keypair for merchant -- used to identify
|
||||
// it to all customers
|
||||
println!("[2] libbolt - generate long-lived key pair for merchant");
|
||||
let merch_keypair = bidirectional::keygen(&pp);
|
||||
|
||||
// customer gnerates an ephemeral keypair for use on a single channel
|
||||
println!("[3] libbolt - generate ephemeral key pair for customer (use with one channel)");
|
||||
let cust_keypair = bidirectional::keygen(&pp);
|
||||
|
||||
// bidirectional::init_merchant_state();
|
||||
|
||||
println!("[4] libbolt - generate the channel identifier");
|
||||
let b0_cust = 10;
|
||||
let b0_merch = 15;
|
||||
let cid = bidirectional::generate_channel_id();
|
||||
let mut msg = "Open Channel ID: ";
|
||||
libbolt::debug_elem_in_hex(msg, &cid);
|
||||
|
||||
// each party executes the init algorithm on the agreed initial challence balance
|
||||
// in order to derive the channel tokens
|
||||
println!("[5a] libbolt - initialize on the customer side with balance {}", b0_cust);
|
||||
let mut init_cust_data = bidirectional::init_customer(&pp, cid, b0_cust, &cust_keypair);
|
||||
|
||||
println!("[5b] libbolt - initialize on the merchant side with balance {}", b0_merch);
|
||||
let mut init_merch_data = bidirectional::init_merchant(&pp, b0_merch, &merch_keypair);
|
||||
|
||||
println!("[6a] libbolt - entering the establish protocol for the channel");
|
||||
let proof1 = bidirectional::establish_customer_phase1(&pp, &init_cust_data);
|
||||
|
||||
println!("[6b] libbolt - obtain the wallet signature from the merchant");
|
||||
let wallet_sig = bidirectional::establish_merchant_phase2(&pp, &init_merch_data, &proof1);
|
||||
|
||||
println!("[6c] libbolt - complete channel establishment");
|
||||
let is_established = bidirectional::establish_customer_phase3(wallet_sig, &mut init_cust_data.csk);
|
||||
|
||||
assert!(is_established);
|
||||
|
||||
println!("Channel has been established! Woohoo!");
|
||||
// println!("[1] libbolt - setup bidirecitonal scheme params");
|
||||
// let pp = bidirectional::setup();
|
||||
//
|
||||
// // generate long-lived keypair for merchant -- used to identify
|
||||
// // it to all customers
|
||||
// println!("[2] libbolt - generate long-lived key pair for merchant");
|
||||
// let merch_keypair = bidirectional::keygen(&pp);
|
||||
//
|
||||
// // customer gnerates an ephemeral keypair for use on a single channel
|
||||
// println!("[3] libbolt - generate ephemeral key pair for customer (use with one channel)");
|
||||
// let cust_keypair = bidirectional::keygen(&pp);
|
||||
//
|
||||
// // bidirectional::init_merchant_state();
|
||||
//
|
||||
// println!("[4] libbolt - generate the channel identifier");
|
||||
// let b0_cust = 10;
|
||||
// let b0_merch = 15;
|
||||
// let cid = bidirectional::generate_channel_id();
|
||||
// let mut msg = "Open Channel ID: ";
|
||||
// libbolt::debug_elem_in_hex(msg, &cid);
|
||||
//
|
||||
// // each party executes the init algorithm on the agreed initial challence balance
|
||||
// // in order to derive the channel tokens
|
||||
// println!("[5a] libbolt - initialize on the customer side with balance {}", b0_cust);
|
||||
// let mut init_cust_data = bidirectional::init_customer(&pp, cid, b0_cust, &cust_keypair);
|
||||
//
|
||||
// println!("[5b] libbolt - initialize on the merchant side with balance {}", b0_merch);
|
||||
// let mut init_merch_data = bidirectional::init_merchant(&pp, b0_merch, &merch_keypair);
|
||||
//
|
||||
// println!("[6a] libbolt - entering the establish protocol for the channel");
|
||||
// let proof1 = bidirectional::establish_customer_phase1(&pp, &init_cust_data);
|
||||
//
|
||||
// println!("[6b] libbolt - obtain the wallet signature from the merchant");
|
||||
// let wallet_sig = bidirectional::establish_merchant_phase2(&pp, &init_merch_data, &proof1);
|
||||
//
|
||||
// println!("[6c] libbolt - complete channel establishment");
|
||||
// let is_established = bidirectional::establish_customer_phase3(wallet_sig, &mut init_cust_data.csk);
|
||||
//
|
||||
// assert!(is_established);
|
||||
//
|
||||
// println!("Channel has been established! Woohoo!");
|
||||
}
|
||||
|
|
|
@ -645,7 +645,7 @@ The customer obtains a new wallet $w_{\sf new} := (B - \epsilon, wpk', wsk', r',
|
|||
\begin{enumerate}
|
||||
\item If a merchant sees a channel closure message, it first parses ${\sf T}_{C}$ to obtain $pk_c$.
|
||||
\item Parse tuple $(m, \sigma) \leftarrow {\sf rc}_{C}$
|
||||
\item ${\sf Verify}(pk_c, \sigma) = 1$ or $\bot$
|
||||
\item ${\sf Verify}(pk_c, m, \sigma) = 1$ or $\bot$
|
||||
\item If signature $\sigma$ verifies, then parse tuple $({\sf cID}, wpk, B) \leftarrow m$.
|
||||
\item Verify that {\sf cID} matches the channel.
|
||||
\item If previous record of $(wpk, \sigma_{rev}) \in {\bf S}$, then output ${\sf rc}_{M} = (({\sf revoked}, \sigma_{rev}), \sigma)$.
|
||||
|
|
|
@ -97,9 +97,9 @@ impl fmt::Display for Signature {
|
|||
}
|
||||
}
|
||||
|
||||
// scheme A - for single messages
|
||||
// scheme A - for a single message
|
||||
|
||||
pub fn setup_A() -> PublicParams {
|
||||
pub fn setupA() -> PublicParams {
|
||||
let rng = &mut rand::thread_rng();
|
||||
let g1 = G1::random(rng);
|
||||
let g2 = G2::random(rng);
|
||||
|
@ -107,7 +107,7 @@ pub fn setup_A() -> PublicParams {
|
|||
return mpk;
|
||||
}
|
||||
|
||||
pub fn keygen_A(mpk : &PublicParams) -> KeyPair {
|
||||
pub fn keygenA(mpk : &PublicParams) -> KeyPair {
|
||||
let rng = &mut rand::thread_rng();
|
||||
let x = Fr::random(rng);
|
||||
let y = Fr::random(rng);
|
||||
|
@ -118,7 +118,7 @@ pub fn keygen_A(mpk : &PublicParams) -> KeyPair {
|
|||
return KeyPair { sk: sk, pk: pk }
|
||||
}
|
||||
|
||||
pub fn sign_A(sk: &SecretKey, m: Fr) -> Signature {
|
||||
pub fn signA(sk: &SecretKey, m: Fr) -> Signature {
|
||||
let rng = &mut rand::thread_rng();
|
||||
let a = G2::random(rng);
|
||||
|
||||
|
@ -128,7 +128,7 @@ pub fn sign_A(sk: &SecretKey, m: Fr) -> Signature {
|
|||
return sig;
|
||||
}
|
||||
|
||||
pub fn verify_A(mpk: &PublicParams, pk: &PublicKey, m: Fr, sig: &Signature) -> bool {
|
||||
pub fn verifyA(mpk: &PublicParams, pk: &PublicKey, m: Fr, sig: &Signature) -> bool {
|
||||
let lhs1 = pairing(pk.Y, sig.a);
|
||||
let rhs1 = pairing(mpk.g1, sig.b);
|
||||
let lhs2 = pairing(pk.X, sig.a) * (pairing(pk.X, sig.b).pow(m));
|
||||
|
|
287
src/lib.rs
287
src/lib.rs
|
@ -13,6 +13,7 @@ use bincode::SizeLimit::Infinite;
|
|||
use bincode::rustc_serialize::{encode, decode};
|
||||
use sodiumoxide::randombytes;
|
||||
use sodiumoxide::crypto::hash::sha512;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub mod prf;
|
||||
pub mod sym;
|
||||
|
@ -472,51 +473,41 @@ pub fn print(g: &G1) -> String {
|
|||
|
||||
////////////////////////////////// SymKeyEnc ///////////////////////////////////
|
||||
|
||||
////////////////////////////////// CL Sigs /////////////////////////////////////
|
||||
|
||||
// refund message
|
||||
#[derive(Clone)]
|
||||
pub struct RefundMessage<'a> {
|
||||
prefix: &'a str, // string prefix for the prefix
|
||||
c_id: Fr, // uniquely identifies the
|
||||
index: i32, // index
|
||||
// ck: Fr, // TODO: l-bit key (from SymKeyEnc)
|
||||
}
|
||||
|
||||
impl<'a> RefundMessage<'a> {
|
||||
pub fn new(_c_id: Fr, _index: i32) -> RefundMessage<'a> {
|
||||
RefundMessage {
|
||||
prefix: "refund", c_id: _c_id, index: _index,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash(&self) -> Fr {
|
||||
let mut input_buf = Vec::new();
|
||||
input_buf.extend_from_slice(self.prefix.as_bytes());
|
||||
let c_id_vec: Vec<u8> = encode(&self.c_id, Infinite).unwrap();
|
||||
// encode cId in the vector
|
||||
input_buf.extend(c_id_vec);
|
||||
// encoee the balance as a hex string
|
||||
let b = format!("{:x}", self.index);
|
||||
input_buf.extend_from_slice(b.as_bytes());
|
||||
// TODO: add the ck vector (l-bit key)
|
||||
// let mut in_str = String::new();
|
||||
// for y in input_buf.iter() {
|
||||
// in_str = format!("{}{:x}", in_str, y);
|
||||
// OLD RefundMessage
|
||||
//impl<'a> RefundMessage<'a> {
|
||||
// pub fn new(_c_id: Fr, _index: i32) -> RefundMessage<'a> {
|
||||
// RefundMessage {
|
||||
// prefix: "refund", c_id: _c_id, index: _index,
|
||||
// }
|
||||
// println!("input_buf: {}", in_str);
|
||||
// }
|
||||
//
|
||||
// pub fn hash(&self) -> Fr {
|
||||
// let mut input_buf = Vec::new();
|
||||
// input_buf.extend_from_slice(self.prefix.as_bytes());
|
||||
// let c_id_vec: Vec<u8> = encode(&self.c_id, Infinite).unwrap();
|
||||
// // encode cId in the vector
|
||||
// input_buf.extend(c_id_vec);
|
||||
// // encoee the balance as a hex string
|
||||
// let b = format!("{:x}", self.index);
|
||||
// input_buf.extend_from_slice(b.as_bytes());
|
||||
// // TODO: add the ck vector (l-bit key)
|
||||
//// let mut in_str = String::new();
|
||||
//// for y in input_buf.iter() {
|
||||
//// in_str = format!("{}{:x}", in_str, y);
|
||||
//// }
|
||||
//// println!("input_buf: {}", in_str);
|
||||
//
|
||||
// // hash the inputs via SHA256
|
||||
// let sha2_digest = sha512::hash(input_buf.as_slice());
|
||||
// // println!("hash: {:?}", sha2_digest);
|
||||
// // let h = format!("{:x}", HexSlice::new(&sha2_digest));
|
||||
// let mut hash_buf: [u8; 64] = [0; 64];
|
||||
// hash_buf.copy_from_slice(&sha2_digest[0..64]);
|
||||
// return Fr::interpret(&hash_buf);
|
||||
// }
|
||||
//}
|
||||
|
||||
// hash the inputs via SHA256
|
||||
let sha2_digest = sha512::hash(input_buf.as_slice());
|
||||
// println!("hash: {:?}", sha2_digest);
|
||||
// let h = format!("{:x}", HexSlice::new(&sha2_digest));
|
||||
let mut hash_buf: [u8; 64] = [0; 64];
|
||||
hash_buf.copy_from_slice(&sha2_digest[0..64]);
|
||||
return Fr::interpret(&hash_buf);
|
||||
}
|
||||
}
|
||||
|
||||
// spend message
|
||||
// spend message (for unidirectional scheme)
|
||||
#[derive(Clone)]
|
||||
pub struct SpendMessage<'a> {
|
||||
prefix: &'a str,
|
||||
|
@ -639,6 +630,87 @@ pub fn hashPubKeyToFr(wpk: &secp256k1::PublicKey) -> Fr {
|
|||
// return Fr::interpret(&hash_buf);
|
||||
//}
|
||||
|
||||
fn convertToFr(input_buf: &Vec<u8>) -> Fr {
|
||||
// hash the inputs via SHA256
|
||||
let sha2_digest = sha512::hash(input_buf.as_slice());
|
||||
// println!("hash: {:?}", sha2_digest);
|
||||
// let h = format!("{:x}", HexSlice::new(&sha2_digest));
|
||||
let mut hash_buf: [u8; 64] = [0; 64];
|
||||
hash_buf.copy_from_slice(&sha2_digest[0..64]);
|
||||
return Fr::interpret(&hash_buf);
|
||||
}
|
||||
|
||||
// refund message
|
||||
#[derive(Clone)]
|
||||
pub struct RefundMessage<'a> {
|
||||
prefix: &'a str, // string prefix for the prefix
|
||||
cid: Fr, // channel identifier
|
||||
wpk: secp256k1::PublicKey,
|
||||
balance: usize, // the balance
|
||||
r: Option<&'a Fr>, // randomness from customer wallet
|
||||
rt: Option<&'a clsigs::SignatureD> // refund token
|
||||
}
|
||||
|
||||
impl<'a> RefundMessage<'a> {
|
||||
pub fn new(_prefix: &'a str, _cid: Fr, _wpk: secp256k1::PublicKey,
|
||||
_balance: usize, _r: Option<&'a Fr>, _rt: Option<&'a clsigs::SignatureD>) -> RefundMessage<'a> {
|
||||
RefundMessage {
|
||||
prefix: _prefix, cid: _cid, wpk: _wpk, balance: _balance, r: _r, rt: _rt
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash(&self) -> Vec<Fr> {
|
||||
let mut v: Vec<Fr> = Vec::new();
|
||||
let mut input_buf = Vec::new();
|
||||
input_buf.extend_from_slice(self.prefix.as_bytes());
|
||||
v.push(convertToFr(&input_buf));
|
||||
|
||||
v.push(self.cid.clone());
|
||||
|
||||
v.push(hashPubKeyToFr(&self.wpk));
|
||||
|
||||
// encoee the balance as a hex string
|
||||
let b = format!("{:x}", self.balance);
|
||||
let mut b_buf = Vec::new();
|
||||
b_buf.extend_from_slice(b.as_bytes());
|
||||
v.push(convertToFr(&b_buf));
|
||||
|
||||
//let r_vec: Vec<u8> = encode(&self.r, Infinite).unwrap();
|
||||
if (!self.r.is_none()) {
|
||||
v.push(self.r.unwrap().clone());
|
||||
}
|
||||
|
||||
if (!self.rt.is_none()) {
|
||||
// TODO: compute hash over the signature contents
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RevokedMessage<'a> {
|
||||
prefix: &'a str,
|
||||
sig: clsigs::SignatureD
|
||||
}
|
||||
|
||||
impl<'a> RevokedMessage<'a> {
|
||||
pub fn new(_prefix: &'a str, _sig: clsigs::SignatureD) -> RevokedMessage<'a> {
|
||||
RevokedMessage {
|
||||
prefix: _prefix, sig: _sig
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash(&self) -> Vec<Fr> {
|
||||
let mut v: Vec<Fr> = Vec::new();
|
||||
let mut input_buf = Vec::new();
|
||||
input_buf.extend_from_slice(self.prefix.as_bytes());
|
||||
v.push(convertToFr(&input_buf));
|
||||
|
||||
// TODO: compute hash over the signature
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
//pub fn create_nizk_proof_one(pp: &PublicParams, pk: &clsigs::PublicKeyD, sk: &clsigs::SecretKeyD) -> Proof {
|
||||
// let rng = &mut rand::thread_rng();
|
||||
|
@ -656,10 +728,6 @@ pub fn hashPubKeyToFr(wpk: &secp256k1::PublicKey) -> Fr {
|
|||
// return Proof { T: T, c: c, s1: s1, s2: s2 };
|
||||
//}
|
||||
|
||||
pub fn verify_nizk_proof_one(proof: &Proof) -> bool {
|
||||
// how do we verify the proof?
|
||||
return true;
|
||||
}
|
||||
////////////////////////////////// NIZKP //////////////////////////////////
|
||||
|
||||
//pub mod unidirectional {
|
||||
|
@ -778,6 +846,8 @@ pub mod bidirectional {
|
|||
use hashPubKeyToFr;
|
||||
use sodiumoxide::randombytes;
|
||||
use secp256k1; // ::{Secp256k1, PublicKey, SecretKey};
|
||||
use RefundMessage;
|
||||
use RevokedMessage;
|
||||
|
||||
pub struct PublicParams {
|
||||
// cm_csp: commit_scheme::CSParams,
|
||||
|
@ -799,11 +869,10 @@ pub mod bidirectional {
|
|||
r: Fr, // random coins for commitment scheme
|
||||
balance: i32, // the balance for the user
|
||||
signature: Option<clsigs::SignatureD>
|
||||
// ck_vec: Vec<sym::SymKey>
|
||||
}
|
||||
|
||||
pub struct MerchSecretKey {
|
||||
sk: clsigs::SecretKeyD,
|
||||
sk: clsigs::SecretKeyD, // merchant signing key
|
||||
balance: i32
|
||||
}
|
||||
|
||||
|
@ -818,6 +887,22 @@ pub mod bidirectional {
|
|||
pub csk: MerchSecretKey
|
||||
}
|
||||
|
||||
pub struct ChannelState {
|
||||
//pub pub_keys: HashMap,
|
||||
pub cid: Fr,
|
||||
pub pay_init: bool
|
||||
}
|
||||
|
||||
pub struct ChannelClosure_C<'a> {
|
||||
message: RefundMessage<'a>,
|
||||
signature: clsigs::SignatureD
|
||||
}
|
||||
|
||||
pub struct ChannelClosure_M<'a> {
|
||||
message: RevokedMessage<'a>,
|
||||
signature: clsigs::SignatureD
|
||||
}
|
||||
|
||||
pub fn setup() -> PublicParams {
|
||||
// TODO: provide option for generating CRS parameters
|
||||
//let cm_pp = commit_scheme::setup(3, None);
|
||||
|
@ -842,7 +927,6 @@ pub mod bidirectional {
|
|||
|
||||
pub fn init_customer(pp: &PublicParams, channelId: Fr, b0_customer: i32, keypair: &clsigs::KeyPairD) -> InitCustomerData {
|
||||
println!("Run Init customer...");
|
||||
sym::init();
|
||||
let rng = &mut rand::thread_rng();
|
||||
// pick two distinct seeds
|
||||
let l = 256;
|
||||
|
@ -905,16 +989,17 @@ pub mod bidirectional {
|
|||
return proof_1;
|
||||
}
|
||||
|
||||
// the merchant calls this method after obtaining
|
||||
pub fn establish_merchant_phase2(pp: &PublicParams, m_data: &InitMerchantData, proof: &clsigs::ProofCV) -> clsigs::SignatureD {
|
||||
// the merchant calls this method after obtaining proof from the customer
|
||||
pub fn establish_merchant_phase2(pp: &PublicParams, m_data: &InitMerchantData,
|
||||
proof: &clsigs::ProofCV) -> clsigs::SignatureD {
|
||||
// verifies proof and produces
|
||||
let wallet_sig = clsigs::bs_gen_signature(&pp.cl_mpk, &m_data.csk.sk, &proof);
|
||||
return wallet_sig;
|
||||
}
|
||||
|
||||
pub fn establish_customer_phase3(sig: clsigs::SignatureD, wallet: &mut CustomerWallet) -> bool {
|
||||
if wallet.signature.is_none() {
|
||||
wallet.signature = Some(sig);
|
||||
pub fn establish_customer_phase3(sig: clsigs::SignatureD, w: &mut CustomerWallet) -> bool {
|
||||
if w.signature.is_none() {
|
||||
w.signature = Some(sig);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -930,15 +1015,85 @@ pub mod bidirectional {
|
|||
println!("Run pay algorithm by Merchant - phase 2");
|
||||
}
|
||||
|
||||
// pub fn refund(pp: &PublicParams, imd : &InitMerchantData, w: Wallet) {
|
||||
// println!("Run Refund...");
|
||||
// }
|
||||
//
|
||||
// pub fn refute() {
|
||||
// println!("Run Refute...");
|
||||
// }
|
||||
//
|
||||
// pub fn resolve() {
|
||||
// println!("Run Resolve...");
|
||||
// }
|
||||
// for customer => on input a wallet w, it outputs a customer channel closure message rc_c
|
||||
pub fn refund<'a>(pp: &PublicParams, state: &ChannelState, m_data: &InitMerchantData,
|
||||
c_data: &InitCustomerData, w: &'a CustomerWallet) -> ChannelClosure_C<'a> {
|
||||
println!("Run Refund...");
|
||||
let mut m;
|
||||
let balance = w.balance as usize;
|
||||
if state.pay_init {
|
||||
// if channel has already been activated, then take unspent funds
|
||||
m = RefundMessage::new("refundToken", state.cid, w.wpk, balance, Some(&w.r), None);
|
||||
} else {
|
||||
// pay protocol not invoked so take the balane
|
||||
//let rng = &mut rand::thread_rng();
|
||||
// let rt // TODO: replace with the H(rt_w) signature from pay protocol
|
||||
m = RefundMessage::new("refundUnsigned", state.cid, w.wpk, balance, None, None);
|
||||
}
|
||||
|
||||
// generate signature on the balance/channel id, etc to obtain funds back
|
||||
let m_vec = m.hash();
|
||||
let sigma = clsigs::signD(&w.sk, &m_vec);
|
||||
return ChannelClosure_C { message: m, signature: sigma };
|
||||
}
|
||||
|
||||
fn exist_in_merchant_state(s: &ChannelState, wpk: &secp256k1::PublicKey, sig_rev: &clsigs::SignatureD) -> bool {
|
||||
// TODO: check the database for the fingerprint for the wpk + sig?
|
||||
return true;
|
||||
}
|
||||
|
||||
fn update_merchant_state(s: &mut ChannelState, wpk: &secp256k1::PublicKey) -> bool {
|
||||
// TODO: implement this method to update channel state db with current public key hash?
|
||||
return true;
|
||||
}
|
||||
|
||||
// for merchant => on input the merchant's current state S_old and a customer channel closure message,
|
||||
// outputs a merchant channel closure message rc_m and updated merchant state S_new
|
||||
pub fn refute<'a>(pp: &PublicParams, T_c: &ChannelToken, m_data: &InitMerchantData,
|
||||
state: &mut ChannelState, rc_c: ChannelClosure_C<'a>) -> Option<ChannelClosure_M<'a>> {
|
||||
println!("Run Refute...");
|
||||
|
||||
let is_valid = clsigs::verifyD(&pp.cl_mpk, &T_c.pk, &rc_c.message.hash(), &rc_c.signature);
|
||||
if is_valid {
|
||||
let wpk = rc_c.message.wpk;
|
||||
let sig_rev = rc_c.signature; // TODO: change to \sigma_rev
|
||||
let balance = rc_c.message.balance;
|
||||
if exist_in_merchant_state(&state, &wpk, &sig_rev) {
|
||||
let rm = RevokedMessage::new("revoked", sig_rev);
|
||||
let signature = clsigs::signD(&m_data.csk.sk, &rm.hash());
|
||||
return Some(ChannelClosure_M { message: rm, signature: signature });
|
||||
} else {
|
||||
// update state to include the user's wallet key
|
||||
assert!(update_merchant_state(state, &wpk));
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
panic!("Signature on customer closure message is invalid!");
|
||||
}
|
||||
}
|
||||
|
||||
// on input th ecustmomer and merchant channel tokens T_c, T_m
|
||||
// along with closure messages rc_c, rc_m
|
||||
pub fn resolve<'a>(pp: &PublicParams, c: &InitCustomerData, m: &InitMerchantData, // cust and merch
|
||||
rc_c: Option<ChannelClosure_C<'a>>, rc_m: Option<ChannelClosure_M<'a>>) -> (i32, i32) {
|
||||
println!("Run Resolve...");
|
||||
let b_total = c.csk.balance + m.csk.balance;
|
||||
if (rc_c.is_none() && rc_m.is_none()) {
|
||||
panic!("Did not specify channel closure messages for either customer or merchant!");
|
||||
}
|
||||
|
||||
if rc_c.is_none() {
|
||||
return (0, 0);
|
||||
}
|
||||
|
||||
let pk_c = &c.T.pk;
|
||||
let w_com = &c.T.w_com;
|
||||
|
||||
let pk_m = &m.T;
|
||||
|
||||
let rc_cust = rc_c.unwrap();
|
||||
//clsigs::verifyD(&pp.cl_mpk);
|
||||
|
||||
return (b_total, 0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue