Merge pull request #46 from str4d/ff-traits

Migrate to ff and group crates
This commit is contained in:
str4d 2019-02-26 20:41:45 +00:00 committed by GitHub
commit 955e6795d5
11 changed files with 101 additions and 113 deletions

View File

@ -11,12 +11,20 @@ version = "0.1.0"
[dependencies] [dependencies]
rand = "0.4" rand = "0.4"
bit-vec = "0.4.4" bit-vec = "0.4.4"
ff = { path = "../ff" }
futures = "0.1" futures = "0.1"
futures-cpupool = "0.1" futures-cpupool = "0.1"
group = { path = "../group" }
num_cpus = "1" num_cpus = "1"
crossbeam = "0.3" crossbeam = "0.3"
pairing = { path = "../pairing" } pairing = { path = "../pairing", optional = true }
byteorder = "1" byteorder = "1"
[features] [features]
default = [] groth16 = ["pairing"]
default = ["groth16"]
[[test]]
name = "mimc"
path = "tests/mimc.rs"
required-features = ["groth16"]

View File

@ -10,12 +10,8 @@
//! This allows us to perform polynomial operations in O(n) //! This allows us to perform polynomial operations in O(n)
//! by performing an O(n log n) FFT over such a domain. //! by performing an O(n log n) FFT over such a domain.
use pairing::{ use ff::{Field, PrimeField, ScalarEngine};
Engine, use group::CurveProjective;
Field,
PrimeField,
CurveProjective
};
use super::{ use super::{
SynthesisError SynthesisError
@ -23,7 +19,7 @@ use super::{
use super::multicore::Worker; use super::multicore::Worker;
pub struct EvaluationDomain<E: Engine, G: Group<E>> { pub struct EvaluationDomain<E: ScalarEngine, G: Group<E>> {
coeffs: Vec<G>, coeffs: Vec<G>,
exp: u32, exp: u32,
omega: E::Fr, omega: E::Fr,
@ -32,7 +28,7 @@ pub struct EvaluationDomain<E: Engine, G: Group<E>> {
minv: E::Fr minv: E::Fr
} }
impl<E: Engine, G: Group<E>> EvaluationDomain<E, G> { impl<E: ScalarEngine, G: Group<E>> EvaluationDomain<E, G> {
pub fn as_ref(&self) -> &[G] { pub fn as_ref(&self) -> &[G] {
&self.coeffs &self.coeffs
} }
@ -189,7 +185,7 @@ impl<E: Engine, G: Group<E>> EvaluationDomain<E, G> {
} }
} }
pub trait Group<E: Engine>: Sized + Copy + Clone + Send + Sync { pub trait Group<E: ScalarEngine>: Sized + Copy + Clone + Send + Sync {
fn group_zero() -> Self; fn group_zero() -> Self;
fn group_mul_assign(&mut self, by: &E::Fr); fn group_mul_assign(&mut self, by: &E::Fr);
fn group_add_assign(&mut self, other: &Self); fn group_add_assign(&mut self, other: &Self);
@ -227,23 +223,23 @@ impl<G: CurveProjective> Group<G::Engine> for Point<G> {
} }
} }
pub struct Scalar<E: Engine>(pub E::Fr); pub struct Scalar<E: ScalarEngine>(pub E::Fr);
impl<E: Engine> PartialEq for Scalar<E> { impl<E: ScalarEngine> PartialEq for Scalar<E> {
fn eq(&self, other: &Scalar<E>) -> bool { fn eq(&self, other: &Scalar<E>) -> bool {
self.0 == other.0 self.0 == other.0
} }
} }
impl<E: Engine> Copy for Scalar<E> { } impl<E: ScalarEngine> Copy for Scalar<E> { }
impl<E: Engine> Clone for Scalar<E> { impl<E: ScalarEngine> Clone for Scalar<E> {
fn clone(&self) -> Scalar<E> { fn clone(&self) -> Scalar<E> {
*self *self
} }
} }
impl<E: Engine> Group<E> for Scalar<E> { impl<E: ScalarEngine> Group<E> for Scalar<E> {
fn group_zero() -> Self { fn group_zero() -> Self {
Scalar(E::Fr::zero()) Scalar(E::Fr::zero())
} }
@ -258,7 +254,7 @@ impl<E: Engine> Group<E> for Scalar<E> {
} }
} }
fn best_fft<E: Engine, T: Group<E>>(a: &mut [T], worker: &Worker, omega: &E::Fr, log_n: u32) fn best_fft<E: ScalarEngine, T: Group<E>>(a: &mut [T], worker: &Worker, omega: &E::Fr, log_n: u32)
{ {
let log_cpus = worker.log_num_cpus(); let log_cpus = worker.log_num_cpus();
@ -269,7 +265,7 @@ fn best_fft<E: Engine, T: Group<E>>(a: &mut [T], worker: &Worker, omega: &E::Fr,
} }
} }
fn serial_fft<E: Engine, T: Group<E>>(a: &mut [T], omega: &E::Fr, log_n: u32) fn serial_fft<E: ScalarEngine, T: Group<E>>(a: &mut [T], omega: &E::Fr, log_n: u32)
{ {
fn bitreverse(mut n: u32, l: u32) -> u32 { fn bitreverse(mut n: u32, l: u32) -> u32 {
let mut r = 0; let mut r = 0;
@ -314,7 +310,7 @@ fn serial_fft<E: Engine, T: Group<E>>(a: &mut [T], omega: &E::Fr, log_n: u32)
} }
} }
fn parallel_fft<E: Engine, T: Group<E>>( fn parallel_fft<E: ScalarEngine, T: Group<E>>(
a: &mut [T], a: &mut [T],
worker: &Worker, worker: &Worker,
omega: &E::Fr, omega: &E::Fr,
@ -375,12 +371,13 @@ fn parallel_fft<E: Engine, T: Group<E>>(
// Test multiplying various (low degree) polynomials together and // Test multiplying various (low degree) polynomials together and
// comparing with naive evaluations. // comparing with naive evaluations.
#[cfg(feature = "pairing")]
#[test] #[test]
fn polynomial_arith() { fn polynomial_arith() {
use pairing::bls12_381::Bls12; use pairing::bls12_381::Bls12;
use rand::{self, Rand}; use rand::{self, Rand};
fn test_mul<E: Engine, R: rand::Rng>(rng: &mut R) fn test_mul<E: ScalarEngine, R: rand::Rng>(rng: &mut R)
{ {
let worker = Worker::new(); let worker = Worker::new();
@ -422,12 +419,13 @@ fn polynomial_arith() {
test_mul::<Bls12, _>(rng); test_mul::<Bls12, _>(rng);
} }
#[cfg(feature = "pairing")]
#[test] #[test]
fn fft_composition() { fn fft_composition() {
use pairing::bls12_381::Bls12; use pairing::bls12_381::Bls12;
use rand; use rand;
fn test_comp<E: Engine, R: rand::Rng>(rng: &mut R) fn test_comp<E: ScalarEngine, R: rand::Rng>(rng: &mut R)
{ {
let worker = Worker::new(); let worker = Worker::new();
@ -460,13 +458,14 @@ fn fft_composition() {
test_comp::<Bls12, _>(rng); test_comp::<Bls12, _>(rng);
} }
#[cfg(feature = "pairing")]
#[test] #[test]
fn parallel_fft_consistency() { fn parallel_fft_consistency() {
use pairing::bls12_381::Bls12; use pairing::bls12_381::Bls12;
use rand::{self, Rand}; use rand::{self, Rand};
use std::cmp::min; use std::cmp::min;
fn test_consistency<E: Engine, R: rand::Rng>(rng: &mut R) fn test_consistency<E: ScalarEngine, R: rand::Rng>(rng: &mut R)
{ {
let worker = Worker::new(); let worker = Worker::new();

View File

@ -2,14 +2,9 @@ use rand::Rng;
use std::sync::Arc; use std::sync::Arc;
use pairing::{ use ff::{Field, PrimeField};
Engine, use group::{CurveAffine, CurveProjective, Wnaf};
PrimeField, use pairing::Engine;
Field,
Wnaf,
CurveProjective,
CurveAffine
};
use super::{ use super::{
Parameters, Parameters,

View File

@ -1,7 +1,7 @@
use group::{CurveAffine, EncodedPoint};
use pairing::{ use pairing::{
Engine, Engine,
CurveAffine, PairingCurveAffine,
EncodedPoint
}; };
use ::{ use ::{
@ -385,9 +385,9 @@ pub struct PreparedVerifyingKey<E: Engine> {
/// Pairing result of alpha*beta /// Pairing result of alpha*beta
alpha_g1_beta_g2: E::Fqk, alpha_g1_beta_g2: E::Fqk,
/// -gamma in G2 /// -gamma in G2
neg_gamma_g2: <E::G2Affine as CurveAffine>::Prepared, neg_gamma_g2: <E::G2Affine as PairingCurveAffine>::Prepared,
/// -delta in G2 /// -delta in G2
neg_delta_g2: <E::G2Affine as CurveAffine>::Prepared, neg_delta_g2: <E::G2Affine as PairingCurveAffine>::Prepared,
/// Copy of IC from `VerifiyingKey`. /// Copy of IC from `VerifiyingKey`.
ic: Vec<E::G1Affine> ic: Vec<E::G1Affine>
} }
@ -486,8 +486,8 @@ mod test_with_bls12_381 {
use super::*; use super::*;
use {Circuit, SynthesisError, ConstraintSystem}; use {Circuit, SynthesisError, ConstraintSystem};
use ff::Field;
use rand::{Rand, thread_rng}; use rand::{Rand, thread_rng};
use pairing::{Field};
use pairing::bls12_381::{Bls12, Fr}; use pairing::bls12_381::{Bls12, Fr};
#[test] #[test]

View File

@ -4,13 +4,9 @@ use std::sync::Arc;
use futures::Future; use futures::Future;
use pairing::{ use ff::{Field, PrimeField};
Engine, use group::{CurveAffine, CurveProjective};
PrimeField, use pairing::Engine;
Field,
CurveProjective,
CurveAffine
};
use super::{ use super::{
ParameterSource, ParameterSource,

View File

@ -1,16 +1,8 @@
use pairing::{ use ff::{
Engine, Field, LegendreSymbol, PrimeField, PrimeFieldDecodingError,
PrimeField, PrimeFieldRepr, ScalarEngine, SqrtField};
PrimeFieldRepr, use group::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
Field, use pairing::{Engine, PairingCurveAffine};
SqrtField,
LegendreSymbol,
CurveProjective,
CurveAffine,
PrimeFieldDecodingError,
GroupDecodingError,
EncodedPoint
};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::fmt; use std::fmt;
@ -263,8 +255,11 @@ impl PrimeField for Fr {
#[derive(Clone)] #[derive(Clone)]
pub struct DummyEngine; pub struct DummyEngine;
impl Engine for DummyEngine { impl ScalarEngine for DummyEngine {
type Fr = Fr; type Fr = Fr;
}
impl Engine for DummyEngine {
type G1 = Fr; type G1 = Fr;
type G1Affine = Fr; type G1Affine = Fr;
type G2 = Fr; type G2 = Fr;
@ -277,8 +272,8 @@ impl Engine for DummyEngine {
fn miller_loop<'a, I>(i: I) -> Self::Fqk fn miller_loop<'a, I>(i: I) -> Self::Fqk
where I: IntoIterator<Item=&'a ( where I: IntoIterator<Item=&'a (
&'a <Self::G1Affine as CurveAffine>::Prepared, &'a <Self::G1Affine as PairingCurveAffine>::Prepared,
&'a <Self::G2Affine as CurveAffine>::Prepared &'a <Self::G2Affine as PairingCurveAffine>::Prepared
)> )>
{ {
let mut acc = <Fr as Field>::zero(); let mut acc = <Fr as Field>::zero();
@ -401,11 +396,8 @@ impl EncodedPoint for FakePoint {
} }
impl CurveAffine for Fr { impl CurveAffine for Fr {
type Pair = Fr;
type PairingResult = Fr;
type Compressed = FakePoint; type Compressed = FakePoint;
type Uncompressed = FakePoint; type Uncompressed = FakePoint;
type Prepared = Fr;
type Projective = Fr; type Projective = Fr;
type Base = Fr; type Base = Fr;
type Scalar = Fr; type Scalar = Fr;
@ -437,6 +429,16 @@ impl CurveAffine for Fr {
res res
} }
fn into_projective(&self) -> Self::Projective {
*self
}
}
impl PairingCurveAffine for Fr {
type Prepared = Fr;
type Pair = Fr;
type PairingResult = Fr;
fn prepare(&self) -> Self::Prepared { fn prepare(&self) -> Self::Prepared {
*self *self
} }
@ -444,8 +446,4 @@ impl CurveAffine for Fr {
fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult { fn pairing_with(&self, other: &Self::Pair) -> Self::PairingResult {
self.mul(*other) self.mul(*other)
} }
fn into_projective(&self) -> Self::Projective {
*self
}
} }

View File

@ -1,8 +1,5 @@
use pairing::{ use ff::{Field, PrimeField};
Engine, use pairing::Engine;
Field,
PrimeField
};
mod dummy_engine; mod dummy_engine;
use self::dummy_engine::*; use self::dummy_engine::*;

View File

@ -1,9 +1,6 @@
use pairing::{ use ff::PrimeField;
Engine, use group::{CurveAffine, CurveProjective};
CurveProjective, use pairing::{Engine, PairingCurveAffine};
CurveAffine,
PrimeField
};
use super::{ use super::{
Proof, Proof,

View File

@ -1,3 +1,6 @@
extern crate ff;
extern crate group;
#[cfg(feature = "pairing")]
extern crate pairing; extern crate pairing;
extern crate rand; extern crate rand;
extern crate num_cpus; extern crate num_cpus;
@ -10,9 +13,10 @@ extern crate byteorder;
pub mod multicore; pub mod multicore;
mod multiexp; mod multiexp;
pub mod domain; pub mod domain;
#[cfg(feature = "groth16")]
pub mod groth16; pub mod groth16;
use pairing::{Engine, Field}; use ff::{Field, ScalarEngine};
use std::ops::{Add, Sub}; use std::ops::{Add, Sub};
use std::fmt; use std::fmt;
@ -24,7 +28,7 @@ use std::marker::PhantomData;
/// rank-1 quadratic constraint systems. The `Circuit` trait represents a /// rank-1 quadratic constraint systems. The `Circuit` trait represents a
/// circuit that can be synthesized. The `synthesize` method is called during /// circuit that can be synthesized. The `synthesize` method is called during
/// CRS generation and during proving. /// CRS generation and during proving.
pub trait Circuit<E: Engine> { pub trait Circuit<E: ScalarEngine> {
/// Synthesize the circuit into a rank-1 quadratic constraint system /// Synthesize the circuit into a rank-1 quadratic constraint system
fn synthesize<CS: ConstraintSystem<E>>( fn synthesize<CS: ConstraintSystem<E>>(
self, self,
@ -61,21 +65,21 @@ pub enum Index {
/// This represents a linear combination of some variables, with coefficients /// This represents a linear combination of some variables, with coefficients
/// in the scalar field of a pairing-friendly elliptic curve group. /// in the scalar field of a pairing-friendly elliptic curve group.
#[derive(Clone)] #[derive(Clone)]
pub struct LinearCombination<E: Engine>(Vec<(Variable, E::Fr)>); pub struct LinearCombination<E: ScalarEngine>(Vec<(Variable, E::Fr)>);
impl<E: Engine> AsRef<[(Variable, E::Fr)]> for LinearCombination<E> { impl<E: ScalarEngine> AsRef<[(Variable, E::Fr)]> for LinearCombination<E> {
fn as_ref(&self) -> &[(Variable, E::Fr)] { fn as_ref(&self) -> &[(Variable, E::Fr)] {
&self.0 &self.0
} }
} }
impl<E: Engine> LinearCombination<E> { impl<E: ScalarEngine> LinearCombination<E> {
pub fn zero() -> LinearCombination<E> { pub fn zero() -> LinearCombination<E> {
LinearCombination(vec![]) LinearCombination(vec![])
} }
} }
impl<E: Engine> Add<(E::Fr, Variable)> for LinearCombination<E> { impl<E: ScalarEngine> Add<(E::Fr, Variable)> for LinearCombination<E> {
type Output = LinearCombination<E>; type Output = LinearCombination<E>;
fn add(mut self, (coeff, var): (E::Fr, Variable)) -> LinearCombination<E> { fn add(mut self, (coeff, var): (E::Fr, Variable)) -> LinearCombination<E> {
@ -85,7 +89,7 @@ impl<E: Engine> Add<(E::Fr, Variable)> for LinearCombination<E> {
} }
} }
impl<E: Engine> Sub<(E::Fr, Variable)> for LinearCombination<E> { impl<E: ScalarEngine> Sub<(E::Fr, Variable)> for LinearCombination<E> {
type Output = LinearCombination<E>; type Output = LinearCombination<E>;
fn sub(self, (mut coeff, var): (E::Fr, Variable)) -> LinearCombination<E> { fn sub(self, (mut coeff, var): (E::Fr, Variable)) -> LinearCombination<E> {
@ -95,7 +99,7 @@ impl<E: Engine> Sub<(E::Fr, Variable)> for LinearCombination<E> {
} }
} }
impl<E: Engine> Add<Variable> for LinearCombination<E> { impl<E: ScalarEngine> Add<Variable> for LinearCombination<E> {
type Output = LinearCombination<E>; type Output = LinearCombination<E>;
fn add(self, other: Variable) -> LinearCombination<E> { fn add(self, other: Variable) -> LinearCombination<E> {
@ -103,7 +107,7 @@ impl<E: Engine> Add<Variable> for LinearCombination<E> {
} }
} }
impl<E: Engine> Sub<Variable> for LinearCombination<E> { impl<E: ScalarEngine> Sub<Variable> for LinearCombination<E> {
type Output = LinearCombination<E>; type Output = LinearCombination<E>;
fn sub(self, other: Variable) -> LinearCombination<E> { fn sub(self, other: Variable) -> LinearCombination<E> {
@ -111,7 +115,7 @@ impl<E: Engine> Sub<Variable> for LinearCombination<E> {
} }
} }
impl<'a, E: Engine> Add<&'a LinearCombination<E>> for LinearCombination<E> { impl<'a, E: ScalarEngine> Add<&'a LinearCombination<E>> for LinearCombination<E> {
type Output = LinearCombination<E>; type Output = LinearCombination<E>;
fn add(mut self, other: &'a LinearCombination<E>) -> LinearCombination<E> { fn add(mut self, other: &'a LinearCombination<E>) -> LinearCombination<E> {
@ -123,7 +127,7 @@ impl<'a, E: Engine> Add<&'a LinearCombination<E>> for LinearCombination<E> {
} }
} }
impl<'a, E: Engine> Sub<&'a LinearCombination<E>> for LinearCombination<E> { impl<'a, E: ScalarEngine> Sub<&'a LinearCombination<E>> for LinearCombination<E> {
type Output = LinearCombination<E>; type Output = LinearCombination<E>;
fn sub(mut self, other: &'a LinearCombination<E>) -> LinearCombination<E> { fn sub(mut self, other: &'a LinearCombination<E>) -> LinearCombination<E> {
@ -135,7 +139,7 @@ impl<'a, E: Engine> Sub<&'a LinearCombination<E>> for LinearCombination<E> {
} }
} }
impl<'a, E: Engine> Add<(E::Fr, &'a LinearCombination<E>)> for LinearCombination<E> { impl<'a, E: ScalarEngine> Add<(E::Fr, &'a LinearCombination<E>)> for LinearCombination<E> {
type Output = LinearCombination<E>; type Output = LinearCombination<E>;
fn add(mut self, (coeff, other): (E::Fr, &'a LinearCombination<E>)) -> LinearCombination<E> { fn add(mut self, (coeff, other): (E::Fr, &'a LinearCombination<E>)) -> LinearCombination<E> {
@ -149,7 +153,7 @@ impl<'a, E: Engine> Add<(E::Fr, &'a LinearCombination<E>)> for LinearCombination
} }
} }
impl<'a, E: Engine> Sub<(E::Fr, &'a LinearCombination<E>)> for LinearCombination<E> { impl<'a, E: ScalarEngine> Sub<(E::Fr, &'a LinearCombination<E>)> for LinearCombination<E> {
type Output = LinearCombination<E>; type Output = LinearCombination<E>;
fn sub(mut self, (coeff, other): (E::Fr, &'a LinearCombination<E>)) -> LinearCombination<E> { fn sub(mut self, (coeff, other): (E::Fr, &'a LinearCombination<E>)) -> LinearCombination<E> {
@ -219,7 +223,7 @@ impl fmt::Display for SynthesisError {
/// Represents a constraint system which can have new variables /// Represents a constraint system which can have new variables
/// allocated and constrains between them formed. /// allocated and constrains between them formed.
pub trait ConstraintSystem<E: Engine>: Sized { pub trait ConstraintSystem<E: ScalarEngine>: Sized {
/// Represents the type of the "root" of this constraint system /// Represents the type of the "root" of this constraint system
/// so that nested namespaces can minimize indirection. /// so that nested namespaces can minimize indirection.
type Root: ConstraintSystem<E>; type Root: ConstraintSystem<E>;
@ -291,9 +295,9 @@ pub trait ConstraintSystem<E: Engine>: Sized {
/// This is a "namespaced" constraint system which borrows a constraint system (pushing /// This is a "namespaced" constraint system which borrows a constraint system (pushing
/// a namespace context) and, when dropped, pops out of the namespace context. /// a namespace context) and, when dropped, pops out of the namespace context.
pub struct Namespace<'a, E: Engine, CS: ConstraintSystem<E> + 'a>(&'a mut CS, PhantomData<E>); pub struct Namespace<'a, E: ScalarEngine, CS: ConstraintSystem<E> + 'a>(&'a mut CS, PhantomData<E>);
impl<'cs, E: Engine, CS: ConstraintSystem<E>> ConstraintSystem<E> for Namespace<'cs, E, CS> { impl<'cs, E: ScalarEngine, CS: ConstraintSystem<E>> ConstraintSystem<E> for Namespace<'cs, E, CS> {
type Root = CS::Root; type Root = CS::Root;
fn one() -> Variable { fn one() -> Variable {
@ -356,7 +360,7 @@ impl<'cs, E: Engine, CS: ConstraintSystem<E>> ConstraintSystem<E> for Namespace<
} }
} }
impl<'a, E: Engine, CS: ConstraintSystem<E>> Drop for Namespace<'a, E, CS> { impl<'a, E: ScalarEngine, CS: ConstraintSystem<E>> Drop for Namespace<'a, E, CS> {
fn drop(&mut self) { fn drop(&mut self) {
self.get_root().pop_namespace() self.get_root().pop_namespace()
} }
@ -364,7 +368,7 @@ impl<'a, E: Engine, CS: ConstraintSystem<E>> Drop for Namespace<'a, E, CS> {
/// Convenience implementation of ConstraintSystem<E> for mutable references to /// Convenience implementation of ConstraintSystem<E> for mutable references to
/// constraint systems. /// constraint systems.
impl<'cs, E: Engine, CS: ConstraintSystem<E>> ConstraintSystem<E> for &'cs mut CS { impl<'cs, E: ScalarEngine, CS: ConstraintSystem<E>> ConstraintSystem<E> for &'cs mut CS {
type Root = CS::Root; type Root = CS::Root;
fn one() -> Variable { fn one() -> Variable {

View File

@ -1,11 +1,5 @@
use pairing::{ use ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine};
CurveAffine, use group::{CurveAffine, CurveProjective};
CurveProjective,
Engine,
PrimeField,
Field,
PrimeFieldRepr
};
use std::sync::Arc; use std::sync::Arc;
use std::io; use std::io;
use bit_vec::{self, BitVec}; use bit_vec::{self, BitVec};
@ -141,7 +135,7 @@ fn multiexp_inner<Q, D, G, S>(
pool: &Worker, pool: &Worker,
bases: S, bases: S,
density_map: D, density_map: D,
exponents: Arc<Vec<<<G::Engine as Engine>::Fr as PrimeField>::Repr>>, exponents: Arc<Vec<<<G::Engine as ScalarEngine>::Fr as PrimeField>::Repr>>,
mut skip: u32, mut skip: u32,
c: u32, c: u32,
handle_trivial: bool handle_trivial: bool
@ -167,8 +161,8 @@ fn multiexp_inner<Q, D, G, S>(
// Create space for the buckets // Create space for the buckets
let mut buckets = vec![<G as CurveAffine>::Projective::zero(); (1 << c) - 1]; let mut buckets = vec![<G as CurveAffine>::Projective::zero(); (1 << c) - 1];
let zero = <G::Engine as Engine>::Fr::zero().into_repr(); let zero = <G::Engine as ScalarEngine>::Fr::zero().into_repr();
let one = <G::Engine as Engine>::Fr::one().into_repr(); let one = <G::Engine as ScalarEngine>::Fr::one().into_repr();
// Sort the bases into buckets // Sort the bases into buckets
for (&exp, density) in exponents.iter().zip(density_map.as_ref().iter()) { for (&exp, density) in exponents.iter().zip(density_map.as_ref().iter()) {
@ -211,7 +205,7 @@ fn multiexp_inner<Q, D, G, S>(
skip += c; skip += c;
if skip >= <G::Engine as Engine>::Fr::NUM_BITS { if skip >= <G::Engine as ScalarEngine>::Fr::NUM_BITS {
// There isn't another region. // There isn't another region.
Box::new(this) Box::new(this)
} else { } else {
@ -238,7 +232,7 @@ pub fn multiexp<Q, D, G, S>(
pool: &Worker, pool: &Worker,
bases: S, bases: S,
density_map: D, density_map: D,
exponents: Arc<Vec<<<G::Engine as Engine>::Fr as PrimeField>::Repr>> exponents: Arc<Vec<<<G::Engine as ScalarEngine>::Fr as PrimeField>::Repr>>
) -> Box<Future<Item=<G as CurveAffine>::Projective, Error=SynthesisError>> ) -> Box<Future<Item=<G as CurveAffine>::Projective, Error=SynthesisError>>
where for<'a> &'a Q: QueryDensity, where for<'a> &'a Q: QueryDensity,
D: Send + Sync + 'static + Clone + AsRef<Q>, D: Send + Sync + 'static + Clone + AsRef<Q>,
@ -261,6 +255,7 @@ pub fn multiexp<Q, D, G, S>(
multiexp_inner(pool, bases, density_map, exponents, 0, c, true) multiexp_inner(pool, bases, density_map, exponents, 0, c, true)
} }
#[cfg(feature = "pairing")]
#[test] #[test]
fn test_with_bls12() { fn test_with_bls12() {
fn naive_multiexp<G: CurveAffine>( fn naive_multiexp<G: CurveAffine>(
@ -280,12 +275,12 @@ fn test_with_bls12() {
} }
use rand::{self, Rand}; use rand::{self, Rand};
use pairing::bls12_381::Bls12; use pairing::{bls12_381::Bls12, Engine};
const SAMPLES: usize = 1 << 14; const SAMPLES: usize = 1 << 14;
let rng = &mut rand::thread_rng(); let rng = &mut rand::thread_rng();
let v = Arc::new((0..SAMPLES).map(|_| <Bls12 as Engine>::Fr::rand(rng).into_repr()).collect::<Vec<_>>()); let v = Arc::new((0..SAMPLES).map(|_| <Bls12 as ScalarEngine>::Fr::rand(rng).into_repr()).collect::<Vec<_>>());
let g = Arc::new((0..SAMPLES).map(|_| <Bls12 as Engine>::G1::rand(rng).into_affine()).collect::<Vec<_>>()); let g = Arc::new((0..SAMPLES).map(|_| <Bls12 as Engine>::G1::rand(rng).into_affine()).collect::<Vec<_>>());
let naive = naive_multiexp(g.clone(), v.clone()); let naive = naive_multiexp(g.clone(), v.clone());

View File

@ -1,4 +1,5 @@
extern crate bellman; extern crate bellman;
extern crate ff;
extern crate pairing; extern crate pairing;
extern crate rand; extern crate rand;
@ -9,10 +10,8 @@ use rand::{thread_rng, Rng};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
// Bring in some tools for using pairing-friendly curves // Bring in some tools for using pairing-friendly curves
use pairing::{ use ff::Field;
Engine, use pairing::Engine;
Field
};
// We're going to use the BLS12-381 pairing-friendly elliptic curve. // We're going to use the BLS12-381 pairing-friendly elliptic curve.
use pairing::bls12_381::{ use pairing::bls12_381::{