diff --git a/docs/bolt_design.tex b/docs/bolt_design.tex index 9d392c2..237773c 100644 --- a/docs/bolt_design.tex +++ b/docs/bolt_design.tex @@ -4,7 +4,7 @@ \usepackage[bookmarks=true]{hyperref} \usepackage{fancyvrb} \hypersetup{ - bookmarks=false, % show bookmarks bar? + bookmarks=false, % show bookmarks bar pdftitle={BOLT}, % title pdfauthor={Joseph Ayo Akinyele}, % author pdfsubject={TeX and LaTeX}, % subject of the document @@ -564,15 +564,6 @@ The customer obtains a new wallet $w_{\sf new} := (B - \epsilon, wpk', wsk', r', \end{enumerate} -%\subsection{Pairing Library} -%\label{sec:pairings} -% -%\todo{Add description of BN curve and library being used} -%% 1. Choice of asymmetric curves -- BN curves, BLS? -%This module is built on top of the RELIC library~\cite{relic-toolkit} which supplies all of the bilinear operations (including the pairing operation $-$ see Section~\ref{sec:definitions}). We instantiate the schemes using the state-of-the-art Barreto-Naehrig (BN) curves~\cite{bn2005} with the embedding degree $k = 12$ (or commonly referred to as {\sf BN-254}).\footnote{Note that we can also use {\sf BN-638} which provides a higher-security level (roughly equivalent to AES-256).} This particular asymmetric curve is known to yield a very efficient pairing implementation and a security level equivalent to AES-128. As a result, this boosts the overall performance of ABE scheme implementations over prior efforts. Other benefits of BN curves include the ability to compress the representation of group elements. This directly translates to making ABE ciphertexts more compact which considerably reduces transmission costs. One downside is that because BN curves are {\em Type-III} pairings, it only permits efficient hashing to the group $\G_1$. -% -%Alternatively, the pairing module could also be instantiated with similar asymmetric curves that yield less efficient pairing implementations but provide higher security levels. These include the Barreto-Lynn-Scott (BLS) curve~\cite{bls2003} with the embedding degree $k = 24$ and the Kachisa-Schaefer-Scott (KSS) curves~\cite{kss2008} with embedding degree $k = 18$. In general, the choice of pairing curve will depend on a variety of factors including the number of pairing computations required and non-pairing operations needed ({\em e.g.}, exponentiations, multiplication, hashing, etc). As new pairing-friendly curves are discovered, these curves can be integrated if they maximize efficiency while preserving security. - \chapter{BOLT Usage} \label{ch:usage} @@ -585,13 +576,13 @@ BOLT is a payment channel protocol. In order to use BOLT, a Customer and Merchan \begin{enumerate} \item {\bf Channel negotiation.} To initiate an interaction, Customer and Merchant agree on the initial balances of the channel, which we denote by A (customer initial balance) and B (merchant initial balance) respectively. The Merchant provides a public key and signed channel opening transaction to Customer. -{\bf Note}: this may or may not be a formal BOLT protocol step, and can be done in various ways. One approach is to have both parties sign a transaction for the underlying currency network. The other is to have both parties do separate transactions on the currency network. We need to figure this out BUT it will be currency specific, so it?s the hardest part. +{\bf Note}: this may or may not be a formal BOLT protocol step, and can be done in various ways. One approach is to have both parties sign a transaction for the underlying currency network. The other is to have both parties do separate transactions on the currency network. We need to figure this out BUT it will be currency specific, so it is the hardest part. -\item {\bf Channel funding.} Customer transmits the channel opening transaction to the currency network, which causes the Customer and Merchant to fund the channel with (A, B) units of currency respectively. This funding is conducted on-chain, and should be conducted using a privacy-preserving currency so as to protect the customer?s identity. +\item {\bf Channel funding.} Customer transmits the channel opening transaction to the currency network, which causes the Customer and Merchant to fund the channel with ({\bf A}, {\bf B}) units of currency respectively. This funding is conducted {\em on-chain}, and should be conducted using a privacy-preserving currency so as to protect the customer's identity. \item {\bf Channel activation.} Once the channel has been funded and the transaction confirmed on the network, the parties now interact directly to activate the channel and prepare it for online payments. -\item {\bf Payment.} This step may occur many times. To initiate a payment, the customer initiates an off-chain payment of D units of currency (of positive or negative value) to the merchant. This payment maintains the total channel balance, but updates the Customer and Merchant?s ownership of the balances. The merchant does not learn which Customer or Channel was involved in the payment. This produces updated state at each party. +\item {\bf Payment.} This step may occur many times. To initiate a payment, the customer initiates an off-chain payment of D units of currency (of positive or negative value) to the merchant. This payment maintains the total channel balance, but updates the Customer and Merchant's ownership of the balances. The merchant does not learn which Customer or Channel was involved in the payment. This produces updated state at each party. \item {\bf Channel closure.} At the conclusion of a channel interaction, the customer or merchant may initiate the closure of the channel. If the parties dispute the balance of the channel, each party transmits a ``closure token'' to the currency network. The payment network must include logic to evaluate the tokens to determine the correct balances {\bf (A, B)} to pay out to the Customer and Merchant respectively. The parties may now withdraw their shares of the resulting channel. @@ -603,10 +594,10 @@ We include a discussion of the precise requirements for the cryptocurrency netwo \paragraph{Hub channels.} BOLT also supports a ``Hub'' mode in which a Customer and Merchant interact via a payment hub. The use of a payment hub significantly increases the flexibility of BOLT, by enabling a hub and spoke model without the need for direct payment channel relationships between each individual Customer and Merchant. More significantly, the Hub does not learn the identity of the Customer or Merchant, nor does it see the payment amount. -The use of a Hub between a given Customer and Merchant requires the creation of two separate channels, one Customer <-> Hub (``CH'') channel, and one Hub<->Merchant (?HM?) channel. The steps in opening and closing each channel are similar to steps (1), (2), (3) and (5) in the description above. However, the payment step (4) differs as follows: +The use of a Hub between a given Customer and Merchant requires the creation of two separate channels, one Customer $\longleftrightarrow$ Hub (``CH'') channel, and one Hub $\longleftrightarrow$ Merchant (``HM'') channel. The steps in opening and closing each channel are similar to steps (1), (2), (3) and (5) in the description above. However, the payment step (4) differs as follows: \begin{itemize} -\item {\bf (Hub-based) Payment.} The Customer initiates an off-chain payment of D units of currency (of positive or negative value) to the Merchant, via the Hub. This payment atomically updates the CH and HM channels such that the Hub?s balance on the CH channel is increased by D units, and the Merchant?s balance on the HM channel is increased by D units. If either channel update fails, the entire transaction fails and both channels fall back to the previous channel balances. +\item {\bf (Hub-based) Payment.} The Customer initiates an off-chain payment of D units of currency (of positive or negative value) to the Merchant, via the Hub. This payment atomically updates the CH and HM channels such that the Hub's balance on the CH channel is increased by D units, and the Merchant's balance on the HM channel is increased by D units. If either channel update fails, the entire transaction fails and both channels fall back to the previous channel balances. \end{itemize} The Hub learns only that a transaction took place, but not the amount or the identities of the Customer or Merchant. diff --git a/src/commit_scheme.rs b/src/commit_scheme.rs index 1b62558..8c1e93c 100644 --- a/src/commit_scheme.rs +++ b/src/commit_scheme.rs @@ -8,6 +8,16 @@ use debug_elem_in_hex; use bincode::SizeLimit::Infinite; use bincode::rustc_serialize::encode; use sodiumoxide::crypto::hash::sha512; + +// define some structures here +#[derive(Copy, Clone)] +pub struct PublicParams { + g1: G1, + g2: G1, + g3: G1 +} + + // define some structures here #[derive(Copy, Clone)] pub struct PublicKey { @@ -60,7 +70,7 @@ impl fmt::Display for Commitment { /* Implements the setup algorithm for the Pedersen92 commitment scheme */ -pub fn setup() -> PublicKey { +pub fn ped92_setup() -> PublicKey { println!("Run Setup..."); let rng = &mut rand::thread_rng(); let g = G1::random(rng); @@ -76,7 +86,7 @@ commit(pk, msg) -> cm where - msg is the message structure for the commitment scheme - cm is the output commitment message for the given message */ -pub fn commit(pk: &PublicKey, m: Fr, R: Option) -> Commitment { +pub fn ped92_commit(pk: &PublicKey, m: Fr, R: Option) -> Commitment { let rng = &mut rand::thread_rng(); let r = R.unwrap_or(Fr::random(rng)); @@ -100,9 +110,9 @@ decommit(pk, cm, msg) -> bool where - pk is the public key generated from setup() - cm is the commitment - m is the message to validate -- outputs T/F for whether the cm is a valid commitmentt to the msg +- outputs T/F for whether the cm is a valid commitment to the msg */ -pub fn decommit(pk: &PublicKey, cm: &Commitment, m: Fr) -> bool { +pub fn ped92_decommit(pk: &PublicKey, cm: &Commitment, m: Fr) -> bool { //let m = msg.hash(); let p = "decommit -> m"; debug_elem_in_hex(p, &m); @@ -110,3 +120,18 @@ pub fn decommit(pk: &PublicKey, cm: &Commitment, m: Fr) -> bool { let dm = (pk.g * m) + (pk.h * cm.d); return dm == cm.c; } + + +/* +Implements the setup algorithm for the Pedersen92 commitment scheme +*/ +pub fn setup() -> PublicParams { + println!("Run Setup..."); + let rng = &mut rand::thread_rng(); + let g1 = G1::random(rng); + let g2 = G1::random(rng); + let g3 = G1::random(rng); + let pk = PublicParams { g1: g1, g2: g2, g3: g3 }; + println!("{}", pp); + return pp; +} diff --git a/src/lib.rs b/src/lib.rs index d90d4c4..1faf158 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -598,7 +598,112 @@ pub fn verify_nizk_proof_one(proof: &Proof) -> bool { } ////////////////////////////////// NIZKP ////////////////////////////////// -pub mod unidirectional { +//pub mod unidirectional { +// use std::fmt; +// use rand; +// use bn::{Group, Fr}; +// use sym; +// use commit_scheme; +// use clsigs; +// use Message; +// use sodiumoxide::randombytes; +// +// pub struct PublicParams { +// cm_mpk: commit_scheme::PublicKey, +// cl_mpk: clsigs::PublicParams, +// l_bits: i32 +// // TODO: add NIZK proof system pub params +// } +// +// pub struct ChannelToken { +// w_com: commit_scheme::Commitment, +// pk: clsigs::PublicKey +// } +// +// pub struct CustSecretKey { +// sk: clsigs::SecretKey, // the secret key for the signature scheme (Is it possible to make this a generic field?) +// k1: Fr, // seed 1 for PRF +// k2: Fr, // seed 2 for PRF +// r: Fr, // random coins for commitment scheme +// balance: i32, // the balance for the user +// ck_vec: Vec +// } +// +// pub struct MerchSecretKey { +// sk: clsigs::SecretKey, +// balance: i32 +// } +// +// pub struct InitCustomerData { +// T: ChannelToken, +// csk: CustSecretKey +// } +// +// pub struct InitMerchantData { +// T: clsigs::PublicKey, +// csk: MerchSecretKey +// } +// +// pub fn setup() -> PublicParams { +// // TODO: provide option for generating CRS parameters +// let cm_pk = commit_scheme::setup(); +// let cl_mpk = clsigs::setup(); +// let l = 256; +// // let nizk = "nizk proof system"; +// let pp = PublicParams { cm_mpk: cm_pk, cl_mpk: cl_mpk, l_bits: l }; +// return pp; +// } +// +// pub fn keygen(pp: &PublicParams) -> clsigs::KeyPair { +// // TODO: figure out what we need from public params to generate keys +// println!("Run Keygen..."); +// let keypair = clsigs::keygen(&pp.cl_mpk); +// return keypair; +// } +// +// pub fn init_customer(pp: &PublicParams, b0_customer: i32, keypair: &clsigs::KeyPair) -> InitCustomerData { +// println!("Run Init customer..."); +// sym::init(); +// let rng = &mut rand::thread_rng(); +// // pick two distinct seeds +// let l = 256; +// let k1 = Fr::random(rng); +// let k2 = Fr::random(rng); +// let r = Fr::random(rng); +// let msg = Message::new(keypair.sk, k1, k2, b0_customer).hash(); +// +// let mut ck_vec: Vec = Vec::new(); +// // generate the vector ck of sym keys +// for i in 1 .. b0_customer { +// let ck = sym::keygen(l); +// ck_vec.push(ck); +// } +// let w_com = commit_scheme::commit(&pp.cm_mpk, msg, Some(r)); +// let t_c = ChannelToken { w_com: w_com, pk: keypair.pk }; +// let csk_c = CustSecretKey { sk: keypair.sk, k1: k1, k2: k2, r: r, balance: b0_customer, ck_vec: ck_vec }; +// return InitCustomerData { T: t_c, csk: csk_c }; +// } +// +// pub fn init_merchant(pp: &PublicParams, b0_merchant: i32, keypair: &clsigs::KeyPair) -> InitMerchantData { +// println!("Run Init merchant..."); +// let csk_m = MerchSecretKey { sk: keypair.sk, balance: b0_merchant }; +// return InitMerchantData { T: keypair.pk, csk: csk_m }; +// } +// +// // TODO: requires NIZK proof system +// pub fn establish_customer(pp: &PublicParams, t_m: &clsigs::PublicKey, csk_c: &CustSecretKey) { +// println ! ("Run establish_customer algorithm..."); +// // set sk_0 to random bytes of length l +// // let sk_0 = random_bytes(pp.l); +// let buf_len: usize = pp.l_bits as usize; +// let mut sk0 = vec![0; buf_len]; +// randombytes::randombytes_into(&mut sk0); +// +// let pi1 = create_nizk_proof_one(csk_c.sk, csk_c.k1, csk_c.k2, ); +// } +//} + +pub mod bidirectional { use std::fmt; use rand; use bn::{Group, Fr}; @@ -609,7 +714,7 @@ pub mod unidirectional { use sodiumoxide::randombytes; pub struct PublicParams { - cm_mpk: commit_scheme::PublicKey, + cm_mpk: commit_scheme::PublicParams, cl_mpk: clsigs::PublicParams, l_bits: i32 // TODO: add NIZK proof system pub params @@ -646,11 +751,11 @@ pub mod unidirectional { pub fn setup() -> PublicParams { // TODO: provide option for generating CRS parameters - let cm_pk = commit_scheme::setup(); + let cm_pp = commit_scheme::setup(); let cl_mpk = clsigs::setup(); let l = 256; // let nizk = "nizk proof system"; - let pp = PublicParams { cm_mpk: cm_pk, cl_mpk: cl_mpk, l_bits: l }; + let pp = PublicParams { cm_mpk: cm_pp, cl_mpk: cl_mpk, l_bits: l }; return pp; } @@ -661,7 +766,7 @@ pub mod unidirectional { return keypair; } - pub fn init_customer(pp: &PublicParams, b0_customer: i32, keypair: &clsigs::KeyPair) -> InitCustomerData { + pub fn init_customer(pp: &PublicParams, channelId: Fr, b0_customer: i32, keypair: &clsigs::KeyPair) -> InitCustomerData { println!("Run Init customer..."); sym::init(); let rng = &mut rand::thread_rng(); @@ -678,7 +783,7 @@ pub mod unidirectional { let ck = sym::keygen(l); ck_vec.push(ck); } - let w_com = commit_scheme::commit(&pp.cm_mpk, msg, Some(r)); + let w_com = commit_scheme::commit(&pp.cm_pp, msg, Some(r)); let t_c = ChannelToken { w_com: w_com, pk: keypair.pk }; let csk_c = CustSecretKey { sk: keypair.sk, k1: k1, k2: k2, r: r, balance: b0_customer, ck_vec: ck_vec }; return InitCustomerData { T: t_c, csk: csk_c };