mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-11 17:55:46 +00:00
Merge commit '4272cfa5b0dceac471bef115955e1534be84a018' into ff-traits
git-subtree-dir: bellman git-subtree-split: 4272cfa5b0dceac471bef115955e1534be84a018
This commit is contained in:
commit
76cd0d92bb
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -43,8 +43,10 @@ dependencies = [
|
|||||||
"bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ff 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"group 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pairing 0.14.2",
|
"pairing 0.14.2",
|
||||||
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -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 = "0.4"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
futures-cpupool = "0.1"
|
futures-cpupool = "0.1"
|
||||||
|
group = "0.1"
|
||||||
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"]
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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]
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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::*;
|
||||||
|
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
@ -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());
|
||||||
|
@ -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::{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user