Randompowers subprotocol simulation

This commit is contained in:
Sean Bowe 2016-08-02 16:14:05 -06:00
parent 79e5782089
commit c05c8c0d90
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
5 changed files with 126 additions and 6 deletions

View File

@ -1,6 +1,6 @@
# mpc
This is a multi-party computation protocol for the key-generation step of Pinnochio zkSNARKs [[PGHR13]](https://eprint.iacr.org/2013/279) designed for use in the Zcash "Sprout" public parameter ceremony.
This is a multi-party computation protocol for the key-generation step of Pinocchio zkSNARKs [[PGHR13]](https://eprint.iacr.org/2013/279) designed for use in the Zcash "Sprout" public parameter ceremony.
## License

View File

@ -14,6 +14,7 @@ extern "C" {
fn libsnarkwrap_Fr_mul(a: *const Fr, b: *const Fr) -> Fr;
fn libsnarkwrap_Fr_sub(a: *const Fr, b: *const Fr) -> Fr;
fn libsnarkwrap_Fr_neg(a: *const Fr) -> Fr;
fn libsnarkwrap_Fr_is_zero(a: *const Fr) -> bool;
}
impl Fr {
@ -21,6 +22,20 @@ impl Fr {
unsafe { libsnarkwrap_Fr_random() }
}
pub fn is_zero(&self) -> bool {
unsafe { libsnarkwrap_Fr_is_zero(self) }
}
pub fn random_nonzero() -> Self {
let mut tmp = Self::random();
while tmp.is_zero() {
tmp = Self::random();
}
return tmp;
}
pub fn from_str(s: &str) -> Self {
for c in s.chars() {
if c != '0' &&
@ -74,3 +89,28 @@ impl Neg for Fr {
unsafe { libsnarkwrap_Fr_neg(&self) }
}
}
#[test]
fn test_basic_arith() {
super::initialize();
let a = Fr::from_str("34563126457335463");
let b = Fr::from_str("23463856875665981");
let ab = Fr::from_str("810984252370463483215040853984203");
let aplusb = Fr::from_str("58026983333001444");
let aminusb = Fr::from_str("11099269581669482");
let aneg = Fr::from_str("21888242871839275222246405745257275088548364400416034343698169623449351160154");
assert!(ab == (a * b));
assert!(aplusb == (a + b));
assert!(aminusb == (a - b));
assert!(aneg == (-a));
}
#[test]
fn test_primitives() {
let a = Fr::from_str("0");
assert!(a.is_zero());
let a = Fr::from_str("1");
assert!(!a.is_zero());
}

View File

@ -33,22 +33,26 @@ extern "C" FieldT libsnarkwrap_Fr_from(const char *a) {
return FieldT(a);
}
extern "C" FieldT libsnarkwrap_Fr_add(const char *a, const char *b) {
extern "C" FieldT libsnarkwrap_Fr_add(FieldT *a, FieldT *b) {
return *a + *b;
}
extern "C" FieldT libsnarkwrap_Fr_sub(const char *a, const char *b) {
extern "C" FieldT libsnarkwrap_Fr_sub(FieldT *a, FieldT *b) {
return *a - *b;
}
extern "C" FieldT libsnarkwrap_Fr_mul(const char *a, const char *b) {
extern "C" FieldT libsnarkwrap_Fr_mul(FieldT *a, FieldT *b) {
return *a * *b;
}
extern "C" FieldT libsnarkwrap_Fr_neg(const char *a) {
extern "C" FieldT libsnarkwrap_Fr_neg(FieldT *a) {
return -(*a);
}
extern "C" bool libsnarkwrap_Fr_is_zero(FieldT *a) {
return a->is_zero();
}
// G1
extern "C" alt_bn128_G1 libsnarkwrap_G1_zero() {

View File

@ -37,6 +37,8 @@ where Group1: Pairing<Group2> {
pairing(&a.p, &b.q) == pairing(&a.q, &b.p)
}
/// This performs a check to see if a large number of (p,q) pairs in G
/// have the same power, with only one pairing.
fn check<'a,
Group1: Group,
Group2: Group,
@ -48,7 +50,7 @@ where Group1: Pairing<Group2>
let mut q = Group1::zero();
for v in i {
let alpha = Fr::random();
let alpha = Fr::random_nonzero();
p = p + *v.0 * alpha;
q = q + *v.1 * alpha;
}
@ -78,6 +80,72 @@ where Group1: Pairing<Group2>
check(Sequences::new(i), a)
}
struct TauPowers {
acc: Fr,
tau: Fr
}
impl TauPowers {
fn new(tau: Fr) -> TauPowers {
TauPowers { acc: Fr::from_str("1"), tau: tau }
}
}
impl Iterator for TauPowers {
type Item = Fr;
fn next(&mut self) -> Option<Fr> {
let tmp = self.acc;
self.acc = tmp * self.tau;
Some(tmp)
}
}
#[test]
fn randompowers_simulation() {
initialize();
let parties = 3;
let d = 1024;
let mut messages: Vec<(Spair<G2>, Vec<G1>, Vec<G2>)> = vec![];
messages.reserve(parties);
for i in 0..parties {
let tau = Fr::random_nonzero();
let rp = Spair::random(&tau);
if i == 0 {
messages.push((
rp,
TauPowers::new(tau).map(|p| G1::one() * p).take(d).collect(),
TauPowers::new(tau).map(|p| G2::one() * p).take(d).collect()
));
} else {
let v1 = messages[i-1].1.iter().zip(TauPowers::new(tau)).map(|(b, p)| *b * p).collect();
let v2 = messages[i-1].2.iter().zip(TauPowers::new(tau)).map(|(b, p)| *b * p).collect();
messages.push((
rp,
v1,
v2
));
}
}
// Check validity
for i in 0..parties {
if i == 0 {
assert!(checkseq(messages[i].1.iter(), &messages[i].0));
assert!(checkseq(messages[i].2.iter(), &Spair::new(&messages[i].1[0], &messages[i].1[1])));
} else {
assert!(checkseq(messages[i].1.iter(), &Spair::new(&messages[i].2[0], &messages[i].2[1])));
assert!(checkseq(messages[i].2.iter(), &Spair::new(&messages[i].1[0], &messages[i].1[1])));
assert!(same_power(&Spair::new(&messages[i-1].1[1], &messages[i].1[1]), &messages[i].0));
}
}
}
#[test]
fn samepower_seq() {
initialize();

View File

@ -26,3 +26,11 @@ impl<'a, T: 'a, I: Iterator<Item=&'a T>> Iterator for Sequences<'a, T, I> {
}
}
}
#[test]
fn test_sequences() {
let a = vec![10, 57, 34, 12];
let b: Vec<(&usize, &usize)> = Sequences::new(a.iter()).collect();
let expected = vec![(&a[0], &a[1]), (&a[1], &a[2]), (&a[2], &a[3])];
assert_eq!(b, expected);
}