From 3aab758a1101f3d3ae56506c6b0fc4714d8f8ae8 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 5 Aug 2016 23:12:34 -0600 Subject: [PATCH] Start splitting protocol specific routines off. --- src/main.rs | 1 + src/protocol/mod.rs | 133 ++++++++++++++++++++++++++++++++++++++++++++ src/randompowers.rs | 10 ++-- 3 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 src/protocol/mod.rs diff --git a/src/main.rs b/src/main.rs index 52c4ba5..2c5f480 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ extern crate snark; mod randompowers; mod util; mod fft; +mod protocol; use snark::*; diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs new file mode 100644 index 0000000..c94b9c3 --- /dev/null +++ b/src/protocol/mod.rs @@ -0,0 +1,133 @@ +use snark::*; +use randompowers::*; + +#[derive(Debug)] +pub enum ProtocolError { + InvalidTauPowersSize +} + +pub struct Samples { + tau: T, + rho_a: T, + rho_b: T, + alpha_a: T, + alpha_b: T, + alpha_c: T, + beta: T, + gamma: T +} + +pub struct Player { + secrets: Samples, + pub d: usize, + omega: Fr, + cs: CS +} + +impl Player { + pub fn new() -> Player { + let (d, omega, cs) = getqap(); + + Player { + secrets: Samples { + tau: Fr::random_nonzero(), + rho_a: Fr::random_nonzero(), + rho_b: Fr::random_nonzero(), + alpha_a: Fr::random_nonzero(), + alpha_b: Fr::random_nonzero(), + alpha_c: Fr::random_nonzero(), + beta: Fr::random_nonzero(), + gamma: Fr::random_nonzero() + }, + d: d, + omega: omega, + cs: cs + } + } + + pub fn spairs(&self) -> Samples> { + Samples { + tau: Spair::random(&self.secrets.tau), + rho_a: Spair::random(&self.secrets.rho_a), + rho_b: Spair::random(&self.secrets.rho_b), + alpha_a: Spair::random(&self.secrets.alpha_a), + alpha_b: Spair::random(&self.secrets.alpha_b), + alpha_c: Spair::random(&self.secrets.alpha_c), + beta: Spair::random(&self.secrets.beta), + gamma: Spair::random(&self.secrets.gamma) + } + } + + pub fn randompowers(&self, v1: &[G1], v2: &[G2]) -> Result<(Vec, Vec), ProtocolError> { + if (v1.len() != v2.len()) || (v1.len() != self.d+1) { + return Err(ProtocolError::InvalidTauPowersSize) + } + + let mut t1 = Vec::with_capacity(self.d+1); + let mut t2 = Vec::with_capacity(self.d+1); + + let mut tp = Fr::one(); + for i in 0..self.d+1 { + t1.push(v1[i] * tp); + t2.push(v2[i] * tp); + + tp = tp * self.secrets.tau; + } + + Ok((t1, t2)) + } +} + +pub fn verify_randompowers( + current: &(Vec, Vec), + last: Option<&(Vec, Vec)>, + rp: &Spair +) -> bool { + current.0[0] == G1::one() && + current.1[0] == G2::one() && + match last { + Some(last) => { + checkseq(current.0.iter(), &Spair::new(¤t.1[0], ¤t.1[1])) && + checkseq(current.1.iter(), &Spair::new(¤t.0[0], ¤t.0[1])) && + same_power(&Spair::new(&last.0[1], ¤t.0[1]), rp) + }, + None => { + checkseq(current.0.iter(), rp) && + checkseq(current.1.iter(), &Spair::new(¤t.0[0], ¤t.0[1])) + } + } +} + +#[test] +fn randompowers_test() { + initialize(); + + const NUM_PARTIES: usize = 3; + + // All parties should initialize with their secret randomness + let parties: Vec = (0..NUM_PARTIES).map(|_| Player::new()).collect(); + // All parties should reveal their s-pairs + let spairs: Vec>> = parties.iter().map(|p| p.spairs()).collect(); + + let mut transcript = vec![]; + + for (i, p) in parties.iter().enumerate() { + use std::iter::repeat; + + if i == 0 { + let v1 = repeat(G1::one()).take(p.d + 1).collect::>(); + let v2 = repeat(G2::one()).take(p.d + 1).collect::>(); + transcript.push(p.randompowers(&v1, &v2).unwrap()); + } else { + let v = p.randompowers(&transcript[i-1].0, &transcript[i-1].1).unwrap(); + transcript.push(v); + } + } + + // Verification + for i in 0..NUM_PARTIES { + assert!(verify_randompowers(&transcript[i], + if i == 0 { None } else { Some(&transcript[i-1]) }, + &spairs[i].tau)); + } +} diff --git a/src/randompowers.rs b/src/randompowers.rs index 5e648f3..bb26633 100644 --- a/src/randompowers.rs +++ b/src/randompowers.rs @@ -1,13 +1,13 @@ use snark::*; use util::*; -struct Spair { +pub struct Spair { p: G, q: G } impl Spair { - fn random(s: &Fr) -> Self { + pub fn random(s: &Fr) -> Self { let mut p = G::zero(); while p.is_zero() { @@ -20,7 +20,7 @@ impl Spair { } } - fn new(p: &G, q: &G) -> Self { + pub fn new(p: &G, q: &G) -> Self { if p.is_zero() { panic!("tried to initialize spair with zero base") } @@ -32,7 +32,7 @@ impl Spair { } } -fn same_power(a: &Spair, b: &Spair) -> bool +pub fn same_power(a: &Spair, b: &Spair) -> bool where Group1: Pairing { pairing(&a.p, &b.q) == pairing(&a.q, &b.p) } @@ -70,7 +70,7 @@ where Group1: Pairing check(i.into_iter().map(|s| (&s.p, &s.q)), a) } -fn checkseq<'a, +pub fn checkseq<'a, Group1: Group, Group2: Group, I: Iterator>