From b47d8193adfca8739450e8131eb469ac563030db Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Tue, 2 Aug 2016 09:34:17 -0600 Subject: [PATCH] Pairings (closes #3) --- src/bnwrap.cpp | 16 ++++++++++++++++ src/curve/fr.rs | 5 +++++ src/curve/gt.rs | 15 +++++++++++++++ src/curve/mod.rs | 26 ++++++++++++++++++++++++++ 4 files changed, 62 insertions(+) diff --git a/src/bnwrap.cpp b/src/bnwrap.cpp index 9611fd2..30c8713 100644 --- a/src/bnwrap.cpp +++ b/src/bnwrap.cpp @@ -17,12 +17,18 @@ using namespace libsnark; typedef Fr FieldT; extern "C" void bnwrap_init() { + libsnark::inhibit_profiling_info = true; + libsnark::inhibit_profiling_counters = true; assert(sodium_init() != -1); init_alt_bn128_params(); } // Fr +extern "C" FieldT bnwrap_Fr_random() { + return FieldT::random_element(); +} + extern "C" FieldT bnwrap_Fr_from(const char *a) { return FieldT(a); } @@ -118,3 +124,13 @@ extern "C" alt_bn128_G2 bnwrap_G2_neg(alt_bn128_G2 *p) { extern "C" alt_bn128_G2 bnwrap_G2_scalarmul(alt_bn128_G2 *p, FieldT *q) { return (*q) * (*p); } + +// Pairing + +extern "C" alt_bn128_GT bnwrap_gt_exp(alt_bn128_GT *p, FieldT *s) { + return (*p) ^ (*s); +} + +extern "C" alt_bn128_GT bnwrap_pairing(alt_bn128_G1 *p, alt_bn128_G2 *q) { + return alt_bn128_reduced_pairing(*p, *q); +} diff --git a/src/curve/fr.rs b/src/curve/fr.rs index 2af139c..9c36a6e 100644 --- a/src/curve/fr.rs +++ b/src/curve/fr.rs @@ -8,6 +8,7 @@ use std::ffi::CString; pub struct Fr([u64; 4]); extern "C" { + fn bnwrap_Fr_random() -> Fr; fn bnwrap_Fr_from(s: *const c_char) -> Fr; fn bnwrap_Fr_add(a: *const Fr, b: *const Fr) -> Fr; fn bnwrap_Fr_mul(a: *const Fr, b: *const Fr) -> Fr; @@ -16,6 +17,10 @@ extern "C" { } impl Fr { + pub fn random() -> Self { + unsafe { bnwrap_Fr_random() } + } + pub fn from_str(s: &str) -> Self { for c in s.chars() { if c != '0' && diff --git a/src/curve/gt.rs b/src/curve/gt.rs index 6f992cc..314e915 100644 --- a/src/curve/gt.rs +++ b/src/curve/gt.rs @@ -1,6 +1,21 @@ +use std::ops::Mul; +use super::Fr; + #[derive(Copy, Clone, Eq, PartialEq)] #[repr(C)] pub struct Gt { a: [u64; 4 * 6], b: [u64; 4 * 6] } + +extern "C" { + fn bnwrap_gt_exp(p: *const Gt, s: *const Fr) -> Gt; +} + +impl Mul for Gt { + type Output = Gt; + + fn mul(self, other: Fr) -> Gt { + unsafe { bnwrap_gt_exp(&self, &other) } + } +} diff --git a/src/curve/mod.rs b/src/curve/mod.rs index 2f6a5a2..088ae47 100644 --- a/src/curve/mod.rs +++ b/src/curve/mod.rs @@ -13,6 +13,7 @@ pub use self::g2::G2; extern "C" { fn bnwrap_init(); + fn bnwrap_pairing(p: *const G1, q: *const G2) -> Gt; } lazy_static! { @@ -29,6 +30,10 @@ pub fn initialize() { } } +pub fn pairing(p: &G1, q: &G2) -> Gt { + unsafe { bnwrap_pairing(p, q) } +} + pub trait GroupElement: Sized + Copy + Clone + @@ -43,6 +48,27 @@ pub trait GroupElement: Sized + fn is_zero(&self) -> bool; } +#[test] +fn pairing_test() { + initialize(); + + for _ in 0..50 { + let p = G1::random(); + let q = G2::random(); + let s = Fr::random(); + + let sp = p * s; + let sq = q * s; + + let a = pairing(&p, &q) * s; + let b = pairing(&sp, &q); + let c = pairing(&p, &sq); + + assert!(a == b); + assert!(b == c); + } +} + mod test_groups { use super::{Fr, G1, G2, initialize, GroupElement};