Merge branch 'master' into ccs08
This commit is contained in:
commit
ea952c10b6
60
README.md
60
README.md
|
@ -69,69 +69,11 @@ extern crate bolt;
|
|||
|
||||
# API
|
||||
|
||||
The libbolt library provides APIs for three types of payment channels:
|
||||
The libbolt library provides APIs for two types of payment channels:
|
||||
|
||||
* unidirectional payment channels (*work in progress*)
|
||||
* bidirectional payment channels
|
||||
* third-party payments
|
||||
|
||||
## Unidirectional Payment Channels
|
||||
|
||||
A unidirectional payment channel enables payments from a customer to a merchant and only supports transfer of fixed-sized values in one direction.
|
||||
|
||||
### Channel Setup and Key Generation
|
||||
|
||||
The first part of setting up unidirectional payment channels involve generating initial setup parameters, channel state and key generation for both parties.
|
||||
|
||||
use bolt::unidirectional;
|
||||
|
||||
// setup unidirectional scheme params
|
||||
let pp = unidirectional::setup(true);
|
||||
|
||||
// generate the initial channel state
|
||||
let mut channel = unidirectional::ChannelState::new(String::from("My New Channel A -> B"));
|
||||
|
||||
To generate keys for both parties, call the `unidirectional::keygen()` routine with the public parameters as input.
|
||||
|
||||
// merchant generates a long-lived key pair
|
||||
let m_keypair = unidirectional::keygen(&pp);
|
||||
|
||||
// customer generates an ephemeral keypair for use on a single channel
|
||||
let c_keypair = unidirectional::keygen(&pp);
|
||||
|
||||
### Initialization
|
||||
|
||||
To initialize the channel for both parties, do the following:
|
||||
|
||||
let b0_merch = 50;
|
||||
let b0_cust = 50;
|
||||
// initialize on the merchant side with balance, b0_merch
|
||||
let mut m_data = unidirectional::init_merchant(&pp, b0_merch, &m_keypair));
|
||||
|
||||
// generate the public params for the commitment scheme
|
||||
let cm_csp = unidirectional::generate_commit_setup(&pp, &m_keypair.pk);
|
||||
|
||||
// initialize on the customer side with balance, b0_cust
|
||||
let mut c_data = unidirectional::init_customer(&pp, // public params
|
||||
&channel, // channel state
|
||||
b0_cust, // init customer balance
|
||||
b0_merch, // init merchant balance
|
||||
&cm_csp, // commitment pub params
|
||||
&c_keypair)); // customer keypair
|
||||
|
||||
|
||||
### Establish Protocol
|
||||
|
||||
**TODO**
|
||||
|
||||
### Pay protocol
|
||||
|
||||
**TODO**
|
||||
|
||||
### Channel Closure Algorithms
|
||||
|
||||
**TODO**
|
||||
|
||||
## Bidirectional Payment Channels
|
||||
|
||||
A bidirectional payment channel enables two parties to exchange arbitrary positive and negative amounts.
|
||||
|
|
67
src/ped92.rs
67
src/ped92.rs
|
@ -4,23 +4,22 @@ use pairing::{Engine, CurveProjective};
|
|||
use ff::Rand;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CSPublicKey<E: Engine> {
|
||||
pub struct CSParams<E: Engine> {
|
||||
pub g: E::G2,
|
||||
pub h: E::G2,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Commitment<E: Engine> {
|
||||
pub c: E::G2,
|
||||
pub r: E::Fr,
|
||||
pub c: E::G2
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CSMultiPublicKey<E: Engine> {
|
||||
pub struct CSMultiParams<E: Engine> {
|
||||
pub pub_bases: Vec<E::G2>
|
||||
}
|
||||
|
||||
//impl<E: Engine> fmt::Display for CSPublicKey<E> {
|
||||
//impl<E: Engine> fmt::Display for CSParams<E> {
|
||||
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// let g_vec: Vec<u8> = encode(&self.g, Infinite).unwrap();
|
||||
// let h_vec: Vec<u8> = encode(&self.h, Infinite).unwrap();
|
||||
|
@ -34,7 +33,7 @@ pub struct CSMultiPublicKey<E: Engine> {
|
|||
// h_s = format!("{}{:x}", h_s, y);
|
||||
// }
|
||||
//
|
||||
// write!(f, "PK : (g=0x{}, h=0x{})", g_s, h_s)
|
||||
// write!(f, "CSP : (g=0x{}, h=0x{})", g_s, h_s)
|
||||
// }
|
||||
//}
|
||||
|
||||
|
@ -55,15 +54,15 @@ pub struct CSMultiPublicKey<E: Engine> {
|
|||
// }
|
||||
//}
|
||||
|
||||
impl<E: Engine> CSPublicKey<E> {
|
||||
impl<E: Engine> CSParams<E> {
|
||||
/*
|
||||
Implements the setup algorithm for the Pedersen92 commitment scheme
|
||||
*/
|
||||
pub fn setup<R: Rng>(rng: &mut R) -> Self {
|
||||
let g = E::G2::rand(rng);
|
||||
let h = E::G2::rand(rng);
|
||||
let pk = CSPublicKey { g, h };
|
||||
return pk;
|
||||
let csp = CSParams { g, h };
|
||||
return csp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -74,9 +73,7 @@ commit(pk, msg) -> cm where
|
|||
*/
|
||||
pub fn commit<R: Rng>(&self, rng: &mut R, m: E::Fr, R: Option<E::Fr>) -> Commitment<E> {
|
||||
let r = R.unwrap_or(E::Fr::rand(rng));
|
||||
//let r = Fr::random(rng);
|
||||
|
||||
//let m = msg.hash();
|
||||
let p = "commit -> m";
|
||||
// c = g^m * h^r
|
||||
let mut c = self.g.clone();
|
||||
|
@ -84,34 +81,30 @@ commit(pk, msg) -> cm where
|
|||
let mut h = self.h.clone();
|
||||
h.mul_assign(r);
|
||||
c.add_assign(&h);
|
||||
// return (c, r) <- d=r
|
||||
let commitment = Commitment { c, r };
|
||||
|
||||
// debugging
|
||||
return commitment;
|
||||
Commitment { c }
|
||||
}
|
||||
|
||||
/*
|
||||
decommit(pk, cm, msg) -> bool where
|
||||
- pk is the public key generated from setup()
|
||||
decommit(csp, cm, msg) -> bool where
|
||||
- cm is the commitment
|
||||
- m is the message to validate
|
||||
- outputs T/F for whether the cm is a valid commitment to the msg
|
||||
*/
|
||||
pub fn decommit(&self, cm: &Commitment<E>, m: E::Fr) -> bool {
|
||||
pub fn decommit(&self, cm: &Commitment<E>, m: &E::Fr, r: &E::Fr) -> bool {
|
||||
let p = "decommit -> m";
|
||||
|
||||
let mut dm = self.g.clone();
|
||||
dm.mul_assign(m);
|
||||
dm.mul_assign(m.clone());
|
||||
let mut h = self.h.clone();
|
||||
h.mul_assign(cm.r.clone());
|
||||
h.mul_assign(r.clone());
|
||||
dm.add_assign(&h);
|
||||
return dm == cm.c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<E: Engine> CSMultiPublicKey<E> {
|
||||
impl<E: Engine> CSMultiParams<E> {
|
||||
/*
|
||||
Implements the setup algorithm for the Pedersen92 commitment scheme over
|
||||
a vector of messages.
|
||||
|
@ -121,35 +114,36 @@ impl<E: Engine> CSMultiPublicKey<E> {
|
|||
for i in 0..len {
|
||||
p.push(E::G2::rand(rng));
|
||||
}
|
||||
return CSMultiPublicKey { pub_bases: p };
|
||||
return CSMultiParams { pub_bases: p };
|
||||
}
|
||||
|
||||
pub fn commit<R: Rng>(&self, rng: &mut R, x: &Vec<E::Fr>, r: E::Fr) -> Commitment<E> {
|
||||
pub fn commit<R: Rng>(&self, rng: &mut R, x: &Vec<E::Fr>, r: &E::Fr) -> Commitment<E> {
|
||||
//let r = R.unwrap_or(Fr::random(rng));
|
||||
// c = g1^m1 * ... * gn^mn * h^r
|
||||
let mut c = self.pub_bases[0].clone();
|
||||
c.mul_assign(r);
|
||||
c.mul_assign(r.clone());
|
||||
for i in 1..x.len() {
|
||||
let mut basis = self.pub_bases[i];
|
||||
basis.mul_assign(x[i]);
|
||||
c.add_assign(&basis);
|
||||
}
|
||||
// return (c, r) <- r
|
||||
Commitment { c, r }
|
||||
Commitment { c: c }
|
||||
}
|
||||
|
||||
pub fn decommit(&self, cm: &Commitment<E>, x: &Vec<E::Fr>) -> bool {
|
||||
pub fn decommit(&self, cm: &Commitment<E>, x: &Vec<E::Fr>, r: &E::Fr) -> bool {
|
||||
let l = x.len();
|
||||
// pub_base[0] => h, x[0] => r
|
||||
// check that cm.r == x[0]
|
||||
let cr = r.clone();
|
||||
let mut dc = self.pub_bases[0].clone();
|
||||
dc.mul_assign(cm.r.clone());
|
||||
dc.mul_assign(cr);
|
||||
for i in 1..l {
|
||||
let mut basis = self.pub_bases[i];
|
||||
basis.mul_assign(x[i]);
|
||||
dc.add_assign(&basis);
|
||||
}
|
||||
return dc == cm.c && cm.r == x[0];
|
||||
return dc == cm.c && cr == x[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,31 +156,34 @@ mod tests {
|
|||
#[test]
|
||||
fn commit_one_message_works() {
|
||||
let rng = &mut thread_rng();
|
||||
let pk = CSPublicKey::<Bls12>::setup(rng);
|
||||
let csp = CSParams::<Bls12>::setup(rng);
|
||||
|
||||
let m1 = Fr::rand(rng);
|
||||
let mut m2 = m1.clone();
|
||||
m2.add_assign(&Fr::one());
|
||||
let r = Fr::rand(rng);
|
||||
let c = pk.commit(rng, m1, Some(r));
|
||||
let c = csp.commit(rng, m1, Some(r));
|
||||
|
||||
assert_eq!(pk.decommit(&c, m1), true);
|
||||
assert_eq!(pk.decommit(&c, m2), false);
|
||||
assert_eq!(csp.decommit(&c, &m1, &r), true);
|
||||
assert_eq!(csp.decommit(&c, &m2, &r), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn commit_n_message_works() {
|
||||
let rng = &mut thread_rng();
|
||||
let len = 3;
|
||||
let csp = CSMultiPublicKey::<Bls12>::setup_gen_params(rng, len);
|
||||
let csp = CSMultiParams::<Bls12>::setup_gen_params(rng, len);
|
||||
|
||||
let mut m: Vec<Fr> = Vec::new();
|
||||
for i in 0..len {
|
||||
m.push(Fr::rand(rng));
|
||||
}
|
||||
let r = m[0].clone();
|
||||
let c = csp.commit(rng, &m, r);
|
||||
let c = csp.commit(rng, &m, &r);
|
||||
|
||||
assert_eq!(csp.decommit(&c, &m), true);
|
||||
assert_eq!(csp.decommit(&c, &m, &r), true);
|
||||
let mut r1 = r.clone();
|
||||
r1.add_assign(&Fr::one());
|
||||
assert_eq!(csp.decommit(&c, &m, &r1), false);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue