diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..9fce2ff --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,47 @@ +name: "Rust CI" +on: + pull_request: + +env: + CARGO_TERM_COLOR: "always" + CARGO_INCREMENTAL: "0" + RUSTC_WRAPPER: "sccache" + SCCACHE_GHA_ENABLED: "true" + # Rust version to use. + nightly: nightly-2024-08-01 + +jobs: + build: + name: CI + strategy: + matrix: + # Needs big runners to run tests + # Only macos-13-xlarge is Apple Silicon, as per: + # https://docs.github.com/en/actions/using-github-hosted-runners/about-larger-runners/about-larger-runners#about-macos-larger-runners + os: [ubuntu-22.04-github-hosted-16core, macos-13-xlarge] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ env.nightly }} + components: rustfmt, clippy + # Remove default `-D warnings`. This is a temporary measure. + rustflags: "" + + - name: Install sccache + uses: mozilla-actions/sccache-action@v0.0.4 + + - name: Format + run: cargo fmt --all -- --check + + # Note: `bellman`, `blake2s_const`, `franklin-crypto`, `codegen` currently have failing tests, so they're temporarily + # excluded from the CI. + + - name: Run tests (boojum) + run: cargo test -p boojum + + - name: Run tests (rescue-poseidon) + run: cargo test -p rescue_poseidon diff --git a/crates/bellman/src/constants.rs b/crates/bellman/src/constants.rs index ddc9e3a..3388622 100644 --- a/crates/bellman/src/constants.rs +++ b/crates/bellman/src/constants.rs @@ -1,18 +1,13 @@ -pub const ETH_BLOCK_10_000_000_HASH: &'static str - = "aa20f7bde5be60603f11a45fc4923aab7552be775403fc00c2e6b805e6297dbe"; +pub const ETH_BLOCK_10_000_000_HASH: &'static str = "aa20f7bde5be60603f11a45fc4923aab7552be775403fc00c2e6b805e6297dbe"; -use crate::pairing::{Engine, CurveProjective}; use crate::byteorder::{BigEndian, ReadBytesExt}; +use crate::pairing::{CurveProjective, Engine}; -pub fn make_random_points_with_unknown_discrete_log_from_seed( - dst: &[u8], - seed: &[u8], - num_points: usize -) -> Vec { +pub fn make_random_points_with_unknown_discrete_log_from_seed(dst: &[u8], seed: &[u8], num_points: usize) -> Vec { let mut result = vec![]; - use rand::{Rng, SeedableRng}; use rand::chacha::ChaChaRng; + use rand::{Rng, SeedableRng}; // Create an RNG based on the outcome of the random beacon let mut rng = { // if we use Blake hasher @@ -36,13 +31,6 @@ pub fn make_random_points_with_unknown_discrete_log_from_seed( result } -pub fn make_random_points_with_unknown_discrete_log( - dst: &[u8], - num_points: usize -) -> Vec { - make_random_points_with_unknown_discrete_log_from_seed::( - dst, - &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), - num_points - ) +pub fn make_random_points_with_unknown_discrete_log(dst: &[u8], num_points: usize) -> Vec { + make_random_points_with_unknown_discrete_log_from_seed::(dst, &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), num_points) } diff --git a/crates/bellman/src/cs.rs b/crates/bellman/src/cs.rs index ea853bd..dd1f2a5 100644 --- a/crates/bellman/src/cs.rs +++ b/crates/bellman/src/cs.rs @@ -1,11 +1,11 @@ -use crate::pairing::{Engine}; use crate::pairing::ff::Field; +use crate::pairing::Engine; -use std::ops::{Add, Sub}; -use std::fmt; use std::error::Error; +use std::fmt; use std::io; use std::marker::PhantomData; +use std::ops::{Add, Sub}; /// Computations are expressed in terms of arithmetic circuits, in particular /// rank-1 quadratic constraint systems. The `Circuit` trait represents a @@ -13,10 +13,7 @@ use std::marker::PhantomData; /// CRS generation and during proving. pub trait Circuit { /// Synthesize the circuit into a rank-1 quadratic constraint system - fn synthesize>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError>; + fn synthesize>(self, cs: &mut CS) -> Result<(), SynthesisError>; } /// Represents a variable in our constraint system. @@ -42,7 +39,7 @@ impl Variable { #[derive(Copy, Clone, PartialEq, Debug, Hash, Eq)] pub enum Index { Input(usize), - Aux(usize) + Aux(usize), } /// This represents a linear combination of some variables, with coefficients @@ -78,7 +75,7 @@ impl Add<(E::Fr, Variable)> for LinearCombination { } } -impl Sub<(E::Fr, Variable)> for LinearCombination { +impl Sub<(E::Fr, Variable)> for LinearCombination { type Output = LinearCombination; fn sub(self, (mut coeff, var): (E::Fr, Variable)) -> LinearCombination { @@ -175,7 +172,7 @@ pub enum SynthesisError { /// During verification, our verifying key was malformed. MalformedVerifyingKey, /// During CRS generation, we observed an unconstrained auxillary variable - UnconstrainedVariable + UnconstrainedVariable, } impl From for SynthesisError { @@ -184,7 +181,6 @@ impl From for SynthesisError { } } - impl SynthesisError { pub fn self_description(&self) -> &str { match *self { @@ -195,7 +191,7 @@ impl SynthesisError { SynthesisError::UnexpectedIdentity => "encountered an identity element in the CRS", SynthesisError::IoError(_) => "encountered an I/O error", SynthesisError::MalformedVerifyingKey => "malformed verifying key", - SynthesisError::UnconstrainedVariable => "auxillary variable was unconstrained" + SynthesisError::UnconstrainedVariable => "auxillary variable was unconstrained", } } } @@ -233,40 +229,36 @@ pub trait ConstraintSystem: Sized { /// determine the assignment of the variable. The given `annotation` function is invoked /// in testing contexts in order to derive a unique name for this variable in the current /// namespace. - fn alloc( - &mut self, - annotation: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into; + fn alloc(&mut self, annotation: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into; /// Allocate a public variable in the constraint system. The provided function is used to /// determine the assignment of the variable. - fn alloc_input( - &mut self, - annotation: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into; + fn alloc_input(&mut self, annotation: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into; /// Enforce that `A` * `B` = `C`. The `annotation` function is invoked in testing contexts /// in order to derive a unique name for the constraint in the current namespace. - fn enforce( - &mut self, - annotation: A, - a: LA, - b: LB, - c: LC - ) - where A: FnOnce() -> AR, AR: Into, - LA: FnOnce(LinearCombination) -> LinearCombination, - LB: FnOnce(LinearCombination) -> LinearCombination, - LC: FnOnce(LinearCombination) -> LinearCombination; + fn enforce(&mut self, annotation: A, a: LA, b: LB, c: LC) + where + A: FnOnce() -> AR, + AR: Into, + LA: FnOnce(LinearCombination) -> LinearCombination, + LB: FnOnce(LinearCombination) -> LinearCombination, + LC: FnOnce(LinearCombination) -> LinearCombination; /// Create a new (sub)namespace and enter into it. Not intended /// for downstream use; use `namespace` instead. fn push_namespace(&mut self, name_fn: N) - where NR: Into, N: FnOnce() -> NR; + where + NR: Into, + N: FnOnce() -> NR; /// Exit out of the existing namespace. Not intended for /// downstream use; use `namespace` instead. @@ -277,11 +269,10 @@ pub trait ConstraintSystem: Sized { fn get_root(&mut self) -> &mut Self::Root; /// Begin a namespace for this constraint system. - fn namespace<'a, NR, N>( - &'a mut self, - name_fn: N - ) -> Namespace<'a, E, Self::Root> - where NR: Into, N: FnOnce() -> NR + fn namespace<'a, NR, N>(&'a mut self, name_fn: N) -> Namespace<'a, E, Self::Root> + where + NR: Into, + N: FnOnce() -> NR, { self.get_root().push_namespace(name_fn); @@ -300,37 +291,31 @@ impl<'cs, E: Engine, CS: ConstraintSystem> ConstraintSystem for Namespace< CS::one() } - fn alloc( - &mut self, - annotation: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc(&mut self, annotation: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { self.0.alloc(annotation, f) } - fn alloc_input( - &mut self, - annotation: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc_input(&mut self, annotation: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { self.0.alloc_input(annotation, f) } - fn enforce( - &mut self, - annotation: A, - a: LA, - b: LB, - c: LC - ) - where A: FnOnce() -> AR, AR: Into, - LA: FnOnce(LinearCombination) -> LinearCombination, - LB: FnOnce(LinearCombination) -> LinearCombination, - LC: FnOnce(LinearCombination) -> LinearCombination + fn enforce(&mut self, annotation: A, a: LA, b: LB, c: LC) + where + A: FnOnce() -> AR, + AR: Into, + LA: FnOnce(LinearCombination) -> LinearCombination, + LB: FnOnce(LinearCombination) -> LinearCombination, + LC: FnOnce(LinearCombination) -> LinearCombination, { self.0.enforce(annotation, a, b, c) } @@ -340,18 +325,18 @@ impl<'cs, E: Engine, CS: ConstraintSystem> ConstraintSystem for Namespace< // never a root constraint system. fn push_namespace(&mut self, _: N) - where NR: Into, N: FnOnce() -> NR + where + NR: Into, + N: FnOnce() -> NR, { panic!("only the root's push_namespace should be called"); } - fn pop_namespace(&mut self) - { + fn pop_namespace(&mut self) { panic!("only the root's pop_namespace should be called"); } - fn get_root(&mut self) -> &mut Self::Root - { + fn get_root(&mut self) -> &mut Self::Root { self.0.get_root() } } @@ -371,54 +356,48 @@ impl<'cs, E: Engine, CS: ConstraintSystem> ConstraintSystem for &'cs mut C CS::one() } - fn alloc( - &mut self, - annotation: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc(&mut self, annotation: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { (**self).alloc(annotation, f) } - fn alloc_input( - &mut self, - annotation: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc_input(&mut self, annotation: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { (**self).alloc_input(annotation, f) } - fn enforce( - &mut self, - annotation: A, - a: LA, - b: LB, - c: LC - ) - where A: FnOnce() -> AR, AR: Into, - LA: FnOnce(LinearCombination) -> LinearCombination, - LB: FnOnce(LinearCombination) -> LinearCombination, - LC: FnOnce(LinearCombination) -> LinearCombination + fn enforce(&mut self, annotation: A, a: LA, b: LB, c: LC) + where + A: FnOnce() -> AR, + AR: Into, + LA: FnOnce(LinearCombination) -> LinearCombination, + LB: FnOnce(LinearCombination) -> LinearCombination, + LC: FnOnce(LinearCombination) -> LinearCombination, { (**self).enforce(annotation, a, b, c) } fn push_namespace(&mut self, name_fn: N) - where NR: Into, N: FnOnce() -> NR + where + NR: Into, + N: FnOnce() -> NR, { (**self).push_namespace(name_fn) } - fn pop_namespace(&mut self) - { + fn pop_namespace(&mut self) { (**self).pop_namespace() } - fn get_root(&mut self) -> &mut Self::Root - { + fn get_root(&mut self) -> &mut Self::Root { (**self).get_root() } -} \ No newline at end of file +} diff --git a/crates/bellman/src/domain.rs b/crates/bellman/src/domain.rs index d605e48..1da1975 100644 --- a/crates/bellman/src/domain.rs +++ b/crates/bellman/src/domain.rs @@ -10,22 +10,14 @@ //! This allows us to perform polynomial operations in O(n) //! by performing an O(n log n) FFT over such a domain. -use crate::pairing::{ - Engine, - CurveProjective -}; +use crate::pairing::{CurveProjective, Engine}; -use crate::pairing::ff::{ - Field, - PrimeField -}; +use crate::pairing::ff::{Field, PrimeField}; -use super::{ - SynthesisError -}; +use super::SynthesisError; -use super::worker::Worker; pub use super::group::*; +use super::worker::Worker; pub struct EvaluationDomain> { coeffs: Vec, @@ -33,7 +25,7 @@ pub struct EvaluationDomain> { omega: E::Fr, omegainv: E::Fr, geninv: E::Fr, - minv: E::Fr + minv: E::Fr, } impl> EvaluationDomain { @@ -49,8 +41,7 @@ impl> EvaluationDomain { self.coeffs } - pub fn from_coeffs(mut coeffs: Vec) -> Result, SynthesisError> - { + pub fn from_coeffs(mut coeffs: Vec) -> Result, SynthesisError> { use crate::pairing::ff::PrimeField; // Compute the size of our evaluation domain @@ -64,7 +55,7 @@ impl> EvaluationDomain { let max_degree = (1 << E::Fr::S) - 1; if coeffs_len > max_degree { - return Err(SynthesisError::PolynomialDegreeTooLarge) + return Err(SynthesisError::PolynomialDegreeTooLarge); } while m < coeffs_len { @@ -74,7 +65,7 @@ impl> EvaluationDomain { // The pairing-friendly curve may not be able to support // large enough (radix2) evaluation domains. if exp > E::Fr::S { - return Err(SynthesisError::PolynomialDegreeTooLarge) + return Err(SynthesisError::PolynomialDegreeTooLarge); } } @@ -94,13 +85,12 @@ impl> EvaluationDomain { omega: omega, omegainv: omega.inverse().unwrap(), geninv: E::Fr::multiplicative_generator().inverse().unwrap(), - minv: E::Fr::from_str(&format!("{}", m)).unwrap().inverse().unwrap() + minv: E::Fr::from_str(&format!("{}", m)).unwrap().inverse().unwrap(), }) } // this one does expect coefficients to be smaller than `num_roots_of_unity/2` as we expect multiplication - pub fn from_coeffs_into_sized(mut coeffs: Vec, size: usize) -> Result, SynthesisError> - { + pub fn from_coeffs_into_sized(mut coeffs: Vec, size: usize) -> Result, SynthesisError> { use crate::pairing::ff::PrimeField; // Compute the size of our evaluation domain @@ -116,7 +106,7 @@ impl> EvaluationDomain { let max_degree = (1 << E::Fr::S) - 1; if coeffs_len > max_degree { - return Err(SynthesisError::PolynomialDegreeTooLarge) + return Err(SynthesisError::PolynomialDegreeTooLarge); } while m < coeffs_len { @@ -126,7 +116,7 @@ impl> EvaluationDomain { // The pairing-friendly curve may not be able to support // large enough (radix2) evaluation domains. if exp > E::Fr::S { - return Err(SynthesisError::PolynomialDegreeTooLarge) + return Err(SynthesisError::PolynomialDegreeTooLarge); } } @@ -146,18 +136,15 @@ impl> EvaluationDomain { omega: omega, omegainv: omega.inverse().unwrap(), geninv: E::Fr::multiplicative_generator().inverse().unwrap(), - minv: E::Fr::from_str(&format!("{}", m)).unwrap().inverse().unwrap() + minv: E::Fr::from_str(&format!("{}", m)).unwrap().inverse().unwrap(), }) } - - pub fn fft(&mut self, worker: &Worker) - { + pub fn fft(&mut self, worker: &Worker) { best_fft(&mut self.coeffs, worker, &self.omega, self.exp); } - pub fn ifft(&mut self, worker: &Worker) - { + pub fn ifft(&mut self, worker: &Worker) { best_fft(&mut self.coeffs, worker, &self.omegainv, self.exp); worker.scope(self.coeffs.len(), |scope, chunk| { @@ -173,8 +160,7 @@ impl> EvaluationDomain { }); } - pub fn distribute_powers(&mut self, worker: &Worker, g: E::Fr) - { + pub fn distribute_powers(&mut self, worker: &Worker, g: E::Fr) { worker.scope(self.coeffs.len(), |scope, chunk| { for (i, v) in self.coeffs.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { @@ -188,14 +174,12 @@ impl> EvaluationDomain { }); } - pub fn coset_fft(&mut self, worker: &Worker) - { + pub fn coset_fft(&mut self, worker: &Worker) { self.distribute_powers(worker, E::Fr::multiplicative_generator()); self.fft(worker); } - pub fn icoset_fft(&mut self, worker: &Worker) - { + pub fn icoset_fft(&mut self, worker: &Worker) { let geninv = self.geninv; self.ifft(worker); @@ -206,8 +190,7 @@ impl> EvaluationDomain { self.ifft(&worker); } - pub fn transform_powers_of_tau_into_lagrange_basis_on_coset(&mut self, worker: &Worker) - { + pub fn transform_powers_of_tau_into_lagrange_basis_on_coset(&mut self, worker: &Worker) { let geninv = self.geninv; self.distribute_powers(worker, geninv); @@ -236,8 +219,7 @@ impl> EvaluationDomain { /// The target polynomial is the zero polynomial in our /// evaluation domain, so we must perform division over /// a coset. - pub fn divide_by_z_on_coset(&mut self, worker: &Worker) - { + pub fn divide_by_z_on_coset(&mut self, worker: &Worker) { let i = self.z(&E::Fr::multiplicative_generator()).inverse().unwrap(); worker.scope(self.coeffs.len(), |scope, chunk| { @@ -282,8 +264,7 @@ impl> EvaluationDomain { } } -pub(crate) fn best_fft>(a: &mut [T], worker: &Worker, omega: &E::Fr, log_n: u32) -{ +pub(crate) fn best_fft>(a: &mut [T], worker: &Worker, omega: &E::Fr, log_n: u32) { let log_cpus = worker.log_num_cpus(); if log_n <= log_cpus { @@ -293,8 +274,7 @@ pub(crate) fn best_fft>(a: &mut [T], worker: &Worker, ome } } -pub(crate) fn serial_fft>(a: &mut [T], omega: &E::Fr, log_n: u32) -{ +pub(crate) fn serial_fft>(a: &mut [T], omega: &E::Fr, log_n: u32) { fn bitreverse(mut n: u32, l: u32) -> u32 { let mut r = 0; for _ in 0..l { @@ -316,36 +296,29 @@ pub(crate) fn serial_fft>(a: &mut [T], omega: &E::Fr, log let mut m = 1; for _ in 0..log_n { - let w_m = omega.pow(&[(n / (2*m)) as u64]); + let w_m = omega.pow(&[(n / (2 * m)) as u64]); let mut k = 0; while k < n { let mut w = E::Fr::one(); for j in 0..m { - let mut t = a[(k+j+m) as usize]; + let mut t = a[(k + j + m) as usize]; t.group_mul_assign(&w); - let mut tmp = a[(k+j) as usize]; + let mut tmp = a[(k + j) as usize]; tmp.group_sub_assign(&t); - a[(k+j+m) as usize] = tmp; - a[(k+j) as usize].group_add_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].group_add_assign(&t); w.mul_assign(&w_m); } - k += 2*m; + k += 2 * m; } m *= 2; } } -pub(crate) fn parallel_fft>( - a: &mut [T], - worker: &Worker, - omega: &E::Fr, - log_n: u32, - log_cpus: u32 -) -{ +pub(crate) fn parallel_fft>(a: &mut [T], worker: &Worker, omega: &E::Fr, log_n: u32, log_cpus: u32) { assert!(log_n >= log_cpus); let num_cpus = 1 << log_cpus; @@ -404,8 +377,7 @@ fn polynomial_arith() { use crate::pairing::bls12_381::Bls12; use rand::{self, Rand}; - fn test_mul(rng: &mut R) - { + fn test_mul(rng: &mut R) { let worker = Worker::new(); for coeffs_a in 0..70 { @@ -451,8 +423,7 @@ fn fft_composition() { use crate::pairing::bls12_381::Bls12; use rand; - fn test_comp(rng: &mut R) - { + fn test_comp(rng: &mut R) { let worker = Worker::new(); for coeffs in 0..10 { @@ -490,8 +461,7 @@ fn parallel_fft_consistency() { use rand::{self, Rand}; use std::cmp::min; - fn test_consistency(rng: &mut R) - { + fn test_consistency(rng: &mut R) { let worker = Worker::new(); for _ in 0..5 { @@ -502,7 +472,7 @@ fn parallel_fft_consistency() { let mut v1 = EvaluationDomain::from_coeffs(v1).unwrap(); let mut v2 = EvaluationDomain::from_coeffs(v1.coeffs.clone()).unwrap(); - for log_cpus in log_d..min(log_d+1, 3) { + for log_cpus in log_d..min(log_d + 1, 3) { parallel_fft(&mut v1.coeffs, &worker, &v1.omega, log_d, log_cpus); serial_fft(&mut v2.coeffs, &v2.omega, log_d); @@ -519,10 +489,10 @@ fn parallel_fft_consistency() { #[test] fn test_field_element_multiplication_bn256() { - use rand::{self, Rand}; use crate::pairing::bn256::Bn256; use crate::pairing::bn256::Fr; use num_cpus; + use rand::{self, Rand}; let cpus = num_cpus::get(); const SAMPLES: usize = 1 << 22; @@ -542,16 +512,16 @@ fn test_field_element_multiplication_bn256() { let duration_ns = start.elapsed().as_nanos() as f64; println!("Elapsed {} ns for {} samples", duration_ns, SAMPLES); - let time_per_sample = duration_ns/(SAMPLES as f64); + let time_per_sample = duration_ns / (SAMPLES as f64); println!("Tested on {} samples on {} CPUs with {} ns per field element multiplication", SAMPLES, cpus, time_per_sample); } #[test] fn test_fft_bn256() { - use rand::{self, Rand}; use crate::pairing::bn256::Bn256; use crate::pairing::bn256::Fr; use num_cpus; + use rand::{self, Rand}; let cpus = num_cpus::get(); const SAMPLES: usize = 1 << 27; @@ -569,6 +539,6 @@ fn test_fft_bn256() { let duration_ns = start.elapsed().as_nanos() as f64; println!("Elapsed {} ns for {} samples", duration_ns, SAMPLES); - let time_per_sample = duration_ns/(SAMPLES as f64); + let time_per_sample = duration_ns / (SAMPLES as f64); println!("Tested on {} samples on {} CPUs with {} ns per field element multiplication", SAMPLES, cpus, time_per_sample); -} \ No newline at end of file +} diff --git a/crates/bellman/src/gm17/generator.rs b/crates/bellman/src/gm17/generator.rs index f1dd3f0..53081bc 100644 --- a/crates/bellman/src/gm17/generator.rs +++ b/crates/bellman/src/gm17/generator.rs @@ -4,40 +4,17 @@ use rand::Rng; use std::sync::Arc; -use crate::pairing::{ - Engine, - Wnaf, - CurveProjective, - CurveAffine -}; - -use crate::pairing::ff::{ - PrimeField, - Field -}; - -use super::{ - Parameters, - VerifyingKey -}; - -use crate::{ - SynthesisError, - Circuit, - ConstraintSystem, - LinearCombination, - Variable, - Index -}; - -use crate::domain::{ - EvaluationDomain, - Scalar -}; - -use crate::worker::{ - Worker -}; +use crate::pairing::{CurveAffine, CurveProjective, Engine, Wnaf}; + +use crate::pairing::ff::{Field, PrimeField}; + +use super::{Parameters, VerifyingKey}; + +use crate::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; + +use crate::domain::{EvaluationDomain, Scalar}; + +use crate::worker::Worker; // /// Generates a random common reference string for // /// a circuit. @@ -79,18 +56,17 @@ struct KeypairAssembly { at_inputs: Vec>, ct_inputs: Vec>, at_aux: Vec>, - ct_aux: Vec> + ct_aux: Vec>, } impl ConstraintSystem for KeypairAssembly { type Root = Self; - fn alloc( - &mut self, - _: A, - _: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc(&mut self, _: A, _: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { // There is no assignment, so we don't even invoke the // function for obtaining one. @@ -106,12 +82,11 @@ impl ConstraintSystem for KeypairAssembly { Ok(Variable(Index::Aux(index))) } - fn alloc_input( - &mut self, - _: A, - _: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc_input(&mut self, _: A, _: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { // There is no assignment, so we don't even invoke the // function for obtaining one. @@ -125,17 +100,13 @@ impl ConstraintSystem for KeypairAssembly { Ok(Variable(Index::Input(index))) } - fn enforce( - &mut self, - _: A, - a: LA, - b: LB, - c: LC - ) - where A: FnOnce() -> AR, AR: Into, - LA: FnOnce(LinearCombination) -> LinearCombination, - LB: FnOnce(LinearCombination) -> LinearCombination, - LC: FnOnce(LinearCombination) -> LinearCombination + fn enforce(&mut self, _: A, a: LA, b: LB, c: LC) + where + A: FnOnce() -> AR, + AR: Into, + LA: FnOnce(LinearCombination) -> LinearCombination, + LB: FnOnce(LinearCombination) -> LinearCombination, + LC: FnOnce(LinearCombination) -> LinearCombination, { use std::ops::{Add, Sub}; @@ -144,9 +115,7 @@ impl ConstraintSystem for KeypairAssembly { // * = y // * = 4* + y - fn quadruple( - coeff: E::Fr - ) -> E::Fr { + fn quadruple(coeff: E::Fr) -> E::Fr { let mut tmp = coeff; tmp.double(); tmp.double(); @@ -154,27 +123,18 @@ impl ConstraintSystem for KeypairAssembly { tmp } - fn eval( - l: LinearCombination, - inputs: &mut [Vec<(E::Fr, usize)>], - aux: &mut [Vec<(E::Fr, usize)>], - this_constraint: usize - ) - { + fn eval(l: LinearCombination, inputs: &mut [Vec<(E::Fr, usize)>], aux: &mut [Vec<(E::Fr, usize)>], this_constraint: usize) { for (index, coeff) in l.0 { match index { Variable(Index::Input(id)) => inputs[id].push((coeff, this_constraint)), - Variable(Index::Aux(id)) => aux[id].push((coeff, this_constraint)) + Variable(Index::Aux(id)) => aux[id].push((coeff, this_constraint)), } } } // * = x_i let i = self.num_constraints; - let y = self.alloc( - || format!("SAP reduction y_{}", i), - || Ok(E::Fr::one()) - ).expect("must allocate SAP reduction variable"); + let y = self.alloc(|| format!("SAP reduction y_{}", i), || Ok(E::Fr::one())).expect("must allocate SAP reduction variable"); self.num_r1cs_aux -= 1; let lc_a = a(LinearCombination::zero()); @@ -210,13 +170,14 @@ impl ConstraintSystem for KeypairAssembly { } fn push_namespace(&mut self, _: N) - where NR: Into, N: FnOnce() -> NR + where + NR: Into, + N: FnOnce() -> NR, { // Do nothing; we don't care about namespaces in this context. } - fn pop_namespace(&mut self) - { + fn pop_namespace(&mut self) { // Do nothing; we don't care about namespaces in this context. } @@ -234,10 +195,12 @@ pub fn generate_parameters( beta: E::Fr, gamma: E::Fr, // delta: E::Fr, - tau: E::Fr + tau: E::Fr, ) -> Result<(), SynthesisError> // Result, SynthesisError> - where E: Engine, C: Circuit +where + E: Engine, + C: Circuit, { let verbose = verbose_flag(); @@ -250,7 +213,7 @@ pub fn generate_parameters( at_inputs: vec![], ct_inputs: vec![], at_aux: vec![], - ct_aux: vec![] + ct_aux: vec![], }; // Allocate the "one" input variable @@ -266,17 +229,11 @@ pub fn generate_parameters( { use std::ops::{Add, Sub}; - fn eval_lc( - l: LinearCombination, - inputs: &mut [Vec<(E::Fr, usize)>], - aux: &mut [Vec<(E::Fr, usize)>], - this_constraint: usize - ) - { + fn eval_lc(l: LinearCombination, inputs: &mut [Vec<(E::Fr, usize)>], aux: &mut [Vec<(E::Fr, usize)>], this_constraint: usize) { for (index, coeff) in l.0 { match index { Variable(Index::Input(id)) => inputs[id].push((coeff, this_constraint)), - Variable(Index::Aux(id)) => aux[id].push((coeff, this_constraint)) + Variable(Index::Aux(id)) => aux[id].push((coeff, this_constraint)), } } } @@ -284,7 +241,7 @@ pub fn generate_parameters( let mut lc_input_0_a: LinearCombination = LinearCombination::zero(); lc_input_0_a = lc_input_0_a.add(input_0.clone()); eval_lc(lc_input_0_a, &mut assembly.at_inputs, &mut assembly.at_aux, assembly.num_constraints); - + assembly.num_constraints += 1; } @@ -295,29 +252,31 @@ pub fn generate_parameters( // 1 is actually input number 0 (identity) for i in 1..assembly.num_inputs { - assembly.enforce(|| "", - |lc| lc + Variable(Index::Input(i)), - |lc| lc + Variable(Index::Input(0)), - |lc| lc + Variable(Index::Input(i)), - ); + assembly.enforce(|| "", |lc| lc + Variable(Index::Input(i)), |lc| lc + Variable(Index::Input(0)), |lc| lc + Variable(Index::Input(i))); } // check that each input generates 2 constraints - assert_eq!(num_inputs_without_identity * 2 + - num_constraints_before_inputs_constraining, - assembly.num_constraints, - "each input must produce two extra constraints"); + assert_eq!( + num_inputs_without_identity * 2 + num_constraints_before_inputs_constraining, + assembly.num_constraints, + "each input must produce two extra constraints" + ); // and that it creates one extra variable - assert_eq!(num_inputs_without_identity + - num_aux_before_inputs_constraining, - assembly.num_aux, - "each input must generate an extra variable"); + assert_eq!( + num_inputs_without_identity + num_aux_before_inputs_constraining, + assembly.num_aux, + "each input must generate an extra variable" + ); - assert_eq!(assembly.num_inputs + assembly.num_r1cs_constraints + assembly.num_r1cs_aux, - assembly.num_inputs + assembly.num_aux, - "each constraint in principle adds one variable"); + assert_eq!( + assembly.num_inputs + assembly.num_r1cs_constraints + assembly.num_r1cs_aux, + assembly.num_inputs + assembly.num_aux, + "each constraint in principle adds one variable" + ); - if verbose {eprintln!("Constraint system size is {}", assembly.num_constraints)}; + if verbose { + eprintln!("Constraint system size is {}", assembly.num_constraints) + }; // Create bases for blind evaluation of polynomials at tau let powers_of_tau = vec![Scalar::(E::Fr::zero()); assembly.num_constraints]; let mut domain = EvaluationDomain::from_coeffs(powers_of_tau)?; @@ -325,9 +284,10 @@ pub fn generate_parameters( // Compute G1 window table let mut g1_wnaf = Wnaf::new(); let g1_wnaf = g1_wnaf.base(g1, { - 2*(assembly.num_inputs + assembly.num_r1cs_constraints + assembly.num_r1cs_aux) - + assembly.num_r1cs_constraints + assembly.num_r1cs_aux - + 2*(assembly.num_inputs + assembly.num_r1cs_constraints) + 2 * (assembly.num_inputs + assembly.num_r1cs_constraints + assembly.num_r1cs_aux) + + assembly.num_r1cs_constraints + + assembly.num_r1cs_aux + + 2 * (assembly.num_inputs + assembly.num_r1cs_constraints) }); // Compute gamma*G2 window table @@ -336,7 +296,7 @@ pub fn generate_parameters( let g2_wnaf = g2_wnaf.base(g2, { // B query assembly.num_inputs + assembly.num_aux - // alternatively expressed as + // alternatively expressed as // assembly.num_inputs + assembly.num_r1cs_constraints + assembly.num_r1cs_aux }); @@ -374,7 +334,9 @@ pub fn generate_parameters( let domain_length = domain.as_ref().len(); - if verbose {eprintln!("Domain length is {} ", domain_length)}; + if verbose { + eprintln!("Domain length is {} ", domain_length) + }; // G1^{gamma^2 * Z(t) * t^i} for 0 <= i < 2^m - 1 for 2^m domains let mut gamma2_z_t_g1 = vec![E::G1::zero(); domain.as_ref().len() - 1]; @@ -382,17 +344,18 @@ pub fn generate_parameters( { // Compute powers of tau - if verbose {eprintln!("computing powers of tau...")}; + if verbose { + eprintln!("computing powers of tau...") + }; let start = std::time::Instant::now(); { let domain = domain.as_mut(); worker.scope(domain.len(), |scope, chunk| { - for (i, subdomain) in domain.chunks_mut(chunk).enumerate() - { + for (i, subdomain) in domain.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut current_power = tau.pow(&[(i*chunk) as u64]); + let mut current_power = tau.pow(&[(i * chunk) as u64]); for p in subdomain { p.0 = current_power; @@ -402,28 +365,30 @@ pub fn generate_parameters( } }); } - if verbose {eprintln!("powers of tau stage 1 done in {} s", start.elapsed().as_millis() as f64 / 1000.0);}; + if verbose { + eprintln!("powers of tau stage 1 done in {} s", start.elapsed().as_millis() as f64 / 1000.0); + }; // z_at_tau = t(x) z_at_tau = domain.z(&tau); - + let mut gamma2_z_t = z_at_tau; gamma2_z_t.mul_assign(&gamma); gamma2_z_t.mul_assign(&gamma); - if verbose {eprintln!("computing the `G1^(gamma^2 * Z(t) * t^i)` query with multiple threads...")}; + if verbose { + eprintln!("computing the `G1^(gamma^2 * Z(t) * t^i)` query with multiple threads...") + }; let start = std::time::Instant::now(); // Compute the H query with multiple threads worker.scope(gamma2_z_t_g1.len(), |scope, chunk| { - for (gamma2_z_t_g1, p) in gamma2_z_t_g1.chunks_mut(chunk).zip(domain.as_ref().chunks(chunk)) - { + for (gamma2_z_t_g1, p) in gamma2_z_t_g1.chunks_mut(chunk).zip(domain.as_ref().chunks(chunk)) { let mut g1_wnaf = g1_wnaf.shared(); scope.spawn(move |_| { // Set values of the H query to g1^{(tau^i * t(tau)) / delta} - for (gamma2_z_t_g1, p) in gamma2_z_t_g1.iter_mut().zip(p.iter()) - { + for (gamma2_z_t_g1, p) in gamma2_z_t_g1.iter_mut().zip(p.iter()) { // Compute final exponent let mut exp = p.0; exp.mul_assign(&gamma2_z_t); @@ -437,7 +402,9 @@ pub fn generate_parameters( }); } }); - if verbose {eprintln!("computing the `G1^(gamma^2 * Z(t) * t^i)` query done in {} s", start.elapsed().as_millis() as f64 / 1000.0);}; + if verbose { + eprintln!("computing the `G1^(gamma^2 * Z(t) * t^i)` query done in {} s", start.elapsed().as_millis() as f64 / 1000.0); + }; } // G1^{gamma * A_i(t)} for 0 <= i <= num_variables @@ -474,8 +441,10 @@ pub fn generate_parameters( // G^{gamma^2 * Z(t) * t^i} for 0 <= i < 2^m - 1 for 2^m domains let mut gamma2_z_t = vec![E::G1::zero(); domain.as_ref().len() - 1]; - if verbose {eprintln!("using inverse FFT to convert to intepolation coefficients...")}; - + if verbose { + eprintln!("using inverse FFT to convert to intepolation coefficients...") + }; + let start = std::time::Instant::now(); // Use inverse FFT to convert to intepolation coefficients @@ -483,9 +452,13 @@ pub fn generate_parameters( let powers_of_tau = domain.into_coeffs(); // domain is now a set of scalars - if verbose {eprintln!("powers of tau evaluation in radix2 domain in {} s", start.elapsed().as_millis() as f64 / 1000.0)}; + if verbose { + eprintln!("powers of tau evaluation in radix2 domain in {} s", start.elapsed().as_millis() as f64 / 1000.0) + }; - if verbose {eprintln!("evaluating polynomials...")}; + if verbose { + eprintln!("evaluating polynomials...") + }; let start = std::time::Instant::now(); // overall strategy: @@ -524,10 +497,8 @@ pub fn generate_parameters( z_at_tau: &E::Fr, // Worker - worker: &Worker - ) - - { + worker: &Worker, + ) { // Sanity check assert_eq!(a_g1.len(), at.len()); assert_eq!(a_g1.len(), ct.len()); @@ -544,29 +515,20 @@ pub fn generate_parameters( // Evaluate polynomials in multiple threads worker.scope(a_g1.len(), |scope, chunk| { - for (((((a_g1, a_g2), c_1_g1), c_2_g1), at), ct) in a_g1.chunks_mut(chunk) - .zip(a_g2.chunks_mut(chunk)) - .zip(c_1_g1.chunks_mut(chunk)) - .zip(c_2_g1.chunks_mut(chunk)) - .zip(at.chunks(chunk)) - .zip(ct.chunks(chunk)) + for (((((a_g1, a_g2), c_1_g1), c_2_g1), at), ct) in a_g1 + .chunks_mut(chunk) + .zip(a_g2.chunks_mut(chunk)) + .zip(c_1_g1.chunks_mut(chunk)) + .zip(c_2_g1.chunks_mut(chunk)) + .zip(at.chunks(chunk)) + .zip(ct.chunks(chunk)) { let mut g1_wnaf = g1_wnaf.shared(); let mut g2_wnaf = g2_wnaf.shared(); scope.spawn(move |_| { - for (((((a_g1, a_g2), c_1_g1), c_2_g1), at), ct) in a_g1.iter_mut() - .zip(a_g2.iter_mut()) - .zip(c_1_g1.iter_mut()) - .zip(c_2_g1.iter_mut()) - .zip(at.iter()) - .zip(ct.iter()) - { - fn eval_at_tau( - powers_of_tau: &[Scalar], - p: &[(E::Fr, usize)] - ) -> E::Fr - { + for (((((a_g1, a_g2), c_1_g1), c_2_g1), at), ct) in a_g1.iter_mut().zip(a_g2.iter_mut()).zip(c_1_g1.iter_mut()).zip(c_2_g1.iter_mut()).zip(at.iter()).zip(ct.iter()) { + fn eval_at_tau(powers_of_tau: &[Scalar], p: &[(E::Fr, usize)]) -> E::Fr { let mut acc = E::Fr::zero(); for &(ref coeff, index) in p { @@ -616,7 +578,7 @@ pub fn generate_parameters( E::G1::batch_normalization(c_1_g1); E::G1::batch_normalization(c_2_g1); }); - }; + } }); } @@ -635,7 +597,7 @@ pub fn generate_parameters( &beta, &gamma, &z_at_tau, - &worker + &worker, ); // Evaluate for inputs. @@ -653,14 +615,16 @@ pub fn generate_parameters( &beta, &gamma, &z_at_tau, - &worker + &worker, ); // for _ in 0..assembly.num_inputs { // c_1_g1.remove(0); // } - if verbose {eprintln!("evaluating polynomials done in {} s", start.elapsed().as_millis() as f64 / 1000.0);}; + if verbose { + eprintln!("evaluating polynomials done in {} s", start.elapsed().as_millis() as f64 / 1000.0); + }; // // Don't allow any elements be unconstrained, so that // // the L query is always fully dense. diff --git a/crates/bellman/src/gm17/mod.rs b/crates/bellman/src/gm17/mod.rs index dc500d7..82aa402 100644 --- a/crates/bellman/src/gm17/mod.rs +++ b/crates/bellman/src/gm17/mod.rs @@ -1,17 +1,11 @@ -use crate::pairing::{ - Engine, - CurveAffine, - EncodedPoint -}; +use crate::pairing::{CurveAffine, EncodedPoint, Engine}; -use crate::{ - SynthesisError -}; +use crate::SynthesisError; use crate::source::SourceBuilder; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use std::io::{self, Read, Write}; use std::sync::Arc; -use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt}; #[cfg(test)] mod tests; @@ -28,23 +22,17 @@ pub use self::generator::*; pub struct Proof { pub a: E::G1Affine, pub b: E::G2Affine, - pub c: E::G1Affine + pub c: E::G1Affine, } impl PartialEq for Proof { fn eq(&self, other: &Self) -> bool { - self.a == other.a && - self.b == other.b && - self.c == other.c + self.a == other.a && self.b == other.b && self.c == other.c } } impl Proof { - pub fn write( - &self, - mut writer: W - ) -> io::Result<()> - { + pub fn write(&self, mut writer: W) -> io::Result<()> { writer.write_all(self.a.into_compressed().as_ref())?; writer.write_all(self.b.into_compressed().as_ref())?; writer.write_all(self.c.into_compressed().as_ref())?; @@ -52,48 +40,38 @@ impl Proof { Ok(()) } - pub fn read( - mut reader: R - ) -> io::Result - { + pub fn read(mut reader: R) -> io::Result { let mut g1_repr = ::Compressed::empty(); let mut g2_repr = ::Compressed::empty(); reader.read_exact(g1_repr.as_mut())?; - let a = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let a = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; reader.read_exact(g2_repr.as_mut())?; - let b = g2_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let b = g2_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; reader.read_exact(g1_repr.as_mut())?; - let c = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; - - Ok(Proof { - a: a, - b: b, - c: c - }) + let c = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; + + Ok(Proof { a: a, b: b, c: c }) } } @@ -118,26 +96,17 @@ pub struct VerifyingKey { // for all public inputs. Because all public inputs have a dummy constraint, // this is the same size as the number of inputs, and never contains points // at infinity. - pub ic: Vec + pub ic: Vec, } impl PartialEq for VerifyingKey { fn eq(&self, other: &Self) -> bool { - self.h_g2 == other.h_g2 && - self.alpha_g1 == other.alpha_g1 && - self.beta_g2 == other.beta_g2 && - self.gamma_g1 == other.gamma_g1 && - self.gamma_g2 == other.gamma_g2 && - self.ic == other.ic + self.h_g2 == other.h_g2 && self.alpha_g1 == other.alpha_g1 && self.beta_g2 == other.beta_g2 && self.gamma_g1 == other.gamma_g1 && self.gamma_g2 == other.gamma_g2 && self.ic == other.ic } } impl VerifyingKey { - pub fn write( - &self, - mut writer: W - ) -> io::Result<()> - { + pub fn write(&self, mut writer: W) -> io::Result<()> { writer.write_all(self.h_g2.into_uncompressed().as_ref())?; writer.write_all(self.alpha_g1.into_uncompressed().as_ref())?; writer.write_all(self.beta_g2.into_uncompressed().as_ref())?; @@ -151,10 +120,7 @@ impl VerifyingKey { Ok(()) } - pub fn read( - mut reader: R - ) -> io::Result - { + pub fn read(mut reader: R) -> io::Result { let mut g1_repr = ::Uncompressed::empty(); let mut g2_repr = ::Uncompressed::empty(); @@ -179,14 +145,13 @@ impl VerifyingKey { for _ in 0..ic_len { reader.read_exact(g1_repr.as_mut())?; - let g1 = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let g1 = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; ic.push(g1); } @@ -197,7 +162,7 @@ impl VerifyingKey { beta_g2: beta_g2, gamma_g1: gamma_g1, gamma_g2: gamma_g2, - ic: ic + ic: ic, }) } } @@ -222,16 +187,16 @@ pub struct Parameters { impl PartialEq for Parameters { fn eq(&self, other: &Self) -> bool { - self.vk == other.vk && - self.a_g1 == other.a_g1 && - self.a_g2 == other.a_g2 && - self.c_1_g1 == other.c_1_g1 && - self.c_2_g1 == other.c_2_g1 && - self.gamma_z == other.gamma_z && - self.gamma_z_g2 == other.gamma_z_g2 && - self.ab_gamma_z_g1 == other.ab_gamma_z_g1 && - self.gamma2_z2_g1 == other.gamma2_z2_g1 && - self.gamma2_z_t == other.gamma2_z_t + self.vk == other.vk + && self.a_g1 == other.a_g1 + && self.a_g2 == other.a_g2 + && self.c_1_g1 == other.c_1_g1 + && self.c_2_g1 == other.c_2_g1 + && self.gamma_z == other.gamma_z + && self.gamma_z_g2 == other.gamma_z_g2 + && self.ab_gamma_z_g1 == other.ab_gamma_z_g1 + && self.gamma2_z2_g1 == other.gamma2_z2_g1 + && self.gamma2_z_t == other.gamma2_z_t } } @@ -560,4 +525,4 @@ impl PartialEq for Parameters { // assert!(!verify_proof(&pvk, &proof, &[a]).unwrap()); // } // } -// } \ No newline at end of file +// } diff --git a/crates/bellman/src/gm17/tests/mod.rs b/crates/bellman/src/gm17/tests/mod.rs index 697065a..2e8e492 100644 --- a/crates/bellman/src/gm17/tests/mod.rs +++ b/crates/bellman/src/gm17/tests/mod.rs @@ -1,22 +1,13 @@ -use crate::pairing::{ - Engine -}; +use crate::pairing::Engine; -use crate::pairing::ff:: { - Field, - PrimeField, -}; +use crate::pairing::ff::{Field, PrimeField}; use super::super::tests::dummy_engine::*; use super::super::tests::XORDemo; use std::marker::PhantomData; -use crate::{ - Circuit, - ConstraintSystem, - SynthesisError -}; +use crate::{Circuit, ConstraintSystem, SynthesisError}; use super::{ generate_parameters, @@ -39,18 +30,10 @@ fn test_gm17_xordemo() { let c = XORDemo:: { a: None, b: None, - _marker: PhantomData + _marker: PhantomData, }; - generate_parameters( - c, - g1, - g2, - alpha, - beta, - gamma, - tau - ).unwrap() + generate_parameters(c, g1, g2, alpha, beta, gamma, tau).unwrap() }; // // This will synthesize the constraint system: diff --git a/crates/bellman/src/groth16/generator.rs b/crates/bellman/src/groth16/generator.rs index a1b6dff..81eb667 100644 --- a/crates/bellman/src/groth16/generator.rs +++ b/crates/bellman/src/groth16/generator.rs @@ -4,48 +4,25 @@ use rand::Rng; use std::sync::Arc; -use crate::pairing::{ - Engine, - Wnaf, - CurveProjective, - CurveAffine -}; - -use crate::pairing::ff::{ - PrimeField, - Field -}; - -use super::{ - Parameters, - VerifyingKey -}; - -use crate::{ - SynthesisError, - Circuit, - ConstraintSystem, - LinearCombination, - Variable, - Index -}; - -use crate::domain::{ - EvaluationDomain, - Scalar -}; - -use crate::worker::{ - Worker -}; +use crate::pairing::{CurveAffine, CurveProjective, Engine, Wnaf}; + +use crate::pairing::ff::{Field, PrimeField}; + +use super::{Parameters, VerifyingKey}; + +use crate::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; + +use crate::domain::{EvaluationDomain, Scalar}; + +use crate::worker::Worker; /// Generates a random common reference string for /// a circuit. -pub fn generate_random_parameters( - circuit: C, - rng: &mut R -) -> Result, SynthesisError> - where E: Engine, C: Circuit, R: Rng +pub fn generate_random_parameters(circuit: C, rng: &mut R) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, + R: Rng, { let g1 = rng.gen(); let g2 = rng.gen(); @@ -55,16 +32,7 @@ pub fn generate_random_parameters( let delta = rng.gen(); let tau = rng.gen(); - generate_parameters::( - circuit, - g1, - g2, - alpha, - beta, - gamma, - delta, - tau - ) + generate_parameters::(circuit, g1, g2, alpha, beta, gamma, delta, tau) } /// This is our assembly structure that we'll use to synthesize the @@ -78,18 +46,17 @@ struct KeypairAssembly { ct_inputs: Vec>, at_aux: Vec>, bt_aux: Vec>, - ct_aux: Vec> + ct_aux: Vec>, } impl ConstraintSystem for KeypairAssembly { type Root = Self; - fn alloc( - &mut self, - _: A, - _: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc(&mut self, _: A, _: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { // There is no assignment, so we don't even invoke the // function for obtaining one. @@ -104,12 +71,11 @@ impl ConstraintSystem for KeypairAssembly { Ok(Variable(Index::Aux(index))) } - fn alloc_input( - &mut self, - _: A, - _: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc_input(&mut self, _: A, _: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { // There is no assignment, so we don't even invoke the // function for obtaining one. @@ -124,29 +90,19 @@ impl ConstraintSystem for KeypairAssembly { Ok(Variable(Index::Input(index))) } - fn enforce( - &mut self, - _: A, - a: LA, - b: LB, - c: LC - ) - where A: FnOnce() -> AR, AR: Into, - LA: FnOnce(LinearCombination) -> LinearCombination, - LB: FnOnce(LinearCombination) -> LinearCombination, - LC: FnOnce(LinearCombination) -> LinearCombination + fn enforce(&mut self, _: A, a: LA, b: LB, c: LC) + where + A: FnOnce() -> AR, + AR: Into, + LA: FnOnce(LinearCombination) -> LinearCombination, + LB: FnOnce(LinearCombination) -> LinearCombination, + LC: FnOnce(LinearCombination) -> LinearCombination, { - fn eval( - l: LinearCombination, - inputs: &mut [Vec<(E::Fr, usize)>], - aux: &mut [Vec<(E::Fr, usize)>], - this_constraint: usize - ) - { + fn eval(l: LinearCombination, inputs: &mut [Vec<(E::Fr, usize)>], aux: &mut [Vec<(E::Fr, usize)>], this_constraint: usize) { for (index, coeff) in l.0 { match index { Variable(Index::Input(id)) => inputs[id].push((coeff, this_constraint)), - Variable(Index::Aux(id)) => aux[id].push((coeff, this_constraint)) + Variable(Index::Aux(id)) => aux[id].push((coeff, this_constraint)), } } } @@ -159,13 +115,14 @@ impl ConstraintSystem for KeypairAssembly { } fn push_namespace(&mut self, _: N) - where NR: Into, N: FnOnce() -> NR + where + NR: Into, + N: FnOnce() -> NR, { // Do nothing; we don't care about namespaces in this context. } - fn pop_namespace(&mut self) - { + fn pop_namespace(&mut self) { // Do nothing; we don't care about namespaces in this context. } @@ -175,17 +132,10 @@ impl ConstraintSystem for KeypairAssembly { } /// Create parameters for a circuit, given some toxic waste. -pub fn generate_parameters( - circuit: C, - g1: E::G1, - g2: E::G2, - alpha: E::Fr, - beta: E::Fr, - gamma: E::Fr, - delta: E::Fr, - tau: E::Fr -) -> Result, SynthesisError> - where E: Engine, C: Circuit +pub fn generate_parameters(circuit: C, g1: E::G1, g2: E::G2, alpha: E::Fr, beta: E::Fr, gamma: E::Fr, delta: E::Fr, tau: E::Fr) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, { let mut assembly = KeypairAssembly { num_inputs: 0, @@ -196,7 +146,7 @@ pub fn generate_parameters( ct_inputs: vec![], at_aux: vec![], bt_aux: vec![], - ct_aux: vec![] + ct_aux: vec![], }; // Allocate the "one" input variable @@ -208,11 +158,7 @@ pub fn generate_parameters( // Input constraints to ensure full density of IC query // x * 0 = 0 for i in 0..assembly.num_inputs { - assembly.enforce(|| "", - |lc| lc + Variable(Index::Input(i)), - |lc| lc, - |lc| lc, - ); + assembly.enforce(|| "", |lc| lc + Variable(Index::Input(i)), |lc| lc, |lc| lc); } elog_verbose!("Making {} powers of tau", assembly.num_constraints); @@ -255,10 +201,9 @@ pub fn generate_parameters( { let powers_of_tau = powers_of_tau.as_mut(); worker.scope(powers_of_tau.len(), |scope, chunk| { - for (i, powers_of_tau) in powers_of_tau.chunks_mut(chunk).enumerate() - { + for (i, powers_of_tau) in powers_of_tau.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut current_tau_power = tau.pow(&[(i*chunk) as u64]); + let mut current_tau_power = tau.pow(&[(i * chunk) as u64]); for p in powers_of_tau { p.0 = current_tau_power; @@ -280,13 +225,11 @@ pub fn generate_parameters( // Compute the H query with multiple threads worker.scope(h.len(), |scope, chunk| { - for (h, p) in h.chunks_mut(chunk).zip(powers_of_tau.as_ref().chunks(chunk)) - { + for (h, p) in h.chunks_mut(chunk).zip(powers_of_tau.as_ref().chunks(chunk)) { let mut g1_wnaf = g1_wnaf.shared(); scope.spawn(move |_| { // Set values of the H query to g1^{(tau^i * t(tau)) / delta} - for (h, p) in h.iter_mut().zip(p.iter()) - { + for (h, p) in h.iter_mut().zip(p.iter()) { // Compute final exponent let mut exp = p.0; exp.mul_assign(&coeff); @@ -319,7 +262,7 @@ pub fn generate_parameters( let mut l = vec![E::G1::zero(); assembly.num_aux]; elog_verbose!("evaluating polynomials..."); - + let _stopwatch = Stopwatch::new(); fn eval( @@ -349,10 +292,8 @@ pub fn generate_parameters( beta: &E::Fr, // Worker - worker: &Worker - ) - - { + worker: &Worker, + ) { // Sanity check assert_eq!(a.len(), at.len()); assert_eq!(a.len(), bt.len()); @@ -363,31 +304,21 @@ pub fn generate_parameters( // Evaluate polynomials in multiple threads worker.scope(a.len(), |scope, chunk| { - for ((((((a, b_g1), b_g2), ext), at), bt), ct) in a.chunks_mut(chunk) - .zip(b_g1.chunks_mut(chunk)) - .zip(b_g2.chunks_mut(chunk)) - .zip(ext.chunks_mut(chunk)) - .zip(at.chunks(chunk)) - .zip(bt.chunks(chunk)) - .zip(ct.chunks(chunk)) + for ((((((a, b_g1), b_g2), ext), at), bt), ct) in a + .chunks_mut(chunk) + .zip(b_g1.chunks_mut(chunk)) + .zip(b_g2.chunks_mut(chunk)) + .zip(ext.chunks_mut(chunk)) + .zip(at.chunks(chunk)) + .zip(bt.chunks(chunk)) + .zip(ct.chunks(chunk)) { let mut g1_wnaf = g1_wnaf.shared(); let mut g2_wnaf = g2_wnaf.shared(); scope.spawn(move |_| { - for ((((((a, b_g1), b_g2), ext), at), bt), ct) in a.iter_mut() - .zip(b_g1.iter_mut()) - .zip(b_g2.iter_mut()) - .zip(ext.iter_mut()) - .zip(at.iter()) - .zip(bt.iter()) - .zip(ct.iter()) - { - fn eval_at_tau( - powers_of_tau: &[Scalar], - p: &[(E::Fr, usize)] - ) -> E::Fr - { + for ((((((a, b_g1), b_g2), ext), at), bt), ct) in a.iter_mut().zip(b_g1.iter_mut()).zip(b_g2.iter_mut()).zip(ext.iter_mut()).zip(at.iter()).zip(bt.iter()).zip(ct.iter()) { + fn eval_at_tau(powers_of_tau: &[Scalar], p: &[(E::Fr, usize)]) -> E::Fr { let mut acc = E::Fr::zero(); for &(ref coeff, index) in p { @@ -433,7 +364,7 @@ pub fn generate_parameters( E::G2::batch_normalization(b_g2); E::G1::batch_normalization(ext); }); - }; + } }); } @@ -452,7 +383,7 @@ pub fn generate_parameters( &gamma_inverse, &alpha, &beta, - &worker + &worker, ); // Evaluate for auxillary variables. @@ -470,7 +401,7 @@ pub fn generate_parameters( &delta_inverse, &alpha, &beta, - &worker + &worker, ); elog_verbose!("evaluating polynomials done in {} s", _stopwatch.elapsed()); @@ -493,7 +424,7 @@ pub fn generate_parameters( gamma_g2: g2.mul(gamma).into_affine(), delta_g1: g1.mul(delta).into_affine(), delta_g2: g2.mul(delta).into_affine(), - ic: ic.into_iter().map(|e| e.into_affine()).collect() + ic: ic.into_iter().map(|e| e.into_affine()).collect(), }; log!("Has generated {} points", a.len()); @@ -506,6 +437,6 @@ pub fn generate_parameters( // Filter points at infinity away from A/B queries a: Arc::new(a.into_iter().filter(|e| !e.is_zero()).map(|e| e.into_affine()).collect()), b_g1: Arc::new(b_g1.into_iter().filter(|e| !e.is_zero()).map(|e| e.into_affine()).collect()), - b_g2: Arc::new(b_g2.into_iter().filter(|e| !e.is_zero()).map(|e| e.into_affine()).collect()) + b_g2: Arc::new(b_g2.into_iter().filter(|e| !e.is_zero()).map(|e| e.into_affine()).collect()), }) } diff --git a/crates/bellman/src/groth16/mod.rs b/crates/bellman/src/groth16/mod.rs index 7abdc24..162ab42 100644 --- a/crates/bellman/src/groth16/mod.rs +++ b/crates/bellman/src/groth16/mod.rs @@ -1,17 +1,11 @@ -use crate::pairing::{ - Engine, - CurveAffine, - EncodedPoint -}; +use crate::pairing::{CurveAffine, EncodedPoint, Engine}; -use crate::{ - SynthesisError -}; +use crate::SynthesisError; use crate::source::SourceBuilder; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use std::io::{self, Read, Write}; use std::sync::Arc; -use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt}; #[cfg(test)] mod tests; @@ -28,23 +22,17 @@ pub use self::verifier::*; pub struct Proof { pub a: E::G1Affine, pub b: E::G2Affine, - pub c: E::G1Affine + pub c: E::G1Affine, } impl PartialEq for Proof { fn eq(&self, other: &Self) -> bool { - self.a == other.a && - self.b == other.b && - self.c == other.c + self.a == other.a && self.b == other.b && self.c == other.c } } impl Proof { - pub fn write( - &self, - mut writer: W - ) -> io::Result<()> - { + pub fn write(&self, mut writer: W) -> io::Result<()> { writer.write_all(self.a.into_compressed().as_ref())?; writer.write_all(self.b.into_compressed().as_ref())?; writer.write_all(self.c.into_compressed().as_ref())?; @@ -52,48 +40,38 @@ impl Proof { Ok(()) } - pub fn read( - mut reader: R - ) -> io::Result - { + pub fn read(mut reader: R) -> io::Result { let mut g1_repr = ::Compressed::empty(); let mut g2_repr = ::Compressed::empty(); reader.read_exact(g1_repr.as_mut())?; - let a = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let a = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; reader.read_exact(g2_repr.as_mut())?; - let b = g2_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let b = g2_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; reader.read_exact(g1_repr.as_mut())?; - let c = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let c = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; - Ok(Proof { - a: a, - b: b, - c: c - }) + Ok(Proof { a: a, b: b, c: c }) } } @@ -122,27 +100,23 @@ pub struct VerifyingKey { // for all public inputs. Because all public inputs have a dummy constraint, // this is the same size as the number of inputs, and never contains points // at infinity. - pub ic: Vec + pub ic: Vec, } impl PartialEq for VerifyingKey { fn eq(&self, other: &Self) -> bool { - self.alpha_g1 == other.alpha_g1 && - self.beta_g1 == other.beta_g1 && - self.beta_g2 == other.beta_g2 && - self.gamma_g2 == other.gamma_g2 && - self.delta_g1 == other.delta_g1 && - self.delta_g2 == other.delta_g2 && - self.ic == other.ic + self.alpha_g1 == other.alpha_g1 + && self.beta_g1 == other.beta_g1 + && self.beta_g2 == other.beta_g2 + && self.gamma_g2 == other.gamma_g2 + && self.delta_g1 == other.delta_g1 + && self.delta_g2 == other.delta_g2 + && self.ic == other.ic } } impl VerifyingKey { - pub fn write( - &self, - mut writer: W - ) -> io::Result<()> - { + pub fn write(&self, mut writer: W) -> io::Result<()> { writer.write_all(self.alpha_g1.into_uncompressed().as_ref())?; writer.write_all(self.beta_g1.into_uncompressed().as_ref())?; writer.write_all(self.beta_g2.into_uncompressed().as_ref())?; @@ -157,10 +131,7 @@ impl VerifyingKey { Ok(()) } - pub fn read( - mut reader: R - ) -> io::Result - { + pub fn read(mut reader: R) -> io::Result { let mut g1_repr = ::Uncompressed::empty(); let mut g2_repr = ::Uncompressed::empty(); @@ -188,14 +159,13 @@ impl VerifyingKey { for _ in 0..ic_len { reader.read_exact(g1_repr.as_mut())?; - let g1 = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let g1 = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; ic.push(g1); } @@ -207,7 +177,7 @@ impl VerifyingKey { gamma_g2: gamma_g2, delta_g1: delta_g1, delta_g2: delta_g2, - ic: ic + ic: ic, }) } } @@ -216,7 +186,7 @@ impl VerifyingKey { pub struct Parameters { pub vk: VerifyingKey, - // Elements of the form ((tau^i * t(tau)) / delta) for i between 0 and + // Elements of the form ((tau^i * t(tau)) / delta) for i between 0 and // m-2 inclusive. Never contains points at infinity. pub h: Arc>, @@ -234,26 +204,17 @@ pub struct Parameters { // G1 and G2 for C/B queries, respectively. Never contains points at // infinity for the same reason as the "A" polynomials. pub b_g1: Arc>, - pub b_g2: Arc> + pub b_g2: Arc>, } impl PartialEq for Parameters { fn eq(&self, other: &Self) -> bool { - self.vk == other.vk && - self.h == other.h && - self.l == other.l && - self.a == other.a && - self.b_g1 == other.b_g1 && - self.b_g2 == other.b_g2 + self.vk == other.vk && self.h == other.h && self.l == other.l && self.a == other.a && self.b_g1 == other.b_g1 && self.b_g2 == other.b_g2 } } impl Parameters { - pub fn write( - &self, - mut writer: W - ) -> io::Result<()> - { + pub fn write(&self, mut writer: W) -> io::Result<()> { self.vk.write(&mut writer)?; writer.write_u32::(self.h.len() as u32)?; @@ -284,47 +245,35 @@ impl Parameters { Ok(()) } - pub fn read( - mut reader: R, - checked: bool - ) -> io::Result - { + pub fn read(mut reader: R, checked: bool) -> io::Result { let read_g1 = |reader: &mut R| -> io::Result { let mut repr = ::Uncompressed::empty(); reader.read_exact(repr.as_mut())?; - if checked { - repr - .into_affine() - } else { - repr - .into_affine_unchecked() - } - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - }) + if checked { repr.into_affine() } else { repr.into_affine_unchecked() } + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + .and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + }) }; let read_g2 = |reader: &mut R| -> io::Result { let mut repr = ::Uncompressed::empty(); reader.read_exact(repr.as_mut())?; - if checked { - repr - .into_affine() - } else { - repr - .into_affine_unchecked() - } - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - }) + if checked { repr.into_affine() } else { repr.into_affine_unchecked() } + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + .and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + }) }; let vk = VerifyingKey::::read(&mut reader)?; @@ -376,7 +325,7 @@ impl Parameters { l: Arc::new(l), a: Arc::new(a), b_g1: Arc::new(b_g1), - b_g2: Arc::new(b_g2) + b_g2: Arc::new(b_g2), }) } } @@ -389,94 +338,46 @@ pub struct PreparedVerifyingKey { /// -delta in G2 neg_delta_g2: ::Prepared, /// Copy of IC from `VerifiyingKey`. - ic: Vec + ic: Vec, } pub trait ParameterSource { type G1Builder: SourceBuilder; type G2Builder: SourceBuilder; - fn get_vk( - &mut self, - num_ic: usize - ) -> Result, SynthesisError>; - fn get_h( - &mut self, - num_h: usize - ) -> Result; - fn get_l( - &mut self, - num_l: usize - ) -> Result; - fn get_a( - &mut self, - num_inputs: usize, - num_aux: usize - ) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError>; - fn get_b_g1( - &mut self, - num_inputs: usize, - num_aux: usize - ) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError>; - fn get_b_g2( - &mut self, - num_inputs: usize, - num_aux: usize - ) -> Result<(Self::G2Builder, Self::G2Builder), SynthesisError>; + fn get_vk(&mut self, num_ic: usize) -> Result, SynthesisError>; + fn get_h(&mut self, num_h: usize) -> Result; + fn get_l(&mut self, num_l: usize) -> Result; + fn get_a(&mut self, num_inputs: usize, num_aux: usize) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError>; + fn get_b_g1(&mut self, num_inputs: usize, num_aux: usize) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError>; + fn get_b_g2(&mut self, num_inputs: usize, num_aux: usize) -> Result<(Self::G2Builder, Self::G2Builder), SynthesisError>; } impl<'a, E: Engine> ParameterSource for &'a Parameters { type G1Builder = (Arc>, usize); type G2Builder = (Arc>, usize); - fn get_vk( - &mut self, - _: usize - ) -> Result, SynthesisError> - { + fn get_vk(&mut self, _: usize) -> Result, SynthesisError> { Ok(self.vk.clone()) } - fn get_h( - &mut self, - _: usize - ) -> Result - { + fn get_h(&mut self, _: usize) -> Result { Ok((self.h.clone(), 0)) } - fn get_l( - &mut self, - _: usize - ) -> Result - { + fn get_l(&mut self, _: usize) -> Result { Ok((self.l.clone(), 0)) } - fn get_a( - &mut self, - num_inputs: usize, - _: usize - ) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError> - { + fn get_a(&mut self, num_inputs: usize, _: usize) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError> { Ok(((self.a.clone(), 0), (self.a.clone(), num_inputs))) } - fn get_b_g1( - &mut self, - num_inputs: usize, - _: usize - ) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError> - { + fn get_b_g1(&mut self, num_inputs: usize, _: usize) -> Result<(Self::G1Builder, Self::G1Builder), SynthesisError> { Ok(((self.b_g1.clone(), 0), (self.b_g1.clone(), num_inputs))) } - fn get_b_g2( - &mut self, - num_inputs: usize, - _: usize - ) -> Result<(Self::G2Builder, Self::G2Builder), SynthesisError> - { + fn get_b_g2(&mut self, num_inputs: usize, _: usize) -> Result<(Self::G2Builder, Self::G2Builder), SynthesisError> { Ok(((self.b_g2.clone(), 0), (self.b_g2.clone(), num_inputs))) } } @@ -484,41 +385,35 @@ impl<'a, E: Engine> ParameterSource for &'a Parameters { #[cfg(test)] mod test_with_bls12_381 { use super::*; - use crate::{Circuit, SynthesisError, ConstraintSystem}; + use crate::{Circuit, ConstraintSystem, SynthesisError}; - use rand::{Rand, thread_rng}; - use crate::pairing::ff::{Field}; use crate::pairing::bls12_381::{Bls12, Fr}; + use crate::pairing::ff::Field; + use rand::{thread_rng, Rand}; #[test] fn serialization() { struct MySillyCircuit { a: Option, - b: Option + b: Option, } impl Circuit for MySillyCircuit { - fn synthesize>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError> - { + fn synthesize>(self, cs: &mut CS) -> Result<(), SynthesisError> { let a = cs.alloc(|| "a", || self.a.ok_or(SynthesisError::AssignmentMissing))?; let b = cs.alloc(|| "b", || self.b.ok_or(SynthesisError::AssignmentMissing))?; - let c = cs.alloc_input(|| "c", || { - let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?; - let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; + let c = cs.alloc_input( + || "c", + || { + let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?; + let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; - a.mul_assign(&b); - Ok(a) - })?; + a.mul_assign(&b); + Ok(a) + }, + )?; - cs.enforce( - || "a*b=c", - |lc| lc + a, - |lc| lc + b, - |lc| lc + c - ); + cs.enforce(|| "a*b=c", |lc| lc + a, |lc| lc + b, |lc| lc + c); Ok(()) } @@ -526,10 +421,7 @@ mod test_with_bls12_381 { let rng = &mut thread_rng(); - let params = generate_random_parameters::( - MySillyCircuit { a: None, b: None }, - rng - ).unwrap(); + let params = generate_random_parameters::(MySillyCircuit { a: None, b: None }, rng).unwrap(); { let mut v = vec![]; @@ -552,14 +444,7 @@ mod test_with_bls12_381 { let mut c = a; c.mul_assign(&b); - let proof = create_random_proof( - MySillyCircuit { - a: Some(a), - b: Some(b) - }, - ¶ms, - rng - ).unwrap(); + let proof = create_random_proof(MySillyCircuit { a: Some(a), b: Some(b) }, ¶ms, rng).unwrap(); let mut v = vec![]; proof.write(&mut v).unwrap(); @@ -573,4 +458,4 @@ mod test_with_bls12_381 { assert!(!verify_proof(&pvk, &proof, &[a]).unwrap()); } } -} \ No newline at end of file +} diff --git a/crates/bellman/src/groth16/prover.rs b/crates/bellman/src/groth16/prover.rs index be92e40..76919e4 100644 --- a/crates/bellman/src/groth16/prover.rs +++ b/crates/bellman/src/groth16/prover.rs @@ -4,55 +4,29 @@ use rand::Rng; use std::sync::Arc; -use crate::pairing::{ - Engine, - CurveProjective, - CurveAffine -}; - -use crate::pairing::ff::{ - PrimeField, - Field -}; - -use super::{ - ParameterSource, - Proof -}; - -use crate::{ - SynthesisError, - Circuit, - ConstraintSystem, - LinearCombination, - Variable, - Index -}; - -use crate::domain::{ - EvaluationDomain, - Scalar -}; - -use crate::source::{ - DensityTracker, - FullDensity -}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; + +use crate::pairing::ff::{Field, PrimeField}; + +use super::{ParameterSource, Proof}; + +use crate::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; + +use crate::domain::{EvaluationDomain, Scalar}; + +use crate::source::{DensityTracker, FullDensity}; use crate::multiexp::*; -use crate::worker::{ - Worker -}; +use crate::worker::Worker; fn eval( lc: &LinearCombination, mut input_density: Option<&mut DensityTracker>, mut aux_density: Option<&mut DensityTracker>, input_assignment: &[E::Fr], - aux_assignment: &[E::Fr] -) -> E::Fr -{ + aux_assignment: &[E::Fr], +) -> E::Fr { let mut acc = E::Fr::zero(); for &(index, coeff) in lc.0.iter() { @@ -64,7 +38,7 @@ fn eval( if let Some(ref mut v) = input_density { v.inc(i); } - }, + } Variable(Index::Aux(i)) => { tmp = aux_assignment[i]; if let Some(ref mut v) = aux_density { @@ -74,28 +48,22 @@ fn eval( } if coeff == E::Fr::one() { - acc.add_assign(&tmp); + acc.add_assign(&tmp); } else { - tmp.mul_assign(&coeff); - acc.add_assign(&tmp); + tmp.mul_assign(&coeff); + acc.add_assign(&tmp); } } acc } -pub(crate) fn field_elements_into_representations( - worker: &Worker, - scalars: Vec -) -> Result::Repr>, SynthesisError> -{ +pub(crate) fn field_elements_into_representations(worker: &Worker, scalars: Vec) -> Result::Repr>, SynthesisError> { let mut representations = vec![::Repr::default(); scalars.len()]; worker.scope(scalars.len(), |scope, chunk| { - for (scalar, repr) in scalars.chunks(chunk) - .zip(representations.chunks_mut(chunk)) { + for (scalar, repr) in scalars.chunks(chunk).zip(representations.chunks_mut(chunk)) { scope.spawn(move |_| { - for (scalar, repr) in scalar.iter() - .zip(repr.iter_mut()) { + for (scalar, repr) in scalar.iter().zip(repr.iter_mut()) { *repr = scalar.into_repr(); } }); @@ -105,18 +73,12 @@ pub(crate) fn field_elements_into_representations( Ok(representations) } -pub(crate) fn scalars_into_representations( - worker: &Worker, - scalars: Vec> -) -> Result::Repr>, SynthesisError> -{ +pub(crate) fn scalars_into_representations(worker: &Worker, scalars: Vec>) -> Result::Repr>, SynthesisError> { let mut representations = vec![::Repr::default(); scalars.len()]; worker.scope(scalars.len(), |scope, chunk| { - for (scalar, repr) in scalars.chunks(chunk) - .zip(representations.chunks_mut(chunk)) { + for (scalar, repr) in scalars.chunks(chunk).zip(representations.chunks_mut(chunk)) { scope.spawn(move |_| { - for (scalar, repr) in scalar.iter() - .zip(repr.iter_mut()) { + for (scalar, repr) in scalar.iter().zip(repr.iter_mut()) { *repr = scalar.0.into_repr(); } }); @@ -127,7 +89,7 @@ pub(crate) fn scalars_into_representations( } // This is a proving assignment with densities precalculated -pub struct PreparedProver{ +pub struct PreparedProver { assignment: ProvingAssignment, } @@ -145,13 +107,13 @@ struct ProvingAssignment { // Assignments of variables input_assignment: Vec, - aux_assignment: Vec + aux_assignment: Vec, } -pub fn prepare_prover( - circuit: C, -) -> Result, SynthesisError> - where E: Engine, C: Circuit +pub fn prepare_prover(circuit: C) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, { let mut prover = ProvingAssignment { a_aux_density: DensityTracker::new(), @@ -161,7 +123,7 @@ pub fn prepare_prover( b: vec![], c: vec![], input_assignment: vec![], - aux_assignment: vec![] + aux_assignment: vec![], }; prover.alloc_input(|| "", || Ok(E::Fr::one()))?; @@ -169,27 +131,18 @@ pub fn prepare_prover( circuit.synthesize(&mut prover)?; for i in 0..prover.input_assignment.len() { - prover.enforce(|| "", - |lc| lc + Variable(Index::Input(i)), - |lc| lc, - |lc| lc, - ); + prover.enforce(|| "", |lc| lc + Variable(Index::Input(i)), |lc| lc, |lc| lc); } - let prepared = PreparedProver { - assignment: prover - }; + let prepared = PreparedProver { assignment: prover }; - return Ok(prepared) + return Ok(prepared); } -impl PreparedProver { - pub fn create_random_proof>( - self, - params: P, - rng: &mut R - ) -> Result, SynthesisError> - where R: Rng +impl PreparedProver { + pub fn create_random_proof>(self, params: P, rng: &mut R) -> Result, SynthesisError> + where + R: Rng, { let r = rng.gen(); let s = rng.gen(); @@ -197,13 +150,7 @@ impl PreparedProver { self.create_proof(params, r, s) } - pub fn create_proof>( - self, - mut params: P, - r: E::Fr, - s: E::Fr - ) -> Result, SynthesisError> - { + pub fn create_proof>(self, mut params: P, r: E::Fr, s: E::Fr) -> Result, SynthesisError> { let prover = self.assignment; let worker = Worker::new(); @@ -257,9 +204,12 @@ impl PreparedProver { { let input_len = prover.input_assignment.len(); let aux_len = prover.aux_assignment.len(); - - elog_verbose!("H quey is densein G1,\nOther queriesare {} elements in G1 and {} elements in G2", - 2*(input_len + aux_len) + aux_len, input_len + aux_len); + + elog_verbose!( + "H quey is densein G1,\nOther queriesare {} elements in G1 and {} elements in G2", + 2 * (input_len + aux_len) + aux_len, + input_len + aux_len + ); } let input_assignment = Arc::new(field_elements_into_representations::(&worker, prover.input_assignment)?); @@ -294,7 +244,7 @@ impl PreparedProver { let b_g1_aux = multiexp(&worker, b_g1_aux_source, b_aux_density.clone(), aux_assignment.clone()); let (b_g2_inputs_source, b_g2_aux_source) = params.get_b_g2(b_input_density_total, b_aux_density_total)?; - + let b_g2_inputs = multiexp(&worker, b_g2_inputs_source, b_input_density, input_assignment); let b_g2_aux = multiexp(&worker, b_g2_aux_source, b_aux_density, aux_assignment); @@ -339,21 +289,19 @@ impl PreparedProver { Ok(Proof { a: g_a.into_affine(), b: g_b.into_affine(), - c: g_c.into_affine() + c: g_c.into_affine(), }) } } - impl ConstraintSystem for ProvingAssignment { type Root = Self; - fn alloc( - &mut self, - _: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc(&mut self, _: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { self.aux_assignment.push(f()?); self.a_aux_density.add_element(); @@ -362,12 +310,11 @@ impl ConstraintSystem for ProvingAssignment { Ok(Variable(Index::Aux(self.aux_assignment.len() - 1))) } - fn alloc_input( - &mut self, - _: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc_input(&mut self, _: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { self.input_assignment.push(f()?); self.b_input_density.add_element(); @@ -375,17 +322,13 @@ impl ConstraintSystem for ProvingAssignment { Ok(Variable(Index::Input(self.input_assignment.len() - 1))) } - fn enforce( - &mut self, - _: A, - a: LA, - b: LB, - c: LC - ) - where A: FnOnce() -> AR, AR: Into, - LA: FnOnce(LinearCombination) -> LinearCombination, - LB: FnOnce(LinearCombination) -> LinearCombination, - LC: FnOnce(LinearCombination) -> LinearCombination + fn enforce(&mut self, _: A, a: LA, b: LB, c: LC) + where + A: FnOnce() -> AR, + AR: Into, + LA: FnOnce(LinearCombination) -> LinearCombination, + LB: FnOnce(LinearCombination) -> LinearCombination, + LC: FnOnce(LinearCombination) -> LinearCombination, { let a = a(LinearCombination::zero()); let b = b(LinearCombination::zero()); @@ -399,14 +342,14 @@ impl ConstraintSystem for ProvingAssignment { None, Some(&mut self.a_aux_density), &self.input_assignment, - &self.aux_assignment + &self.aux_assignment, ))); self.b.push(Scalar(eval( &b, Some(&mut self.b_input_density), Some(&mut self.b_aux_density), &self.input_assignment, - &self.aux_assignment + &self.aux_assignment, ))); self.c.push(Scalar(eval( &c, @@ -417,18 +360,19 @@ impl ConstraintSystem for ProvingAssignment { None, None, &self.input_assignment, - &self.aux_assignment + &self.aux_assignment, ))); } fn push_namespace(&mut self, _: N) - where NR: Into, N: FnOnce() -> NR + where + NR: Into, + N: FnOnce() -> NR, { // Do nothing; we don't care about namespaces in this context. } - fn pop_namespace(&mut self) - { + fn pop_namespace(&mut self) { // Do nothing; we don't care about namespaces in this context. } @@ -437,12 +381,11 @@ impl ConstraintSystem for ProvingAssignment { } } -pub fn create_random_proof>( - circuit: C, - params: P, - rng: &mut R -) -> Result, SynthesisError> - where E: Engine, C: Circuit, R: Rng +pub fn create_random_proof>(circuit: C, params: P, rng: &mut R) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, + R: Rng, { let r = rng.gen(); let s = rng.gen(); @@ -450,13 +393,10 @@ pub fn create_random_proof>( create_proof::(circuit, params, r, s) } -pub fn create_proof>( - circuit: C, - params: P, - r: E::Fr, - s: E::Fr -) -> Result, SynthesisError> - where E: Engine, C: Circuit +pub fn create_proof>(circuit: C, params: P, r: E::Fr, s: E::Fr) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, { let prover = prepare_prover(circuit)?; diff --git a/crates/bellman/src/groth16/tests/mod.rs b/crates/bellman/src/groth16/tests/mod.rs index 307f813..cbdf864 100644 --- a/crates/bellman/src/groth16/tests/mod.rs +++ b/crates/bellman/src/groth16/tests/mod.rs @@ -1,29 +1,15 @@ -use crate::pairing::{ - Engine -}; +use crate::pairing::Engine; -use crate::pairing::ff:: { - Field, - PrimeField, -}; +use crate::pairing::ff::{Field, PrimeField}; use super::super::tests::dummy_engine::*; use super::super::tests::XORDemo; use std::marker::PhantomData; -use crate::{ - Circuit, - ConstraintSystem, - SynthesisError -}; +use crate::{Circuit, ConstraintSystem, SynthesisError}; -use super::{ - generate_parameters, - prepare_verifying_key, - create_proof, - verify_proof -}; +use super::{create_proof, generate_parameters, prepare_verifying_key, verify_proof}; #[test] fn test_xordemo() { @@ -39,19 +25,10 @@ fn test_xordemo() { let c = XORDemo:: { a: None, b: None, - _marker: PhantomData + _marker: PhantomData, }; - generate_parameters( - c, - g1, - g2, - alpha, - beta, - gamma, - delta, - tau - ).unwrap() + generate_parameters(c, g1, g2, alpha, beta, gamma, delta, tau).unwrap() }; // This will synthesize the constraint system: @@ -159,33 +136,19 @@ fn test_xordemo() { 59158 */ - let u_i = [59158, 48317, 21767, 10402].iter().map(|e| { - Fr::from_str(&format!("{}", e)).unwrap() - }).collect::>(); - let v_i = [0, 0, 60619, 30791].iter().map(|e| { - Fr::from_str(&format!("{}", e)).unwrap() - }).collect::>(); - let w_i = [0, 23320, 41193, 41193].iter().map(|e| { - Fr::from_str(&format!("{}", e)).unwrap() - }).collect::>(); - - for (u, a) in u_i.iter() - .zip(¶ms.a[..]) - { + let u_i = [59158, 48317, 21767, 10402].iter().map(|e| Fr::from_str(&format!("{}", e)).unwrap()).collect::>(); + let v_i = [0, 0, 60619, 30791].iter().map(|e| Fr::from_str(&format!("{}", e)).unwrap()).collect::>(); + let w_i = [0, 23320, 41193, 41193].iter().map(|e| Fr::from_str(&format!("{}", e)).unwrap()).collect::>(); + + for (u, a) in u_i.iter().zip(¶ms.a[..]) { assert_eq!(u, a); } - for (v, b) in v_i.iter() - .filter(|&&e| e != Fr::zero()) - .zip(¶ms.b_g1[..]) - { + for (v, b) in v_i.iter().filter(|&&e| e != Fr::zero()).zip(¶ms.b_g1[..]) { assert_eq!(v, b); } - for (v, b) in v_i.iter() - .filter(|&&e| e != Fr::zero()) - .zip(¶ms.b_g2[..]) - { + for (v, b) in v_i.iter().filter(|&&e| e != Fr::zero()).zip(¶ms.b_g2[..]) { assert_eq!(v, b); } @@ -229,15 +192,10 @@ fn test_xordemo() { let c = XORDemo { a: Some(true), b: Some(false), - _marker: PhantomData + _marker: PhantomData, }; - create_proof( - c, - ¶ms, - r, - s - ).unwrap() + create_proof(c, ¶ms, r, s).unwrap() }; // A(x) = @@ -253,7 +211,7 @@ fn test_xordemo() { expected_a.add_assign(&u_i[0]); // a_0 = 1 expected_a.add_assign(&u_i[1]); // a_1 = 1 expected_a.add_assign(&u_i[2]); // a_2 = 1 - // a_3 = 0 + // a_3 = 0 assert_eq!(proof.a, expected_a); } @@ -270,7 +228,7 @@ fn test_xordemo() { expected_b.add_assign(&v_i[0]); // a_0 = 1 expected_b.add_assign(&v_i[1]); // a_1 = 1 expected_b.add_assign(&v_i[2]); // a_2 = 1 - // a_3 = 0 + // a_3 = 0 assert_eq!(proof.b, expected_b); } @@ -322,9 +280,5 @@ fn test_xordemo() { assert_eq!(expected_c, proof.c); } - assert!(verify_proof( - &pvk, - &proof, - &[Fr::one()] - ).unwrap()); + assert!(verify_proof(&pvk, &proof, &[Fr::one()]).unwrap()); } diff --git a/crates/bellman/src/groth16/verifier.rs b/crates/bellman/src/groth16/verifier.rs index eef3b88..290c8ff 100644 --- a/crates/bellman/src/groth16/verifier.rs +++ b/crates/bellman/src/groth16/verifier.rs @@ -1,25 +1,12 @@ -use crate::pairing::{ - Engine, - CurveProjective, - CurveAffine -}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; -use crate::pairing::ff::{PrimeField}; +use crate::pairing::ff::PrimeField; -use super::{ - Proof, - VerifyingKey, - PreparedVerifyingKey -}; +use super::{PreparedVerifyingKey, Proof, VerifyingKey}; -use crate::{ - SynthesisError -}; +use crate::SynthesisError; -pub fn prepare_verifying_key( - vk: &VerifyingKey -) -> PreparedVerifyingKey -{ +pub fn prepare_verifying_key(vk: &VerifyingKey) -> PreparedVerifyingKey { let mut gamma = vk.gamma_g2; gamma.negate(); let mut delta = vk.delta_g2; @@ -29,16 +16,11 @@ pub fn prepare_verifying_key( alpha_g1_beta_g2: E::pairing(vk.alpha_g1, vk.beta_g2), neg_gamma_g2: gamma.prepare(), neg_delta_g2: delta.prepare(), - ic: vk.ic.clone() + ic: vk.ic.clone(), } } -pub fn verify_proof<'a, E: Engine>( - pvk: &'a PreparedVerifyingKey, - proof: &Proof, - public_inputs: &[E::Fr] -) -> Result -{ +pub fn verify_proof<'a, E: Engine>(pvk: &'a PreparedVerifyingKey, proof: &Proof, public_inputs: &[E::Fr]) -> Result { if (public_inputs.len() + 1) != pvk.ic.len() { return Err(SynthesisError::MalformedVerifyingKey); } @@ -57,11 +39,14 @@ pub fn verify_proof<'a, E: Engine>( // A * B + inputs * (-gamma) + C * (-delta) = alpha * beta // which allows us to do a single final exponentiation. - Ok(E::final_exponentiation( - &E::miller_loop([ + Ok(E::final_exponentiation(&E::miller_loop( + [ (&proof.a.prepare(), &proof.b.prepare()), (&acc.into_affine().prepare(), &pvk.neg_gamma_g2), - (&proof.c.prepare(), &pvk.neg_delta_g2) - ].iter()) - ).unwrap() == pvk.alpha_g1_beta_g2) + (&proof.c.prepare(), &pvk.neg_delta_g2), + ] + .iter(), + )) + .unwrap() + == pvk.alpha_g1_beta_g2) } diff --git a/crates/bellman/src/group.rs b/crates/bellman/src/group.rs index 8671d76..02014c8 100644 --- a/crates/bellman/src/group.rs +++ b/crates/bellman/src/group.rs @@ -1,16 +1,8 @@ -use crate::pairing::{ - Engine, - CurveProjective -}; +use crate::pairing::{CurveProjective, Engine}; -use crate::pairing::ff::{ - Field, - PrimeField -}; +use crate::pairing::ff::{Field, PrimeField}; -use super::{ - SynthesisError -}; +use super::SynthesisError; pub trait Group: Sized + Copy + Clone + Send + Sync { fn group_zero() -> Self; @@ -27,7 +19,7 @@ impl PartialEq for Point { } } -impl Copy for Point { } +impl Copy for Point {} impl Clone for Point { fn clone(&self) -> Point { @@ -58,7 +50,7 @@ impl PartialEq for Scalar { } } -impl Copy for Scalar { } +impl Copy for Scalar {} impl Clone for Scalar { fn clone(&self) -> Scalar { @@ -79,4 +71,4 @@ impl Group for Scalar { fn group_sub_assign(&mut self, other: &Self) { self.0.sub_assign(&other.0); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/kate_commitment/mod.rs b/crates/bellman/src/kate_commitment/mod.rs index 2277d9a..fcf2b85 100644 --- a/crates/bellman/src/kate_commitment/mod.rs +++ b/crates/bellman/src/kate_commitment/mod.rs @@ -1,10 +1,10 @@ -use crate::pairing::{Engine, CurveAffine, CurveProjective}; use crate::ff::{Field, PrimeField}; -use crate::worker::Worker; -use crate::plonk::polynomials::*; -use std::sync::Arc; use crate::multiexp; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; +use crate::plonk::polynomials::*; +use crate::worker::Worker; use crate::SynthesisError; +use std::sync::Arc; pub trait CrsType {} @@ -20,29 +20,24 @@ pub struct Crs { pub g1_bases: Arc>, pub g2_monomial_bases: Arc>, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } -use std::io::{Read, Write}; +use crate::byteorder::BigEndian; use crate::byteorder::ReadBytesExt; use crate::byteorder::WriteBytesExt; -use crate::byteorder::BigEndian; +use std::io::{Read, Write}; impl PartialEq for Crs { fn eq(&self, other: &Self) -> bool { - self.g1_bases == other.g1_bases - && self.g2_monomial_bases == other.g2_monomial_bases + self.g1_bases == other.g1_bases && self.g2_monomial_bases == other.g2_monomial_bases } } -impl Eq for Crs { } +impl Eq for Crs {} impl Crs { - pub fn write( - &self, - mut writer: W - ) -> std::io::Result<()> - { + pub fn write(&self, mut writer: W) -> std::io::Result<()> { writer.write_u64::(self.g1_bases.len() as u64)?; for g in &self.g1_bases[..] { writer.write_all(g.into_uncompressed().as_ref())?; @@ -56,10 +51,7 @@ impl Crs { Ok(()) } - pub fn read( - mut reader: R - ) -> std::io::Result - { + pub fn read(mut reader: R) -> std::io::Result { use crate::pairing::EncodedPoint; let mut g1_repr = ::Uncompressed::empty(); @@ -69,7 +61,7 @@ impl Crs { let mut g1_bases = Vec::with_capacity(num_g1 as usize); - for _ in 0..num_g1 { + for _ in 0..num_g1 { reader.read_exact(g1_repr.as_mut())?; let p = g1_repr.into_affine().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; g1_bases.push(p); @@ -80,7 +72,7 @@ impl Crs { let mut g2_bases = Vec::with_capacity(num_g2 as usize); - for _ in 0..num_g2 { + for _ in 0..num_g2 { reader.read_exact(g2_repr.as_mut())?; let p = g2_repr.into_affine().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; g2_bases.push(p); @@ -89,12 +81,12 @@ impl Crs { let new = Self { g1_bases: Arc::new(g1_bases), g2_monomial_bases: Arc::new(g2_bases), - - _marker: std::marker::PhantomData + + _marker: std::marker::PhantomData, }; - Ok(new) - } + Ok(new) + } } impl Crs { @@ -107,8 +99,7 @@ impl Crs { Self { g1_bases: Arc::new(g1), g2_monomial_bases: Arc::new(g2), - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } @@ -118,22 +109,21 @@ impl Crs { let mut g2 = vec![E::G2Affine::one(); 2]; - use crate::group::Scalar; use crate::domain::EvaluationDomain; + use crate::group::Scalar; use crate::pairing::Wnaf; let mut coeffs = vec![Scalar::(E::Fr::one()); size]; - + { let gen = E::Fr::from_str("42").unwrap(); g2[1] = g2[1].mul(gen.into_repr()).into_affine(); worker.scope(coeffs.len(), |scope, chunk| { - for (i, p) in coeffs.chunks_mut(chunk).enumerate() - { + for (i, p) in coeffs.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut current_p = gen.pow(&[(i*chunk) as u64]); + let mut current_p = gen.pow(&[(i * chunk) as u64]); for p in p.iter_mut() { p.0 = current_p; @@ -150,12 +140,10 @@ impl Crs { let mut g1 = vec![E::G1Affine::zero().into_projective(); size]; worker.scope(g1.len(), |scope, chunk| { - for (g1, p) in g1.chunks_mut(chunk).zip(coeffs.chunks(chunk)) - { + for (g1, p) in g1.chunks_mut(chunk).zip(coeffs.chunks(chunk)) { let mut g1_wnaf = g1_wnaf.shared(); scope.spawn(move |_| { - for (g1, p) in g1.iter_mut().zip(p.iter()) - { + for (g1, p) in g1.iter_mut().zip(p.iter()) { // Compute final exponent let exp = p.0; @@ -174,8 +162,7 @@ impl Crs { Self { g1_bases: Arc::new(g1), g2_monomial_bases: Arc::new(g2), - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } } @@ -191,18 +178,17 @@ impl Crs { Self { g1_bases: Arc::new(g1), g2_monomial_bases: Arc::new(g2), - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } - + pub fn crs_42(size: usize, worker: &Worker) -> Self { let tmp = Crs::::crs_42(size, &worker); Self::from_powers(&tmp, size, &worker) } - pub fn from_powers(powers: &Crs::, size: usize, worker: &Worker) -> Self { + pub fn from_powers(powers: &Crs, size: usize, worker: &Worker) -> Self { assert!(size.is_power_of_two()); assert!(size <= powers.g1_bases.len()); @@ -211,16 +197,15 @@ impl Crs { let g1 = g1.into_iter().map(|el| Point(el.into_projective())).collect(); - use crate::group::Point; use crate::domain::EvaluationDomain; + use crate::group::Point; let mut g1 = EvaluationDomain::from_coeffs(g1).expect("must fit into the domain"); g1.transform_powers_of_tau_into_lagrange_basis(&worker); let mut g1: Vec<_> = g1.into_coeffs().into_iter().map(|el| el.0).collect(); worker.scope(g1.len(), |scope, chunk| { - for g1 in g1.chunks_mut(chunk) - { + for g1 in g1.chunks_mut(chunk) { scope.spawn(move |_| { // Batch normalize E::G1::batch_normalization(g1); @@ -233,8 +218,7 @@ impl Crs { Self { g1_bases: Arc::new(g1), g2_monomial_bases: Arc::new(g2), - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } } @@ -250,8 +234,7 @@ impl Crs { Self { g1_bases: Arc::new(g1), g2_monomial_bases: Arc::new(g2), - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } @@ -261,7 +244,7 @@ impl Crs { Self::from_powers(&tmp, size, &worker) } - pub fn from_powers(powers: &Crs::, size: usize, worker: &Worker) -> Self { + pub fn from_powers(powers: &Crs, size: usize, worker: &Worker) -> Self { assert!(size.is_power_of_two()); assert!(size <= powers.g1_bases.len()); @@ -270,8 +253,8 @@ impl Crs { let g1: Vec<_> = g1.into_iter().map(|el| Point(el.into_projective())).collect(); - use crate::group::Point; use crate::domain::EvaluationDomain; + use crate::group::Point; let mut g1 = EvaluationDomain::from_coeffs(g1).expect("must fit into the domain"); @@ -279,8 +262,7 @@ impl Crs { let mut g1: Vec<_> = g1.into_coeffs().into_iter().map(|el| el.0).collect(); worker.scope(g1.len(), |scope, chunk| { - for g1 in g1.chunks_mut(chunk) - { + for g1 in g1.chunks_mut(chunk) { scope.spawn(move |_| { // Batch normalize E::G1::batch_normalization(g1); @@ -293,24 +275,17 @@ impl Crs { Self { g1_bases: Arc::new(g1), g2_monomial_bases: Arc::new(g2), - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } } -pub(crate) fn elements_into_representations( - worker: &Worker, - scalars: &[E::Fr] -) -> Result::Repr>, SynthesisError> -{ +pub(crate) fn elements_into_representations(worker: &Worker, scalars: &[E::Fr]) -> Result::Repr>, SynthesisError> { let mut representations = vec![::Repr::default(); scalars.len()]; worker.scope(scalars.len(), |scope, chunk| { - for (scalar, repr) in scalars.chunks(chunk) - .zip(representations.chunks_mut(chunk)) { + for (scalar, repr) in scalars.chunks(chunk).zip(representations.chunks_mut(chunk)) { scope.spawn(move |_| { - for (scalar, repr) in scalar.iter() - .zip(repr.iter_mut()) { + for (scalar, repr) in scalar.iter().zip(repr.iter_mut()) { *repr = scalar.into_repr(); } }); @@ -320,113 +295,57 @@ pub(crate) fn elements_into_representations( Ok(representations) } -pub fn commit_using_monomials( - poly: &Polynomial, - crs: &Crs, - worker: &Worker -) -> Result { - let scalars_repr = elements_into_representations::( - &worker, - &poly.as_ref() - )?; +pub fn commit_using_monomials(poly: &Polynomial, crs: &Crs, worker: &Worker) -> Result { + let scalars_repr = elements_into_representations::(&worker, &poly.as_ref())?; - let res = multiexp::dense_multiexp::( - &worker, - &crs.g1_bases[..scalars_repr.len()], - &scalars_repr - )?; + let res = multiexp::dense_multiexp::(&worker, &crs.g1_bases[..scalars_repr.len()], &scalars_repr)?; Ok(res.into_affine()) } -pub fn commit_using_values( - poly: &Polynomial, - crs: &Crs, - worker: &Worker -) -> Result { +pub fn commit_using_values(poly: &Polynomial, crs: &Crs, worker: &Worker) -> Result { assert_eq!(poly.size(), crs.g1_bases.len()); - let scalars_repr = elements_into_representations::( - &worker, - &poly.as_ref() - )?; + let scalars_repr = elements_into_representations::(&worker, &poly.as_ref())?; - let res = multiexp::dense_multiexp::( - &worker, - &crs.g1_bases, - &scalars_repr - )?; + let res = multiexp::dense_multiexp::(&worker, &crs.g1_bases, &scalars_repr)?; Ok(res.into_affine()) } -pub fn commit_using_raw_values( - values: &[E::Fr], - crs: &Crs, - worker: &Worker -) -> Result { +pub fn commit_using_raw_values(values: &[E::Fr], crs: &Crs, worker: &Worker) -> Result { assert_eq!(values.len().next_power_of_two(), crs.g1_bases.len()); - let scalars_repr = elements_into_representations::( - &worker, - &values - )?; + let scalars_repr = elements_into_representations::(&worker, &values)?; - let res = multiexp::dense_multiexp::( - &worker, - &crs.g1_bases[0..values.len()], - &scalars_repr - )?; + let res = multiexp::dense_multiexp::(&worker, &crs.g1_bases[0..values.len()], &scalars_repr)?; Ok(res.into_affine()) } use crate::source::QueryDensity; -pub fn commit_using_values_with_density ( - values: &[E::Fr], - density: D, - crs: &Crs, - worker: &Worker -) -> Result - where for<'a> &'a Q: QueryDensity, - D: Send + Sync + 'static + Clone + AsRef +pub fn commit_using_values_with_density(values: &[E::Fr], density: D, crs: &Crs, worker: &Worker) -> Result +where + for<'a> &'a Q: QueryDensity, + D: Send + Sync + 'static + Clone + AsRef, { use futures::Future; // assert_eq!(values.len(), crs.g1_bases.len()); - let scalars_repr = elements_into_representations::( - &worker, - &values - )?; + let scalars_repr = elements_into_representations::(&worker, &values)?; // scalars_repr.resize(crs.g1_bases.len(), ::Repr::default()); - let res = multiexp::multiexp( - &worker, - (crs.g1_bases.clone(), 0), - density, - Arc::new(scalars_repr) - ).wait()?; + let res = multiexp::multiexp(&worker, (crs.g1_bases.clone(), 0), density, Arc::new(scalars_repr)).wait()?; Ok(res.into_affine()) } -pub fn commit_using_values_on_coset( - poly: &Polynomial, - crs: &Crs, - worker: &Worker -) -> Result { +pub fn commit_using_values_on_coset(poly: &Polynomial, crs: &Crs, worker: &Worker) -> Result { assert_eq!(poly.size(), crs.g1_bases.len()); - let scalars_repr = elements_into_representations::( - &worker, - &poly.as_ref() - )?; + let scalars_repr = elements_into_representations::(&worker, &poly.as_ref())?; - let res = multiexp::dense_multiexp::( - &worker, - &crs.g1_bases, - &scalars_repr - )?; + let res = multiexp::dense_multiexp::(&worker, &crs.g1_bases, &scalars_repr)?; Ok(res.into_affine()) } @@ -446,7 +365,7 @@ pub fn calculate_batch_opening_quotient_from_monomials( } let quotient = divide_single::(tmp.as_ref(), at); - + Polynomial::from_coeffs(quotient) } @@ -455,29 +374,19 @@ pub fn open_from_monomials( at: E::Fr, _expected_value: E::Fr, crs: &Crs, - worker: &Worker + worker: &Worker, ) -> Result { assert!(poly.size().is_power_of_two()); let division_result = divide_single::(poly.as_ref(), at); assert!(division_result.len().is_power_of_two()); let division_result = Polynomial::from_coeffs(division_result)?; - let opening_proof = commit_using_monomials( - &division_result, - &crs, - &worker - )?; + let opening_proof = commit_using_monomials(&division_result, &crs, &worker)?; Ok(opening_proof) } -pub fn open_from_values( - poly: &Polynomial, - at: E::Fr, - expected_value: E::Fr, - crs: &Crs, - worker: &Worker -) -> Result { +pub fn open_from_values(poly: &Polynomial, at: E::Fr, expected_value: E::Fr, crs: &Crs, worker: &Worker) -> Result { assert!(poly.size().is_power_of_two()); let division_result = vec![E::Fr::one(); poly.size()]; let mut division_result = Polynomial::from_values(division_result)?; @@ -486,9 +395,7 @@ pub fn open_from_values( division_result.batch_inversion(&worker)?; worker.scope(division_result.size(), |scope, chunk_size| { - for (result, values) in division_result.as_mut().chunks_mut(chunk_size) - .zip(poly.as_ref().chunks(chunk_size)) - { + for (result, values) in division_result.as_mut().chunks_mut(chunk_size).zip(poly.as_ref().chunks(chunk_size)) { scope.spawn(move |_| { for (r, &val) in result.iter_mut().zip(values.iter()) { let mut tmp = val; @@ -510,7 +417,7 @@ pub fn open_from_values_on_coset( at: E::Fr, expected_value: E::Fr, crs: &Crs, - worker: &Worker + worker: &Worker, ) -> Result { assert!(poly.size().is_power_of_two()); let division_result = vec![coset_factor; poly.size()]; @@ -520,9 +427,7 @@ pub fn open_from_values_on_coset( division_result.batch_inversion(&worker)?; worker.scope(division_result.size(), |scope, chunk_size| { - for (result, values) in division_result.as_mut().chunks_mut(chunk_size) - .zip(poly.as_ref().chunks(chunk_size)) - { + for (result, values) in division_result.as_mut().chunks_mut(chunk_size).zip(poly.as_ref().chunks(chunk_size)) { scope.spawn(move |_| { for (r, &val) in result.iter_mut().zip(values.iter()) { let mut tmp = val; @@ -544,7 +449,7 @@ pub fn perform_batched_divisor_for_opening( opening_values: &[E::Fr], challenge: E::Fr, challenge_start: E::Fr, - worker: &Worker + worker: &Worker, ) -> Result<(Polynomial, E::Fr), SynthesisError> { assert!(polynomials.len() == opening_values.len(), "different number of polynomials and opening values"); // assert!(polynomials.len() > 1, "should aggregate only two or more polynomials"); @@ -588,33 +493,20 @@ pub fn perform_batched_divisor_for_opening( pub fn perform_batch_opening_from_values( polynomials: Vec>, - crs: &Crs::, + crs: &Crs, open_at: E::Fr, opening_values: &[E::Fr], challenge: E::Fr, - worker: &Worker + worker: &Worker, ) -> Result { - let (aggregation, _) = perform_batched_divisor_for_opening::( - polynomials, - open_at, - opening_values, - challenge, - E::Fr::one(), - &worker - )?; + let (aggregation, _) = perform_batched_divisor_for_opening::(polynomials, open_at, opening_values, challenge, E::Fr::one(), &worker)?; let opening_proof = commit_using_values(&aggregation, &crs, &worker)?; Ok(opening_proof) } -pub fn is_valid_opening( - commitment: E::G1Affine, - z: E::Fr, - opening_value: E::Fr, - opening_proof: E::G1Affine, - g2_by_x: E::G2Affine -) -> bool { +pub fn is_valid_opening(commitment: E::G1Affine, z: E::Fr, opening_value: E::Fr, opening_proof: E::G1Affine, g2_by_x: E::G2Affine) -> bool { // (f(x) - f(z))/(x - z) = op(x) // f(x) = f(z) + op(x) * (x - z) @@ -631,29 +523,19 @@ pub fn is_valid_opening( let mut pair_with_x_part = opening_proof; pair_with_x_part.negate(); - let result = E::final_exponentiation( - &E::miller_loop( - &[ - (&pair_with_1_part.into_affine().prepare(), &E::G2Affine::one().prepare()), - (&pair_with_x_part.prepare(), &g2_by_x.prepare()), - ] - )); - + let result = E::final_exponentiation(&E::miller_loop(&[ + (&pair_with_1_part.into_affine().prepare(), &E::G2Affine::one().prepare()), + (&pair_with_x_part.prepare(), &g2_by_x.prepare()), + ])); + if let Some(res) = result { return res == E::Fqk::one(); } - + false } -pub fn is_valid_multiopening( - commitments: &[E::G1Affine], - z: E::Fr, - opening_values: &[E::Fr], - opening_proof: E::G1Affine, - challenge: E::Fr, - g2_by_x: E::G2Affine -) -> bool { +pub fn is_valid_multiopening(commitments: &[E::G1Affine], z: E::Fr, opening_values: &[E::Fr], opening_proof: E::G1Affine, challenge: E::Fr, g2_by_x: E::G2Affine) -> bool { assert!(commitments.len() == opening_values.len()); // \sum_{i} alpha^i (f(x) - f(z))/(x - z) = op(x) @@ -662,14 +544,14 @@ pub fn is_valid_multiopening( // e(\sum_{i} alpha^i (f(x) - f(z)) + z*op(x), 1) * e(-op(x), x) == 1 // e(0, 0) let mut aggregation = E::G1::zero(); - + let mut this_challenge = E::Fr::one(); // later change for efficiency for (c, v) in commitments.iter().zip(opening_values.iter()) { let mut pair_with_1_part = c.into_projective(); let gen_by_opening_value = E::G1Affine::one().mul(v.into_repr()); pair_with_1_part.sub_assign(&gen_by_opening_value); - + pair_with_1_part.mul_assign(this_challenge.into_repr()); aggregation.add_assign(&pair_with_1_part); @@ -683,25 +565,19 @@ pub fn is_valid_multiopening( let mut pair_with_x_part = opening_proof; pair_with_x_part.negate(); - let result = E::final_exponentiation( - &E::miller_loop( - &[ - (&aggregation.into_affine().prepare(), &E::G2Affine::one().prepare()), - (&pair_with_x_part.prepare(), &g2_by_x.prepare()), - ] - )); - + let result = E::final_exponentiation(&E::miller_loop(&[ + (&aggregation.into_affine().prepare(), &E::G2Affine::one().prepare()), + (&pair_with_x_part.prepare(), &g2_by_x.prepare()), + ])); + if let Some(res) = result { return res == E::Fqk::one(); } - + false } -pub(crate) fn divide_single( - poly: &[E::Fr], - opening_point: E::Fr, -) -> Vec { +pub(crate) fn divide_single(poly: &[E::Fr], opening_point: E::Fr) -> Vec { // we are only interested in quotient without a reminder, so we actually don't need opening value let mut b = opening_point; b.negate(); @@ -713,7 +589,7 @@ pub(crate) fn divide_single( for (q, r) in q.iter_mut().rev().skip(1).zip(poly.iter().rev()) { if !found_one { if r.is_zero() { - continue + continue; } else { found_one = true; } @@ -729,12 +605,10 @@ pub(crate) fn divide_single( q } -pub fn make_crs_from_ignition_transcript + ?Sized>( - path: &S -) -> Result, SynthesisError> { - use crate::pairing::bn256::{Bn256, Fq, Fq2, Fq12}; - use crate::pairing::EncodedPoint; +pub fn make_crs_from_ignition_transcript + ?Sized>(path: &S) -> Result, SynthesisError> { use crate::ff::{PrimeField, PrimeFieldRepr}; + use crate::pairing::bn256::{Bn256, Fq, Fq12, Fq2}; + use crate::pairing::EncodedPoint; use std::io::BufRead; const CHUNKS: usize = 20; @@ -772,12 +646,9 @@ pub fn make_crs_from_ignition_transcript + ?Sized>( let c1 = Fq::from_raw_repr(fq_repr).expect("c0 for B coeff for G2"); - let b_coeff_fq2 = Fq2 { - c0: c0, - c1: c1 - }; + let b_coeff_fq2 = Fq2 { c0: c0, c1: c1 }; - for _ in 0..5_040_000{ + for _ in 0..5_040_000 { // we have to manually read X and Y coordinates for k in 0..4 { fq_repr.as_mut()[k] = reader.read_u64::().expect("must read u64"); @@ -815,70 +686,53 @@ pub fn make_crs_from_ignition_transcript + ?Sized>( for k in 0..4 { fq_repr.as_mut()[k] = reader.read_u64::().expect("must read u64"); } - + let x_c0 = Fq::from_repr(fq_repr).expect("must be valid field element encoding"); - + for k in 0..4 { fq_repr.as_mut()[k] = reader.read_u64::().expect("must read u64"); } - + let x_c1 = Fq::from_repr(fq_repr).expect("must be valid field element encoding"); - + for k in 0..4 { fq_repr.as_mut()[k] = reader.read_u64::().expect("must read u64"); } - + let y_c0 = Fq::from_repr(fq_repr).expect("must be valid field element encoding"); - + for k in 0..4 { fq_repr.as_mut()[k] = reader.read_u64::().expect("must read u64"); } - + let y_c1 = Fq::from_repr(fq_repr).expect("must be valid field element encoding"); - - let x = Fq2 { - c0: x_c0, - c1: x_c1 - }; - - let y = Fq2 { - c0: y_c0, - c1: y_c1 - }; - + + let x = Fq2 { c0: x_c0, c1: x_c1 }; + + let y = Fq2 { c0: y_c0, c1: y_c1 }; + { let mut lhs = y; lhs.square(); - + let mut rhs = x; rhs.square(); rhs.mul_assign(&x); rhs.add_assign(&b_coeff_fq2); - + assert!(lhs == rhs); } - + let g2 = ::G2Affine::from_xy_unchecked(x, y); g2_bases.push(g2); - + // sanity check by using pairing - { + { // check e(g1, g2^x) == e(g1^{x}, g2) - let valid = Bn256::final_exponentiation( - &Bn256::miller_loop( - &[ - (&g1_bases[0].prepare(), &g2.prepare()) - ] - ) - ).unwrap() == Bn256::final_exponentiation( - &Bn256::miller_loop( - &[ - (&g1_bases[1].prepare(), &g2_bases[0].prepare()) - ] - ) - ).unwrap(); - + let valid = Bn256::final_exponentiation(&Bn256::miller_loop(&[(&g1_bases[0].prepare(), &g2.prepare())])).unwrap() + == Bn256::final_exponentiation(&Bn256::miller_loop(&[(&g1_bases[1].prepare(), &g2_bases[0].prepare())])).unwrap(); + assert!(valid); } } @@ -887,7 +741,7 @@ pub fn make_crs_from_ignition_transcript + ?Sized>( reader.read_exact(&mut tmp).expect("must skip 128 bytes of irrelevant G2 point"); } - // read to end + // read to end reader.consume(64); assert_eq!(reader.fill_buf().unwrap().len(), 0); @@ -899,20 +753,20 @@ pub fn make_crs_from_ignition_transcript + ?Sized>( let new = Crs:: { g1_bases: Arc::new(g1_bases), g2_monomial_bases: Arc::new(g2_bases), - - _marker: std::marker::PhantomData + + _marker: std::marker::PhantomData, }; - Ok(new) + Ok(new) } #[cfg(test)] pub(crate) mod test { use super::*; + use crate::ff::{Field, PrimeField}; use crate::pairing::bn256::{Bn256, Fr}; - use crate::worker::Worker; - use crate::ff::{PrimeField, Field}; use crate::plonk::polynomials::*; + use crate::worker::Worker; #[test] fn test_transformations_of_crs_1() { @@ -949,7 +803,6 @@ pub(crate) mod test { // so bases must be b_0 + b_1 = 1 and b_0 - b_1 = tau / gen // so b_0 = 1 + tau/gen/2, b_1 = 1 - tau/gen/2 - let one = Fr::one(); let mut two = Fr::one(); @@ -971,7 +824,6 @@ pub(crate) mod test { assert!(commitment == commitment_values); assert!(commitment == commitment_values_on_coset); - } #[test] @@ -997,7 +849,6 @@ pub(crate) mod test { assert!(commitment == commitment_values); assert!(commitment == commitment_values_on_coset); - } #[test] @@ -1023,7 +874,6 @@ pub(crate) mod test { assert!(commitment == commitment_values); assert!(commitment == commitment_values_on_coset); - } #[test] @@ -1075,7 +925,7 @@ pub(crate) mod test { fn test_open_ignition_setup() { let large_setup = make_crs_from_ignition_transcript("/Users/alexvlasov/Downloads/setup").unwrap(); let base_path = std::path::Path::new("/Users/alexvlasov/Downloads/setup/processed"); - + for n in 20..=26 { let full_path = base_path.join(&format!("setup_2^{}.key", n)); println!("Opening {}", full_path.to_string_lossy()); @@ -1086,8 +936,8 @@ pub(crate) mod test { let truncated_key = Crs:: { g1_bases: Arc::new(large_setup.g1_bases[..size].to_vec()), g2_monomial_bases: large_setup.g2_monomial_bases.clone(), - - _marker: std::marker::PhantomData + + _marker: std::marker::PhantomData, }; let mut writer = std::io::BufWriter::with_capacity(1 << 24, file); @@ -1100,7 +950,7 @@ pub(crate) mod test { let base_path = std::path::Path::new("/Users/alexvlasov/Downloads/setup/processed"); let worker = crate::worker::Worker::new(); - + for n in 20..=26 { let full_path = base_path.join(&format!("setup_2^{}.key", n)); println!("Opening {}", full_path.to_string_lossy()); @@ -1124,7 +974,7 @@ pub(crate) mod test { #[test] fn test_crs_serialization() { let worker = Worker::new(); - let mut buffer = Vec::with_capacity(1<<28); + let mut buffer = Vec::with_capacity(1 << 28); let crs = Crs::::crs_42(1024, &worker); crs.write(&mut buffer).expect("must serialize CRS"); @@ -1133,31 +983,23 @@ pub(crate) mod test { assert!(new == crs); } - use rand::{Rng}; + use rand::Rng; + + pub(crate) fn make_random_field_elements(worker: &Worker, num_elements: usize) -> Vec { + use rand::{ChaChaRng, Rand, Rng, SeedableRng, XorShiftRng}; - pub(crate) fn make_random_field_elements( - worker: &Worker, - num_elements: usize, - ) -> Vec { - use rand::{XorShiftRng, SeedableRng, Rand, Rng, ChaChaRng}; - let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); make_random_field_elements_for_rng(worker, num_elements, rng) } - pub(crate) fn make_random_field_elements_for_rng( - worker: &Worker, - num_elements: usize, - mut rng: R - ) -> Vec { + pub(crate) fn make_random_field_elements_for_rng(worker: &Worker, num_elements: usize, mut rng: R) -> Vec { let mut result = vec![F::zero(); num_elements]; - use rand::{XorShiftRng, SeedableRng, Rand, Rng, ChaChaRng}; + use rand::{ChaChaRng, Rand, Rng, SeedableRng, XorShiftRng}; worker.scope(result.len(), |scope, chunk| { - for r in result.chunks_mut(chunk) - { + for r in result.chunks_mut(chunk) { let seed: [u32; 4] = rng.gen(); let subrng = ChaChaRng::from_seed(&seed); scope.spawn(move |_| { @@ -1169,32 +1011,24 @@ pub(crate) mod test { } }); - result + result } - fn make_random_g1_points( - worker: &Worker, - num_elements: usize, - ) -> Vec { - use rand::{XorShiftRng, SeedableRng, Rand, Rng, ChaChaRng}; - + fn make_random_g1_points(worker: &Worker, num_elements: usize) -> Vec { + use rand::{ChaChaRng, Rand, Rng, SeedableRng, XorShiftRng}; + let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - make_random_g1_points_for_rng(worker, num_elements, rng) + make_random_g1_points_for_rng(worker, num_elements, rng) } - fn make_random_g1_points_for_rng( - worker: &Worker, - num_elements: usize, - mut rng: R - ) -> Vec { + fn make_random_g1_points_for_rng(worker: &Worker, num_elements: usize, mut rng: R) -> Vec { let mut result = vec![G::zero(); num_elements]; - use rand::{XorShiftRng, SeedableRng, Rand, Rng, ChaChaRng}; - + use rand::{ChaChaRng, Rand, Rng, SeedableRng, XorShiftRng}; + worker.scope(result.len(), |scope, chunk| { - for r in result.chunks_mut(chunk) - { + for r in result.chunks_mut(chunk) { let seed: [u32; 4] = rng.gen(); let subrng = ChaChaRng::from_seed(&seed); scope.spawn(move |_| { @@ -1207,7 +1041,7 @@ pub(crate) mod test { } }); - result + result } #[test] @@ -1228,7 +1062,7 @@ pub(crate) mod test { for size in vec![1 << 23, 1 << 24, 1 << 25, 1 << 26] { for cpus in vec![16, 32, 48, 64] { - // for cpus in vec![16, 24, 32] { + // for cpus in vec![16, 24, 32] { let s = &scalars[..size]; let g = &points[..size]; @@ -1240,20 +1074,13 @@ pub(crate) mod test { let subtime = Instant::now(); - let scalars_repr = super::elements_into_representations::( - &subworker, - s - ).unwrap(); + let scalars_repr = super::elements_into_representations::(&subworker, s).unwrap(); println!("Scalars conversion taken {:?}", subtime.elapsed()); let subtime = Instant::now(); - let _ = multiexp::dense_multiexp::<::G1Affine>( - &subworker, - g, - &scalars_repr - ).unwrap(); + let _ = multiexp::dense_multiexp::<::G1Affine>(&subworker, g, &scalars_repr).unwrap(); println!("Multiexp taken {:?}", subtime.elapsed()); @@ -1266,8 +1093,8 @@ pub(crate) mod test { #[ignore] fn test_future_based_multiexp_performance_on_large_data() { use crate::pairing::bn256::{Bn256, Fr}; - use std::time::Instant; use std::sync::Arc; + use std::time::Instant; let max_size = 1 << 26; let worker = Worker::new(); @@ -1281,7 +1108,7 @@ pub(crate) mod test { for size in vec![1 << 23, 1 << 24, 1 << 25, 1 << 26] { for cpus in vec![16, 32, 48, 64] { - // for cpus in vec![16, 24, 32] { + // for cpus in vec![16, 24, 32] { let s = &scalars[..size]; let g = points[..size].to_vec(); let g = Arc::from(g); @@ -1294,10 +1121,7 @@ pub(crate) mod test { let subtime = Instant::now(); - let scalars_repr = super::elements_into_representations::( - &subworker, - s - ).unwrap(); + let scalars_repr = super::elements_into_representations::(&subworker, s).unwrap(); let scalars_repr = Arc::from(scalars_repr); @@ -1305,11 +1129,7 @@ pub(crate) mod test { let subtime = Instant::now(); - let _ = multiexp::future_based_multiexp::<::G1Affine>( - &subworker, - Arc::clone(&g), - Arc::clone(&scalars_repr) - ).wait(); + let _ = multiexp::future_based_multiexp::<::G1Affine>(&subworker, Arc::clone(&g), Arc::clone(&scalars_repr)).wait(); println!("Future based multiexp taken {:?}", subtime.elapsed()); @@ -1343,10 +1163,7 @@ pub(crate) mod test { } } - fn serialize_affine_points_for_fpga( - points: &[E::G1Affine], - mut dst: W - ) -> Result<(), std::io::Error> { + fn serialize_affine_points_for_fpga(points: &[E::G1Affine], mut dst: W) -> Result<(), std::io::Error> { use crate::pairing::ff::PrimeFieldRepr; println!("First point = {}", points[0]); @@ -1358,14 +1175,11 @@ pub(crate) mod test { let repr = y.into_raw_repr(); repr.write_le(&mut dst)?; } - + Ok(()) } - fn serialize_scalars_for_fpga( - scalars: &[E::Fr], - mut dst: W - ) -> Result<(), std::io::Error> { + fn serialize_scalars_for_fpga(scalars: &[E::Fr], mut dst: W) -> Result<(), std::io::Error> { use crate::pairing::ff::PrimeFieldRepr; println!("First scalar = {}", scalars[0]); @@ -1373,14 +1187,11 @@ pub(crate) mod test { let repr = s.into_repr(); repr.write_le(&mut dst)?; } - + Ok(()) } - fn serialize_projective_points_for_fpga( - points: &[E::G1], - mut dst: W - ) -> Result<(), std::io::Error> { + fn serialize_projective_points_for_fpga(points: &[E::G1], mut dst: W) -> Result<(), std::io::Error> { use crate::pairing::ff::PrimeFieldRepr; let (x, y, z) = points[1].into_xyz_unchecked(); @@ -1397,13 +1208,13 @@ pub(crate) mod test { let repr = z.into_raw_repr(); repr.write_le(&mut dst)?; } - + Ok(()) } fn simulate_first_buckets(points: &[E::G1Affine], scalars: &[E::Fr], c: usize, random_point: E::G1Affine) -> Vec { - use crate::pairing::ff::ScalarEngine; use crate::pairing::ff::PrimeFieldRepr; + use crate::pairing::ff::ScalarEngine; let skip = 0; let mask = (1u64 << c) - 1u64; @@ -1433,8 +1244,8 @@ pub(crate) mod test { } fn test_multiexps_inner(max_size: usize, sizes: Vec, num_cpus: Vec) { - use std::time::Instant; use std::sync::Arc; + use std::time::Instant; let worker = Worker::new(); @@ -1451,18 +1262,11 @@ pub(crate) mod test { let subworker = Worker::new_with_cpus(cpus); - let scalars_repr = super::elements_into_representations::( - &subworker, - s - ).unwrap(); + let scalars_repr = super::elements_into_representations::(&subworker, s).unwrap(); let subtime = Instant::now(); - let _ = multiexp::dense_multiexp::( - &subworker, - &g, - &scalars_repr - ).unwrap(); + let _ = multiexp::dense_multiexp::(&subworker, &g, &scalars_repr).unwrap(); println!("Dense simple multiexp of size {} taken {:?} on {} cpus", size, subtime.elapsed(), cpus); @@ -1714,9 +1518,9 @@ pub(crate) mod test { // assert!(max_parallel_jobs >= 1); // use rand::{XorShiftRng, SeedableRng, Rand, Rng, ChaChaRng}; - + // let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - + // for _ in 0..max_parallel_jobs { // let seed: [u32; 4] = rng.gen(); // let mut subrng = ChaChaRng::from_seed(&seed); @@ -1800,15 +1604,15 @@ pub(crate) mod test { // fn test_l3_shared_multiexp(max_parallel_jobs: usize, max_size: usize, cpus_per_job: usize, window: usize) { // use std::time::Instant; - + // let mut bases = vec![]; // let mut scalars = vec![]; // let worker = Worker::new(); // use rand::{XorShiftRng, SeedableRng, Rand, Rng, ChaChaRng}; - + // let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - + // for _ in 0..max_parallel_jobs { // let seed: [u32; 4] = rng.gen(); // let mut subrng = ChaChaRng::from_seed(&seed); @@ -1840,17 +1644,17 @@ pub(crate) mod test { // &bases[0][..], // &exps[..], // ).unwrap(); - + // let elapsed = subtime.elapsed(); - + // println!("L3 shared multiexp for {} jobs of size {} with {} CPUs per job and {} bits window taken {:?}", j, max_size, cpus_per_job, window, elapsed); // } // } fn test_future_based_multiexps_over_window_sizes(max_size: usize, sizes: Vec, num_cpus: Vec, windows: Vec) { - use std::time::Instant; - use std::sync::Arc; use crate::source::FullDensity; + use std::sync::Arc; + use std::time::Instant; let worker = Worker::new(); @@ -1868,10 +1672,7 @@ pub(crate) mod test { let s = &scalars[..size]; let g = points[..size].to_vec(); - let scalars_repr = super::elements_into_representations::( - &worker, - s - ).unwrap(); + let scalars_repr = super::elements_into_representations::(&worker, s).unwrap(); let g = Arc::from(g); let s = Arc::from(scalars_repr); @@ -1883,35 +1684,20 @@ pub(crate) mod test { let window = window as u32; - let _ = multiexp::future_based_dense_multiexp_over_fixed_width_windows( - &subworker, - Arc::clone(&g), - Arc::clone(&s), - window - ).wait(); + let _ = multiexp::future_based_dense_multiexp_over_fixed_width_windows(&subworker, Arc::clone(&g), Arc::clone(&s), window).wait(); alt_subresults.push((window, subtime.elapsed().as_millis())); let subtime = Instant::now(); - let _ = multiexp::multiexp_with_fixed_width::<_, _, _, _>( - &subworker, - (Arc::clone(&g), 0), - FullDensity, - Arc::clone(&s), - window - ).wait(); + let _ = multiexp::multiexp_with_fixed_width::<_, _, _, _>(&subworker, (Arc::clone(&g), 0), FullDensity, Arc::clone(&s), window).wait(); subresults.push((window, subtime.elapsed().as_millis())); } - subresults.sort_by(|a, b| { - a.1.cmp(&b.1) - }); + subresults.sort_by(|a, b| a.1.cmp(&b.1)); - alt_subresults.sort_by(|a, b| { - a.1.cmp(&b.1) - }); + alt_subresults.sort_by(|a, b| a.1.cmp(&b.1)); println!("Standard future based multiexp of size {} on {} CPUs:", size, cpus); for (window, time_ms) in &subresults[0..3] { @@ -1929,7 +1715,7 @@ pub(crate) mod test { #[test] #[ignore] fn test_different_multiexps() { - test_multiexp_bn254(1<<20, vec![1 << 20], vec![3, 4, 6]); + test_multiexp_bn254(1 << 20, vec![1 << 20], vec![3, 4, 6]); } #[test] @@ -1939,7 +1725,7 @@ pub(crate) mod test { let worker = Worker::new(); assert!(worker.cpus >= 16, "should be tested only on large machines"); - + let sizes = vec![1 << 23, 1 << 24, 1 << 25, 1 << 26]; let cpus = vec![8, 12, 16, 24, 32, 48]; // test_multiexp_bn254(max_size, sizes, cpus); @@ -1950,7 +1736,7 @@ pub(crate) mod test { // #[ignore] // fn test_small_data_different_windows() { // let max_size = 1 << 20; - + // let sizes = vec![1 << 16, 1 << 17, 1 << 18, 1 << 19, 1 << 20]; // let cpus = vec![3, 4, 6]; // let windows = vec![7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]; @@ -1964,7 +1750,7 @@ pub(crate) mod test { // let worker = Worker::new(); // assert!(worker.cpus >= 16, "should be tested only on large machines"); - + // let sizes = vec![1 << 20, 1 << 21, 1 << 22, 1 << 23, 1 << 24, 1 << 25, 1 << 26]; // let cpus = vec![8, 12, 16, 24, 32, 48]; // let windows = vec![7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]; @@ -1979,7 +1765,7 @@ pub(crate) mod test { // let worker = Worker::new(); // assert!(worker.cpus >= 16, "should be tested only on large machines"); - + // let sizes = vec![1 << 20, 1 << 21, 1 << 22, 1 << 23, 1 << 24, 1 << 25, 1 << 26]; // let cpus = vec![8, 12, 16, 24, 32, 48]; // let windows = vec![10, 11, 12, 13, 14, 15, 16]; @@ -1995,7 +1781,7 @@ pub(crate) mod test { // let worker = Worker::new(); // assert!(worker.cpus >= 16, "should be tested only on large machines"); - + // let sizes = vec![1 << 20, 1 << 21, 1 << 22, 1 << 23, 1 << 24, 1 << 25, 1 << 26]; // let cpus = vec![8, 12, 16, 24, 32, 48]; // let windows = vec![7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]; @@ -2003,15 +1789,11 @@ pub(crate) mod test { // test_future_based_multiexps_over_window_sizes_bn254_compact(max_size, sizes, cpus, windows); // } - fn make_random_points_with_unknown_discrete_log( - dst: &[u8], - seed: &[u8], - num_points: usize - ) -> Vec { + fn make_random_points_with_unknown_discrete_log(dst: &[u8], seed: &[u8], num_points: usize) -> Vec { let mut result = vec![]; - use rand::{Rng, SeedableRng}; use rand::chacha::ChaChaRng; + use rand::{Rng, SeedableRng}; // Create an RNG based on the outcome of the random beacon let mut rng = { // if we use Blake hasher @@ -2037,22 +1819,18 @@ pub(crate) mod test { #[test] fn produce_fpga_test_vectors() { - use crate::pairing::ff::ScalarEngine; use crate::pairing::bls12_381::Bls12; + use crate::pairing::ff::ScalarEngine; - let worker =crate::worker::Worker::new(); + let worker = crate::worker::Worker::new(); - let random_point = make_random_points_with_unknown_discrete_log::( - &b"fpga_dst"[..], - &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), - 1 - )[0]; + let random_point = make_random_points_with_unknown_discrete_log::(&b"fpga_dst"[..], &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), 1)[0]; let (x, y) = random_point.into_xy_unchecked(); println!("Random point in Montgomery form: X = {}, Y = {}", x.into_raw_repr(), y.into_raw_repr()); let base_path = std::path::Path::new("./"); - + for n in vec![6, 7, 20] { let points_path = base_path.join(&format!("input_points_2^{}.key", n)); let scalars_path = base_path.join(&format!("input_scalars_2^{}.key", n)); @@ -2083,17 +1861,13 @@ pub(crate) mod test { #[test] fn produce_bn254_fpga_test_vectors() { - use crate::pairing::ff::ScalarEngine; use crate::pairing::bn256::{Bn256, Fr}; + use crate::pairing::ff::ScalarEngine; let bucket_width = 16; let worker = crate::worker::Worker::new(); - let random_point = make_random_points_with_unknown_discrete_log::( - &b"fpga_dst"[..], - &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), - 1 - )[0]; + let random_point = make_random_points_with_unknown_discrete_log::(&b"fpga_dst"[..], &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), 1)[0]; let (x, y) = random_point.into_xy_unchecked(); println!("Random point in Montgomery form: X = {}, Y = {}", x.into_raw_repr(), y.into_raw_repr()); @@ -2104,7 +1878,7 @@ pub(crate) mod test { if (Fr::NUM_BITS as usize) % bucket_width != 0 { num_buckets += 1; } - + for n in vec![6, 7, 20] { let points_path = base_path.join(&format!("bn_254_input_points_2^{}_width_{}.key", n, bucket_width)); let scalars_path = base_path.join(&format!("bn_254_input_scalars_2^{}_width_{}.key", n, bucket_width)); @@ -2142,22 +1916,18 @@ pub(crate) mod test { #[test] fn produce_fpga_window_12_test_vectors() { let width = 12; - use crate::pairing::ff::ScalarEngine; use crate::pairing::bls12_381::Bls12; + use crate::pairing::ff::ScalarEngine; let worker = crate::worker::Worker::new(); - let random_point = make_random_points_with_unknown_discrete_log::( - &b"fpga_dst"[..], - &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), - 1 - )[0]; + let random_point = make_random_points_with_unknown_discrete_log::(&b"fpga_dst"[..], &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), 1)[0]; let (x, y) = random_point.into_xy_unchecked(); println!("Random point in Montgomery form: X = {}, Y = {}", x.into_raw_repr(), y.into_raw_repr()); let base_path = std::path::Path::new("./"); - + for n in vec![6, 7, 20] { let points_path = base_path.join(&format!("input_points_2^{}.key", n)); let scalars_path = base_path.join(&format!("input_scalars_2^{}.key", n)); @@ -2186,4 +1956,3 @@ pub(crate) mod test { } } } - diff --git a/crates/bellman/src/lib.rs b/crates/bellman/src/lib.rs index 31b0a23..f2294a7 100644 --- a/crates/bellman/src/lib.rs +++ b/crates/bellman/src/lib.rs @@ -1,18 +1,17 @@ -#![ allow( dead_code, unused_imports, unused_mut, unused_variables, unused_macros, unused_assignments, unreachable_patterns ) ] +#![allow(dead_code, unused_imports, unused_mut, unused_variables, unused_macros, unused_assignments, unreachable_patterns)] #![cfg_attr(feature = "allocator", feature(allocator_api))] #[macro_use] - extern crate cfg_if; -pub extern crate pairing; -extern crate rand; extern crate bit_vec; extern crate byteorder; +pub extern crate pairing; +extern crate rand; pub use pairing::*; pub use smallvec; -use crate::pairing::ff as ff; +use crate::pairing::ff; pub use ff::*; #[macro_use] @@ -42,9 +41,9 @@ pub mod kate_commitment; pub mod constants; mod group; -mod source; mod multiexp; mod prefetch; +mod source; #[cfg(test)] mod tests; @@ -69,10 +68,10 @@ cfg_if! { mod cs; pub use self::cs::*; -use std::str::FromStr; use std::env; +use std::str::FromStr; -cfg_if!{ +cfg_if! { if #[cfg(any(not(feature = "nolog"), feature = "sonic"))] { fn verbose_flag() -> bool { option_env!("BELLMAN_VERBOSE").unwrap_or("0") == "1" diff --git a/crates/bellman/src/log.rs b/crates/bellman/src/log.rs index 179600b..392b4cd 100644 --- a/crates/bellman/src/log.rs +++ b/crates/bellman/src/log.rs @@ -91,4 +91,4 @@ cfg_if! { } } } -} \ No newline at end of file +} diff --git a/crates/bellman/src/marlin/generator.rs b/crates/bellman/src/marlin/generator.rs index 5905266..ea570d9 100644 --- a/crates/bellman/src/marlin/generator.rs +++ b/crates/bellman/src/marlin/generator.rs @@ -2,42 +2,20 @@ use crate::log::Stopwatch; use rand::Rng; -use std::sync::Arc; use std::collections::HashMap; +use std::sync::Arc; + +use crate::pairing::{CurveAffine, CurveProjective, Engine, Wnaf}; + +use crate::pairing::ff::{Field, PrimeField}; + +use super::IndexedSetup; + +use crate::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; + +use crate::domain::{EvaluationDomain, Scalar}; -use crate::pairing::{ - Engine, - Wnaf, - CurveProjective, - CurveAffine -}; - -use crate::pairing::ff::{ - PrimeField, - Field -}; - -use super::{ - IndexedSetup, -}; - -use crate::{ - SynthesisError, - Circuit, - ConstraintSystem, - LinearCombination, - Variable, - Index -}; - -use crate::domain::{ - EvaluationDomain, - Scalar -}; - -use crate::worker::{ - Worker -}; +use crate::worker::Worker; use crate::plonk::polynomials::*; @@ -70,9 +48,7 @@ impl KeypairAssembly { fn pad_square_to_size(&mut self, size: usize) -> Result<(), SynthesisError> { for _ in (self.num_inputs + self.num_aux)..size { - self.alloc(|| "", || { - Ok(E::Fr::one()) - })?; + self.alloc(|| "", || Ok(E::Fr::one()))?; } self.a_rows.resize(size, LinearCombination::zero()); @@ -84,19 +60,14 @@ impl KeypairAssembly { Ok(()) } - fn into_indexer_input(self, _worker: &Worker) -> - Result<(usize, usize, (Vec>, Vec> , Vec>)), SynthesisError> - { + fn into_indexer_input(self, _worker: &Worker) -> Result<(usize, usize, (Vec>, Vec>, Vec>)), SynthesisError> { let domain_h_size = self.num_inputs + self.num_aux; let domain_h_size = domain_h_size.next_power_of_two(); let domain_k_size = *[self.num_non_zero_in_a, self.num_non_zero_in_b, self.num_non_zero_in_c].iter().max().expect("must exist"); let domain_k_size = domain_k_size.next_power_of_two(); - fn into_sparse_matrix( - constraints: Vec>, - num_inputs: usize) - -> Vec> { + fn into_sparse_matrix(constraints: Vec>, num_inputs: usize) -> Vec> { let mut result = Vec::with_capacity(constraints.len()); for row in constraints.into_iter() { let mut new = Vec::with_capacity(row.0.len()); @@ -104,9 +75,9 @@ impl KeypairAssembly { match var { Variable(Index::Input(i)) => { new.push((i, coeff)); - }, + } Variable(Index::Aux(i)) => { - new.push((i+num_inputs, coeff)); + new.push((i + num_inputs, coeff)); } } } @@ -123,11 +94,7 @@ impl KeypairAssembly { let b_matrix = into_sparse_matrix(self.b_rows, num_inputs); let c_matrix = into_sparse_matrix(self.c_rows, num_inputs); - Ok(( - domain_h_size, - domain_k_size, - (a_matrix, b_matrix, c_matrix) - )) + Ok((domain_h_size, domain_k_size, (a_matrix, b_matrix, c_matrix))) } } @@ -138,10 +105,9 @@ pub(crate) fn materialize_domain_elements(domain: &Domain, wor let generator = domain.generator; worker.scope(values.len(), |scope, chunk| { - for (i, values) in values.chunks_mut(chunk).enumerate() - { + for (i, values) in values.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut current_power = generator.pow(&[(i*chunk) as u64]); + let mut current_power = generator.pow(&[(i * chunk) as u64]); for p in values { *p = current_power; @@ -154,11 +120,7 @@ pub(crate) fn materialize_domain_elements(domain: &Domain, wor values } -pub(crate) fn eval_unnormalized_bivariate_lagrange_poly_over_diaginal( - vanishing_degree: u64, - evaluate_on_domain: &Domain, - worker: &Worker -) -> Vec { +pub(crate) fn eval_unnormalized_bivariate_lagrange_poly_over_diaginal(vanishing_degree: u64, evaluate_on_domain: &Domain, worker: &Worker) -> Vec { let mut values = vec![F::zero(); evaluate_on_domain.size as usize]; let mut repr = F::Repr::default(); @@ -174,10 +136,9 @@ pub(crate) fn eval_unnormalized_bivariate_lagrange_poly_over_diaginal( - alpha: F, - vanishing_poly_size: u64, - evaluate_on_domain: &Domain, - worker: &Worker -) -> Vec { +pub(crate) fn eval_unnormalized_bivariate_lagrange_poly_over_different_inputs(alpha: F, vanishing_poly_size: u64, evaluate_on_domain: &Domain, worker: &Worker) -> Vec { // (vanishing(X) - vanishing(alpha)) / (x - alpha) // we evaluate it on the domain where vanishing(X) == 0 - // and make it as + // and make it as // vanishing(alpha) / (alpha - x) let vanishing_at_alpha = evaluate_vanishing_for_size(&alpha, vanishing_poly_size); let inv_vanishing_at_alpha = vanishing_at_alpha.inverse().ok_or(SynthesisError::DivisionByZero).expect("should not vanish on random x"); @@ -218,11 +174,7 @@ pub(crate) fn eval_unnormalized_bivariate_lagrange_poly_over_different_inputs( - domain_0: &Domain, - domain_1: &Domain, - index: usize -) -> usize { +pub(crate) fn reindex_from_one_domain_to_another_assuming_natural_ordering(domain_0: &Domain, domain_1: &Domain, index: usize) -> usize { assert!(domain_0.size <= domain_1.size); let lde_factor = domain_1.size / domain_0.size; @@ -233,11 +185,7 @@ pub(crate) fn reindex_from_one_domain_to_another_assuming_natural_ordering( - domain_0: &Domain, - domain_1: &Domain, - index: usize -) -> usize { +fn reindex_from_one_domain_to_another_assuming_bitreversed_ordering(domain_0: &Domain, domain_1: &Domain, index: usize) -> usize { assert!(domain_0.size <= domain_1.size); // in bitreversed ordering element of index i will always be in the beginning and unchanged index @@ -248,12 +196,11 @@ fn reindex_from_one_domain_to_another_assuming_bitreversed_ordering ConstraintSystem for KeypairAssembly { type Root = Self; - fn alloc( - &mut self, - _: A, - _: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc(&mut self, _: A, _: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { // There is no assignment, so we don't even invoke the // function for obtaining one. @@ -264,12 +211,11 @@ impl ConstraintSystem for KeypairAssembly { Ok(Variable(Index::Aux(index))) } - fn alloc_input( - &mut self, - _: A, - _: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc_input(&mut self, _: A, _: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { // There is no assignment, so we don't even invoke the // function for obtaining one. @@ -280,40 +226,24 @@ impl ConstraintSystem for KeypairAssembly { Ok(Variable(Index::Input(index))) } - fn enforce( - &mut self, - _: A, - a: LA, - b: LB, - c: LC - ) - where A: FnOnce() -> AR, AR: Into, - LA: FnOnce(LinearCombination) -> LinearCombination, - LB: FnOnce(LinearCombination) -> LinearCombination, - LC: FnOnce(LinearCombination) -> LinearCombination + fn enforce(&mut self, _: A, a: LA, b: LB, c: LC) + where + A: FnOnce() -> AR, + AR: Into, + LA: FnOnce(LinearCombination) -> LinearCombination, + LB: FnOnce(LinearCombination) -> LinearCombination, + LC: FnOnce(LinearCombination) -> LinearCombination, { fn sort_vars(v_0: &Variable, v_1: &Variable) -> std::cmp::Ordering { match (v_0, v_1) { - (Variable(Index::Input(v_0_value)), Variable(Index::Input(v_1_value))) => { - v_0_value.cmp(v_1_value) - }, - (Variable(Index::Input(_)), Variable(Index::Aux(_))) => { - std::cmp::Ordering::Less - }, - (Variable(Index::Aux(_)), Variable(Index::Input(_))) => { - std::cmp::Ordering::Greater - }, - (Variable(Index::Aux(v_0_value)), Variable(Index::Aux(v_1_value))) => { - v_0_value.cmp(v_1_value) - } + (Variable(Index::Input(v_0_value)), Variable(Index::Input(v_1_value))) => v_0_value.cmp(v_1_value), + (Variable(Index::Input(_)), Variable(Index::Aux(_))) => std::cmp::Ordering::Less, + (Variable(Index::Aux(_)), Variable(Index::Input(_))) => std::cmp::Ordering::Greater, + (Variable(Index::Aux(v_0_value)), Variable(Index::Aux(v_1_value))) => v_0_value.cmp(v_1_value), } } - - fn deduplicate_with_sort( - lc: LinearCombination, - scratch: &mut HashMap - ) -> LinearCombination { + fn deduplicate_with_sort(lc: LinearCombination, scratch: &mut HashMap) -> LinearCombination { assert!(scratch.is_empty()); if lc.as_ref().len() == 0 { @@ -395,13 +325,14 @@ impl ConstraintSystem for KeypairAssembly { } fn push_namespace(&mut self, _: N) - where NR: Into, N: FnOnce() -> NR + where + NR: Into, + N: FnOnce() -> NR, { // Do nothing; we don't care about namespaces in this context. } - fn pop_namespace(&mut self) - { + fn pop_namespace(&mut self) { // Do nothing; we don't care about namespaces in this context. } @@ -411,10 +342,10 @@ impl ConstraintSystem for KeypairAssembly { } /// Create parameters for a circuit, given some toxic waste. -pub fn generate_parameters( - circuit: C, -) -> Result, SynthesisError> - where E: Engine, C: Circuit +pub fn generate_parameters(circuit: C) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, { let mut assembly = KeypairAssembly { num_inputs: 0, @@ -459,13 +390,8 @@ pub fn generate_parameters( matrix: Vec>, domain_h: &Domain, domain_k: &Domain, - worker: &Worker - ) -> Result< - ( - usize, - [Polynomial; 3], - [Vec; 2] - ), SynthesisError> { + worker: &Worker, + ) -> Result<(usize, [Polynomial; 3], [Vec; 2]), SynthesisError> { let mut row_vec = Vec::with_capacity(domain_k.size as usize); let mut col_vec = Vec::with_capacity(domain_k.size as usize); let mut val_vec = Vec::with_capacity(domain_k.size as usize); @@ -473,11 +399,7 @@ pub fn generate_parameters( let mut inverses_for_lagrange_polys = Vec::with_capacity(domain_k.size as usize); let domain_h_elements = materialize_domain_elements(domain_h, worker); - let unnormalized_largrange_values_over_k = eval_unnormalized_bivariate_lagrange_poly_over_diaginal( - domain_h.size, - domain_k, - &worker - ); + let unnormalized_largrange_values_over_k = eval_unnormalized_bivariate_lagrange_poly_over_diaginal(domain_h.size, domain_k, &worker); let mut row_indexes = Vec::with_capacity(domain_k.size as usize); let mut col_indexes = Vec::with_capacity(domain_k.size as usize); @@ -486,7 +408,7 @@ pub fn generate_parameters( for (col_index, coeff) in row { let row_val = domain_h_elements[row_index]; row_indexes.push(row_index); - let col_val = domain_h_elements[col_index]; // TODO: do something with inputs? + let col_val = domain_h_elements[col_index]; // TODO: do something with inputs? col_indexes.push(col_index); row_vec.push(row_val); @@ -495,15 +417,9 @@ pub fn generate_parameters( // row and column indexes are over H, but we can quickly pull their values from evaluations // over K - let idx_row_into_larger_domain = reindex_from_one_domain_to_another_assuming_natural_ordering( - domain_h, - domain_k, - row_index); + let idx_row_into_larger_domain = reindex_from_one_domain_to_another_assuming_natural_ordering(domain_h, domain_k, row_index); - let idx_col_into_larger_domain = reindex_from_one_domain_to_another_assuming_natural_ordering( - domain_h, - domain_k, - col_index); + let idx_col_into_larger_domain = reindex_from_one_domain_to_another_assuming_natural_ordering(domain_h, domain_k, col_index); let mut lagrange_eval_value = unnormalized_largrange_values_over_k[idx_row_into_larger_domain]; lagrange_eval_value.mul_assign(&unnormalized_largrange_values_over_k[idx_col_into_larger_domain]); @@ -515,7 +431,7 @@ pub fn generate_parameters( let mut inverses_for_lagrange = Polynomial::from_values_unpadded(inverses_for_lagrange_polys)?; inverses_for_lagrange.batch_inversion(&worker)?; - + let mut val_values = Polynomial::from_values_unpadded(val_vec)?; val_values.mul_assign(&worker, &inverses_for_lagrange); @@ -571,11 +487,7 @@ pub fn generate_parameters( }) } -pub fn evaluate_bivariate_lagrange_at_point( - x: F, - y: F, - vanishing_domain_size: u64 -) -> Result { +pub fn evaluate_bivariate_lagrange_at_point(x: F, y: F, vanishing_domain_size: u64) -> Result { if x == y { return evaluate_bivariate_lagrange_at_diagonal_point(x, vanishing_domain_size); } @@ -593,7 +505,7 @@ pub fn evaluate_bivariate_lagrange_at_point( num.mul_assign(&den); Ok(num) -} +} pub fn evaluate_bivariate_lagrange_at_diagonal_point(x: F, vanishing_domain_size: u64) -> Result { let mut repr = F::Repr::default(); @@ -604,7 +516,7 @@ pub fn evaluate_bivariate_lagrange_at_diagonal_point(x: F, vanish result.mul_assign(&size_as_fe); Ok(result) -} +} fn evaluate_bivariate_lagrange_at_point_for_vanishing_y(x: F, y: F, vanishing_domain_size: u64) -> Result { if x == y { @@ -624,7 +536,7 @@ fn evaluate_bivariate_lagrange_at_point_for_vanishing_y(x: F, y: num.mul_assign(&den); Ok(num) -} +} pub(crate) fn evaluate_vanishing_for_size(point: &F, vanishing_domain_size: u64) -> F { let mut result = point.pow(&[vanishing_domain_size]); @@ -640,85 +552,68 @@ pub(crate) struct IndexerTester { } impl Circuit for IndexerTester { - fn synthesize>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError> - { - let a_var = cs.alloc(|| "a", || { - if let Some(a_value) = self.a { - Ok(a_value) - } else { - Err(SynthesisError::AssignmentMissing) - } - })?; + fn synthesize>(self, cs: &mut CS) -> Result<(), SynthesisError> { + let a_var = cs.alloc( + || "a", + || { + if let Some(a_value) = self.a { + Ok(a_value) + } else { + Err(SynthesisError::AssignmentMissing) + } + }, + )?; - cs.enforce( - || "a is zero", - |lc| lc + a_var, - |lc| lc + CS::one(), - |lc| lc - ); + cs.enforce(|| "a is zero", |lc| lc + a_var, |lc| lc + CS::one(), |lc| lc); - let b_var = cs.alloc(|| "b", || { - if let Some(b_value) = self.b { - Ok(b_value) - } else { - Err(SynthesisError::AssignmentMissing) - } - })?; + let b_var = cs.alloc( + || "b", + || { + if let Some(b_value) = self.b { + Ok(b_value) + } else { + Err(SynthesisError::AssignmentMissing) + } + }, + )?; - cs.enforce( - || "b is one", - |lc| lc + b_var, - |lc| lc + CS::one(), - |lc| lc + CS::one() - ); + cs.enforce(|| "b is one", |lc| lc + b_var, |lc| lc + CS::one(), |lc| lc + CS::one()); - let c_var = cs.alloc_input(|| "c", || { - if let Some(a_value) = self.a { - Ok(a_value) - } else { - Err(SynthesisError::AssignmentMissing) - } - })?; + let c_var = cs.alloc_input( + || "c", + || { + if let Some(a_value) = self.a { + Ok(a_value) + } else { + Err(SynthesisError::AssignmentMissing) + } + }, + )?; - cs.enforce( - || "a is equal to c", - |lc| lc + a_var, - |lc| lc + CS::one(), - |lc| lc + c_var - ); + cs.enforce(|| "a is equal to c", |lc| lc + a_var, |lc| lc + CS::one(), |lc| lc + c_var); cs.enforce( - || "large linear combinations (valid)", + || "large linear combinations (valid)", |lc| lc + a_var + b_var + c_var, |lc| lc + CS::one(), - |lc| lc + a_var + b_var + c_var - ); - - cs.enforce( - || "large linear combinations (invalid)", - |lc| lc + a_var + b_var + c_var, |lc| lc + a_var + b_var + c_var, - |lc| lc ); + cs.enforce(|| "large linear combinations (invalid)", |lc| lc + a_var + b_var + c_var, |lc| lc + a_var + b_var + c_var, |lc| lc); + Ok(()) } } #[cfg(test)] mod test { - use crate::tests::XORDemo; + use super::*; use crate::plonk::domains::*; + use crate::tests::XORDemo; use crate::worker::Worker; - use super::*; use std::marker::PhantomData; - fn test_over_engine_and_circuit>( - circuit: C - ) { + fn test_over_engine_and_circuit>(circuit: C) { let params = generate_parameters(circuit).unwrap(); let worker = Worker::new(); @@ -776,12 +671,12 @@ mod test { #[test] fn test_interpolation_poly_1() { - use crate::pairing::bn256::{Bn256}; + use crate::pairing::bn256::Bn256; let c = XORDemo:: { a: None, b: None, - _marker: PhantomData + _marker: PhantomData, }; test_over_engine_and_circuit(c); @@ -791,11 +686,8 @@ mod test { fn test_interpolation_poly_2() { use crate::pairing::bn256::{Bn256, Fr}; - let c = IndexerTester:: { - a: None, - b: None, - }; + let c = IndexerTester:: { a: None, b: None }; test_over_engine_and_circuit(c); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/marlin/mod.rs b/crates/bellman/src/marlin/mod.rs index 38232be..9750e84 100644 --- a/crates/bellman/src/marlin/mod.rs +++ b/crates/bellman/src/marlin/mod.rs @@ -38,5 +38,5 @@ pub struct Proof { pub a_col_on_beta_3: E::Fr, pub b_col_on_beta_3: E::Fr, pub c_col_on_beta_3: E::Fr, - pub f_3_at_beta_3: E::Fr -} \ No newline at end of file + pub f_3_at_beta_3: E::Fr, +} diff --git a/crates/bellman/src/marlin/prover.rs b/crates/bellman/src/marlin/prover.rs index 3a5734d..04b1fae 100644 --- a/crates/bellman/src/marlin/prover.rs +++ b/crates/bellman/src/marlin/prover.rs @@ -6,48 +6,25 @@ use std::sync::Arc; use futures::Future; -use crate::pairing::{ - Engine, - CurveProjective, - CurveAffine -}; - -use crate::pairing::ff::{ - PrimeField, - Field -}; - -use super::{ - IndexedSetup -}; - -use crate::{ - SynthesisError, - Circuit, - ConstraintSystem, - LinearCombination, - Variable, - Index -}; - -use crate::worker::{ - Worker -}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; + +use crate::pairing::ff::{Field, PrimeField}; + +use super::IndexedSetup; + +use crate::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; + +use crate::worker::Worker; -use crate::plonk::polynomials::*; use crate::plonk::domains::*; +use crate::plonk::polynomials::*; use super::generator::*; use super::Proof; use crate::kate_commitment::*; -fn eval( - lc: LinearCombination, - input_assignment: &[E::Fr], - aux_assignment: &[E::Fr] -) -> E::Fr -{ +fn eval(lc: LinearCombination, input_assignment: &[E::Fr], aux_assignment: &[E::Fr]) -> E::Fr { let mut acc = E::Fr::zero(); for (index, coeff) in lc.0.into_iter() { @@ -56,17 +33,17 @@ fn eval( match index { Variable(Index::Input(i)) => { tmp = input_assignment[i]; - }, + } Variable(Index::Aux(i)) => { tmp = aux_assignment[i]; } } if coeff == E::Fr::one() { - acc.add_assign(&tmp); + acc.add_assign(&tmp); } else { - tmp.mul_assign(&coeff); - acc.add_assign(&tmp); + tmp.mul_assign(&coeff); + acc.add_assign(&tmp); } } @@ -74,7 +51,7 @@ fn eval( } // This is a proving assignment with densities precalculated -pub struct PreparedProver{ +pub struct PreparedProver { assignment: ProvingAssignment, } @@ -87,20 +64,20 @@ struct ProvingAssignment { // Assignments of variables input_assignment: Vec, - aux_assignment: Vec + aux_assignment: Vec, } -pub fn prepare_prover( - circuit: C, -) -> Result, SynthesisError> - where E: Engine, C: Circuit +pub fn prepare_prover(circuit: C) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, { let mut prover = ProvingAssignment { a: vec![], b: vec![], c: vec![], input_assignment: vec![], - aux_assignment: vec![] + aux_assignment: vec![], }; prover.alloc_input(|| "CS::ONE", || Ok(E::Fr::one()))?; @@ -115,14 +92,11 @@ pub fn prepare_prover( // ); // } - let prepared = PreparedProver { - assignment: prover - }; + let prepared = PreparedProver { assignment: prover }; - return Ok(prepared) + return Ok(prepared); } - pub struct IndexPrecomputations { // values on 2K size coset for the last check pub a_row_over_2k_coset: Polynomial, @@ -202,12 +176,11 @@ impl IndexPrecomputations { }; Ok(new) - } } pub struct PrecomputedBases { - pub crs_values_on_h: Crs::, - pub crs_values_on_k: Crs::, + pub crs_values_on_h: Crs, + pub crs_values_on_k: Crs, // pub crs_values_on_h_coset: Crs:: } @@ -236,14 +209,8 @@ impl PrecomputedBases { } } -impl PreparedProver { - pub fn create_proof( - self, - params: &IndexedSetup, - crs: &PrecomputedBases, - precomputations: &IndexPrecomputations, - ) -> Result<(), SynthesisError> - { +impl PreparedProver { + pub fn create_proof(self, params: &IndexedSetup, crs: &PrecomputedBases, precomputations: &IndexPrecomputations) -> Result<(), SynthesisError> { // this prover performs the following: // - commit to the witness vector `w` and to the results of application of the A/B/C matrixes // to it as `z_a`, `z_b`, `z_c` (we may ommit commitment to `z_c` and just claim it's value) @@ -261,7 +228,7 @@ impl PreparedProver { // - perform a third sumcheck to claim that q_2(x) was evaluated correctly: // we later check that q_2(beta_2) = r(alpha, beta_2) * \sum_{m \in M} * M(beta_2, beta_1) // for this purpose we need to prove correctness of M(beta_2, beta_1) relatively to the initial indexing - // for this we define individual polynomials over domain K f_m = M(x, beta_1, beta_2) = Func(indexing, beta_1, beta_2) such that + // for this we define individual polynomials over domain K f_m = M(x, beta_1, beta_2) = Func(indexing, beta_1, beta_2) such that // after summing out over x we'll get the value M(beta_2, beta_1). To achieve this we perform a sumcheck let worker = Worker::new(); @@ -356,7 +323,7 @@ impl PreparedProver { // By this moment we should have oracles to all the witness polynomials, as well as Af, Bf, Cf - // first sumcheck is for the polynomial + // first sumcheck is for the polynomial // Q_1(X) = r(alpha, X) * F_1(X) + r_m(alpha, X) * F_2(X) // where r_m(alpha, X) = \sum_{k \in K} r(X, k) M (k, Y) // F_1(X) is result of applying one of the matrixes (A/B/C) on the vector of witnesses @@ -365,12 +332,7 @@ impl PreparedProver { // \sum_{H} r(alpha, X) ( \sum_{M} eta_M * z_M(X) ) - witness(X) * \sum_{M} ( \eta_M r_M(alpha, X)) ) // where z_M(X) = (M * witness)(X) - let r_alpha_x_values = eval_unnormalized_bivariate_lagrange_poly_over_different_inputs( - alpha, - domain_h.size, - &domain_h, - &worker - ); + let r_alpha_x_values = eval_unnormalized_bivariate_lagrange_poly_over_different_inputs(alpha, domain_h.size, &domain_h, &worker); let r_alpha_x_values_over_h = Polynomial::from_values(r_alpha_x_values)?; @@ -398,21 +360,18 @@ impl PreparedProver { row_indexes: &Vec, col_indexes: &Vec, domain_h: &Domain, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { let mut result = vec![F::zero(); domain_h.size as usize]; let to_spawn = worker.get_num_spawned_threads(col_indexes.len()); let mut subresults = vec![result.clone(); to_spawn]; - // M(X, Y) for X = omega^row_index and Y = omega^col_index is equal to the + // M(X, Y) for X = omega^row_index and Y = omega^col_index is equal to the // R1CS matrix M value at (row_index, col_index) worker.scope(col_indexes.len(), |scope, chunk_size| { - for (chunk_id, ((subres, row_chunk), col_chunk)) in subresults.chunks_mut(1) - .zip(row_indexes.chunks(chunk_size)) - .zip(col_indexes.chunks(chunk_size)) - .enumerate() { + for (chunk_id, ((subres, row_chunk), col_chunk)) in subresults.chunks_mut(1).zip(row_indexes.chunks(chunk_size)).zip(col_indexes.chunks(chunk_size)).enumerate() { scope.spawn(move |_| { let start = chunk_id * chunk_size; let write_to_subres = &mut subres[0]; @@ -465,7 +424,7 @@ impl PreparedProver { ¶ms.a_row_indexes, ¶ms.a_col_indexes, &domain_h, - &worker + &worker, )?; let r_b_alpha_x = construct_r_m_from_matrix( @@ -475,7 +434,7 @@ impl PreparedProver { ¶ms.b_row_indexes, ¶ms.b_col_indexes, &domain_h, - &worker + &worker, )?; let r_c_alpha_x = construct_r_m_from_matrix( @@ -485,7 +444,7 @@ impl PreparedProver { ¶ms.c_row_indexes, ¶ms.c_col_indexes, &domain_h, - &worker + &worker, )?; // sum_{m} eta_m * z_m @@ -541,7 +500,7 @@ impl PreparedProver { fn calculate_grand_sum_over_subdomain_assuming_natural_ordering_with_normalization( values: &Polynomial, - worker: &Worker + worker: &Worker, ) -> Result<(F, Polynomial), SynthesisError> { let mut result = vec![F::zero(); values.size() + 2]; @@ -550,16 +509,16 @@ impl PreparedProver { let mut subsums_sub = vec![F::zero(); num_threads as usize]; worker.scope(values.as_ref().len(), |scope, chunk| { - for (chunk_idx, (((grand_sum, elements), s_main), s_sub)) in result[2..].chunks_mut(chunk) - .zip(values.as_ref().chunks(chunk)) - .zip(subsums_main.chunks_mut(1)) - .zip(subsums_sub.chunks_mut(1)) - .enumerate() { + for (chunk_idx, (((grand_sum, elements), s_main), s_sub)) in result[2..] + .chunks_mut(chunk) + .zip(values.as_ref().chunks(chunk)) + .zip(subsums_main.chunks_mut(1)) + .zip(subsums_sub.chunks_mut(1)) + .enumerate() + { scope.spawn(move |_| { let start_idx = chunk_idx * chunk; - for (i, (g, el)) in grand_sum.iter_mut() - .zip(elements.iter()) - .enumerate() { + for (i, (g, el)) in grand_sum.iter_mut().zip(elements.iter()).enumerate() { let this_idx = start_idx + i; if this_idx & 1 == 0 { s_main[0].add_assign(&el); @@ -591,7 +550,7 @@ impl PreparedProver { let domain_sum_main = subsums_main.pop().expect("has at least one value"); let domain_sum_sub = subsums_sub.pop().expect("has at least one value"); - let subdomain_size_as_fe = F::from_str(&format!("{}", values.size()/2)).expect("must be a valid element"); + let subdomain_size_as_fe = F::from_str(&format!("{}", values.size() / 2)).expect("must be a valid element"); let one_over_size = subdomain_size_as_fe.inverse().ok_or(SynthesisError::DivisionByZero)?; let mut normalization_on_main = domain_sum_main; @@ -605,10 +564,7 @@ impl PreparedProver { assert_eq!(result.len() - chunk_len - 2, chunk_len * subsums_main.len()); worker.scope(0, |scope, _| { - for (chunk_idx, ((g, s_main), s_sub)) in result[(chunk_len+2)..].chunks_mut(chunk_len) - .zip(subsums_main.chunks(1)) - .zip(subsums_sub.chunks(1)) - .enumerate() { + for (chunk_idx, ((g, s_main), s_sub)) in result[(chunk_len + 2)..].chunks_mut(chunk_len).zip(subsums_main.chunks(1)).zip(subsums_sub.chunks(1)).enumerate() { scope.spawn(move |_| { let start_idx = (chunk_idx + 1) * chunk_len; let c_main = s_main[0]; @@ -620,7 +576,6 @@ impl PreparedProver { } else { g.add_assign(&c_sub); } - } }); } @@ -638,11 +593,7 @@ impl PreparedProver { Ok((domain_sum_main, Polynomial::from_values_unpadded(result)?)) } - let (proper_q_1_sum_over_2h, proper_q_1_grand_sum_poly_values_over_2h) = - calculate_grand_sum_over_subdomain_assuming_natural_ordering_with_normalization( - &proper_q_1_values_on_2h, - &worker - )?; + let (proper_q_1_sum_over_2h, proper_q_1_grand_sum_poly_values_over_2h) = calculate_grand_sum_over_subdomain_assuming_natural_ordering_with_normalization(&proper_q_1_values_on_2h, &worker)?; // let rotated_proper_q_1_grand_sum_poly_values_over_2h = proper_q_1_grand_sum_poly_values_over_2h.clone().rotate(2)?; @@ -655,14 +606,9 @@ impl PreparedProver { quotient.add_assign(&worker, &proper_q_1_grand_sum_poly_values_over_2h_coeffs.coset_fft(&worker)); quotient.sub_assign(&worker, &proper_q_1_grand_sum_poly_values_over_2h_coeffs_shifted.coset_fft(&worker)); - let domain_2h = Domain::new_for_size((params.domain_h_size*2) as u64)?; + let domain_2h = Domain::new_for_size((params.domain_h_size * 2) as u64)?; - let mut vanishing_of_degree_h_on_2h = evaluate_vanishing_polynomial_of_degree_on_domain( - domain_h.size, - &E::Fr::multiplicative_generator(), - &domain_2h, - &worker - )?; + let mut vanishing_of_degree_h_on_2h = evaluate_vanishing_polynomial_of_degree_on_domain(domain_h.size, &E::Fr::multiplicative_generator(), &domain_2h, &worker)?; vanishing_of_degree_h_on_2h.batch_inversion(&worker)?; quotient.mul_assign(&worker, &vanishing_of_degree_h_on_2h); @@ -694,7 +640,6 @@ impl PreparedProver { println!("Committing Q1 and it's sumcheck poly"); - // this is formally correct polynomial as it coincides with a sum of q_1 on H everywhere let (q_1_sum_over_h, q_1_grand_sum_poly_values_over_h) = q_1_poly_values_over_h.calculate_grand_sum(&worker)?; @@ -710,26 +655,25 @@ impl PreparedProver { // let mut z_omega = z; // z_omega.mul_assign(&domain_h.generator); - + // let grand_sum_at_z = q_1_grand_sum_poly_coeffs.evaluate_at(&worker, z); // let grand_sum_at_z_omega = q_1_grand_sum_poly_coeffs.evaluate_at(&worker, z_omega); // let el_at_z = q_1_poly_coeffs.evaluate_at(&worker, z); // let vanishing_at_z = evaluate_vanishing_for_size(&z, domain_h.size); // let quotient_at_z = q_1_sumcheck_quotient_over_h_coeffs.evaluate_at(&worker, z); - + // let mut lhs = grand_sum_at_z; // lhs.sub_assign(&grand_sum_at_z_omega); // lhs.add_assign(&el_at_z); - + // let mut rhs = vanishing_at_z; // rhs.mul_assign("ient_at_z); - + // assert_eq!(lhs, rhs, "q_1 sumcheck must pass"); // } // we would later need to evaluate q_1(z) and q_1_sum(z) and q_1_sum(z*omega) - let beta_1 = E::Fr::from_str("137").unwrap(); // claim values of z_a, z_b, z_c and h at beta_1 @@ -754,12 +698,7 @@ impl PreparedProver { // now we need to make q_2 = r(alpha, X) M(X, beta) - let r_beta_1_x_values = eval_unnormalized_bivariate_lagrange_poly_over_different_inputs( - beta_1, - domain_h.size, - &domain_h, - &worker - ); + let r_beta_1_x_values = eval_unnormalized_bivariate_lagrange_poly_over_different_inputs(beta_1, domain_h.size, &domain_h, &worker); let r_beta_1_x_values_over_h = Polynomial::from_values(r_beta_1_x_values)?; @@ -770,21 +709,18 @@ impl PreparedProver { row_indexes: &Vec, col_indexes: &Vec, domain_h: &Domain, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { let mut result = vec![F::zero(); domain_h.size as usize]; let to_spawn = worker.get_num_spawned_threads(col_indexes.len()); let mut subresults = vec![result.clone(); to_spawn]; - // M(X, Y) for X = omega^row_index and Y = omega^col_index is equal to the + // M(X, Y) for X = omega^row_index and Y = omega^col_index is equal to the // R1CS matrix M value at (row_index, col_index) worker.scope(col_indexes.len(), |scope, chunk_size| { - for (chunk_id, ((subres, row_chunk), col_chunk)) in subresults.chunks_mut(1) - .zip(row_indexes.chunks(chunk_size)) - .zip(col_indexes.chunks(chunk_size)) - .enumerate() { + for (chunk_id, ((subres, row_chunk), col_chunk)) in subresults.chunks_mut(1).zip(row_indexes.chunks(chunk_size)).zip(col_indexes.chunks(chunk_size)).enumerate() { scope.spawn(move |_| { let start = chunk_id * chunk_size; let write_to_subres = &mut subres[0]; @@ -835,7 +771,7 @@ impl PreparedProver { ¶ms.a_row_indexes, ¶ms.a_col_indexes, &domain_h, - &worker + &worker, )?; let r_b_x_beta_on_h = materialize_m_x_beta( @@ -845,7 +781,7 @@ impl PreparedProver { ¶ms.a_row_indexes, ¶ms.a_col_indexes, &domain_h, - &worker + &worker, )?; let r_c_x_beta_on_h = materialize_m_x_beta( @@ -855,10 +791,10 @@ impl PreparedProver { ¶ms.a_row_indexes, ¶ms.a_col_indexes, &domain_h, - &worker + &worker, )?; - let beta_2 = E::Fr::from_str("456").unwrap(); + let beta_2 = E::Fr::from_str("456").unwrap(); let mut r_m_beta_sum = r_a_x_beta_on_h; r_m_beta_sum.scale(&worker, eta_a); @@ -896,26 +832,27 @@ impl PreparedProver { // let q_2_commitment = commit_using_values(&q_2_poly_values_on_h, &crs.crs_values_on_h, &worker)?; let q_2_sum_commitment = commit_using_values(&q_2_grand_sum_over_h, &crs.crs_values_on_h, &worker)?; - // TODO: check if it's better to reduce it to the single poly of degree 6K then to + // TODO: check if it's better to reduce it to the single poly of degree 6K then to // three independent ones of degree 2k - let beta_2 = E::Fr::from_str("456").unwrap(); - + let beta_2 = E::Fr::from_str("456").unwrap(); + // now calculate a polynomial f_3 over K using a definition fn evaluate_bivariate_lagrange_over_row_or_col_poly( x: F, vanishing_poly_size: u64, - row_or_col_evaluations_on_domain: &Polynomial, + row_or_col_evaluations_on_domain: &Polynomial, evaluate_on_domain: &Domain, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { assert!(evaluate_on_domain.size as usize == row_or_col_evaluations_on_domain.size()); let vanishing_at_x = evaluate_vanishing_for_size(&x, vanishing_poly_size); let inv_vanishing_at_x = vanishing_at_x.inverse().ok_or(SynthesisError::DivisionByZero)?; let mut inverses = row_or_col_evaluations_on_domain.clone(); - inverses.map(&worker, |element| { // (x - col(k))/van(x) + inverses.map(&worker, |element| { + // (x - col(k))/van(x) let mut tmp = x; tmp.sub_assign(&*element); tmp.mul_assign(&inv_vanishing_at_x); @@ -948,53 +885,17 @@ impl PreparedProver { let b_col_values_at_k = b_col_poly.fft(&worker); let c_col_values_at_k = c_col_poly.fft(&worker); - let r_beta_1_col_a_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly( - beta_1, - domain_h.size, - &a_col_values_at_k, - &domain_k, - &worker - )?; + let r_beta_1_col_a_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly(beta_1, domain_h.size, &a_col_values_at_k, &domain_k, &worker)?; - let r_beta_1_col_b_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly( - beta_1, - domain_h.size, - &b_col_values_at_k, - &domain_k, - &worker - )?; + let r_beta_1_col_b_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly(beta_1, domain_h.size, &b_col_values_at_k, &domain_k, &worker)?; - let r_beta_1_col_c_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly( - beta_1, - domain_h.size, - &c_col_values_at_k, - &domain_k, - &worker - )?; + let r_beta_1_col_c_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly(beta_1, domain_h.size, &c_col_values_at_k, &domain_k, &worker)?; - let r_beta_2_row_a_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly( - beta_2, - domain_h.size, - &a_row_values_at_k, - &domain_k, - &worker - )?; + let r_beta_2_row_a_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly(beta_2, domain_h.size, &a_row_values_at_k, &domain_k, &worker)?; - let r_beta_2_row_b_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly( - beta_2, - domain_h.size, - &b_row_values_at_k, - &domain_k, - &worker - )?; + let r_beta_2_row_b_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly(beta_2, domain_h.size, &b_row_values_at_k, &domain_k, &worker)?; - let r_beta_2_row_c_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly( - beta_2, - domain_h.size, - &c_row_values_at_k, - &domain_k, - &worker - )?; + let r_beta_2_row_c_values_over_k = evaluate_bivariate_lagrange_over_row_or_col_poly(beta_2, domain_h.size, &c_row_values_at_k, &domain_k, &worker)?; // do multiplication over K let mut f_3_a_values_over_k_by_eta_a = precomputations.a_val_over_k.clone(); @@ -1176,7 +1077,7 @@ impl PreparedProver { // this contains eta_M let mut tmp = q_3_a_by_eta_a_values_over_2k_coset; // into 2*K size - // tmp.scale(&worker, linearization_challenge); + // tmp.scale(&worker, linearization_challenge); tmp.mul_assign(&worker, &a_row_minus_beta_2_over_2k_coset); tmp.mul_assign(&worker, &a_col_minus_beta_1_over_2k_coset); @@ -1212,7 +1113,7 @@ impl PreparedProver { vanishing_degree: u64, coset_factor: &F, domain: &Domain, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { let domain_generator = domain.generator; @@ -1243,9 +1144,9 @@ impl PreparedProver { } // let mut vanishing_of_degree_k_on_2k = evaluate_vanishing_polynomial_of_degree_on_domain( - // domain_k.size, - // &E::Fr::multiplicative_generator(), - // &domain_2k, + // domain_k.size, + // &E::Fr::multiplicative_generator(), + // &domain_2k, // &worker // )?; @@ -1253,7 +1154,7 @@ impl PreparedProver { // f_3_well_formedness_poly_values_over_2k_coset.mul_assign(&worker, &vanishing_of_degree_k_on_2k); // drop(vanishing_of_degree_k_on_2k); - + // We can compute faster like this if domain is of size 2k // we divide by the polynomial that is vanishing on k, but not on 2k @@ -1284,16 +1185,10 @@ impl PreparedProver { let beta_3 = E::Fr::from_str("12345678890").unwrap(); - let f_3_well_formedness_baryc_at_beta_3 = f_3_well_formedness_poly_values_over_2k_coset.barycentric_over_coset_evaluate_at( - &worker, - beta_3, - &E::Fr::multiplicative_generator() - )?; + let f_3_well_formedness_baryc_at_beta_3 = f_3_well_formedness_poly_values_over_2k_coset.barycentric_over_coset_evaluate_at(&worker, beta_3, &E::Fr::multiplicative_generator())?; - let (f_3_even_values_on_k, f_3_odd_values_on_k) = f_3_well_formedness_poly_values_over_2k_coset.split_into_even_and_odd_assuming_natural_ordering( - &worker, - &E::Fr::multiplicative_generator() - )?; + let (f_3_even_values_on_k, f_3_odd_values_on_k) = + f_3_well_formedness_poly_values_over_2k_coset.split_into_even_and_odd_assuming_natural_ordering(&worker, &E::Fr::multiplicative_generator())?; // TODO: commit to the linear combination using some other linearization challenge @@ -1360,15 +1255,9 @@ impl PreparedProver { let col_b_eval = params.b_col_poly.evaluate_at(&worker, beta_3); let col_c_eval = params.c_col_poly.evaluate_at(&worker, beta_3); - let polys_for_opening_for_domain_k_at_beta_3_by_gen = vec![ - f_3_even_values_on_k, - f_3_odd_values_on_k, - ]; + let polys_for_opening_for_domain_k_at_beta_3_by_gen = vec![f_3_even_values_on_k, f_3_odd_values_on_k]; - let values_for_opening_for_domain_k_at_beta_3_by_gen = vec![ - f_3_even_eval, - f_3_odd_eval, - ]; + let values_for_opening_for_domain_k_at_beta_3_by_gen = vec![f_3_even_eval, f_3_odd_eval]; let challenge_1 = E::Fr::from_str("99999").unwrap(); @@ -1378,7 +1267,7 @@ impl PreparedProver { &values_for_opening_for_domain_k_at_beta_3_by_gen, challenge_1, E::Fr::one(), - &worker + &worker, )?; let polys_for_opening_for_domain_k_at_beta_3 = vec![ @@ -1423,23 +1312,15 @@ impl PreparedProver { &values_for_opening_for_domain_k_at_beta_3, challenge_1, next_challenge, - &worker + &worker, )?; aggregation_on_k.add_assign(&worker, &aggregation_at_beta_3); drop(aggregation_at_beta_3); - let polys_for_opening_for_domain_k_at_beta_3_by_omega = vec![ - q_3_a_by_eta_a_grand_sum_over_k, - q_3_b_by_eta_b_grand_sum_over_k, - q_3_c_by_eta_c_grand_sum_over_k, - ]; + let polys_for_opening_for_domain_k_at_beta_3_by_omega = vec![q_3_a_by_eta_a_grand_sum_over_k, q_3_b_by_eta_b_grand_sum_over_k, q_3_c_by_eta_c_grand_sum_over_k]; - let values_for_opening_for_domain_k_at_beta_3_by_omega = vec![ - q_3_a_by_eta_a_sum_eval_shifted, - q_3_b_by_eta_b_sum_eval_shifted, - q_3_c_by_eta_c_sum_eval_shifted, - ]; + let values_for_opening_for_domain_k_at_beta_3_by_omega = vec![q_3_a_by_eta_a_sum_eval_shifted, q_3_b_by_eta_b_sum_eval_shifted, q_3_c_by_eta_c_sum_eval_shifted]; let (aggregation_at_beta_3_by_omega, _) = perform_batched_divisor_for_opening::( polys_for_opening_for_domain_k_at_beta_3_by_omega, @@ -1447,20 +1328,15 @@ impl PreparedProver { &values_for_opening_for_domain_k_at_beta_3_by_omega, challenge_1, next_challenge, - &worker + &worker, )?; aggregation_on_k.add_assign(&worker, &aggregation_at_beta_3_by_omega); drop(aggregation_at_beta_3_by_omega); - let proof_on_k = commit_using_values( - &aggregation_on_k, - &crs.crs_values_on_k, - &worker - )?; - + let proof_on_k = commit_using_values(&aggregation_on_k, &crs.crs_values_on_k, &worker)?; - // TODO: add aggregate here to compute for openings of individual + // TODO: add aggregate here to compute for openings of individual // f_3_a_values_over_k_by_eta_a, // f_3_b_values_over_k_by_eta_b, // f_3_c_values_over_k_by_eta_c, @@ -1490,7 +1366,6 @@ impl PreparedProver { // let q_3_b_by_eta_b_sum_eval_shifted = q_3_b_by_eta_b_grand_sum_over_k.barycentric_evaluate_at(&worker, beta_2_by_omega)?; // let q_3_c_by_eta_c_sum_eval_shifted = q_3_c_by_eta_c_grand_sum_over_k.barycentric_evaluate_at(&worker, beta_2_by_omega)?; - // let challenge_2 = E::Fr::from_str("999991234").unwrap(); // let polys_for_opening_for_domain_k_at_beta_3 = vec![ @@ -1560,15 +1435,9 @@ impl PreparedProver { let q_2_sum_eval_at_beta_2 = q_2_grand_sum_over_h.barycentric_evaluate_at(&worker, beta_2)?; let q_2_sum_eval_at_beta_2_shifted = q_2_grand_sum_over_h.barycentric_evaluate_at(&worker, beta_2_by_omega)?; - let polys_for_opening_for_domain_h_at_beta_2 = vec![ - q_2_poly_values_on_h, - q_2_grand_sum_over_h.clone(), - ]; + let polys_for_opening_for_domain_h_at_beta_2 = vec![q_2_poly_values_on_h, q_2_grand_sum_over_h.clone()]; - let values_for_opening_for_domain_h_at_beta_2 = vec![ - q_2_eval_at_beta_2, - q_2_sum_eval_at_beta_2, - ]; + let values_for_opening_for_domain_h_at_beta_2 = vec![q_2_eval_at_beta_2, q_2_sum_eval_at_beta_2]; let (mut aggregation_on_h, next_challenge) = perform_batched_divisor_for_opening::( polys_for_opening_for_domain_h_at_beta_2, @@ -1576,16 +1445,12 @@ impl PreparedProver { &values_for_opening_for_domain_h_at_beta_2, challenge_2, E::Fr::one(), - &worker + &worker, )?; - let polys_for_opening_for_domain_h_at_beta_2_by_omega = vec![ - q_2_grand_sum_over_h, - ]; + let polys_for_opening_for_domain_h_at_beta_2_by_omega = vec![q_2_grand_sum_over_h]; - let values_for_opening_for_domain_h_at_beta_2_by_omega = vec![ - q_2_sum_eval_at_beta_2_shifted, - ]; + let values_for_opening_for_domain_h_at_beta_2_by_omega = vec![q_2_sum_eval_at_beta_2_shifted]; let (aggregation_at_beta_2_by_omega, next_challenge) = perform_batched_divisor_for_opening::( polys_for_opening_for_domain_h_at_beta_2_by_omega, @@ -1593,10 +1458,9 @@ impl PreparedProver { &values_for_opening_for_domain_h_at_beta_2_by_omega, challenge_2, next_challenge, - &worker + &worker, )?; - aggregation_on_h.add_assign(&worker, &aggregation_at_beta_2_by_omega); drop(aggregation_at_beta_2_by_omega); @@ -1641,7 +1505,7 @@ impl PreparedProver { &values_for_opening_for_domain_h_at_beta_1, challenge_2, next_challenge, - &worker + &worker, )?; aggregation_on_h.add_assign(&worker, &aggregation_at_beta_1); @@ -1669,19 +1533,11 @@ impl PreparedProver { // this is an opening for everything on H - let proof_on_h = commit_using_values( - &aggregation_on_h, - &crs.crs_values_on_h, - &worker - )?; + let proof_on_h = commit_using_values(&aggregation_on_h, &crs.crs_values_on_h, &worker)?; // fun time - do the checks - fn compute_from_even_and_odd( - even: F, - odd: F, - at: F, - ) -> F { + fn compute_from_even_and_odd(even: F, odd: F, at: F) -> F { let mut res = odd; res.mul_assign(&at); res.add_assign(&even); @@ -1717,7 +1573,7 @@ impl PreparedProver { let mut tmp = vanishing_on_beta_1_by_vanishing_on_beta_2; tmp.mul_assign(&val_a_at_beta_3); tmp.mul_assign(&eta_a); - + let mut t_row = beta_2; t_row.sub_assign(&row_a_at_beta_3); @@ -1736,7 +1592,7 @@ impl PreparedProver { let mut tmp = vanishing_on_beta_1_by_vanishing_on_beta_2; tmp.mul_assign(&val_b_at_beta_3); tmp.mul_assign(&eta_b); - + let mut t_row = beta_2; t_row.sub_assign(&row_b_at_beta_3); @@ -1755,7 +1611,7 @@ impl PreparedProver { let mut tmp = vanishing_on_beta_1_by_vanishing_on_beta_2; tmp.mul_assign(&val_c_at_beta_3); tmp.mul_assign(&eta_c); - + let mut t_row = beta_2; t_row.sub_assign(&row_c_at_beta_3); @@ -1775,7 +1631,7 @@ impl PreparedProver { assert_eq!(lhs, rhs, "f_3 wellformedness check"); // sumchecks for q_3_m polys - + let mut sigma_3_a_over_size_of_k = one_over_k; sigma_3_a_over_size_of_k.mul_assign(&sigma_3_a); @@ -1817,11 +1673,7 @@ impl PreparedProver { { // r(alpha, beta_2) * sigma_3 = sigma_2 - let r_alpha_beta_2 = evaluate_bivariate_lagrange_at_point( - alpha, - beta_2, - domain_h.size - )?; + let r_alpha_beta_2 = evaluate_bivariate_lagrange_at_point(alpha, beta_2, domain_h.size)?; println!("r(alpha, beta_2) = {}", r_alpha_beta_2); @@ -1881,11 +1733,7 @@ impl PreparedProver { { // reconstruct value of r(alpha, beta_1) * \sum_{m} z_m(beta_1) - (sum{m} M(beta_1, alpha)) * w(beta_1) = q_1(beta_1) - let r_alpha_beta_1 = evaluate_bivariate_lagrange_at_point( - alpha, - beta_1, - domain_h.size - )?; + let r_alpha_beta_1 = evaluate_bivariate_lagrange_at_point(alpha, beta_1, domain_h.size)?; let mut lhs = sum_a_b_c_at_beta_1; lhs.mul_assign(&r_alpha_beta_1); @@ -1947,7 +1795,7 @@ impl PreparedProver { let mut rhs = h_at_beta_1; rhs.mul_assign(&vanishing_at_beta_1); - + assert!(lhs == rhs, "ab - c == h * z_H"); } @@ -1955,7 +1803,7 @@ impl PreparedProver { // now we need to perform all the openings - // For domain K: + // For domain K: // - val_a_at_z, val_b_at_z, val_c_at_z // - row_a_at_z, row_b_at_z, row_c_at_z // - col_a_at_z, col_b_at_z, col_c_at_z @@ -1966,7 +1814,7 @@ impl PreparedProver { // - q_3_c_by_eta_a_commitment at z, // - q_3_c_by_eta_a_sum_commitment at z and at z*omega - // For domain 2K (and we can move it into two openings on K): + // For domain 2K (and we can move it into two openings on K): // - f_3_well_formedness_poly_at_z // for domain H: @@ -1974,14 +1822,10 @@ impl PreparedProver { // - q_1_at_z, q_1_sum_at_z, q_1_sum_at_z_omega // - q_2_at_z, q_2_sum_at_z, q_2_sum_at_z_omega - - // // ------------------------------------------- // // sanity checks - - // let q_3_a_by_eta_a_at_z = q_3_a_by_eta_a_poly_coeffs.evaluate_at(&worker, z); // let q_3_b_by_eta_b_at_z = q_3_b_by_eta_b_poly_coeffs.evaluate_at(&worker, z); // let q_3_c_by_eta_c_at_z = q_3_c_by_eta_c_poly_coeffs.evaluate_at(&worker, z); @@ -2004,7 +1848,7 @@ impl PreparedProver { // let mut tmp = vanishing_on_beta_1_by_vanishing_on_beta_2; // tmp.mul_assign(&val_a_at_z); // tmp.mul_assign(&eta_a); - + // let mut t_row = beta_2; // t_row.sub_assign(&row_a_at_z); @@ -2023,7 +1867,7 @@ impl PreparedProver { // let mut tmp = vanishing_on_beta_1_by_vanishing_on_beta_2; // tmp.mul_assign(&val_b_at_z); // tmp.mul_assign(&eta_b); - + // let mut t_row = beta_2; // t_row.sub_assign(&row_b_at_z); @@ -2042,7 +1886,7 @@ impl PreparedProver { // let mut tmp = vanishing_on_beta_1_by_vanishing_on_beta_2; // tmp.mul_assign(&val_c_at_z); // tmp.mul_assign(&eta_c); - + // let mut t_row = beta_2; // t_row.sub_assign(&row_c_at_z); @@ -2094,71 +1938,54 @@ impl PreparedProver { impl ConstraintSystem for ProvingAssignment { type Root = Self; - fn alloc( - &mut self, - _: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc(&mut self, _: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { self.aux_assignment.push(f()?); Ok(Variable(Index::Aux(self.aux_assignment.len() - 1))) } - fn alloc_input( - &mut self, - _: A, - f: F - ) -> Result - where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into + fn alloc_input(&mut self, _: A, f: F) -> Result + where + F: FnOnce() -> Result, + A: FnOnce() -> AR, + AR: Into, { self.input_assignment.push(f()?); Ok(Variable(Index::Input(self.input_assignment.len() - 1))) } - fn enforce( - &mut self, - _: A, - a: LA, - b: LB, - c: LC - ) - where A: FnOnce() -> AR, AR: Into, - LA: FnOnce(LinearCombination) -> LinearCombination, - LB: FnOnce(LinearCombination) -> LinearCombination, - LC: FnOnce(LinearCombination) -> LinearCombination + fn enforce(&mut self, _: A, a: LA, b: LB, c: LC) + where + A: FnOnce() -> AR, + AR: Into, + LA: FnOnce(LinearCombination) -> LinearCombination, + LB: FnOnce(LinearCombination) -> LinearCombination, + LC: FnOnce(LinearCombination) -> LinearCombination, { let a = a(LinearCombination::zero()); let b = b(LinearCombination::zero()); let c = c(LinearCombination::zero()); - self.a.push(eval( - a, - &self.input_assignment, - &self.aux_assignment - )); - self.b.push(eval( - b, - &self.input_assignment, - &self.aux_assignment - )); - self.c.push(eval( - c, - &self.input_assignment, - &self.aux_assignment - )); + self.a.push(eval(a, &self.input_assignment, &self.aux_assignment)); + self.b.push(eval(b, &self.input_assignment, &self.aux_assignment)); + self.c.push(eval(c, &self.input_assignment, &self.aux_assignment)); } fn push_namespace(&mut self, _: N) - where NR: Into, N: FnOnce() -> NR + where + NR: Into, + N: FnOnce() -> NR, { // Do nothing; we don't care about namespaces in this context. } - fn pop_namespace(&mut self) - { + fn pop_namespace(&mut self) { // Do nothing; we don't care about namespaces in this context. } @@ -2180,12 +2007,10 @@ impl ConstraintSystem for ProvingAssignment { // create_proof::(circuit, params, r, s) // } -pub fn create_proof( - circuit: C, - params: &IndexedSetup, - bases: &PrecomputedBases, -) -> Result<(), SynthesisError> - where E: Engine, C: Circuit +pub fn create_proof(circuit: C, params: &IndexedSetup, bases: &PrecomputedBases) -> Result<(), SynthesisError> +where + E: Engine, + C: Circuit, { let worker = Worker::new(); println!("Start making precomputations"); @@ -2196,9 +2021,7 @@ pub fn create_proof( prover.create_proof(params, &bases, &precomputations) } -pub fn test_over_engine_and_circuit + Clone>( - circuit: C, -) { +pub fn test_over_engine_and_circuit + Clone>(circuit: C) { let params = generate_parameters(circuit.clone()).unwrap(); let worker = Worker::new(); @@ -2210,10 +2033,7 @@ pub fn test_over_engine_and_circuit + Clone>( let _ = create_proof(circuit, ¶ms, &bases).unwrap(); } -pub fn test_over_engine_and_circuit_with_proving_key + Clone>( - circuit: C, - base_path: String -) { +pub fn test_over_engine_and_circuit_with_proving_key + Clone>(circuit: C, base_path: String) { let params = generate_parameters(circuit.clone()).unwrap(); let bases = read_test_keys::(base_path); @@ -2224,11 +2044,7 @@ pub fn test_over_engine_and_circuit_with_proving_key + let _ = create_proof(circuit, ¶ms, &bases).unwrap(); } -pub fn serialize_bases>( - bases: &PrecomputedBases, - h_file_path: P, - k_file_path: P -) -> std::io::Result<()> { +pub fn serialize_bases>(bases: &PrecomputedBases, h_file_path: P, k_file_path: P) -> std::io::Result<()> { // let mut h_writer = std::fs::File::open(h_file_path)?; // let mut k_writer = std::fs::File::open(k_file_path)?; @@ -2241,17 +2057,14 @@ pub fn serialize_bases>( Ok(()) } -pub fn deserialize_bases>( - h_file_path: P, - k_file_path: P -) -> Result, SynthesisError> { +pub fn deserialize_bases>(h_file_path: P, k_file_path: P) -> Result, SynthesisError> { let mut h_reader = std::fs::File::open(h_file_path)?; let mut k_reader = std::fs::File::open(k_file_path)?; let h_values = Crs::::read(&mut h_reader)?; let k_values = Crs::::read(&mut k_reader)?; - let new = PrecomputedBases::{ + let new = PrecomputedBases:: { crs_values_on_h: h_values, crs_values_on_k: k_values, }; @@ -2259,10 +2072,7 @@ pub fn deserialize_bases>( Ok(new) } -pub fn create_test_keys + Clone>( - circuit: C, - base_file_name: String -) { +pub fn create_test_keys + Clone>(circuit: C, base_file_name: String) { let params = generate_parameters(circuit.clone()).unwrap(); let path_h = format!("{}_h.key", base_file_name); @@ -2275,9 +2085,7 @@ pub fn create_test_keys + Clone>( serialize_bases(&bases, &path_h, &path_k).expect("must serialize the bases"); } -pub fn read_test_keys( - base_file_name: String -) -> PrecomputedBases { +pub fn read_test_keys(base_file_name: String) -> PrecomputedBases { let path_h = format!("{}_h.key", base_file_name); let path_k = format!("{}_k.key", base_file_name); @@ -2288,21 +2096,21 @@ pub fn read_test_keys( #[cfg(test)] mod test { - use crate::tests::XORDemo; + use super::super::generator::*; + use super::*; use crate::plonk::domains::*; + use crate::tests::XORDemo; use crate::worker::Worker; - use super::*; use std::marker::PhantomData; - use super::super::generator::*; #[test] fn test_proving_1() { - use crate::pairing::bn256::{Bn256}; + use crate::pairing::bn256::Bn256; let c = XORDemo:: { a: Some(true), b: Some(true), - _marker: PhantomData + _marker: PhantomData, }; test_over_engine_and_circuit(c); @@ -2312,13 +2120,8 @@ mod test { fn test_proving_2() { use crate::pairing::bn256::{Bn256, Fr}; - let c = IndexerTester:: { - a: None, - b: None, - }; + let c = IndexerTester:: { a: None, b: None }; test_over_engine_and_circuit(c); } - - -} \ No newline at end of file +} diff --git a/crates/bellman/src/multicore.rs b/crates/bellman/src/multicore.rs index abba18d..001d429 100644 --- a/crates/bellman/src/multicore.rs +++ b/crates/bellman/src/multicore.rs @@ -4,33 +4,32 @@ //! crossbeam but may be extended in the future to //! allow for various parallelism strategies. -extern crate num_cpus; -extern crate futures; extern crate crossbeam; +extern crate futures; +extern crate num_cpus; -use std::future::{Future}; +use std::future::Future; +use std::pin::Pin; use std::task::{Context, Poll}; -use std::pin::{Pin}; -use self::crossbeam::thread::{Scope}; +use self::crossbeam::thread::Scope; -use self::futures::future::{lazy}; -use self::futures::channel::oneshot::{channel, Sender, Receiver}; -use self::futures::executor::{block_on}; -use self::futures::executor::{ThreadPool}; +use self::futures::channel::oneshot::{channel, Receiver, Sender}; +use self::futures::executor::block_on; +use self::futures::executor::ThreadPool; +use self::futures::future::lazy; #[derive(Clone)] pub struct Worker { pub(crate) cpus: usize, - pool: ThreadPool + pool: ThreadPool, } - impl Worker { // We don't expose this outside the library so that // all `Worker` instances have the same number of // CPUs configured. - + pub fn new_with_cpus(cpus: usize) -> Worker { Worker { cpus: cpus, @@ -50,67 +49,52 @@ impl Worker { pub fn split_at(&self, at: usize) -> (Self, Self) { assert!(0 < at && at < self.cpus); - let first = Self { - cpus: at, - pool: self.pool.clone() - }; + let first = Self { cpus: at, pool: self.pool.clone() }; let second = Self { cpus: self.cpus - at, - pool: self.pool.clone() + pool: self.pool.clone(), }; (first, second) } - pub fn log_num_cpus(&self) -> u32 { log2_floor(self.cpus) } - pub fn compute( - &self, f: F - ) -> WorkerFuture - where F: FnOnce() -> Result + Send + 'static, - T: Send + 'static, - E: Send + 'static + pub fn compute(&self, f: F) -> WorkerFuture + where + F: FnOnce() -> Result + Send + 'static, + T: Send + 'static, + E: Send + 'static, { let (sender, receiver) = channel(); let lazy_future = lazy(move |_| { - let res = f(); + let res = f(); if !sender.is_canceled() { let _ = sender.send(res); } }); - let worker_future = WorkerFuture { - receiver - }; + let worker_future = WorkerFuture { receiver }; self.pool.spawn_ok(lazy_future); worker_future } - pub fn scope<'a, F, R>( - &self, - elements: usize, - f: F - ) -> R - where F: FnOnce(&Scope<'a>, usize) -> R + pub fn scope<'a, F, R>(&self, elements: usize, f: F) -> R + where + F: FnOnce(&Scope<'a>, usize) -> R, { let chunk_size = self.get_chunk_size(elements); - crossbeam::scope(|scope| { - f(scope, chunk_size) - }).expect("must run") + crossbeam::scope(|scope| f(scope, chunk_size)).expect("must run") } - pub fn get_chunk_size( - &self, - elements: usize - ) -> usize { + pub fn get_chunk_size(&self, elements: usize) -> usize { let chunk_size = if elements <= self.cpus { 1 } else { @@ -120,10 +104,7 @@ impl Worker { chunk_size } - pub fn get_num_spawned_threads( - &self, - elements: usize - ) -> usize { + pub fn get_num_spawned_threads(&self, elements: usize) -> usize { let num_spawned = if elements <= self.cpus { elements } else { @@ -132,7 +113,7 @@ impl Worker { if spawned * chunk < elements { spawned += 1; } - assert!(spawned <= 2*self.cpus); + assert!(spawned <= 2 * self.cpus); spawned }; @@ -151,23 +132,22 @@ impl Worker { } pub struct WorkerFuture { - receiver: Receiver> + receiver: Receiver>, } impl Future for WorkerFuture { type Output = Result; - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll - { + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { let rec = unsafe { self.map_unchecked_mut(|s| &mut s.receiver) }; match rec.poll(cx) { Poll::Ready(v) => { if let Ok(v) = v { - return Poll::Ready(v) + return Poll::Ready(v); } else { panic!("Worker future can not have canceled sender"); } - }, + } Poll::Pending => { return Poll::Pending; } @@ -186,7 +166,7 @@ fn log2_floor(num: usize) -> u32 { let mut pow = 0; - while (1 << (pow+1)) <= num { + while (1 << (pow + 1)) <= num { pow += 1; } diff --git a/crates/bellman/src/multiexp.rs b/crates/bellman/src/multiexp.rs index 3bd5904..eb12ff0 100644 --- a/crates/bellman/src/multiexp.rs +++ b/crates/bellman/src/multiexp.rs @@ -1,25 +1,17 @@ -use crate::pairing::{ - CurveAffine, - CurveProjective, - Engine -}; - -use crate::pairing::ff::{ - PrimeField, - Field, - PrimeFieldRepr, - ScalarEngine}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; + +use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine}; -use std::sync::Arc; use super::source::*; -use std::future::{Future}; +use std::future::Future; +use std::pin::Pin; +use std::sync::Arc; use std::task::{Context, Poll}; -use std::pin::{Pin}; extern crate futures; -use self::futures::future::{join_all, JoinAll}; use self::futures::executor::block_on; +use self::futures::future::{join_all, JoinAll}; use super::worker::{Worker, WorkerFuture}; @@ -32,7 +24,7 @@ use cfg_if; /// - make `2^c - 1` buckets and initialize them with `G = infinity` (that's equivalent of zero) /// - there is no bucket for "zero" cause it's not necessary /// - go over the pairs `(base, scalar)` -/// - for each scalar calculate `scalar % 2^c` and add the base (without any multiplications!) to the +/// - for each scalar calculate `scalar % 2^c` and add the base (without any multiplications!) to the /// corresponding bucket /// - at the end each bucket will have an accumulated value that should be multiplied by the corresponding factor /// between `1` and `2^c - 1` to get the right value @@ -46,7 +38,7 @@ use cfg_if; /// - spawn more threads until you exhaust all the bit length /// - you will get roughly `[bitlength / c] + 1` inaccumulators /// - double the highest accumulator enough times, add to the next one, double the result, add the next accumulator, continue -/// +/// /// Demo why it works: /// ```text /// a * G + b * H = (a_2 * (2^c)^2 + a_1 * (2^c)^1 + a_0) * G + (b_2 * (2^c)^2 + b_1 * (2^c)^1 + b_0) * H @@ -64,12 +56,13 @@ fn multiexp_inner( exponents: Arc::Repr>>, skip: u32, c: u32, - handle_trivial: bool -) -> WorkerFuture< ::Projective, SynthesisError> - where for<'a> &'a Q: QueryDensity, - D: Send + Sync + 'static + Clone + AsRef, - G: CurveAffine, - S: SourceBuilder + handle_trivial: bool, +) -> WorkerFuture<::Projective, SynthesisError> +where + for<'a> &'a Q: QueryDensity, + D: Send + Sync + 'static + Clone + AsRef, + G: CurveAffine, + S: SourceBuilder, { // Perform this region of the multiexp let this = { @@ -107,7 +100,7 @@ fn multiexp_inner( bases.skip(1)?; } } else { - // Place multiplication into the bucket: Separate s * P as + // Place multiplication into the bucket: Separate s * P as // (s/2^c) * P + (s mod 2^c) P // First multiplication is c bits less, so one can do it, // sum results from different buckets and double it c times, @@ -124,7 +117,7 @@ fn multiexp_inner( } } } - + // also measure this cycle: let start = std::time::Instant::now(); @@ -158,12 +151,13 @@ fn multiexp_inner_impl( exponents: Arc::Repr>>, skip: u32, c: u32, - handle_trivial: bool -) -> WorkerFuture< ::Projective, SynthesisError> - where for<'a> &'a Q: QueryDensity, - D: Send + Sync + 'static + Clone + AsRef, - G: CurveAffine, - S: SourceBuilder + handle_trivial: bool, +) -> WorkerFuture<::Projective, SynthesisError> +where + for<'a> &'a Q: QueryDensity, + D: Send + Sync + 'static + Clone + AsRef, + G: CurveAffine, + S: SourceBuilder, { multiexp_inner(pool, bases, density_map, exponents, skip, c, handle_trivial) // multiexp_inner_with_prefetch_stable(pool, bases, density_map, exponents, skip, c, handle_trivial) @@ -176,12 +170,13 @@ fn multiexp_inner_with_prefetch_stable( exponents: Arc::Repr>>, skip: u32, c: u32, - handle_trivial: bool -) -> WorkerFuture< ::Projective, SynthesisError> - where for<'a> &'a Q: QueryDensity, - D: Send + Sync + 'static + Clone + AsRef, - G: CurveAffine, - S: SourceBuilder + handle_trivial: bool, +) -> WorkerFuture<::Projective, SynthesisError> +where + for<'a> &'a Q: QueryDensity, + D: Send + Sync + 'static + Clone + AsRef, + G: CurveAffine, + S: SourceBuilder, { // Perform this region of the multiexp let this = { @@ -210,9 +205,7 @@ fn multiexp_inner_with_prefetch_stable( let mask = (1u64 << c) - 1; // Sort the bases into buckets - for ((&exp, &next_exp), density) in exponents.iter() - .zip(exponents.iter().skip(1).chain(padding.iter())) - .zip(density_map.as_ref().iter()) { + for ((&exp, &next_exp), density) in exponents.iter().zip(exponents.iter().skip(1).chain(padding.iter())).zip(density_map.as_ref().iter()) { // no matter what happens - prefetch next bucket if next_exp != zero && next_exp != one { let mut next_exp = next_exp; @@ -222,7 +215,6 @@ fn multiexp_inner_with_prefetch_stable( let p: *const ::Projective = &buckets[(next_exp - 1) as usize]; crate::prefetch::prefetch_l1_pointer(p); } - } // Go over density and exponents if density { @@ -235,7 +227,7 @@ fn multiexp_inner_with_prefetch_stable( bases.skip(1)?; } } else { - // Place multiplication into the bucket: Separate s * P as + // Place multiplication into the bucket: Separate s * P as // (s/2^c) * P + (s mod 2^c) P // First multiplication is c bits less, so one can do it, // sum results from different buckets and double it c times, @@ -270,15 +262,9 @@ fn multiexp_inner_with_prefetch_stable( this } - /// Perform multi-exponentiation. The caller is responsible for ensuring the /// query size is the same as the number of exponents. -pub fn future_based_multiexp( - pool: &Worker, - bases: Arc>, - exponents: Arc::Repr>> -) -> ChunksJoiner< ::Projective > -{ +pub fn future_based_multiexp(pool: &Worker, bases: Arc>, exponents: Arc::Repr>>) -> ChunksJoiner<::Projective> { assert!(exponents.len() <= bases.len()); let c = if exponents.len() < 32 { 3u32 @@ -295,7 +281,7 @@ pub fn future_based_multiexp( width += 1; } } - + width }; @@ -315,22 +301,17 @@ pub fn future_based_multiexp( let join = join_all(futures); - ChunksJoiner { - join, - c - } + ChunksJoiner { join, c } } - /// Perform multi-exponentiation. The caller is responsible for ensuring the /// query size is the same as the number of exponents. pub fn future_based_dense_multiexp_over_fixed_width_windows( pool: &Worker, bases: Arc>, exponents: Arc::Repr>>, - c: u32 -) -> ChunksJoiner< ::Projective > -{ + c: u32, +) -> ChunksJoiner<::Projective> { assert!(exponents.len() <= bases.len()); let mut skip = 0; @@ -351,10 +332,7 @@ pub fn future_based_dense_multiexp_over_fixed_width_windows( let join = join_all(futures); - ChunksJoiner { - join, - c - } + ChunksJoiner { join, c } } fn future_based_dense_multiexp_impl( @@ -363,9 +341,8 @@ fn future_based_dense_multiexp_impl( exponents: Arc::Repr>>, skip: u32, c: u32, - handle_trivial: bool -) -> WorkerFuture< ::Projective, SynthesisError> -{ + handle_trivial: bool, +) -> WorkerFuture<::Projective, SynthesisError> { // Perform this region of the multiexp let this = { let bases = bases.clone(); @@ -390,9 +367,7 @@ fn future_based_dense_multiexp_impl( let mask = 1 << c; // Sort the bases into buckets - for ((&exp, base), &next_exp) in exponents.iter() - .zip(bases.iter()) - .zip(exponents.iter().skip(1).chain(padding.iter())) { + for ((&exp, base), &next_exp) in exponents.iter().zip(bases.iter()).zip(exponents.iter().skip(1).chain(padding.iter())) { // no matter what happens - prefetch next bucket if next_exp != zero && next_exp != one { let mut next_exp = next_exp; @@ -402,19 +377,18 @@ fn future_based_dense_multiexp_impl( let p: *const ::Projective = &buckets[(next_exp - 1) as usize]; crate::prefetch::prefetch_l1_pointer(p); } - } // Go over density and exponents if exp == zero { - continue + continue; } else if exp == one { if handle_trivial { acc.add_assign_mixed(base); } else { - continue + continue; } } else { - // Place multiplication into the bucket: Separate s * P as + // Place multiplication into the bucket: Separate s * P as // (s/2^c) * P + (s mod 2^c) P // First multiplication is c bits less, so one can do it, // sum results from different buckets and double it c times, @@ -454,9 +428,8 @@ fn future_based_buffered_dense_multiexp_impl( exponents: Arc::Repr>>, skip: u32, c: u32, - handle_trivial: bool -) -> WorkerFuture< ::Projective, SynthesisError> -{ + handle_trivial: bool, +) -> WorkerFuture<::Projective, SynthesisError> { // Perform this region of the multiexp let this = { let bases = bases.clone(); @@ -483,19 +456,18 @@ fn future_based_buffered_dense_multiexp_impl( let mut buffers: Vec> = vec![Vec::with_capacity(BUFFER_SIZE); (1 << c) - 1]; // Sort the bases into buckets - for (&exp, &base) in exponents.iter() - .zip(bases.iter()) { + for (&exp, &base) in exponents.iter().zip(bases.iter()) { // Go over density and exponents if exp == zero { - continue + continue; } else if exp == one { if handle_trivial { acc.add_assign_mixed(&base); } else { - continue + continue; } } else { - // Place multiplication into the bucket: Separate s * P as + // Place multiplication into the bucket: Separate s * P as // (s/2^c) * P + (s mod 2^c) P // First multiplication is c bits less, so one can do it, // sum results from different buckets and double it c times, @@ -508,7 +480,7 @@ fn future_based_buffered_dense_multiexp_impl( let idx = (exp - 1) as usize; if buffers[idx].len() == BUFFER_SIZE { let mut el = buckets[idx]; - for b in buffers[idx].iter(){ + for b in buffers[idx].iter() { el.add_assign_mixed(&b); } buffers[idx].truncate(0); @@ -550,22 +522,14 @@ fn future_based_buffered_dense_multiexp_impl( /// Perform multi-exponentiation. The caller is responsible for ensuring the /// query size is the same as the number of exponents. -pub fn multiexp( - pool: &Worker, - bases: S, - density_map: D, - exponents: Arc::Fr as PrimeField>::Repr>> -) -> ChunksJoiner< ::Projective > - where for<'a> &'a Q: QueryDensity, - D: Send + Sync + 'static + Clone + AsRef, - G: CurveAffine, - S: SourceBuilder +pub fn multiexp(pool: &Worker, bases: S, density_map: D, exponents: Arc::Fr as PrimeField>::Repr>>) -> ChunksJoiner<::Projective> +where + for<'a> &'a Q: QueryDensity, + D: Send + Sync + 'static + Clone + AsRef, + G: CurveAffine, + S: SourceBuilder, { - let c = if exponents.len() < 32 { - 3u32 - } else { - (f64::from(exponents.len() as u32)).ln().ceil() as u32 - }; + let c = if exponents.len() < 32 { 3u32 } else { (f64::from(exponents.len() as u32)).ln().ceil() as u32 }; if let Some(query_size) = density_map.as_ref().get_query_size() { // If the density map has a known query size, it should not be @@ -590,10 +554,7 @@ pub fn multiexp( let join = join_all(futures); - ChunksJoiner { - join, - c - } + ChunksJoiner { join, c } } pub(crate) fn multiexp_with_fixed_width( @@ -601,12 +562,13 @@ pub(crate) fn multiexp_with_fixed_width( bases: S, density_map: D, exponents: Arc::Fr as PrimeField>::Repr>>, - c: u32 -) -> ChunksJoiner< ::Projective > - where for<'a> &'a Q: QueryDensity, - D: Send + Sync + 'static + Clone + AsRef, - G: CurveAffine, - S: SourceBuilder + c: u32, +) -> ChunksJoiner<::Projective> +where + for<'a> &'a Q: QueryDensity, + D: Send + Sync + 'static + Clone + AsRef, + G: CurveAffine, + S: SourceBuilder, { if let Some(query_size) = density_map.as_ref().get_query_size() { // If the density map has a known query size, it should not be @@ -631,29 +593,25 @@ pub(crate) fn multiexp_with_fixed_width( let join = join_all(futures); - ChunksJoiner { - join, - c - } + ChunksJoiner { join, c } } pub struct ChunksJoiner { - join: JoinAll< WorkerFuture >, - c: u32 + join: JoinAll>, + c: u32, } impl Future for ChunksJoiner { type Output = Result; - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll - { + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { let c = self.as_ref().c; let join = unsafe { self.map_unchecked_mut(|s| &mut s.join) }; match join.poll(cx) { Poll::Ready(v) => { let v = join_chunks(v, c); return Poll::Ready(v); - }, + } Poll::Pending => { return Poll::Pending; } @@ -667,8 +625,7 @@ impl ChunksJoiner { } } -fn join_chunks - (chunks: Vec>, c: u32) -> Result { +fn join_chunks(chunks: Vec>, c: u32) -> Result { if chunks.len() == 0 { return Ok(G::zero()); } @@ -689,21 +646,15 @@ fn join_chunks Ok(higher) } - /// Perform multi-exponentiation. The caller is responsible for ensuring that /// the number of bases is the same as the number of exponents. #[allow(dead_code)] -pub fn dense_multiexp( - pool: &Worker, - bases: & [G], - exponents: & [<::Fr as PrimeField>::Repr] -) -> Result<::Projective, SynthesisError> -{ +pub fn dense_multiexp(pool: &Worker, bases: &[G], exponents: &[<::Fr as PrimeField>::Repr]) -> Result<::Projective, SynthesisError> { if exponents.len() != bases.len() { return Err(SynthesisError::AssignmentMissing); } // do some heuristics here - // we proceed chunks of all points, and all workers do the same work over + // we proceed chunks of all points, and all workers do the same work over // some scalar width, so to have expected number of additions into buckets to 1 // we have to take log2 from the expected chunk(!) length let c = if exponents.len() < 32 { @@ -721,14 +672,13 @@ pub fn dense_multiexp( fn dense_multiexp_inner( pool: &Worker, - bases: & [G], - exponents: & [<::Fr as PrimeField>::Repr], + bases: &[G], + exponents: &[<::Fr as PrimeField>::Repr], mut skip: u32, c: u32, - handle_trivial: bool -) -> Result<::Projective, SynthesisError> -{ - use std::sync::{Mutex}; + handle_trivial: bool, +) -> Result<::Projective, SynthesisError> { + use std::sync::Mutex; // Perform this region of the multiexp. We use a different strategy - go over region in parallel, // then over another region, etc. No Arc required let this = { @@ -738,7 +688,7 @@ fn dense_multiexp_inner( pool.scope(bases.len(), |scope, chunk| { for (base, exp) in bases.chunks(chunk).zip(exponents.chunks(chunk)) { let this_region_rwlock = arc.clone(); - // let handle = + // let handle = scope.spawn(move |_| { let mut buckets = vec![::Projective::zero(); (1 << c) - 1]; // Accumulate the result @@ -781,14 +731,13 @@ fn dense_multiexp_inner( let mut guard = match this_region_rwlock.lock() { Ok(guard) => guard, Err(_) => { - panic!("poisoned!"); + panic!("poisoned!"); // poisoned.into_inner() } }; (*guard).add_assign(&acc); }); - } }); @@ -805,8 +754,7 @@ fn dense_multiexp_inner( return Ok(this); } else { // next region is actually higher than this one, so double it enough times - let mut next_region = dense_multiexp_inner( - pool, bases, exponents, skip, c, false).unwrap(); + let mut next_region = dense_multiexp_inner(pool, bases, exponents, skip, c, false).unwrap(); for _ in 0..c { next_region.double(); } @@ -838,11 +786,7 @@ fn get_window_size_for_length(length: usize, chunk_length: usize) -> u32 { mod test { use super::*; - fn naive_multiexp( - bases: Arc>, - exponents: Arc::Repr>> - ) -> G::Projective - { + fn naive_multiexp(bases: Arc>, exponents: Arc::Repr>>) -> G::Projective { assert_eq!(bases.len(), exponents.len()); let mut acc = G::Projective::zero(); @@ -856,8 +800,8 @@ mod test { #[test] fn test_new_multiexp_with_bls12() { - use rand::{self, Rand}; use crate::pairing::bls12_381::Bls12; + use rand::{self, Rand}; use self::futures::executor::block_on; @@ -871,23 +815,15 @@ mod test { let pool = Worker::new(); - let fast = block_on( - multiexp( - &pool, - (g, 0), - FullDensity, - v - ) - ).unwrap(); + let fast = block_on(multiexp(&pool, (g, 0), FullDensity, v)).unwrap(); assert_eq!(naive, fast); } - #[test] fn test_valid_bn254_multiexp() { - use rand::{self, Rand}; use crate::pairing::bn256::Bn256; + use rand::{self, Rand}; const SAMPLES: usize = 1 << 22; @@ -896,11 +832,7 @@ mod test { let rng = &mut rand::thread_rng(); let v = (0..SAMPLES).map(|_| ::Fr::rand(rng).into_repr()).collect::>(); let g = (0..SAMPLES).map(|_| ::G1::rand(rng).into_affine()).collect::>(); - let dense = dense_multiexp( - &pool, - &g, - &v, - ).unwrap(); + let dense = dense_multiexp(&pool, &g, &v).unwrap(); let v = Arc::new(v); let g = Arc::new(g); @@ -911,22 +843,11 @@ mod test { use self::futures::executor::block_on; - let fast_dense = future_based_multiexp( - &pool, - g.clone(), - v.clone() - ).wait().unwrap(); + let fast_dense = future_based_multiexp(&pool, g.clone(), v.clone()).wait().unwrap(); assert_eq!(naive, fast_dense); - let fast = block_on( - multiexp( - &pool, - (g, 0), - FullDensity, - v - ) - ).unwrap(); + let fast = block_on(multiexp(&pool, (g, 0), FullDensity, v)).unwrap(); assert_eq!(naive, fast); } @@ -934,10 +855,9 @@ mod test { #[test] #[ignore] fn test_new_multexp_speed_with_bn256() { - - use rand::{self, Rand}; use crate::pairing::bn256::Bn256; use num_cpus; + use rand::{self, Rand}; let cpus = num_cpus::get(); const SAMPLES: usize = 1 << 22; @@ -952,18 +872,11 @@ mod test { let start = std::time::Instant::now(); - let _fast = block_on( - multiexp( - &pool, - (g, 0), - FullDensity, - v - ) - ).unwrap(); + let _fast = block_on(multiexp(&pool, (g, 0), FullDensity, v)).unwrap(); let duration_ns = start.elapsed().as_nanos() as f64; println!("Elapsed {} ns for {} samples", duration_ns, SAMPLES); - let time_per_sample = duration_ns/(SAMPLES as f64); + let time_per_sample = duration_ns / (SAMPLES as f64); println!("Tested on {} samples on {} CPUs with {} ns per multiplication", SAMPLES, cpus, time_per_sample); } @@ -973,11 +886,7 @@ mod test { chunk_len += 1; } let raw_size = (f64::from(chunk_len as u32)).ln(); - let new_window_size = if raw_size.floor() + 0.5 < raw_size { - raw_size.ceil() as u32 - } else { - raw_size.floor() as u32 - }; + let new_window_size = if raw_size.floor() + 0.5 < raw_size { raw_size.ceil() as u32 } else { raw_size.floor() as u32 }; let window_size = (f64::from(chunk_len as u32)).ln().ceil() as u32; let mut num_windows = bits / window_size; @@ -993,7 +902,10 @@ mod test { num_uncompensated_windows += 1; } - println!("For size {} and {} cores: chunk len {}, {} windows, average window {} bits, leftover {} bits. Alternative window size = {}", size, threads, chunk_len, num_windows, window_size, leftover, new_window_size); + println!( + "For size {} and {} cores: chunk len {}, {} windows, average window {} bits, leftover {} bits. Alternative window size = {}", + size, threads, chunk_len, num_windows, window_size, leftover, new_window_size + ); // println!("Raw window size = {}", raw_size); // println!("Uncompensated: {} windows, arevage window {} bits, leftover {} bits", num_uncompensated_windows, uncompensated_window, uncompensated_leftover); @@ -1002,7 +914,7 @@ mod test { #[test] fn test_sizes_for_bn254() { - let sizes = vec![1<<23, 1<<24]; + let sizes = vec![1 << 23, 1 << 24]; let cores = vec![8, 12, 16, 24, 32, 48]; for size in sizes { for &core in &cores { @@ -1013,8 +925,8 @@ mod test { #[test] fn bench_bls_addition() { - use rand::{self, Rand}; use crate::pairing::bls12_381::Bls12; + use rand::{self, Rand}; let size = 100000u32; let rng = &mut rand::thread_rng(); @@ -1024,22 +936,24 @@ mod test { let start = std::time::Instant::now(); - let C = (0..size).map(|i| { - let mut temp = A[i as usize]; - temp.add_assign(&B[i as usize]); - temp - }).collect::>(); + let C = (0..size) + .map(|i| { + let mut temp = A[i as usize]; + temp.add_assign(&B[i as usize]); + temp + }) + .collect::>(); let duration_ns = start.elapsed().as_nanos() as f64; println!("Elapsed {} ns for {} samples", duration_ns, size); - let time_per_sample = duration_ns/(size as f64); + let time_per_sample = duration_ns / (size as f64); println!("Elapsed {} ns per sample", time_per_sample); } - + #[test] fn bench_bls_doubling() { - use rand::{self, Rand}; use crate::pairing::bls12_381::Bls12; + use rand::{self, Rand}; let size = 100000u32; let rng = &mut rand::thread_rng(); @@ -1048,22 +962,24 @@ mod test { let start = std::time::Instant::now(); - let B = (0..size).map(|i| { - let mut temp = A[i as usize]; - temp.double(); - temp - }).collect::>(); + let B = (0..size) + .map(|i| { + let mut temp = A[i as usize]; + temp.double(); + temp + }) + .collect::>(); let duration_ns = start.elapsed().as_nanos() as f64; println!("Elapsed {} ns for {} samples", duration_ns, size); - let time_per_sample = duration_ns/(size as f64); + let time_per_sample = duration_ns / (size as f64); println!("Elapsed {} ns per sample", time_per_sample); } #[test] fn bench_Pippenger_with_small_chunk() { - use rand::{self, Rand}; use crate::pairing::bls12_381::Bls12; + use rand::{self, Rand}; let size = 1000000u32; let rng = &mut rand::thread_rng(); @@ -1076,19 +992,11 @@ mod test { let start = std::time::Instant::now(); - let fast = block_on( - multiexp( - &pool, - (g, 0), - FullDensity, - v - ) - ).unwrap(); + let fast = block_on(multiexp(&pool, (g, 0), FullDensity, v)).unwrap(); let duration_ns = start.elapsed().as_nanos() as f64; println!("Elapsed {} ns for Pippenger", duration_ns); - let time_per_sample = duration_ns/(size as f64); + let time_per_sample = duration_ns / (size as f64); println!("Elapsed {} ns per sample", time_per_sample); - } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/adaptor/alternative.rs b/crates/bellman/src/plonk/adaptor/alternative.rs index 934607c..765a382 100644 --- a/crates/bellman/src/plonk/adaptor/alternative.rs +++ b/crates/bellman/src/plonk/adaptor/alternative.rs @@ -1,19 +1,19 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; use crate::SynthesisError; -use crate::plonk::cs::gates::Gate; use crate::plonk::cs::gates::Coeff; -use crate::plonk::cs::gates::Variable as PlonkVariable; +use crate::plonk::cs::gates::Gate; use crate::plonk::cs::gates::Index as PlonkIndex; +use crate::plonk::cs::gates::Variable as PlonkVariable; use crate::plonk::cs::Circuit as PlonkCircuit; use crate::plonk::cs::ConstraintSystem as PlonkConstraintSystem; use std::marker::PhantomData; -use std::collections::{HashSet, HashMap}; +use std::collections::{HashMap, HashSet}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MergeLcVariant { @@ -34,8 +34,8 @@ pub enum TranspilationVariant { IntoSingleAdditionGate((E::Fr, E::Fr, E::Fr, E::Fr)), IntoMultipleAdditionGates((E::Fr, E::Fr, E::Fr, E::Fr), Vec), MergeLinearCombinations((MergeLcVariant, E::Fr, Box>)), - IsConstant(E::Fr), - TransformLc(Box<(TranspilationVariant, TranspilationVariant, TranspilationVariant)>) + IsConstant(E::Fr), + TransformLc(Box<(TranspilationVariant, TranspilationVariant, TranspilationVariant)>), } impl std::fmt::Debug for TranspilationVariant { @@ -44,37 +44,37 @@ impl std::fmt::Debug for TranspilationVariant { TranspilationVariant::LeaveAsSingleVariable(c) => { writeln!(f, "Variant: leave LC as a single variable")?; writeln!(f, "With coefficient {}", c)?; - }, + } TranspilationVariant::IntoQuandaticGate(c) => { writeln!(f, "Variant: into quadratic gate")?; writeln!(f, "{} + {} * x + {} * x^2", c.0, c.1, c.2)?; - }, + } TranspilationVariant::IntoLinearGate(c) => { writeln!(f, "Variant: into linear gate")?; writeln!(f, "{} + {} * x", c.0, c.1)?; - }, + } TranspilationVariant::IntoSingleAdditionGate(c) => { writeln!(f, "Variant: into single addition gate")?; writeln!(f, "{}*a + {}*b + {}*c + {} = 0", c.0, c.1, c.2, c.3)?; - }, + } TranspilationVariant::IntoMultipleAdditionGates(c, next) => { writeln!(f, "Variant: into multiple addition gates")?; writeln!(f, "{}*a + {}*b + {}*c + {} = 0", c.0, c.1, c.2, c.3)?; writeln!(f, "{:?}", next)?; - }, + } TranspilationVariant::MergeLinearCombinations(c) => { writeln!(f, "Variant: merge linear combinations")?; writeln!(f, "Merge with hint: {:?}", c.0)?; - }, + } TranspilationVariant::IsConstant(c) => { writeln!(f, "Variant: into constant factor {}", c)?; - }, + } TranspilationVariant::TransformLc(b) => { writeln!(f, "Variant: into combinatoric transform LC")?; writeln!(f, "A: {:?}", b.as_ref().0)?; writeln!(f, "B: {:?}", b.as_ref().1)?; writeln!(f, "C: {:?}", b.as_ref().2)?; - }, + } } Ok(()) @@ -114,17 +114,12 @@ impl Transpiler { current_lc_number } - fn enforce_lc_as_gates( - &mut self, - lc: LinearCombination, - multiplier: E::Fr, - free_term_constant: E::Fr - ) -> TranspilationVariant { + fn enforce_lc_as_gates(&mut self, lc: LinearCombination, multiplier: E::Fr, free_term_constant: E::Fr) -> TranspilationVariant { // let zero_fr = E::Fr::zero(); let one_fr = E::Fr::one(); let (lc, mut constant_coeff) = split_constant_term::(lc); - + let (contains_constant, num_linear_terms) = num_unique_values::(&lc, &mut self.scratch); assert!(!contains_constant, "must have split constant term before"); assert!(num_linear_terms > 0); @@ -135,7 +130,7 @@ impl Transpiler { // let hint = TranspilationVariant::::LeaveAsSingleVariable(coeff); // return hint - // } + // } // else if num_linear_terms == 1 && (contains_constant || free_term_constant != zero_fr) { // let (_, mut constant_coeff) = get_constant_term::(&lc); // let (_, single_var, mut linear_coeff) = get_first_variable_with_coeff::(&lc); @@ -148,7 +143,7 @@ impl Transpiler { // return hint; // } - // else + // else if num_linear_terms <= 3 { let (mut a_coef, mut b_coef, mut c_coef) = rewrite_lc_into_single_enforcement_gate(&lc, self, &mut (self.scratch.clone())); // we've made a sinlge addition gate, but we may need to scale it (my multipler) @@ -169,7 +164,7 @@ impl Transpiler { constant_coeff.sub_assign(&free_term_constant); } - + let hint = TranspilationVariant::::IntoSingleAdditionGate((a_coef, b_coef, c_coef, constant_coeff)); return hint; @@ -204,7 +199,7 @@ impl Transpiler { fn rewrite_lc(&mut self, lc: &LinearCombination, multiplier: E::Fr, free_term_constant: E::Fr) -> (Variable, TranspilationVariant) { let zero_fr = E::Fr::zero(); let one_fr = E::Fr::one(); - + let (contains_constant, num_linear_terms) = num_unique_values::(&lc, &mut self.scratch); assert!(num_linear_terms > 0); if num_linear_terms == 1 && !contains_constant && free_term_constant == zero_fr { @@ -234,7 +229,7 @@ impl Transpiler { constant_coeff.sub_assign(&free_term_constant); } - + let hint = TranspilationVariant::::IntoSingleAdditionGate((a_coef, b_coef, c_coef, constant_coeff)); return (new_var, hint); @@ -267,11 +262,9 @@ impl Transpiler { } } -impl crate::ConstraintSystem for Transpiler -{ +impl crate::ConstraintSystem for Transpiler { type Root = Self; - fn one() -> crate::Variable { crate::Variable::new_unchecked(crate::Index::Input(0)) } @@ -287,11 +280,7 @@ impl crate::ConstraintSystem for Transpiler Ok(crate::Variable::new_unchecked(crate::Index::Aux(self.current_plonk_aux_idx))) } - fn alloc_input( - &mut self, - _: A, - _f: F, - ) -> Result + fn alloc_input(&mut self, _: A, _f: F) -> Result where F: FnOnce() -> Result, A: FnOnce() -> AR, @@ -332,12 +321,12 @@ impl crate::ConstraintSystem for Transpiler let (a_is_constant, a_constant_coeff) = is_constant::(&a); let (b_is_constant, b_constant_coeff) = is_constant::(&b); - let (c_is_constant, c_constant_coeff) = is_constant::(&c); + let (c_is_constant, c_constant_coeff) = is_constant::(&c); match (a_is_constant, b_is_constant, c_is_constant) { (true, true, true) => { unreachable!("R1CS has a gate 1 * 1 = 1"); - }, + } (true, false, true) | (false, true, true) => { // we have something like c0 * LC = c1 let lc = if !a_is_constant { @@ -365,9 +354,8 @@ impl crate::ConstraintSystem for Transpiler // println!("Hint = {:?}", hint); self.hints.push((current_lc_number, hint)); - - }, - (false, false, true) => { + } + (false, false, true) => { // potential quadatic gate let (is_quadratic_gate, coeffs) = is_quadratic_gate::(&a, &b, &c, &mut self.scratch); if is_quadratic_gate { @@ -394,8 +382,7 @@ impl crate::ConstraintSystem for Transpiler // println!("Hint = {:?}", hint); self.hints.push((current_lc_number, hint)); - - }, + } (true, false, false) | (false, true, false) => { // LC * 1 = LC @@ -458,8 +445,7 @@ impl crate::ConstraintSystem for Transpiler self.hints.push((current_lc_number, hint)); return; - - }, + } (true, true, false) => { // A and B are some constants let mut final_constant = a_constant_coeff; @@ -474,8 +460,7 @@ impl crate::ConstraintSystem for Transpiler // println!("Hint = {:?}", hint); self.hints.push((current_lc_number, hint)); - - }, + } (false, false, false) => { // potentially it can still be quadratic let (is_quadratic_gate, coeffs) = is_quadratic_gate::(&a, &b, &c, &mut self.scratch); @@ -492,7 +477,7 @@ impl crate::ConstraintSystem for Transpiler } // rewrite into addition gates and multiplication gates - + let (_new_a_var, hint_a) = self.rewrite_lc(&a, one_fr, zero_fr); let (_new_b_var, hint_b) = self.rewrite_lc(&b, one_fr, zero_fr); let (_new_c_var, hint_c) = self.rewrite_lc(&c, one_fr, zero_fr); @@ -505,7 +490,7 @@ impl crate::ConstraintSystem for Transpiler self.hints.push((current_lc_number, hint)); } - } + } } fn push_namespace(&mut self, _: N) @@ -527,16 +512,16 @@ impl crate::ConstraintSystem for Transpiler // List of heuristics -use crate::{LinearCombination, ConstraintSystem, Variable}; +use crate::{ConstraintSystem, LinearCombination, Variable}; fn is_quadratic_gate>( - a: &LinearCombination, - b: &LinearCombination, + a: &LinearCombination, + b: &LinearCombination, c: &LinearCombination, - scratch: &mut HashSet:: + scratch: &mut HashSet, ) -> (bool, (E::Fr, E::Fr, E::Fr)) { let zero = E::Fr::zero(); - + let (_a_containts_constant, a_constant_coeff) = get_constant_term::(&a); let (_b_containts_constant, b_constant_coeff) = get_constant_term::(&b); let (_c_containts_constant, c_constant_coeff) = get_constant_term::(&c); @@ -585,7 +570,7 @@ fn is_quadratic_gate>( } return (true, (constant_term, linear_term, quadratic_term)); - } + } (false, (zero, zero, zero)) } @@ -595,7 +580,7 @@ fn is_constant>(lc: &LinearCombination) -> if lc.as_ref().len() == 0 { return (true, E::Fr::zero()); } - + let result = get_constant_term::(&lc); if result.0 && lc.as_ref().len() == 1 { @@ -607,7 +592,7 @@ fn is_constant>(lc: &LinearCombination) -> fn get_constant_term>(lc: &LinearCombination) -> (bool, E::Fr) { let cs_one = CS::one(); - + for (var, coeff) in lc.as_ref().iter() { if var == &cs_one { return (true, *coeff); @@ -619,7 +604,7 @@ fn get_constant_term>(lc: &LinearCombination< fn get_first_variable>(lc: &LinearCombination) -> (bool, Variable) { let cs_one = CS::one(); - + for (var, _) in lc.as_ref().iter() { if var != &cs_one { return (true, *var); @@ -631,7 +616,7 @@ fn get_first_variable>(lc: &LinearCombination fn get_first_variable_with_coeff>(lc: &LinearCombination) -> (bool, Variable, E::Fr) { let cs_one = CS::one(); - + for (var, coeff) in lc.as_ref().iter() { if var != &cs_one { return (true, *var, *coeff); @@ -641,11 +626,11 @@ fn get_first_variable_with_coeff>(lc: &Linear (false, cs_one, E::Fr::zero()) } -fn num_unique_values>(lc: &LinearCombination, scratch: &mut HashSet::) -> (bool, usize) { +fn num_unique_values>(lc: &LinearCombination, scratch: &mut HashSet) -> (bool, usize) { let cs_one = CS::one(); debug_assert!(scratch.is_empty()); - + let mut contains_constant = false; for (var, _) in lc.as_ref().iter() { @@ -663,11 +648,11 @@ fn num_unique_values>(lc: &LinearCombination< (contains_constant, num_unique_without_constant) } -fn is_linear_term>(lc: &LinearCombination, scratch: &mut HashSet::) -> (bool, Variable, E::Fr) { +fn is_linear_term>(lc: &LinearCombination, scratch: &mut HashSet) -> (bool, Variable, E::Fr) { let cs_one = CS::one(); debug_assert!(scratch.is_empty()); - + let mut linear_coeff = E::Fr::zero(); for (var, coeff) in lc.as_ref().iter() { @@ -683,24 +668,20 @@ fn is_linear_term>(lc: &LinearCombination, let terms: Vec<_> = scratch.drain().collect(); let term = terms[0]; - return (true, term, linear_coeff) + return (true, term, linear_coeff); } else { scratch.clear(); - return (false, cs_one, E::Fr::zero()) - } + return (false, cs_one, E::Fr::zero()); + } } -fn rewrite_lc_into_single_enforcement_gate>( - lc: &LinearCombination, - _cs: &mut CS, - scratch: &mut HashSet -) -> (E::Fr, E::Fr, E::Fr) { +fn rewrite_lc_into_single_enforcement_gate>(lc: &LinearCombination, _cs: &mut CS, scratch: &mut HashSet) -> (E::Fr, E::Fr, E::Fr) { let (_contains_constant, num_linear_terms) = num_unique_values::(&lc, scratch); assert!(num_linear_terms > 0 && num_linear_terms <= 3); assert!(!_contains_constant); - // this linear combination has only 2 non-constant terms that + // this linear combination has only 2 non-constant terms that // we can just make an addition gate let cs_one = CS::one(); @@ -735,7 +716,7 @@ fn rewrite_lc_into_single_enforcement_gate>( fn rewrite_lc_into_multiple_enforcement_gates>( lc: &LinearCombination, cs: &mut CS, - scratch: &mut HashSet + scratch: &mut HashSet, ) -> ((E::Fr, E::Fr, E::Fr), Vec) // first rewrite is full, than it's Z + a * X - Y = 0 { // assert!(lc.as_ref().len() > 3); @@ -817,11 +798,7 @@ fn rewrite_lc_into_multiple_enforcement_gates let mut c_coeff = E::Fr::one(); c_coeff.negate(); - let _new_var = cs.alloc(|| "allocate addition gate", - || { - unreachable!() - } - ).expect("must allocate an extra variable"); + let _new_var = cs.alloc(|| "allocate addition gate", || unreachable!()).expect("must allocate an extra variable"); let first_addition_gate = (a_coeff, b_coeff, c_coeff); @@ -829,7 +806,7 @@ fn rewrite_lc_into_multiple_enforcement_gates // for (var, coeff) in it { // if var != &cs_one { // extra_coefficients.push(*coeff); - // new_var = cs.alloc(|| "allocate addition gate", + // new_var = cs.alloc(|| "allocate addition gate", // || { // unreachable!() // } @@ -854,11 +831,7 @@ fn rewrite_lc_into_multiple_enforcement_gates if var != &cs_one { if gates_created != cycle_len - 2 { extra_coefficients.push(*coeff); - let _new_var = cs.alloc(|| "allocate addition gate", - || { - unreachable!() - } - ).expect("must allocate an extra variable"); + let _new_var = cs.alloc(|| "allocate addition gate", || unreachable!()).expect("must allocate an extra variable"); gates_created += 1; } else { let (_last_var, last_coeff) = it.next().expect("there should be a last chain variable"); @@ -877,12 +850,12 @@ fn rewrite_lc_into_multiple_enforcement_gates fn rewrite_lc_into_single_addition_gate>( lc: &LinearCombination, cs: &mut CS, - scratch: &mut HashSet + scratch: &mut HashSet, ) -> (Variable, (E::Fr, E::Fr, E::Fr, E::Fr)) { let (_contains_constant, num_linear_terms) = num_unique_values::(&lc, scratch); assert!(num_linear_terms > 0 && num_linear_terms <= 3); - // this linear combination has only 2 non-constant terms that + // this linear combination has only 2 non-constant terms that // we can just make an addition gate let cs_one = CS::one(); @@ -911,10 +884,7 @@ fn rewrite_lc_into_single_addition_gate>( let mut c_coeff = E::Fr::one(); c_coeff.negate(); - let new_var = cs.alloc(|| "allocate addition gate", - || { - unreachable!() - }).expect("must allocate an extra variable"); + let new_var = cs.alloc(|| "allocate addition gate", || unreachable!()).expect("must allocate an extra variable"); (new_var, (a_coeff, b_coeff, c_coeff, constant_term)) } @@ -922,7 +892,7 @@ fn rewrite_lc_into_single_addition_gate>( fn rewrite_lc_into_multiple_addition_gates>( lc: &LinearCombination, cs: &mut CS, - scratch: &mut HashSet + scratch: &mut HashSet, ) -> (Variable, (E::Fr, E::Fr, E::Fr, E::Fr), Vec) // first rewrite is full, than it's Z + a * X - Y = 0 { assert!(lc.as_ref().len() > 2); @@ -958,11 +928,7 @@ fn rewrite_lc_into_multiple_addition_gates>( let mut c_coeff = E::Fr::one(); c_coeff.negate(); - let mut new_var = cs.alloc(|| "allocate addition gate", - || { - unreachable!() - } - ).expect("must allocate an extra variable"); + let mut new_var = cs.alloc(|| "allocate addition gate", || unreachable!()).expect("must allocate an extra variable"); let first_addition_gate = (a_coeff, b_coeff, c_coeff, constant_term); @@ -970,21 +936,14 @@ fn rewrite_lc_into_multiple_addition_gates>( for (var, coeff) in it { if var != &cs_one { extra_coefficients.push(*coeff); - new_var = cs.alloc(|| "allocate addition gate", - || { - unreachable!() - } - ).expect("must allocate an extra variable"); + new_var = cs.alloc(|| "allocate addition gate", || unreachable!()).expect("must allocate an extra variable"); } } (new_var, first_addition_gate, extra_coefficients) } -fn deduplicate>( - lc: LinearCombination, - scratch: &mut HashMap -) -> LinearCombination { +fn deduplicate>(lc: LinearCombination, scratch: &mut HashMap) -> LinearCombination { assert!(scratch.is_empty()); for (var, coeff) in lc.0.into_iter() { @@ -1000,10 +959,7 @@ fn deduplicate>( LinearCombination(as_vec) } -fn deduplicate_stable>( - lc: LinearCombination, - scratch: &mut HashMap -) -> LinearCombination { +fn deduplicate_stable>(lc: LinearCombination, scratch: &mut HashMap) -> LinearCombination { assert!(scratch.is_empty()); if lc.as_ref().len() == 0 { @@ -1043,11 +999,11 @@ fn deduplicate_stable>( fn subtract_lcs_with_dedup_stable>( lc_0: LinearCombination, lc_1: LinearCombination, - scratch: &mut HashMap + scratch: &mut HashMap, ) -> LinearCombination { assert!(scratch.is_empty()); - if lc_0.as_ref().len() == 0 && lc_1.as_ref().len() == 0{ + if lc_0.as_ref().len() == 0 && lc_1.as_ref().len() == 0 { return lc_0; } @@ -1094,9 +1050,7 @@ fn subtract_lcs_with_dedup_stable>( LinearCombination(deduped_vec) } -fn split_constant_term>( - mut lc: LinearCombination, -) -> (LinearCombination, E::Fr) { +fn split_constant_term>(mut lc: LinearCombination) -> (LinearCombination, E::Fr) { if lc.as_ref().len() == 0 { return (lc, E::Fr::zero()); } @@ -1121,7 +1075,6 @@ fn split_constant_term>( } } - pub struct Adaptor<'a, E: Engine, CS: PlonkConstraintSystem + 'a> { cs: &'a mut CS, hints: &'a Vec<(usize, TranspilationVariant)>, @@ -1164,7 +1117,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { // make a new variable based on existing ones fn make_single_addition_gate(&mut self, lc: &LinearCombination, gate_coeffs: (E::Fr, E::Fr, E::Fr, E::Fr)) -> Result { let zero_fr = E::Fr::zero(); - + let mut minus_one_fr = E::Fr::one(); minus_one_fr.negate(); @@ -1181,7 +1134,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { let mut a_var = PlonkVariable::new_unchecked(PlonkIndex::Aux(0)); for (var, _) in it { if var == &cs_one { - continue + continue; } else { a_var = convert_variable(*var); break; @@ -1190,8 +1143,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { let a_value = self.cs.get_value(a_var); - let new_var = self.cs.alloc( - || { + let new_var = self.cs.alloc(|| { let mut c_value = a_value?; c_value.mul_assign(&a_coeff); c_value.add_assign(&constant_coeff); @@ -1211,7 +1163,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { for (var, _) in it { if var == &cs_one { - continue + continue; } else { if !found_a { found_a = true; @@ -1226,20 +1178,19 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { let a_value = self.cs.get_value(a_var); let b_value = self.cs.get_value(b_var); - let new_var = self.cs.alloc( - || { - let a_value = a_value?; - let mut b_value = b_value?; - b_value.mul_assign(&b_coeff); - let mut c_value = a_value; - c_value.mul_assign(&a_coeff); - c_value.add_assign(&b_value); - c_value.add_assign(&constant_coeff); - // c_value.negate(); - - Ok(c_value) - // c = - constant - a*a_coeff - b*b_coeff - })?; + let new_var = self.cs.alloc(|| { + let a_value = a_value?; + let mut b_value = b_value?; + b_value.mul_assign(&b_coeff); + let mut c_value = a_value; + c_value.mul_assign(&a_coeff); + c_value.add_assign(&b_value); + c_value.add_assign(&constant_coeff); + // c_value.negate(); + + Ok(c_value) + // c = - constant - a*a_coeff - b*b_coeff + })?; self.cs.new_gate((a_var, b_var, new_var), (a_coeff, b_coeff, c_coeff, zero_fr, constant_coeff))?; @@ -1248,13 +1199,9 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { } // make a new variable based on existing ones - fn enforce_lc_with_single_addition_gate( - &mut self, - lc: LinearCombination, - gate_coeffs: (E::Fr, E::Fr, E::Fr, E::Fr) - ) -> Result<(), SynthesisError> { + fn enforce_lc_with_single_addition_gate(&mut self, lc: LinearCombination, gate_coeffs: (E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let zero_fr = E::Fr::zero(); - + let mut minus_one_fr = E::Fr::one(); minus_one_fr.negate(); @@ -1283,7 +1230,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { if !found_a { found_a = true; a_var = convert_variable(*var); - } else if need_b && !found_b{ + } else if need_b && !found_b { found_b = true; b_var = convert_variable(*var); } else if need_c { @@ -1302,15 +1249,10 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { } // make a new variable based on existing ones - fn make_chain_of_addition_gates( - &mut self, - lc: &LinearCombination, - first_gate_coeffs: (E::Fr, E::Fr, E::Fr, E::Fr), - chain_coeffs: Vec - ) -> Result { + fn make_chain_of_addition_gates(&mut self, lc: &LinearCombination, first_gate_coeffs: (E::Fr, E::Fr, E::Fr, E::Fr), chain_coeffs: Vec) -> Result { let zero_fr = E::Fr::zero(); let one_fr = E::Fr::one(); - + let mut minus_one_fr = E::Fr::one(); minus_one_fr.negate(); @@ -1336,7 +1278,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { for (var, _) in &mut it { if var == &cs_one { - continue + continue; } else { if !found_a { found_a = true; @@ -1351,20 +1293,19 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { let a_value = self.cs.get_value(a_var); let b_value = self.cs.get_value(b_var); - let new_var = self.cs.alloc( - || { - let a_value = a_value?; - let mut b_value = b_value?; - b_value.mul_assign(&b_coeff); - let mut c_value = a_value; - c_value.mul_assign(&a_coeff); - c_value.add_assign(&b_value); - c_value.add_assign(&constant_coeff); - // c_value.negate(); - - Ok(c_value) - // c = - constant - a*a_coeff - b*b_coeff - })?; + let new_var = self.cs.alloc(|| { + let a_value = a_value?; + let mut b_value = b_value?; + b_value.mul_assign(&b_coeff); + let mut c_value = a_value; + c_value.mul_assign(&a_coeff); + c_value.add_assign(&b_value); + c_value.add_assign(&constant_coeff); + // c_value.negate(); + + Ok(c_value) + // c = - constant - a*a_coeff - b*b_coeff + })?; self.cs.new_gate((a_var, b_var, new_var), (a_coeff, b_coeff, c_coeff, zero_fr, constant_coeff))?; @@ -1375,7 +1316,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { let mut chain_iter = chain_coeffs.into_iter(); - for (var, _)in &mut it { + for (var, _) in &mut it { if var != &cs_one { let hint_coeff = chain_iter.next().expect("chain coefficient must exist"); let original_var = convert_variable(*var); @@ -1384,14 +1325,13 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { let old_new_var = new_var; - new_var = self.cs.alloc( - || { - let mut new = original_var_value?; - new.mul_assign(&hint_coeff); - new.add_assign(&new_var_value?); + new_var = self.cs.alloc(|| { + let mut new = original_var_value?; + new.mul_assign(&hint_coeff); + new.add_assign(&new_var_value?); - Ok(new) - })?; + Ok(new) + })?; self.cs.new_gate((old_new_var, original_var, new_var), (one_fr, hint_coeff, minus_one_fr, zero_fr, zero_fr))?; } @@ -1403,15 +1343,10 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { } // make a new variable based on existing ones - fn enforce_lc_using_chain_of_addition_gates( - &mut self, - lc: LinearCombination, - first_gate_coeffs: (E::Fr, E::Fr, E::Fr, E::Fr), - chain_coeffs: Vec - ) -> Result<(), SynthesisError> { + fn enforce_lc_using_chain_of_addition_gates(&mut self, lc: LinearCombination, first_gate_coeffs: (E::Fr, E::Fr, E::Fr, E::Fr), chain_coeffs: Vec) -> Result<(), SynthesisError> { let zero_fr = E::Fr::zero(); let one_fr = E::Fr::one(); - + let mut minus_one_fr = E::Fr::one(); minus_one_fr.negate(); @@ -1440,7 +1375,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { for (var, _) in &mut it { if var == &cs_one { - continue + continue; } else { if !found_a { found_a = true; @@ -1455,20 +1390,19 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { let a_value = self.cs.get_value(a_var); let b_value = self.cs.get_value(b_var); - let new_var = self.cs.alloc( - || { - let a_value = a_value?; - let mut b_value = b_value?; - b_value.mul_assign(&b_coeff); - let mut c_value = a_value; - c_value.mul_assign(&a_coeff); - c_value.add_assign(&b_value); - c_value.add_assign(&constant_coeff); - // c_value.negate(); - - Ok(c_value) - // c = - constant - a*a_coeff - b*b_coeff - })?; + let new_var = self.cs.alloc(|| { + let a_value = a_value?; + let mut b_value = b_value?; + b_value.mul_assign(&b_coeff); + let mut c_value = a_value; + c_value.mul_assign(&a_coeff); + c_value.add_assign(&b_value); + c_value.add_assign(&constant_coeff); + // c_value.negate(); + + Ok(c_value) + // c = - constant - a*a_coeff - b*b_coeff + })?; self.cs.new_gate((a_var, b_var, new_var), (a_coeff, b_coeff, c_coeff, zero_fr, constant_coeff))?; @@ -1495,14 +1429,13 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { let old_new_var = new_var; - new_var = self.cs.alloc( - || { - let mut new = original_var_value?; - new.mul_assign(&hint_coeff); - new.add_assign(&new_var_value?); + new_var = self.cs.alloc(|| { + let mut new = original_var_value?; + new.mul_assign(&hint_coeff); + new.add_assign(&new_var_value?); - Ok(new) - })?; + Ok(new) + })?; self.cs.new_gate((old_new_var, original_var, new_var), (one_fr, hint_coeff, minus_one_fr, zero_fr, zero_fr))?; gates_created += 1; @@ -1528,7 +1461,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { // fn rewrite_lc(&mut self, lc: &LinearCombination, multiplier: E::Fr, free_term_constant: E::Fr) -> (Variable, TranspilationVariant) { // let one_fr = E::Fr::one(); - + // let (contains_constant, num_linear_terms) = num_unique_values::(&lc, &mut self.scratch); // assert!(num_linear_terms > 0); // if num_linear_terms == 1 && !contains_constant { @@ -1554,7 +1487,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { // constant_coeff.sub_assign(&free_term_constant); // } - + // let hint = TranspilationVariant::::IntoSingleAdditionGate((a_coef, b_coef, c_coef, constant_coeff)); // return (new_var, hint); @@ -1587,9 +1520,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> Adaptor<'a, E, CS> { // } } -impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem - for Adaptor<'a, E, CS> -{ +impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem for Adaptor<'a, E, CS> { type Root = Self; fn one() -> crate::Variable { @@ -1602,9 +1533,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem AR, AR: Into, { - let var = self.cs.alloc(|| { - f().map_err(|_| crate::SynthesisError::AssignmentMissing) - })?; + let var = self.cs.alloc(|| f().map_err(|_| crate::SynthesisError::AssignmentMissing))?; Ok(match var { PlonkVariable(PlonkIndex::Aux(index)) => crate::Variable::new_unchecked(crate::Index::Aux(index)), @@ -1612,19 +1541,13 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem( - &mut self, - _: A, - f: F, - ) -> Result + fn alloc_input(&mut self, _: A, f: F) -> Result where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into, { - let var = self.cs.alloc_input(|| { - f().map_err(|_| crate::SynthesisError::AssignmentMissing) - })?; + let var = self.cs.alloc_input(|| f().map_err(|_| crate::SynthesisError::AssignmentMissing))?; Ok(match var { PlonkVariable(PlonkIndex::Input(index)) => crate::Variable::new_unchecked(crate::Index::Input(index)), @@ -1645,9 +1568,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem(a(crate::LinearCombination::zero()), &mut self.deduplication_scratch) }; let b = { deduplicate_stable::(b(crate::LinearCombination::zero()), &mut self.deduplication_scratch) }; @@ -1670,7 +1591,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem(&a); let (b_is_constant, b_constant_coeff) = is_constant::(&b); - let (c_is_constant, c_constant_coeff) = is_constant::(&c); + let (c_is_constant, c_constant_coeff) = is_constant::(&c); let (a_has_variable, a_first_variable) = get_first_variable::(&a); let (b_has_variable, b_first_variable) = get_first_variable::(&b); @@ -1698,8 +1619,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem { let var = if c_has_variable { convert_variable(c_first_variable) @@ -1712,54 +1632,46 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem { let (t_a, t_b, t_c) = *boxed_hints; let mut multiplication_constant = one_fr; let a_var = match t_a { - TranspilationVariant::IntoSingleAdditionGate(coeffs) => { - self.make_single_addition_gate(&a, coeffs).expect("must make a gate") - }, - TranspilationVariant::IntoMultipleAdditionGates(coeffs, chain) => { - self.make_chain_of_addition_gates(&a, coeffs, chain).expect("must make a gate") - }, + TranspilationVariant::IntoSingleAdditionGate(coeffs) => self.make_single_addition_gate(&a, coeffs).expect("must make a gate"), + TranspilationVariant::IntoMultipleAdditionGates(coeffs, chain) => self.make_chain_of_addition_gates(&a, coeffs, chain).expect("must make a gate"), TranspilationVariant::LeaveAsSingleVariable(coeff) => { assert!(a_has_variable); multiplication_constant.mul_assign(&coeff); convert_variable(a_first_variable) - }, - _ => {unreachable!("{:?}", t_a)} + } + _ => { + unreachable!("{:?}", t_a) + } }; let b_var = match t_b { - TranspilationVariant::IntoSingleAdditionGate(coeffs) => { - self.make_single_addition_gate(&b, coeffs).expect("must make a gate") - }, - TranspilationVariant::IntoMultipleAdditionGates(coeffs, chain) => { - self.make_chain_of_addition_gates(&b, coeffs, chain).expect("must make a gate") - }, + TranspilationVariant::IntoSingleAdditionGate(coeffs) => self.make_single_addition_gate(&b, coeffs).expect("must make a gate"), + TranspilationVariant::IntoMultipleAdditionGates(coeffs, chain) => self.make_chain_of_addition_gates(&b, coeffs, chain).expect("must make a gate"), TranspilationVariant::LeaveAsSingleVariable(coeff) => { assert!(b_has_variable); multiplication_constant.mul_assign(&coeff); convert_variable(b_first_variable) - }, - _ => {unreachable!("{:?}", t_b)} + } + _ => { + unreachable!("{:?}", t_b) + } }; let (c_is_just_a_constant, c_var, mut c_coeff) = match t_c { - TranspilationVariant::IntoSingleAdditionGate(coeffs) => { - (false, Some(self.make_single_addition_gate(&c, coeffs).expect("must make a gate")), one_fr) - }, - TranspilationVariant::IntoMultipleAdditionGates(coeffs, chain) => { - (false, Some(self.make_chain_of_addition_gates(&c, coeffs, chain).expect("must make a gate")), one_fr) - }, + TranspilationVariant::IntoSingleAdditionGate(coeffs) => (false, Some(self.make_single_addition_gate(&c, coeffs).expect("must make a gate")), one_fr), + TranspilationVariant::IntoMultipleAdditionGates(coeffs, chain) => (false, Some(self.make_chain_of_addition_gates(&c, coeffs, chain).expect("must make a gate")), one_fr), TranspilationVariant::LeaveAsSingleVariable(coeff) => { assert!(c_has_variable); (false, Some(convert_variable(c_first_variable)), coeff) - }, + } TranspilationVariant::IsConstant(value) => { assert!(c_is_constant); assert!(c_constant_coeff == value); @@ -1771,7 +1683,9 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem {unreachable!("{:?}", t_c)} + _ => { + unreachable!("{:?}", t_c) + } }; if c_is_just_a_constant { @@ -1779,13 +1693,17 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem { // self.make_chain_of_addition_gates(&c, coeffs, chain).expect("must make a gate"); // let ann: String = _ann().into(); @@ -1803,26 +1721,26 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem { // let ann: String = _ann().into(); // println!("Enforcing {}", ann); // println!("Hint is {:?}", hint); unreachable!() - }, + } TranspilationVariant::IsConstant(_) => { // let ann: String = _ann().into(); // println!("Enforcing {}", ann); // println!("Hint is {:?}", hint); unreachable!() - }, + } TranspilationVariant::LeaveAsSingleVariable(_) => { // let ann: String = _ann().into(); // println!("Enforcing {}", ann); // println!("Hint is {:?}", hint); unreachable!() - }, + } TranspilationVariant::MergeLinearCombinations((merge_variant, coeff, merge_hint)) => { let multiplier = if a_is_constant { a_constant_coeff @@ -1846,7 +1764,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem(final_lc, c, &mut self.deduplication_scratch) // final_lc - &c - }, + } MergeLcVariant::MergeBCThroughConstantA => { assert!(a_is_constant); let mut final_lc = b; @@ -1858,7 +1776,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem(final_lc, c, &mut self.deduplication_scratch) // final_lc - &c - }, + } MergeLcVariant::CIsTheOnlyMeaningful => { let mut tmp = one_fr; tmp.mul_assign(&a_constant_coeff); @@ -1866,7 +1784,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem { unreachable!() } @@ -1877,10 +1795,10 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem { self.enforce_lc_with_single_addition_gate(lc_into_rewriting, coeffs).expect("must make a gate"); - }, + } TranspilationVariant::IntoMultipleAdditionGates(coeffs, chain) => { self.enforce_lc_using_chain_of_addition_gates(lc_into_rewriting, coeffs, chain).expect("must make a gate"); - }, + } // TranspilationVariant::LeaveAsSingleVariable(coeff) => { // let (contains_a_variable, variable) = get_first_variable::(&lc_into_rewriting); // assert!(contains_a_variable); @@ -1897,7 +1815,7 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem(&mut self, _: N) @@ -1919,8 +1837,12 @@ impl<'a, E: Engine, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem PlonkVariable { let var = match r1cs_variable.get_unchecked() { - crate::Index::Input(0) => {unreachable!("can not convert input variable number 0 (CS::one)")}, - crate::Index::Aux(0) => {unreachable!("can not convert aux variable labeled as 0 (taken by Plonk CS)")}, + crate::Index::Input(0) => { + unreachable!("can not convert input variable number 0 (CS::one)") + } + crate::Index::Aux(0) => { + unreachable!("can not convert aux variable labeled as 0 (taken by Plonk CS)") + } crate::Index::Input(i) => PlonkVariable(PlonkIndex::Input(i)), crate::Index::Aux(i) => PlonkVariable(PlonkIndex::Aux(i)), }; @@ -1930,18 +1852,19 @@ fn convert_variable(r1cs_variable: crate::Variable) -> PlonkVariable { use std::cell::Cell; -pub struct AdaptorCircuit<'a, E:Engine, C: crate::Circuit>{ +pub struct AdaptorCircuit<'a, E: Engine, C: crate::Circuit> { circuit: Cell>, hints: &'a Vec<(usize, TranspilationVariant)>, } -impl<'a, E:Engine, C: crate::Circuit> AdaptorCircuit<'a, E, C> { - pub fn new<'b>(circuit: C, hints: &'b Vec<(usize, TranspilationVariant)>) -> Self - where 'b: 'a +impl<'a, E: Engine, C: crate::Circuit> AdaptorCircuit<'a, E, C> { + pub fn new<'b>(circuit: C, hints: &'b Vec<(usize, TranspilationVariant)>) -> Self + where + 'b: 'a, { Self { circuit: Cell::new(Some(circuit)), - hints: hints + hints: hints, } } } @@ -1970,16 +1893,16 @@ impl<'a, E: Engine, C: crate::Circuit> PlonkCircuit for AdaptorCircuit<'a, #[test] fn transpile_xor_using_adaptor() { - use crate::tests::XORDemo; use crate::cs::Circuit; use crate::pairing::bn256::Bn256; use crate::plonk::plonk::generator::*; use crate::plonk::plonk::prover::*; + use crate::tests::XORDemo; let c = XORDemo:: { a: None, b: None, - _marker: PhantomData + _marker: PhantomData, }; let mut transpiler = Transpiler::new(); @@ -1991,7 +1914,7 @@ fn transpile_xor_using_adaptor() { let c = XORDemo:: { a: None, b: None, - _marker: PhantomData + _marker: PhantomData, }; let adapted_curcuit = AdaptorCircuit::new(c, &hints); @@ -2007,7 +1930,7 @@ fn transpile_xor_using_adaptor() { let c = XORDemo:: { a: Some(true), b: Some(true), - _marker: PhantomData + _marker: PhantomData, }; println!("Trying to prove"); @@ -2019,4 +1942,4 @@ fn transpile_xor_using_adaptor() { prover.finalize(); assert!(prover.is_satisfied()); -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/adaptor/mod.rs b/crates/bellman/src/plonk/adaptor/mod.rs index 6487cdd..379568a 100644 --- a/crates/bellman/src/plonk/adaptor/mod.rs +++ b/crates/bellman/src/plonk/adaptor/mod.rs @@ -1,12 +1,12 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; use crate::SynthesisError; -use crate::plonk::cs::gates::Gate; use crate::plonk::cs::gates::Coeff; -use crate::plonk::cs::gates::Variable as PlonkVariable; +use crate::plonk::cs::gates::Gate; use crate::plonk::cs::gates::Index as PlonkIndex; +use crate::plonk::cs::gates::Variable as PlonkVariable; use crate::plonk::cs::Circuit as PlonkCircuit; use crate::plonk::cs::ConstraintSystem as PlonkConstraintSystem; @@ -73,7 +73,7 @@ pub mod alternative; // LB: FnOnce(crate::LinearCombination) -> crate::LinearCombination, // LC: FnOnce(crate::LinearCombination) -> crate::LinearCombination, // { - + // /// Represents either a "true" variable or a constant // /// auxillary variable. // #[derive(Copy, Clone, PartialEq, Debug, Hash, Eq)] @@ -82,7 +82,7 @@ pub mod alternative; // InputVar(PlonkVariable), // ConstVar // } - + // fn convert(lc: crate::LinearCombination) -> Vec<(E::Fr, Var)> { // let mut ret = Vec::with_capacity(lc.as_ref().len()); @@ -104,11 +104,11 @@ pub mod alternative; // let c_terms = convert(c(crate::LinearCombination::zero())); // ///first check if we are dealing with a boolean constraint -// ///we use the following euristics: -// ///analyse comment string +// ///we use the following euristics: +// ///analyse comment string // ///calculate the number of arguments in each linear combination - in boolean constraint length of each lc is at most 2 // /// this function returns true in the case of boolean constraint - + // fn handle_boolean_constraint( // la: &Vec<(E::Fr, Var)>, // lb: &Vec<(E::Fr, Var)>, @@ -120,7 +120,6 @@ pub mod alternative; // { // return true; // } - // fn eval_lc_short>( // term1: (E::Fr, PlonkVariable), @@ -147,14 +146,13 @@ pub mod alternative; // Some(extra_value) // } - // fn allocate_new_lc_var>( // term1: (E::Fr, PlonkVariable), // term2: (E::Fr, PlonkVariable), // cs: &mut CS, // ) -> PlonkVariable // { - + // let extra_value = eval_lc_short(term1, term2, &*cs); // let extra_variable = cs.alloc(|| // { @@ -165,17 +163,16 @@ pub mod alternative; // } // } // ).expect("must allocate"); - + // cs.enforce_mul_3((term1.1, term2.1, extra_variable)).expect("must allocate"); // extra_variable // } - // fn allocate_lc_intermediate_variables>( -// terms: Vec<(E::Fr, Var)>, +// terms: Vec<(E::Fr, Var)>, // cs: &mut CS, // ) -> (PlonkVariable, Option) { - + // debug_assert!(terms.len() > 2); // let mut const_var_found = false; // let mut const_coeff = E::Fr::zero(); @@ -198,7 +195,7 @@ pub mod alternative; // Some((E::Fr::one(), new_val)) // } // } -// } +// } // } // } @@ -213,13 +210,12 @@ pub mod alternative; // true => Some(const_coeff) // } ; -// return (var, coef) +// return (var, coef) // } - -// /// after parsing we should return on of three possible results: +// /// after parsing we should return on of three possible results: // /// variable, constant or sum variable + constant - + // fn parse_lc>( // terms: Vec<(E::Fr, Var)>, // cs: &mut CS, @@ -244,7 +240,7 @@ pub mod alternative; // 2 => { // let (c_0, v_0) = terms[0]; // let (c_1, v_1) = terms[1]; - + // //check of one of v_0, v_1 is constant and the other is variable or vice versa // //the case of two constants is impossible in real cs! // let result = match (v_0, v_1) { @@ -252,7 +248,7 @@ pub mod alternative; // (Var::ConstVar, Var::InputVar(pv)) => (Some((c_1, pv)), Some(c_0)), // (Var::InputVar(pv0), Var::InputVar(pv1)) => { // let extra_variable = allocate_new_lc_var((c_0, pv0), (c_1, pv1), cs); -// (Some((E::Fr::one(), extra_variable)), None) +// (Some((E::Fr::one(), extra_variable)), None) // } // (Var::ConstVar, Var::ConstVar) => unreachable!(), // }; @@ -263,8 +259,8 @@ pub mod alternative; // _ => { // // here we need to allocate intermediate variables and output the last one // let last_vars = allocate_lc_intermediate_variables(terms, cs); -// return (Some((E::Fr::one(), last_vars.0)), last_vars.1); -// } +// return (Some((E::Fr::one(), last_vars.0)), last_vars.1); +// } // } // } @@ -272,7 +268,6 @@ pub mod alternative; // let b_var = parse_lc(b_terms, self.cs); // let c_var = parse_lc(c_terms, self.cs); - // /// parse result and return expr of the form: coeff * var + constant // fn unfold_var>( @@ -281,11 +276,11 @@ pub mod alternative; // cs: &mut CS, // ) -> (E::Fr, PlonkVariable, E::Fr) // { - + // let result = match var { // (Some((coeff, var)), Some(constant)) => (coeff, var, constant), // (Some((coeff, var)), None) => (coeff, var, E::Fr::zero()), -// (None, Some(constant)) => (E::Fr::zero(), stub, constant), +// (None, Some(constant)) => (E::Fr::zero(), stub, constant), // _ => unreachable!(), // }; @@ -294,9 +289,8 @@ pub mod alternative; // // our final equation is of the following form // // (x a_var + c_1) (y b_var + c_2) = (z c_var + c_3) -// // we can convert it to standard PLONK form: +// // we can convert it to standard PLONK form: // // (xy) a_var + b_var + (x c_2) a_var + (y c_1) b_var - z c_var + (c_1 c_2 - c_3) */ - // let (mut x, a_var, mut c_1) : (E::Fr, PlonkVariable, E::Fr) = unfold_var(a_var, CS::ZERO, self.cs); // let (mut y, b_var, c_2) : (E::Fr, PlonkVariable, E::Fr) = unfold_var(b_var, CS::ZERO, self.cs); // let (mut z, c_var, mut c_3) : (E::Fr, PlonkVariable, E::Fr) = unfold_var(c_var, CS::ZERO, self.cs); @@ -311,7 +305,7 @@ pub mod alternative; // c_3.negate(); // c_1.add_assign(&c_3); -// self.cs.new_gate((a_var, b_var, c_var), (a_coef, x, y, z, c_1)); +// self.cs.new_gate((a_var, b_var, c_var), (a_coef, x, y, z, c_1)); // } // fn push_namespace(&mut self, _: N) @@ -348,4 +342,4 @@ pub mod alternative; // Ok(()) // } -// } \ No newline at end of file +// } diff --git a/crates/bellman/src/plonk/better_better_cs/cs.rs b/crates/bellman/src/plonk/better_better_cs/cs.rs index d4c6265..e0f2b6c 100644 --- a/crates/bellman/src/plonk/better_better_cs/cs.rs +++ b/crates/bellman/src/plonk/better_better_cs/cs.rs @@ -1,26 +1,26 @@ -use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use crate::pairing::{Engine, CurveAffine, CurveProjective}; use crate::bit_vec::BitVec; +use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; -use crate::{SynthesisError}; +use crate::SynthesisError; #[cfg(feature = "allocator")] use std::alloc::{Allocator, Global}; use std::collections::HashMap; use std::marker::PhantomData; -use crate::worker::Worker; use crate::plonk::domains::*; use crate::plonk::polynomials::*; +use crate::worker::Worker; -pub use crate::plonk::cs::variable::*; +pub use super::lookup_tables::*; use crate::plonk::better_cs::utils::*; -pub use super::lookup_tables::{*}; +pub use crate::plonk::cs::variable::*; use crate::plonk::fft::cooley_tukey_ntt::*; -use super::utils::*; pub use super::data_structures::*; pub use super::setup::*; +use super::utils::*; pub use super::gates::main_gate_with_d_next::*; @@ -56,9 +56,7 @@ pub trait Circuit { type MainGate: MainGate; fn synthesize + 'static>(&self, cs: &mut CS) -> Result<(), SynthesisError>; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![Self::MainGate::default().into_internal()] - ) + Ok(vec![Self::MainGate::default().into_internal()]) } } @@ -66,7 +64,7 @@ pub trait Circuit { pub enum Coefficient { PlusOne, MinusOne, - Other + Other, } #[derive(Clone, Debug, Hash, PartialEq, Eq)] @@ -84,12 +82,7 @@ pub(crate) struct PolynomialOpeningRequest { pub(crate) dilation: TimeDilation, } -pub trait GateInternal: Send - + Sync - + 'static - + std::any::Any - + std::fmt::Debug -{ +pub trait GateInternal: Send + Sync + 'static + std::any::Any + std::fmt::Debug { fn name(&self) -> &'static str; fn degree(&self) -> usize; fn can_include_public_inputs(&self) -> bool; @@ -106,26 +99,26 @@ pub trait GateInternal: Send fn num_quotient_terms(&self) -> usize; fn verify_on_row<'a>(&self, row: usize, poly_storage: &AssembledPolynomialStorage<'a, E>, last_row: bool) -> E::Fr; fn contribute_into_quotient<'a, 'b>( - &self, + &self, domain_size: usize, poly_storage: &mut AssembledPolynomialStorage<'a, E>, - monomials_storage: & AssembledPolynomialStorageForMonomialForms<'b, E>, + monomials_storage: &AssembledPolynomialStorageForMonomialForms<'b, E>, challenges: &[E::Fr], omegas_bitreversed: &BitReversedOmegas, omegas_inv_bitreversed: &OmegasInvBitreversed, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError>; fn contribute_into_linearization<'a>( - &self, + &self, domain_size: usize, at: E::Fr, queried_values: &std::collections::HashMap, - monomials_storage: & AssembledPolynomialStorageForMonomialForms<'a, E>, + monomials_storage: &AssembledPolynomialStorageForMonomialForms<'a, E>, challenges: &[E::Fr], - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError>; fn contribute_into_verification_equation( - &self, + &self, domain_size: usize, at: E::Fr, queried_values: &std::collections::HashMap, @@ -134,7 +127,7 @@ pub trait GateInternal: Send fn put_public_inputs_into_selector_id(&self) -> Option; fn box_clone(&self) -> Box>; fn contribute_into_linearization_commitment( - &self, + &self, domain_size: usize, at: E::Fr, queried_values: &std::collections::HashMap, @@ -143,12 +136,7 @@ pub trait GateInternal: Send ) -> Result; } -pub trait Gate: GateInternal - + Sized - + Clone - + std::hash::Hash - + std::default::Default -{ +pub trait Gate: GateInternal + Sized + Clone + std::hash::Hash + std::default::Default { fn as_internal(&self) -> &dyn GateInternal { self as &dyn GateInternal } @@ -158,7 +146,7 @@ pub trait Gate: GateInternal } } -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use smallvec::SmallVec; pub const DEFAULT_SMALLVEC_CAPACITY: usize = 8; @@ -173,39 +161,36 @@ pub trait MainGate: Gate { fn index_for_constant_term() -> usize; fn range_of_next_step_linear_terms() -> std::ops::Range; fn format_term(instance: MainGateTerm, padding: Variable) -> Result<(SmallVec<[Variable; DEFAULT_SMALLVEC_CAPACITY]>, SmallVec<[E::Fr; DEFAULT_SMALLVEC_CAPACITY]>), SynthesisError>; - fn format_linear_term_with_duplicates(instance: MainGateTerm, padding: Variable) -> Result<(SmallVec<[Variable; DEFAULT_SMALLVEC_CAPACITY]>, SmallVec<[E::Fr; DEFAULT_SMALLVEC_CAPACITY]>), SynthesisError>; + fn format_linear_term_with_duplicates( + instance: MainGateTerm, + padding: Variable, + ) -> Result<(SmallVec<[Variable; DEFAULT_SMALLVEC_CAPACITY]>, SmallVec<[E::Fr; DEFAULT_SMALLVEC_CAPACITY]>), SynthesisError>; fn dummy_vars_to_inscribe(dummy: Variable) -> SmallVec<[Variable; DEFAULT_SMALLVEC_CAPACITY]>; fn empty_coefficients() -> SmallVec<[E::Fr; DEFAULT_SMALLVEC_CAPACITY]>; fn contribute_into_quotient_for_public_inputs<'a, 'b>( - &self, + &self, domain_size: usize, public_inputs: &[E::Fr], poly_storage: &mut AssembledPolynomialStorage<'b, E>, - monomial_storage: & AssembledPolynomialStorageForMonomialForms<'a, E>, + monomial_storage: &AssembledPolynomialStorageForMonomialForms<'a, E>, challenges: &[E::Fr], omegas_bitreversed: &BitReversedOmegas, omegas_inv_bitreversed: &OmegasInvBitreversed, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError>; fn contribute_into_linearization_for_public_inputs<'a>( - &self, + &self, domain_size: usize, public_inputs: &[E::Fr], at: E::Fr, queried_values: &std::collections::HashMap, - monomials_storage: & AssembledPolynomialStorageForMonomialForms<'a, E>, + monomials_storage: &AssembledPolynomialStorageForMonomialForms<'a, E>, challenges: &[E::Fr], - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError>; - fn add_inputs_into_quotient( - &self, - domain_size: usize, - public_inputs: &[E::Fr], - at: E::Fr, - challenges: &[E::Fr], - ) -> Result; + fn add_inputs_into_quotient(&self, domain_size: usize, public_inputs: &[E::Fr], at: E::Fr, challenges: &[E::Fr]) -> Result; // fn contribute_into_verification_equation_for_public_inputs( - // &self, + // &self, // domain_size: usize, // public_inputs: &[E::Fr], // at: E::Fr, @@ -213,7 +198,7 @@ pub trait MainGate: Gate { // challenges: &[E::Fr], // ) -> Result; fn contribute_into_linearization_commitment_for_public_inputs( - &self, + &self, domain_size: usize, public_inputs: &[E::Fr], at: E::Fr, @@ -224,7 +209,10 @@ pub trait MainGate: Gate { } impl std::hash::Hash for dyn GateInternal { - fn hash(&self, state: &mut H) where H: std::hash::Hasher { + fn hash(&self, state: &mut H) + where + H: std::hash::Hasher, + { self.type_id().hash(state); self.name().hash(state); self.degree().hash(state); @@ -233,9 +221,7 @@ impl std::hash::Hash for dyn GateInternal { impl PartialEq for dyn GateInternal { fn eq(&self, other: &Self) -> bool { - self.type_id() == other.type_id() && - self.name() == other.name() && - self.degree() == other.degree() + self.type_id() == other.type_id() && self.name() == other.name() && self.degree() == other.degree() } } @@ -251,12 +237,12 @@ pub struct LinearCombinationOfTerms(pub Vec); impl LinearCombinationOfTerms { fn terms(&self) -> &[PolynomialMultiplicativeTerm] { - &self.0[..] + &self.0[..] } } #[derive(Clone, Debug)] -pub enum ArithmeticTerm{ +pub enum ArithmeticTerm { Product(smallvec::SmallVec<[Variable; 2]>, E::Fr), SingleVariable(Variable, E::Fr), Constant(E::Fr), @@ -281,17 +267,17 @@ impl ArithmeticTerm { terms.push(other); ArithmeticTerm::Product(terms, coeff) - }, + } ArithmeticTerm::SingleVariable(this, coeff) => { let terms = smallvec::smallvec![this, other]; ArithmeticTerm::Product(terms, coeff) - }, + } ArithmeticTerm::Constant(coeff) => { let terms = smallvec::smallvec![other]; ArithmeticTerm::Product(terms, coeff) - }, + } } } @@ -299,13 +285,13 @@ impl ArithmeticTerm { match self { ArithmeticTerm::Product(_, ref mut coeff) => { coeff.mul_assign(by); - }, + } ArithmeticTerm::SingleVariable(_, ref mut coeff) => { coeff.mul_assign(by); - }, + } ArithmeticTerm::Constant(ref mut coeff) => { coeff.mul_assign(by); - }, + } } } } @@ -313,11 +299,11 @@ impl ArithmeticTerm { const DEFAULT_SMALLVEC_CAPACITY_FOR_TERM: usize = 8; #[derive(Clone, Debug)] -pub struct MainGateTerm{ +pub struct MainGateTerm { pub(crate) terms: smallvec::SmallVec<[ArithmeticTerm; DEFAULT_SMALLVEC_CAPACITY_FOR_TERM]>, pub(crate) vars_scratch: std::collections::HashMap, pub(crate) num_multiplicative_terms: usize, - pub(crate) num_constant_terms: usize + pub(crate) num_constant_terms: usize, } impl MainGateTerm { @@ -326,7 +312,7 @@ impl MainGateTerm { terms: smallvec::smallvec![], vars_scratch: std::collections::HashMap::with_capacity(DEFAULT_SMALLVEC_CAPACITY_FOR_TERM), num_multiplicative_terms: 0, - num_constant_terms: 0 + num_constant_terms: 0, } } @@ -339,15 +325,15 @@ impl MainGateTerm { ArithmeticTerm::Product(_, _) => { self.num_multiplicative_terms += 1; self.terms.push(other); - }, + } ArithmeticTerm::SingleVariable(var, coeff) => { - // deduplicate + // deduplicate if self.vars_scratch.get(&var).is_some() { let index = *self.vars_scratch.get(&var).unwrap(); match &mut self.terms[index] { ArithmeticTerm::SingleVariable(_, ref mut c) => { c.add_assign(&coeff); - }, + } _ => { unreachable!() } @@ -357,14 +343,14 @@ impl MainGateTerm { self.vars_scratch.insert(var, self.terms.len()); self.terms.push(other); } - }, + } ArithmeticTerm::Constant(_) => { self.num_constant_terms += 1; self.terms.push(other); - }, + } } - - debug_assert!(self.num_constant_terms <= 1, "must duplicate constants"); + + debug_assert!(self.num_constant_terms <= 1, "must duplicate constants"); } pub fn add_assign_allowing_duplicates(&mut self, other: ArithmeticTerm) { @@ -372,81 +358,75 @@ impl MainGateTerm { ArithmeticTerm::Product(_, _) => { self.num_multiplicative_terms += 1; self.terms.push(other); - }, + } ArithmeticTerm::SingleVariable(_, _) => { // we just push and don't even count this variable as duplicatable self.terms.push(other); - }, + } ArithmeticTerm::Constant(_) => { self.num_constant_terms += 1; self.terms.push(other); - }, + } } - - debug_assert!(self.num_constant_terms <= 1, "must duplicate constants"); + + debug_assert!(self.num_constant_terms <= 1, "must duplicate constants"); } pub fn sub_assign(&mut self, mut other: ArithmeticTerm) { match &mut other { ArithmeticTerm::Product(_, ref mut coeff) => { coeff.negate(); - }, + } ArithmeticTerm::SingleVariable(_, ref mut coeff) => { coeff.negate(); - }, + } ArithmeticTerm::Constant(ref mut coeff) => { - coeff.negate(); - }, + coeff.negate(); + } } self.add_assign(other); - debug_assert!(self.num_constant_terms <= 1, "must not duplicate constants"); + debug_assert!(self.num_constant_terms <= 1, "must not duplicate constants"); } pub fn sub_assign_allowing_duplicates(&mut self, mut other: ArithmeticTerm) { match &mut other { ArithmeticTerm::Product(_, ref mut coeff) => { coeff.negate(); - }, + } ArithmeticTerm::SingleVariable(_, ref mut coeff) => { coeff.negate(); - }, + } ArithmeticTerm::Constant(ref mut coeff) => { - coeff.negate(); - }, + coeff.negate(); + } } self.add_assign_allowing_duplicates(other); - debug_assert!(self.num_constant_terms <= 1, "must not duplicate constants"); + debug_assert!(self.num_constant_terms <= 1, "must not duplicate constants"); } } -pub fn get_from_map_unchecked<'a, 'b: 'a, E: Engine>( - key_with_dilation: PolynomialInConstraint, - ldes_map: &'a AssembledPolynomialStorage<'b, E> -) -> &'a Polynomial { - +pub fn get_from_map_unchecked<'a, 'b: 'a, E: Engine>(key_with_dilation: PolynomialInConstraint, ldes_map: &'a AssembledPolynomialStorage<'b, E>) -> &'a Polynomial { let (key, dilation_value) = key_with_dilation.into_id_and_raw_dilation(); let r = if dilation_value == 0 { match key { - k @ PolyIdentifier::VariablesPolynomial(..) => { - ldes_map.state_map.get(&k).expect(&format!("Must get poly {:?} from ldes storage", &k)).as_ref() - }, - k @ PolyIdentifier::WitnessPolynomial(..) => { - ldes_map.witness_map.get(&k).expect(&format!("Must get poly {:?} from ldes storage", &k)).as_ref() - }, - k @ PolyIdentifier::GateSetupPolynomial(..) => { - ldes_map.setup_map.get(&k).expect(&format!("Must get poly {:?} from ldes storage", &k)).as_ref() - }, + k @ PolyIdentifier::VariablesPolynomial(..) => ldes_map.state_map.get(&k).expect(&format!("Must get poly {:?} from ldes storage", &k)).as_ref(), + k @ PolyIdentifier::WitnessPolynomial(..) => ldes_map.witness_map.get(&k).expect(&format!("Must get poly {:?} from ldes storage", &k)).as_ref(), + k @ PolyIdentifier::GateSetupPolynomial(..) => ldes_map.setup_map.get(&k).expect(&format!("Must get poly {:?} from ldes storage", &k)).as_ref(), _ => { unreachable!(); } } } else { - ldes_map.scratch_space.get(&key_with_dilation).expect(&format!("Must get poly {:?} from lde storage", &key_with_dilation)).as_ref() + ldes_map + .scratch_space + .get(&key_with_dilation) + .expect(&format!("Must get poly {:?} from lde storage", &key_with_dilation)) + .as_ref() }; r @@ -459,8 +439,8 @@ pub fn ensure_in_map_or_create<'a, 'b, E: Engine>( omegas_bitreversed: &BitReversedOmegas, lde_factor: usize, coset_factor: E::Fr, - monomials_map: & AssembledPolynomialStorageForMonomialForms<'a, E>, - ldes_map: &mut AssembledPolynomialStorage<'b, E> + monomials_map: &AssembledPolynomialStorageForMonomialForms<'a, E>, + ldes_map: &mut AssembledPolynomialStorage<'b, E>, ) -> Result<(), SynthesisError> { assert!(ldes_map.is_bitreversed); assert_eq!(ldes_map.lde_factor, lde_factor); @@ -475,17 +455,17 @@ pub fn ensure_in_map_or_create<'a, 'b, E: Engine>( if ldes_map.state_map.get(&k).is_some() { contains_in_scratch_or_maps = true; } - }, + } k @ PolyIdentifier::WitnessPolynomial(..) => { if ldes_map.witness_map.get(&k).is_some() { contains_in_scratch_or_maps = true; } - }, + } k @ PolyIdentifier::GateSetupPolynomial(..) => { if ldes_map.setup_map.get(&k).is_some() { contains_in_scratch_or_maps = true; } - }, + } _ => { unreachable!(); } @@ -500,15 +480,9 @@ pub fn ensure_in_map_or_create<'a, 'b, E: Engine>( // optimistic case: we have already calculated value without dilation // but now need to just rotate let lde_without_dilation = match key { - k @ PolyIdentifier::VariablesPolynomial(..) => { - ldes_map.state_map.get(&k) - }, - k @ PolyIdentifier::WitnessPolynomial(..) => { - ldes_map.witness_map.get(&k) - }, - k @ PolyIdentifier::GateSetupPolynomial(..) => { - ldes_map.setup_map.get(&k) - }, + k @ PolyIdentifier::VariablesPolynomial(..) => ldes_map.state_map.get(&k), + k @ PolyIdentifier::WitnessPolynomial(..) => ldes_map.witness_map.get(&k), + k @ PolyIdentifier::GateSetupPolynomial(..) => ldes_map.setup_map.get(&k), _ => { unreachable!(); } @@ -539,32 +513,21 @@ pub fn ensure_in_map_or_create<'a, 'b, E: Engine>( // perform LDE and push let monomial = match key { - k @ PolyIdentifier::VariablesPolynomial(..) => { - monomials_map.state_map.get(&k).unwrap().as_ref() - }, - k @ PolyIdentifier::WitnessPolynomial(..) => { - monomials_map.witness_map.get(&k).unwrap().as_ref() - }, - k @ PolyIdentifier::GateSetupPolynomial(..) => { - monomials_map.setup_map.get(&k).unwrap().as_ref() - }, + k @ PolyIdentifier::VariablesPolynomial(..) => monomials_map.state_map.get(&k).unwrap().as_ref(), + k @ PolyIdentifier::WitnessPolynomial(..) => monomials_map.witness_map.get(&k).unwrap().as_ref(), + k @ PolyIdentifier::GateSetupPolynomial(..) => monomials_map.setup_map.get(&k).unwrap().as_ref(), _ => { unreachable!(); } }; - - let lde = monomial.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - omegas_bitreversed, - &coset_factor - )?; - + + let lde = monomial.clone().bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, omegas_bitreversed, &coset_factor)?; + let final_lde = if dilation_value != 0 { let rotation_factor = dilation_value * lde_factor; let f = lde.clone_shifted_assuming_bitreversed(rotation_factor, worker)?; drop(lde); - + f } else { lde @@ -578,13 +541,13 @@ pub fn ensure_in_map_or_create<'a, 'b, E: Engine>( match key { k @ PolyIdentifier::VariablesPolynomial(..) => { ldes_map.state_map.insert(k, proxy); - }, + } k @ PolyIdentifier::WitnessPolynomial(..) => { ldes_map.witness_map.insert(k, proxy); - }, + } k @ PolyIdentifier::GateSetupPolynomial(..) => { ldes_map.setup_map.insert(k, proxy); - }, + } _ => { unreachable!(); } @@ -652,19 +615,15 @@ pub trait ConstraintSystem { where F: FnOnce() -> Result; - fn new_single_gate_for_trace_step>(&mut self, + fn new_single_gate_for_trace_step>( + &mut self, equation: &G, coefficients_assignments: &[E::Fr], variables_assignments: &[Variable], - witness_assignments: &[E::Fr] + witness_assignments: &[E::Fr], ) -> Result<(), SynthesisError> { self.begin_gates_batch_for_step()?; - self.new_gate_in_batch( - equation, - coefficients_assignments, - variables_assignments, - witness_assignments - )?; + self.new_gate_in_batch(equation, coefficients_assignments, variables_assignments, witness_assignments)?; self.end_gates_batch_for_step() } @@ -675,29 +634,16 @@ pub trait ConstraintSystem { let mg = Self::MainGate::default(); - self.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - ) + self.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[]) } fn begin_gates_batch_for_step(&mut self) -> Result<(), SynthesisError>; - fn new_gate_in_batch>(&mut self, - equation: &G, - coefficients_assignments: &[E::Fr], - variables_assignments: &[Variable], - witness_assignments: &[E::Fr] - ) -> Result<(), SynthesisError>; + fn new_gate_in_batch>(&mut self, equation: &G, coefficients_assignments: &[E::Fr], variables_assignments: &[Variable], witness_assignments: &[E::Fr]) -> Result<(), SynthesisError>; fn end_gates_batch_for_step(&mut self) -> Result<(), SynthesisError>; - fn allocate_variables_without_gate(&mut self, - variables_assignments: &[Variable], - witness_assignments: &[E::Fr] - ) -> Result<(), SynthesisError>; + fn allocate_variables_without_gate(&mut self, variables_assignments: &[Variable], witness_assignments: &[E::Fr]) -> Result<(), SynthesisError>; - fn get_value(&self, _variable: Variable) -> Result { + fn get_value(&self, _variable: Variable) -> Result { Err(SynthesisError::AssignmentMissing) } @@ -707,10 +653,10 @@ pub trait ConstraintSystem { fn get_explicit_one(&mut self) -> Result; fn add_table(&mut self, table: LookupTableApplication) -> Result>, SynthesisError>; - fn get_table(&self, functional_name: &str) -> Result>, SynthesisError>; + fn get_table(&self, functional_name: &str) -> Result>, SynthesisError>; fn add_multitable(&mut self, table: MultiTableApplication) -> Result<(), SynthesisError>; - fn get_multitable(&self, functional_name: &str) -> Result>, SynthesisError>; + fn get_multitable(&self, functional_name: &str) -> Result>, SynthesisError>; fn apply_single_lookup_gate(&mut self, variables: &[Variable], gate: Arc>) -> Result<(), SynthesisError>; fn apply_multi_lookup_gate(&mut self, variables: &[Variable], gate: Arc>) -> Result<(), SynthesisError>; @@ -722,10 +668,10 @@ pub trait ConstraintSystem { #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct PlonkCsWidth4WithNextStepParams; impl PlonkConstraintSystemParams for PlonkCsWidth4WithNextStepParams { - const STATE_WIDTH: usize = 4; + const STATE_WIDTH: usize = 4; const WITNESS_WIDTH: usize = 0; const HAS_WITNESS_POLYNOMIALS: bool = false; - const HAS_CUSTOM_GATES: bool = false; + const HAS_CUSTOM_GATES: bool = false; const CAN_ACCESS_NEXT_TRACE_STEP: bool = true; } @@ -733,34 +679,33 @@ impl PlonkConstraintSystemParams for PlonkCsWidth4WithNextStepPara pub struct PlonkCsWidth4WithNextStepAndCustomGatesParams; impl PlonkConstraintSystemParams for PlonkCsWidth4WithNextStepAndCustomGatesParams { - const STATE_WIDTH: usize = 4; + const STATE_WIDTH: usize = 4; const WITNESS_WIDTH: usize = 0; const HAS_WITNESS_POLYNOMIALS: bool = false; const HAS_CUSTOM_GATES: bool = true; const CAN_ACCESS_NEXT_TRACE_STEP: bool = true; } -#[cfg(not(feature="allocator"))] +#[cfg(not(feature = "allocator"))] macro_rules! new_vec_with_allocator { ($capacity:expr) => { Vec::with_capacity($capacity) - } + }; } -#[cfg(feature="allocator")] +#[cfg(feature = "allocator")] macro_rules! new_vec_with_allocator { ($capacity:expr) => { Vec::with_capacity_in($capacity, A::default()) - } + }; } - use crate::plonk::polynomials::*; #[derive(Clone, serde::Serialize, serde::Deserialize)] -#[cfg_attr(feature = "allocator",serde(bound(serialize = "A: serde::Serialize", deserialize = "'de: 'static, A: serde::Deserialize<'de>")))] +#[cfg_attr(feature = "allocator", serde(bound(serialize = "A: serde::Serialize", deserialize = "'de: 'static, A: serde::Deserialize<'de>")))] #[cfg_attr(not(feature = "allocator"), serde(bound(deserialize = "'de: 'static")))] -pub struct PolynomialStorage { +pub struct PolynomialStorage { #[cfg(feature = "allocator")] #[cfg_attr(feature = "allocator", serde(serialize_with = "serialize_hashmap_with_allocator"))] #[cfg_attr(feature = "allocator", serde(deserialize_with = "deserialize_hashmap_with_allocator"))] @@ -809,7 +754,7 @@ impl_poly_storage! { setup_map: std::collections::HashMap::new(), } } - + pub fn get_value(&self, poly: &PolynomialInConstraint, n: usize) -> Result { match poly { PolynomialInConstraint(PolyIdentifier::VariablesPolynomial(_), TimeDilation(_)) => { @@ -823,7 +768,7 @@ impl_poly_storage! { .ok_or(SynthesisError::AssignmentMissing)? .get(final_index) .ok_or(SynthesisError::AssignmentMissing)?; - + Ok(value) }, PolynomialInConstraint(PolyIdentifier::WitnessPolynomial(_), TimeDilation(_)) => { @@ -834,7 +779,7 @@ impl_poly_storage! { } } } - + pub fn get_variable(&self, poly: &PolynomialInConstraint, n: usize) -> Result { match poly { PolynomialInConstraint(PolyIdentifier::VariablesPolynomial(idx), TimeDilation(dilation)) => { @@ -845,7 +790,7 @@ impl_poly_storage! { .ok_or(SynthesisError::AssignmentMissing)? .get(final_index) .ok_or(SynthesisError::AssignmentMissing)?; - + Ok(value) }, _ => { @@ -859,7 +804,7 @@ impl_poly_storage! { #[serde(bound(serialize = "dyn GateInternal: serde::Serialize", deserialize = "'de: 'static, dyn GateInternal: serde::Deserialize<'de>"))] pub struct GateDensityStorage(pub std::collections::HashMap>, BitVec>); -impl Default for GateDensityStorage{ +impl Default for GateDensityStorage { fn default() -> Self { Self(std::collections::HashMap::new()) } @@ -884,9 +829,15 @@ pub type ProvingAssembly = Assembly; pub type SetupAssembly = Assembly; #[derive(Clone, serde::Serialize, serde::Deserialize)] -#[cfg_attr(feature = "allocator", serde(bound(serialize = "MG: serde::Serialize, A: serde::Serialize", deserialize = "'de: 'static, MG: serde::Deserialize<'de>, A: serde::Deserialize<'de>")))] +#[cfg_attr( + feature = "allocator", + serde(bound( + serialize = "MG: serde::Serialize, A: serde::Serialize", + deserialize = "'de: 'static, MG: serde::Deserialize<'de>, A: serde::Deserialize<'de>" + )) +)] #[cfg_attr(not(feature = "allocator"), serde(bound(serialize = "MG: serde::Serialize", deserialize = "'de: 'static, MG: serde::Deserialize<'de>")))] -pub struct Assembly, MG: MainGate, S: SynthesisMode, #[cfg(feature = "allocator")]A: Allocator + Default = Global> { +pub struct Assembly, MG: MainGate, S: SynthesisMode, #[cfg(feature = "allocator")] A: Allocator + Default = Global> { #[cfg(feature = "allocator")] pub inputs_storage: PolynomialStorage, #[cfg(not(feature = "allocator"))] @@ -955,7 +906,7 @@ pub struct Assembly, MG: MainGate, } -cfg_if!{ +cfg_if! { if #[cfg(feature = "allocator")]{ use serde::de::{Visitor, SeqAccess, MapAccess}; @@ -963,7 +914,7 @@ cfg_if!{ m1: PhantomData, m2: PhantomData, } - + impl VecVisitor{ pub fn new() -> Self{ Self{ @@ -972,18 +923,18 @@ cfg_if!{ } } } - + impl<'de, T, B> Visitor<'de> for VecVisitor where T: Deserialize<'de>, B: Allocator + Default, { type Value = Vec; - + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a sequence") } - + fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, @@ -991,25 +942,25 @@ cfg_if!{ let size_hint = seq.size_hint(); let size_hint = std::cmp::min(size_hint.unwrap_or(0), 4096); let mut values = Vec::with_capacity_in(size_hint, B::default()); - + while let Ok(result) = seq.next_element() { match result{ Some(value) => values.push(value), None => (), } } - - + + Ok(values) } } - + struct TwoDVecVisitor { m1: PhantomData, m2: PhantomData, } - - + + impl TwoDVecVisitor{ pub fn new() -> Self{ Self{ @@ -1018,18 +969,18 @@ cfg_if!{ } } } - + impl<'de, T, B> Visitor<'de> for TwoDVecVisitor where T: Deserialize<'de>, B: Allocator + Default, { type Value = Vec>; - + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a sequence") } - + fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, @@ -1037,10 +988,10 @@ cfg_if!{ let size_hint = seq.size_hint(); let size_hint = std::cmp::min(size_hint.unwrap_or(0), 4096); let mut final_result = Vec::with_capacity(size_hint); - - + + while let Ok(result) = seq.next_element::>() { - match result{ + match result{ Some(sub_vec) => { let size_hint = seq.size_hint(); let size_hint = std::cmp::min(size_hint.unwrap_or(0), 4096); @@ -1048,22 +999,22 @@ cfg_if!{ for el in sub_vec{ values.push(el) } - final_result.push(values); + final_result.push(values); }, None => (), } } - + Ok(final_result) } } - + struct MapVisitor { m0: PhantomData, m1: PhantomData, m2: PhantomData, } - + impl MapVisitor{ pub fn new() -> Self{ Self{ @@ -1073,7 +1024,7 @@ cfg_if!{ } } } - + impl<'de, K, T, B> Visitor<'de> for MapVisitor where T: Deserialize<'de>, @@ -1081,11 +1032,11 @@ cfg_if!{ B: Allocator + Default { type Value = HashMap>; - + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a 2d sequence") } - + fn visit_map(self, mut map: A) -> Result where A: MapAccess<'de>, @@ -1093,7 +1044,7 @@ cfg_if!{ let size_hint = map.size_hint(); let size_hint = std::cmp::min(size_hint.unwrap_or(0), 4096); let mut final_map = HashMap::with_capacity(size_hint); - + while let Ok(entry) = map.next_entry::>() { let mut values = vec![]; match entry{ @@ -1105,20 +1056,20 @@ cfg_if!{ None => (), } } - - + + Ok(final_map) } } - + fn serialize_vec_with_allocator(data: &Vec, serializer: S) -> Result where S: serde::Serializer { data.serialize(serializer) } - + fn deserialize_vec_with_allocator<'de, D, T: serde::Deserialize<'de>, A: Allocator + Default + serde::Deserialize<'de>>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_seq(VecVisitor::new()) } - + fn serialize_2d_vec_with_allocator(data: &Vec>, serializer: S) -> Result where S: serde::Serializer { use serde::ser::SerializeSeq; let mut seq = serializer.serialize_seq(Some(data.len()))?; @@ -1129,14 +1080,14 @@ cfg_if!{ } seq.end() } - - fn deserialize_2d_vec_with_allocator<'de, D, T: serde::Deserialize<'de>, A: Allocator + Default + serde::Deserialize<'de>>(deserializer: D) -> Result>, D::Error> where D: serde::Deserializer<'de> { + + fn deserialize_2d_vec_with_allocator<'de, D, T: serde::Deserialize<'de>, A: Allocator + Default + serde::Deserialize<'de>>(deserializer: D) -> Result>, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_seq(TwoDVecVisitor::new()) } - + fn serialize_hashmap_with_allocator(data: &HashMap>, serializer: S) -> Result where S: serde::Serializer { use serde::ser::{SerializeMap, SerializeSeq}; - + let mut s = serializer.serialize_map(Some(data.len()))?; for (k, v) in data{ s.serialize_key(k)?; @@ -1146,19 +1097,18 @@ cfg_if!{ } s.end() } - + fn deserialize_hashmap_with_allocator<'de, D,K: serde::Deserialize<'de>, T: serde::Deserialize<'de>, A: Allocator + Default>(deserializer: D) -> Result>, D::Error> where D: serde::Deserializer<'de> { deserializer.deserialize_map(MapVisitor::new()) } } } - macro_rules! impl_assembly { {impl Assembly $inherent:tt} => { #[cfg(feature = "allocator")] impl, MG: MainGate, S: SynthesisMode, A: Allocator + Default + 'static + Send + Sync> Assembly $inherent - + #[cfg(not(feature = "allocator"))] impl, MG: MainGate, S: SynthesisMode> Assembly $inherent }; @@ -1171,32 +1121,32 @@ macro_rules! impl_assembly { } } -impl_assembly!{ +impl_assembly! { impl ConstraintSystem { type Params = P; type MainGate = MG; - + // allocate a variable #[inline] fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result { - + self.num_aux += 1; let index = self.num_aux; if S::PRODUCE_WITNESS { let value = value()?; self.aux_assingments.push(value); } - + Ok(Variable(Index::Aux(index))) } - + // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result { self.num_inputs += 1; let index = self.num_inputs; @@ -1204,46 +1154,46 @@ impl_assembly!{ let value = value()?; self.input_assingments.push(value); } - + let input_var = Variable(Index::Input(index)); - + let mut main_gate = MainGateTerm::::new(); main_gate.sub_assign(ArithmeticTerm::from_variable(input_var)); - + let dummy = Self::get_dummy_variable(); let (variables_assignments, coefficients_assignments) = MG::format_term(main_gate, dummy).expect("must make empty padding gate"); - + let n = self.num_input_gates; Self::allocate_into_storage( - &MG::default(), - &mut self.inputs_storage, - n, - &coefficients_assignments, - &variables_assignments, + &MG::default(), + &mut self.inputs_storage, + n, + &coefficients_assignments, + &variables_assignments, &[] )?; - + self.num_input_gates += 1; - + Ok(input_var) } - + #[inline] fn get_main_gate(&self) -> &MG { &self.main_gate } - + #[inline] fn begin_gates_batch_for_step(&mut self) -> Result<(), SynthesisError> { debug_assert!(self.trace_step_for_batch.is_none()); let n = self.num_aux_gates; self.num_aux_gates += 1; self.trace_step_for_batch = Some(n); - + Ok(()) } - - fn new_gate_in_batch>(&mut self, + + fn new_gate_in_batch>(&mut self, gate: &G, coefficients_assignments: &[E::Fr], variables_assignments: &[Variable], @@ -1251,10 +1201,10 @@ impl_assembly!{ ) -> Result<(), SynthesisError> { // check that gate is ok for config // debug_assert!(check_gate_is_allowed_for_params::(&gate), format!("supplied params do not work with gate {:?}", gate)); - + let n = self.trace_step_for_batch.unwrap(); // make zero-enumerated index - + Self::allocate_into_storage( gate, &mut self.aux_storage, @@ -1263,9 +1213,9 @@ impl_assembly!{ variables_assignments, witness_assignments, )?; - + self.add_gate_into_list(gate); - + if S::PRODUCE_SETUP { if let Some(tracker) = self.aux_gate_density.0.get_mut(gate.as_internal() as &dyn GateInternal) { if tracker.len() != n { @@ -1282,21 +1232,21 @@ impl_assembly!{ debug_assert_eq!(n+1, tracker.len()); } } - + Ok(()) } - - fn allocate_variables_without_gate(&mut self, + + fn allocate_variables_without_gate(&mut self, variables_assignments: &[Variable], witness_assignments: &[E::Fr] ) -> Result<(), SynthesisError> { let n = self.trace_step_for_batch.expect("may only be called in a batch"); // make zero-enumerated index - + let empty_coefficients = Self::MainGate::empty_coefficients(); - + let gate = Self::MainGate::default(); - + Self::allocate_into_storage( &gate, &mut self.aux_storage, @@ -1305,10 +1255,10 @@ impl_assembly!{ variables_assignments, witness_assignments, )?; - + if S::PRODUCE_SETUP { let apply_gate = false; - + let tracker = self.aux_gate_density.0.get_mut(gate.as_internal() as &dyn GateInternal).unwrap(); if tracker.len() != n { let padding = n - tracker.len(); @@ -1317,18 +1267,18 @@ impl_assembly!{ tracker.push(apply_gate); debug_assert_eq!(n+1, tracker.len()); } - + Ok(()) } - + fn end_gates_batch_for_step(&mut self) -> Result<(), SynthesisError> { debug_assert!(self.trace_step_for_batch.is_some()); let n = self.trace_step_for_batch.take().unwrap(); debug_assert_eq!(n+1, self.num_aux_gates, "invalid batch id"); - + Ok(()) } - + #[inline] fn get_value(&self, var: Variable) -> Result { if !S::PRODUCE_WITNESS { @@ -1337,10 +1287,10 @@ impl_assembly!{ let value = match var { Variable(Index::Aux(0)) => { // use crate::rand::Rng; - + // let mut rng = crate::rand::thread_rng(); // let value: E::Fr = rng.gen(); - + // value E::Fr::zero() // return Err(SynthesisError::AssignmentMissing); @@ -1355,57 +1305,57 @@ impl_assembly!{ self.aux_assingments[aux - 1] } }; - + Ok(value) } - + #[inline] fn get_dummy_variable() -> Variable { Self::dummy_variable() } - + fn get_explicit_zero(&mut self) -> Result { if let Some(var) = self.explicit_zero_variable { return Ok(var); } - + let value = E::Fr::zero(); let zero = self.alloc(|| Ok(value))?; - + let self_term = ArithmeticTerm::from_variable(zero); let other_term = ArithmeticTerm::constant(value); let mut term = MainGateTerm::new(); term.add_assign(self_term); term.sub_assign(other_term); - + self.allocate_main_gate(term)?; - + self.explicit_zero_variable = Some(zero); - + Ok(zero) } - + fn get_explicit_one(&mut self) -> Result { if let Some(var) = self.explicit_one_variable { return Ok(var); } - + let value = E::Fr::one(); let one = self.alloc(|| Ok(value))?; - + let self_term = ArithmeticTerm::from_variable(one); let other_term = ArithmeticTerm::constant(value); let mut term = MainGateTerm::new(); term.add_assign(self_term); term.sub_assign(other_term); - + self.allocate_main_gate(term)?; - + self.explicit_one_variable = Some(one); - + Ok(one) } - + fn add_table(&mut self, table: LookupTableApplication) -> Result>, SynthesisError> { assert!(table.applies_over().len() == 3, "only support tables of width 3"); assert!(table.can_be_combined(), "can only add tables that are combinable"); @@ -1413,7 +1363,7 @@ impl_assembly!{ let table_name = table.functional_name(); let table_id = table.table_id(); let number_of_entries = table.size(); - + // ensure sorted format when we add table let mut entries = Self::ensure_sorted_table(&table); assert_eq!(entries.len(), 3); @@ -1426,43 +1376,43 @@ impl_assembly!{ entries_as_arrays.push([a, b, c]); entries_into_table_row.insert([a, b, c], idx); } - + let shared = Arc::from(table); let res = shared.clone(); - + self.tables.push(shared); self.individual_table_canonical_sorted_entries.insert(table_name.clone(), entries_as_arrays); - self.individual_table_entries_lookups.insert(table_name.clone(), entries_into_table_row); + self.individual_table_entries_lookups.insert(table_name.clone(), entries_into_table_row); let buffer_for_current_table = if let Some(mut buffer) = self.reusable_buffer_for_lookup_entries.pop(){ buffer.clear(); buffer }else{ // println!("allocating new buffer for table {}", table_name); - + new_vec_with_allocator!(0) }; - + self.individual_table_entries.insert(table_name.clone(), buffer_for_current_table); self.known_table_names.push(table_name.clone()); self.table_selectors.insert(table_name.clone(), BitVec::new()); self.known_table_ids.insert(table_name, table_id); - + self.total_length_of_all_tables += number_of_entries; - + Ok(res) } - + fn get_table(&self, name: &str) -> Result>, SynthesisError> { for t in self.tables.iter() { if t.functional_name() == name { return Ok(Arc::clone(t)); } } - + Err(SynthesisError::AssignmentMissing) } - + fn add_multitable(&mut self, table: MultiTableApplication) -> Result<(), SynthesisError> { let table_name = table.functional_name(); let mut exists = false; @@ -1475,37 +1425,37 @@ impl_assembly!{ self.multitables.push(Arc::from(table)); self.multitable_selectors.insert(table_name.clone(), BitVec::new()); self.individual_table_entries.insert(table_name.clone(), new_vec_with_allocator!(0)); - + Ok(()) } - + fn get_multitable(&self, functional_name: &str) -> Result>, SynthesisError> { for t in self.multitables.iter() { if t.functional_name() == functional_name { return Ok(Arc::clone(t)); } } - + Err(SynthesisError::AssignmentMissing) } - + #[track_caller] fn apply_single_lookup_gate(&mut self, variables: &[Variable], table: Arc>) -> Result<(), SynthesisError> { let n = self.trace_step_for_batch.expect("may only add table constraint in a transaction"); // make zero-enumerated index - + if S::PRODUCE_SETUP { debug_assert!(self.tables.contains(&table)); assert!(table.can_be_combined() == true); assert!(table.applies_over().len() == 3); - + let table_name = table.functional_name(); let table_id = table.table_id(); - + // we need to: // - mark that this table applies at this row // - add values into the list to later on make a sorted polynomial - + let tracker = self.table_selectors.get_mut(&table_name).unwrap(); if tracker.len() != n { let padding = n - tracker.len(); @@ -1513,15 +1463,15 @@ impl_assembly!{ } tracker.push(true); debug_assert_eq!(n+1, tracker.len()); - + // keep track of what table is applied at what row self.table_ids_poly.resize(n, E::Fr::zero()); self.table_ids_poly.push(table_id); } - + if S::PRODUCE_WITNESS { let table_name = table.functional_name(); - + // add values for lookup table sorting later let keys_and_values_len = table.applies_over().len(); let mut table_entries = arrayvec::ArrayVec::<_, 3>::new(); @@ -1531,53 +1481,53 @@ impl_assembly!{ } use std::convert::TryInto; let table_entries_as_array: [_; 3] = table_entries.into_inner().unwrap(); - + let entries = self.individual_table_entries.get_mut(&table_name).unwrap(); assert_eq!(variables.len(), table.applies_over().len()); // // This check is substituted by the lookup from values into index below // let valid_entries = table.is_valid_entry(&table_entries_as_array[..keys_and_values_len]); // assert!(valid_entries); - + // if !valid_entries { // return Err(SynthesisError::Unsatisfiable); // } let row_idx = self.individual_table_entries_lookups.get(&table_name).unwrap().get(&table_entries_as_array); assert!(row_idx.is_some(), "table most likely doesn't contain a row for {:?}", table_entries_as_array); - + entries.push(*row_idx.unwrap() as u32); } - + self.num_table_lookups += 1; - + Ok(()) } - + #[track_caller] fn apply_multi_lookup_gate(&mut self, variables: &[Variable], table: Arc>) -> Result<(), SynthesisError> { unimplemented!("not implementing multitable for now"); } - + fn get_current_step_number(&self) -> usize { self.n() } - + fn get_current_aux_gate_number(&self) -> usize { self.num_aux_gates } } - + } -impl_assembly!{ +impl_assembly! { impl Assembly{ fn allocate_into_storage>( gate: &G, #[cfg(feature = "allocator")] - storage: &mut PolynomialStorage, + storage: &mut PolynomialStorage, #[cfg(not(feature = "allocator"))] - storage: &mut PolynomialStorage, + storage: &mut PolynomialStorage, n: usize, coefficients_assignments: &[E::Fr], variables_assignments: &[Variable], @@ -1623,7 +1573,7 @@ impl_assembly!{ let poly_ref = storage.witness_map.entry(key).or_insert(vec![]); if poly_ref.len() < n { poly_ref.resize(n, E::Fr::zero()); - } + } poly_ref.push(*witness_it.next().unwrap_or(&zero)); } @@ -1642,17 +1592,17 @@ impl_assembly!{ for &p in gate.all_queried_polynomials().into_iter() { self.all_queried_polys_in_constraints.insert(p); } - + self.sorted_gates.push(gate.clone().into_internal()); let degree = gate.degree(); if self.max_constraint_degree < degree { self.max_constraint_degree = degree; } - } + } } - pub fn new() -> Self { + pub fn new() -> Self { let mut tmp = Self { inputs_storage: PolynomialStorage::new(), aux_storage: PolynomialStorage::new(), @@ -1713,7 +1663,7 @@ impl_assembly!{ tmp.add_gate_into_list(&MG::default()); tmp - } + } pub fn new_specialized_for_proving_assembly_and_state_4(domain_size: usize, aux_size: usize, num_lookup_tables: usize, max_num_lookup_entries: usize) -> Self { assert!(domain_size <= 1 << ::S); @@ -1811,18 +1761,18 @@ impl_assembly!{ let new_size = *new_size_candidates.iter().max().unwrap(); assert!( - new_size <= 1usize << E::Fr::S, - "Padded circuit size is {}, that is larget than number of roots of unity 2^{}. Padded from {} gates and {} lookup table accesses", - new_size, + new_size <= 1usize << E::Fr::S, + "Padded circuit size is {}, that is larget than number of roots of unity 2^{}. Padded from {} gates and {} lookup table accesses", + new_size, E::Fr::S, self.n(), total_number_of_table_entries, ); assert!( - new_size <= (1usize << E::Fr::S) / >::Params::STATE_WIDTH, - "Circuit size is {}, that is larget than number of roots of unity 2^{} for copy-permutation over {} polys. Padded from {} gates and {} lookup table accesses", - new_size, - E::Fr::S, + new_size <= (1usize << E::Fr::S) / >::Params::STATE_WIDTH, + "Circuit size is {}, that is larget than number of roots of unity 2^{} for copy-permutation over {} polys. Padded from {} gates and {} lookup table accesses", + new_size, + E::Fr::S, >::Params::STATE_WIDTH, self.n(), total_number_of_table_entries, @@ -1887,19 +1837,19 @@ impl_assembly!{ let new_size = *new_size_candidates.iter().max().unwrap(); assert!( - new_size <= 1usize << E::Fr::S, + new_size <= 1usize << E::Fr::S, " - size is {}, that is larget than number of roots of unity 2^{}. Padded from {} gates and {} lookup table accesses", - new_size, + size is {}, that is larget than number of roots of unity 2^{}. Padded from {} gates and {} lookup table accesses", + new_size, E::Fr::S, self.n(), total_number_of_table_entries, ); assert!( - new_size <= (1usize << E::Fr::S) / >::Params::STATE_WIDTH, - "Circuit size is {}, that is larget than number of roots of unity 2^{} for copy-permutation over {} polys. Padded from {} gates and {} lookup table accesses", - new_size, - E::Fr::S, + new_size <= (1usize << E::Fr::S) / >::Params::STATE_WIDTH, + "Circuit size is {}, that is larget than number of roots of unity 2^{} for copy-permutation over {} polys. Padded from {} gates and {} lookup table accesses", + new_size, + E::Fr::S, >::Params::STATE_WIDTH, self.n(), total_number_of_table_entries, @@ -1946,11 +1896,11 @@ impl_assembly!{ // pad special purpose table selector poly self.table_ids_poly.resize(new_size_for_aux, E::Fr::zero()); - } + } } assert!((self.n()+1).is_power_of_two(), "padded circuit size is not power of two. self.n() = {}", self.n()); - + self.is_finalized = true; } @@ -2128,7 +2078,7 @@ impl_assembly!{ permutations[i] = permutation.clone(); for (original, new) in partition.into_iter() - .zip(permutation.into_iter()) + .zip(permutation.into_iter()) { // (column_idx, trace_step_idx) let new_zero_enumerated = new.1 - 1; @@ -2249,7 +2199,7 @@ impl_assembly!{ } let gate_selector_values = self.output_gate_selectors(&worker)?; - + if known_gates_list.len() > 1 { assert_eq!(gate_selector_values.len(), known_gates_list.len(), "numbers of selectors and known gates mismatch"); } @@ -2302,10 +2252,10 @@ impl_assembly!{ } pub fn perform_setup( - &self, + &self, worker: &Worker ) -> Result< - (std::collections::HashMap>, Vec>), + (std::collections::HashMap>, Vec>), SynthesisError > { let map = self.make_setup_polynomials(true)?; @@ -2356,17 +2306,17 @@ impl_assembly!{ Ok(poly_values) } - pub fn calculate_t_polynomial_values_for_single_application_tables(&self) -> + pub fn calculate_t_polynomial_values_for_single_application_tables(&self) -> Result>, SynthesisError> { if !S::PRODUCE_SETUP { return Err(SynthesisError::AssignmentMissing); } - + if self.tables.len() == 0 { return Ok(vec![]) } - + // we should pass over every table and append it let mut width = 0; @@ -2432,14 +2382,14 @@ impl_assembly!{ result } - // pub fn calculate_interleaved_t_polys(&self) -> + // pub fn calculate_interleaved_t_polys(&self) -> // Result>, SynthesisError> { // assert!(self.is_finalized); - + // if self.tables.len() == 0 { // return Ok(vec![]) // } - + // // we should pass over every table and append it // let mut width = 0; @@ -2492,7 +2442,7 @@ impl_assembly!{ // break 'inner; // } else { - // // go for a next one + // // go for a next one // place_into_idx += 1; // } // } @@ -2503,7 +2453,7 @@ impl_assembly!{ // } // pub fn calculate_s_poly_contributions_from_witness(&self) -> - // Result>, SynthesisError> + // Result>, SynthesisError> // { // if self.tables.len() == 0 { // return Ok(vec![]); @@ -2553,7 +2503,7 @@ impl_assembly!{ // } pub fn calculate_s_poly_contributions_from_witness(&self, delinearization_challenge: E::Fr) -> - Result, SynthesisError> + Result, SynthesisError> { if self.tables.len() == 0 { return Ok(vec![]); @@ -2613,7 +2563,7 @@ impl_assembly!{ pub fn calculate_table_type_values( &self - ) -> + ) -> Result, SynthesisError> { assert!(self.is_finalized); @@ -2686,7 +2636,7 @@ impl_assembly!{ pub fn calculate_masked_lookup_entries( &self, storage: &AssembledPolynomialStorage - ) -> + ) -> Result>, SynthesisError> { assert!(self.is_finalized); @@ -2733,7 +2683,7 @@ impl_assembly!{ &self, storage: &AssembledPolynomialStorage, selector: &PolynomialProxy<'a, E::Fr, Values> - ) -> + ) -> Result>, SynthesisError> { assert!(self.is_finalized); @@ -2898,14 +2848,14 @@ impl_assembly!{ } pub fn make_assembled_poly_storage<'a>( - &self, - worker: &Worker, + &self, + worker: &Worker, with_finalization: bool ) -> Result, SynthesisError> { if with_finalization { assert!(self.is_finalized); } - + let (state_polys, witness_polys) = self.make_state_and_witness_polynomials(&worker, with_finalization)?; let mut state_polys_map = std::collections::HashMap::new(); @@ -2972,8 +2922,8 @@ impl_assembly!{ for (&k, v) in value_form_storage.state_map.iter() { let mon_form = v.as_ref().clone_padded_to_domain()?.ifft_using_bitreversed_ntt( - &worker, - omegas_inv, + &worker, + omegas_inv, &E::Fr::one() )?; let mon_form = PolynomialProxy::from_owned(mon_form); @@ -2982,8 +2932,8 @@ impl_assembly!{ for (&k, v) in value_form_storage.witness_map.iter() { let mon_form = v.as_ref().clone_padded_to_domain()?.ifft_using_bitreversed_ntt( - &worker, - omegas_inv, + &worker, + omegas_inv, &E::Fr::one() )?; let mon_form = PolynomialProxy::from_owned(mon_form); @@ -2993,8 +2943,8 @@ impl_assembly!{ if include_setup { for (&k, v) in value_form_storage.gate_selectors.iter() { let mon_form = v.as_ref().clone_padded_to_domain()?.ifft_using_bitreversed_ntt( - &worker, - omegas_inv, + &worker, + omegas_inv, &E::Fr::one() )?; let mon_form = PolynomialProxy::from_owned(mon_form); @@ -3003,8 +2953,8 @@ impl_assembly!{ for (&k, v) in value_form_storage.setup_map.iter() { let mon_form = v.as_ref().clone_padded_to_domain()?.ifft_using_bitreversed_ntt( - &worker, - omegas_inv, + &worker, + omegas_inv, &E::Fr::one() )?; let mon_form = PolynomialProxy::from_owned(mon_form); @@ -3021,38 +2971,30 @@ impl_assembly!{ mod test { use super::*; - use crate::pairing::Engine; use crate::pairing::ff::PrimeField; + use crate::pairing::Engine; - struct TestCircuit4{ - _marker: PhantomData + struct TestCircuit4 { + _marker: PhantomData, } impl Circuit for TestCircuit4 { type MainGate = Width4MainGateWithDNext; fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let a = cs.alloc(|| { - Ok(E::Fr::from_str("10").unwrap()) - })?; + let a = cs.alloc(|| Ok(E::Fr::from_str("10").unwrap()))?; println!("A = {:?}", a); - let b = cs.alloc(|| { - Ok(E::Fr::from_str("20").unwrap()) - })?; + let b = cs.alloc(|| Ok(E::Fr::from_str("20").unwrap()))?; println!("B = {:?}", b); - let c = cs.alloc(|| { - Ok(E::Fr::from_str("200").unwrap()) - })?; + let c = cs.alloc(|| Ok(E::Fr::from_str("200").unwrap()))?; println!("C = {:?}", c); - let d = cs.alloc(|| { - Ok(E::Fr::from_str("100").unwrap()) - })?; + let d = cs.alloc(|| Ok(E::Fr::from_str("100").unwrap()))?; println!("D = {:?}", d); @@ -3074,7 +3016,7 @@ mod test { cs.allocate_main_gate(term)?; - // c - a*b == 0 + // c - a*b == 0 let mut ab_term = ArithmeticTerm::from_variable(a).mul_by_variable(b); ab_term.scale(&negative_one); @@ -3085,7 +3027,7 @@ mod test { cs.allocate_main_gate(term)?; - // d - 100 == 0 + // d - 100 == 0 let hundred = ArithmeticTerm::constant(E::Fr::from_str("100").unwrap()); let d_term = ArithmeticTerm::from_variable(d); @@ -3099,11 +3041,9 @@ mod test { // Ok(E::Fr::from_str("20").unwrap()) // })?; - let gamma = cs.alloc(|| { - Ok(E::Fr::from_str("20").unwrap()) - })?; + let gamma = cs.alloc(|| Ok(E::Fr::from_str("20").unwrap()))?; - // gamma - b == 0 + // gamma - b == 0 let gamma_term = ArithmeticTerm::from_variable(gamma); let b_term = ArithmeticTerm::from_variable(b); @@ -3127,11 +3067,7 @@ mod test { // here d is equal = 2a, so we need to place b there // and compensate it with -b somewhere before - cs.new_single_gate_for_trace_step(&CS::MainGate::default(), - &coeffs, - &vars, - &[] - )?; + cs.new_single_gate_for_trace_step(&CS::MainGate::default(), &coeffs, &vars, &[])?; let mut term = MainGateTerm::::new(); term.add_assign(ArithmeticTerm::from_variable(b)); @@ -3141,30 +3077,21 @@ mod test { coeffs[3] = negative_one; vars[3] = b; - cs.new_single_gate_for_trace_step(&CS::MainGate::default(), - &coeffs, - &vars, - &[] - )?; + cs.new_single_gate_for_trace_step(&CS::MainGate::default(), &coeffs, &vars, &[])?; Ok(()) } } - struct TestCircuit4WithLookups{ - _marker: PhantomData + struct TestCircuit4WithLookups { + _marker: PhantomData, } impl Circuit for TestCircuit4WithLookups { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Width4MainGateWithDNext::default().into_internal(), - TestBitGate::default().into_internal() - ] - ) + Ok(vec![Width4MainGateWithDNext::default().into_internal(), TestBitGate::default().into_internal()]) } fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { @@ -3182,44 +3109,30 @@ mod test { cs.add_table(xor_table)?; cs.add_table(and_table)?; - let a = cs.alloc(|| { - Ok(E::Fr::from_str("10").unwrap()) - })?; + let a = cs.alloc(|| Ok(E::Fr::from_str("10").unwrap()))?; println!("A = {:?}", a); - let b = cs.alloc(|| { - Ok(E::Fr::from_str("20").unwrap()) - })?; + let b = cs.alloc(|| Ok(E::Fr::from_str("20").unwrap()))?; println!("B = {:?}", b); - let c = cs.alloc(|| { - Ok(E::Fr::from_str("200").unwrap()) - })?; + let c = cs.alloc(|| Ok(E::Fr::from_str("200").unwrap()))?; println!("C = {:?}", c); - let d = cs.alloc(|| { - Ok(E::Fr::from_str("100").unwrap()) - })?; + let d = cs.alloc(|| Ok(E::Fr::from_str("100").unwrap()))?; println!("D = {:?}", d); - let e = cs.alloc(|| { - Ok(E::Fr::from_str("2").unwrap()) - })?; + let e = cs.alloc(|| Ok(E::Fr::from_str("2").unwrap()))?; let binary_x_value = E::Fr::from_str("3").unwrap(); let binary_y_value = E::Fr::from_str("1").unwrap(); - let binary_x = cs.alloc(|| { - Ok(binary_x_value) - })?; + let binary_x = cs.alloc(|| Ok(binary_x_value))?; - let binary_y = cs.alloc(|| { - Ok(binary_y_value) - })?; + let binary_y = cs.alloc(|| Ok(binary_y_value))?; let one = E::Fr::one(); @@ -3239,7 +3152,7 @@ mod test { cs.allocate_main_gate(term)?; - // c - a*b == 0 + // c - a*b == 0 let mut ab_term = ArithmeticTerm::from_variable(a).mul_by_variable(b); ab_term.scale(&negative_one); @@ -3259,24 +3172,19 @@ mod test { let and_result_value = table.query(&[binary_x_value, binary_y_value])?[0]; - let binary_z = cs.alloc(|| { - Ok(and_result_value) - })?; + let binary_z = cs.alloc(|| Ok(and_result_value))?; cs.begin_gates_batch_for_step()?; let vars = [binary_x, binary_y, binary_z, dummy]; - cs.allocate_variables_without_gate( - &vars, - &[] - )?; + cs.allocate_variables_without_gate(&vars, &[])?; cs.apply_single_lookup_gate(&vars[..num_keys_and_values], table)?; cs.end_gates_batch_for_step()?; } - // d - 100 == 0 + // d - 100 == 0 let hundred = ArithmeticTerm::constant(E::Fr::from_str("100").unwrap()); let d_term = ArithmeticTerm::from_variable(d); @@ -3302,12 +3210,7 @@ mod test { let (vars, coeffs) = CS::MainGate::format_linear_term_with_duplicates(term, dummy)?; - cs.new_gate_in_batch( - &CS::MainGate::default(), - &coeffs, - &vars, - &[] - )?; + cs.new_gate_in_batch(&CS::MainGate::default(), &coeffs, &vars, &[])?; cs.apply_single_lookup_gate(&vars[..num_keys_and_values], table)?; @@ -3321,17 +3224,12 @@ mod test { let xor_result_value = table.query(&[binary_x_value, binary_y_value])?[0]; - let binary_z = cs.alloc(|| { - Ok(xor_result_value) - })?; + let binary_z = cs.alloc(|| Ok(xor_result_value))?; cs.begin_gates_batch_for_step()?; let vars = [binary_x, binary_y, binary_z, dummy]; - cs.allocate_variables_without_gate( - &vars, - &[] - )?; + cs.allocate_variables_without_gate(&vars, &[])?; cs.apply_single_lookup_gate(&vars[..num_keys_and_values], table)?; @@ -3340,31 +3238,21 @@ mod test { let one = cs.get_explicit_one()?; - cs.new_single_gate_for_trace_step( - &TestBitGate::default(), - &[], - &[one], - &[], - )?; + cs.new_single_gate_for_trace_step(&TestBitGate::default(), &[], &[one], &[])?; Ok(()) } } - - struct TestCircuit4WithLookupsManyGatesSmallTable{ - _marker: PhantomData + struct TestCircuit4WithLookupsManyGatesSmallTable { + _marker: PhantomData, } impl Circuit for TestCircuit4WithLookupsManyGatesSmallTable { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Width4MainGateWithDNext::default().into_internal(), - ] - ) + Ok(vec![Width4MainGateWithDNext::default().into_internal()]) } fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { @@ -3382,34 +3270,24 @@ mod test { cs.add_table(xor_table)?; cs.add_table(and_table)?; - let a = cs.alloc(|| { - Ok(E::Fr::from_str("10").unwrap()) - })?; + let a = cs.alloc(|| Ok(E::Fr::from_str("10").unwrap()))?; - let b = cs.alloc(|| { - Ok(E::Fr::from_str("20").unwrap()) - })?; + let b = cs.alloc(|| Ok(E::Fr::from_str("20").unwrap()))?; - let c = cs.alloc(|| { - Ok(E::Fr::from_str("200").unwrap()) - })?; + let c = cs.alloc(|| Ok(E::Fr::from_str("200").unwrap()))?; let binary_x_value = E::Fr::from_str("3").unwrap(); let binary_y_value = E::Fr::from_str("1").unwrap(); - let binary_x = cs.alloc(|| { - Ok(binary_x_value) - })?; + let binary_x = cs.alloc(|| Ok(binary_x_value))?; - let binary_y = cs.alloc(|| { - Ok(binary_y_value) - })?; + let binary_y = cs.alloc(|| Ok(binary_y_value))?; let mut negative_one = E::Fr::one(); negative_one.negate(); for _ in 0..((1 << 11) - 100) { - // c - a*b == 0 + // c - a*b == 0 let mut ab_term = ArithmeticTerm::from_variable(a).mul_by_variable(b); ab_term.scale(&negative_one); @@ -3430,17 +3308,12 @@ mod test { let and_result_value = table.query(&[binary_x_value, binary_y_value])?[0]; - let binary_z = cs.alloc(|| { - Ok(and_result_value) - })?; + let binary_z = cs.alloc(|| Ok(and_result_value))?; cs.begin_gates_batch_for_step()?; let vars = [binary_x, binary_y, binary_z, dummy]; - cs.allocate_variables_without_gate( - &vars, - &[] - )?; + cs.allocate_variables_without_gate(&vars, &[])?; cs.apply_single_lookup_gate(&vars[..num_keys_and_values], table)?; @@ -3463,12 +3336,7 @@ mod test { let (vars, coeffs) = CS::MainGate::format_linear_term_with_duplicates(term, dummy)?; - cs.new_gate_in_batch( - &CS::MainGate::default(), - &coeffs, - &vars, - &[] - )?; + cs.new_gate_in_batch(&CS::MainGate::default(), &coeffs, &vars, &[])?; cs.apply_single_lookup_gate(&vars[..num_keys_and_values], table)?; @@ -3482,17 +3350,12 @@ mod test { let xor_result_value = table.query(&[binary_x_value, binary_y_value])?[0]; - let binary_z = cs.alloc(|| { - Ok(xor_result_value) - })?; + let binary_z = cs.alloc(|| Ok(xor_result_value))?; cs.begin_gates_batch_for_step()?; let vars = [binary_x, binary_y, binary_z, dummy]; - cs.allocate_variables_without_gate( - &vars, - &[] - )?; + cs.allocate_variables_without_gate(&vars, &[])?; cs.apply_single_lookup_gate(&vars[..num_keys_and_values], table)?; @@ -3510,9 +3373,7 @@ mod test { let mut assembly = TrivialAssembly::::new(); - let circuit = TestCircuit4:: { - _marker: PhantomData - }; + let circuit = TestCircuit4:: { _marker: PhantomData }; circuit.synthesize(&mut assembly).expect("must work"); @@ -3520,7 +3381,7 @@ mod test { // println!("Assembly state polys = {:?}", assembly.storage.state_map); - // println!("Assembly setup polys = {:?}", assembly.storage.setup_map); + // println!("Assembly setup polys = {:?}", assembly.storage.setup_map); println!("Assembly contains {} gates", assembly.n()); assembly.finalize(); @@ -3536,15 +3397,13 @@ mod test { #[test] fn test_setup_and_prove_custom_gate_and_tables() { use crate::pairing::bn256::{Bn256, Fr}; - use crate::worker::Worker; - use crate::plonk::better_better_cs::verifier::*; use crate::plonk::better_better_cs::setup::VerificationKey; + use crate::plonk::better_better_cs::verifier::*; + use crate::worker::Worker; let mut assembly = SetupAssembly::::new(); - let circuit = TestCircuit4WithLookups:: { - _marker: PhantomData - }; + let circuit = TestCircuit4WithLookups:: { _marker: PhantomData }; circuit.synthesize(&mut assembly).expect("must work"); @@ -3565,25 +3424,18 @@ mod test { let size = assembly.n().next_power_of_two(); - use crate::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; use crate::kate_commitment::*; + use crate::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; let crs_mons = Crs::::crs_42(size, &worker); - let proof = assembly.create_proof::, RollingKeccakTranscript>( - &worker, - &setup, - &crs_mons, - None - ).unwrap(); + let proof = assembly + .create_proof::, RollingKeccakTranscript>(&worker, &setup, &crs_mons, None) + .unwrap(); let vk = VerificationKey::from_setup(&setup, &worker, &crs_mons).unwrap(); - let valid = verify::, RollingKeccakTranscript>( - &vk, - &proof, - None, - ).unwrap(); + let valid = verify::, RollingKeccakTranscript>(&vk, &proof, None).unwrap(); assert!(valid); println!("Done!"); @@ -3592,15 +3444,13 @@ mod test { #[test] fn test_setup_and_prove_single_gate_and_tables() { use crate::pairing::bn256::{Bn256, Fr}; - use crate::worker::Worker; - use crate::plonk::better_better_cs::verifier::*; use crate::plonk::better_better_cs::setup::VerificationKey; + use crate::plonk::better_better_cs::verifier::*; + use crate::worker::Worker; let mut assembly = SetupAssembly::::new(); - let circuit = TestCircuit4WithLookupsManyGatesSmallTable:: { - _marker: PhantomData - }; + let circuit = TestCircuit4WithLookupsManyGatesSmallTable:: { _marker: PhantomData }; circuit.synthesize(&mut assembly).expect("must work"); @@ -3621,25 +3471,18 @@ mod test { let size = assembly.n().next_power_of_two(); - use crate::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; use crate::kate_commitment::*; + use crate::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; let crs_mons = Crs::::crs_42(size, &worker); - let proof = assembly.create_proof::, RollingKeccakTranscript>( - &worker, - &setup, - &crs_mons, - None - ).unwrap(); + let proof = assembly + .create_proof::, RollingKeccakTranscript>(&worker, &setup, &crs_mons, None) + .unwrap(); let vk = VerificationKey::from_setup(&setup, &worker, &crs_mons).unwrap(); - let valid = verify::, RollingKeccakTranscript>( - &vk, - &proof, - None, - ).unwrap(); + let valid = verify::, RollingKeccakTranscript>(&vk, &proof, None).unwrap(); assert!(valid); } @@ -3647,15 +3490,13 @@ mod test { #[test] fn test_bench_long_synthesis() { use crate::pairing::bn256::{Bn256, Fr}; - use crate::worker::Worker; - use crate::plonk::better_better_cs::verifier::*; use crate::plonk::better_better_cs::setup::VerificationKey; + use crate::plonk::better_better_cs::verifier::*; + use crate::worker::Worker; let mut assembly = TrivialAssembly::::new(); - let circuit = TestCircuit4:: { - _marker: PhantomData - }; + let circuit = TestCircuit4:: { _marker: PhantomData }; circuit.synthesize(&mut assembly).expect("must work"); @@ -3681,9 +3522,7 @@ mod test { } fn all_queried_polynomials(&self) -> &'static [PolynomialInConstraint] { - const A: [PolynomialInConstraint; 1] = [ - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ]; + const A: [PolynomialInConstraint; 1] = [PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))]; &A } @@ -3693,9 +3532,7 @@ mod test { } fn variable_polynomials(&self) -> &'static [PolyIdentifier] { - const A: [PolyIdentifier; 1] = [ - PolyIdentifier::VariablesPolynomial(0), - ]; + const A: [PolyIdentifier; 1] = [PolyIdentifier::VariablesPolynomial(0)]; &A } @@ -3718,8 +3555,8 @@ mod test { fn verify_on_row<'a>(&self, row: usize, poly_storage: &AssembledPolynomialStorage<'a, E>, _last_row: bool) -> E::Fr { let q_a = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(0), row); - - // (A - 1) * A + + // (A - 1) * A let mut tmp = q_a; tmp.sub_assign(&E::Fr::one()); tmp.mul_assign(&q_a); @@ -3728,14 +3565,14 @@ mod test { } fn contribute_into_quotient<'a, 'b>( - &self, + &self, domain_size: usize, poly_storage: &mut AssembledPolynomialStorage<'a, E>, - monomials_storage: & AssembledPolynomialStorageForMonomialForms<'b, E>, + monomials_storage: &AssembledPolynomialStorageForMonomialForms<'b, E>, challenges: &[E::Fr], omegas_bitreversed: &BitReversedOmegas, _omegas_inv_bitreversed: &OmegasInvBitreversed, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { assert!(domain_size.is_power_of_two()); assert_eq!(challenges.len(), >::num_quotient_terms(&self)); @@ -3746,41 +3583,28 @@ mod test { assert!(poly_storage.is_bitreversed); let coset_factor = E::Fr::multiplicative_generator(); - + for &p in >::all_queried_polynomials(&self).into_iter() { - ensure_in_map_or_create(&worker, - p, - domain_size, - omegas_bitreversed, - lde_factor, - coset_factor, - monomials_storage, - poly_storage - )?; + ensure_in_map_or_create(&worker, p, domain_size, omegas_bitreversed, lde_factor, coset_factor, monomials_storage, poly_storage)?; } let ldes_storage = &*poly_storage; - // (A - 1) * A - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); + // (A - 1) * A + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); let mut tmp = a_ref.clone(); drop(a_ref); let one = E::Fr::one(); - tmp.map(&worker, - |el| { - let mut tmp = *el; - tmp.sub_assign(&one); - tmp.mul_assign(&*el); + tmp.map(&worker, |el| { + let mut tmp = *el; + tmp.sub_assign(&one); + tmp.mul_assign(&*el); - *el = tmp; - }, - ); + *el = tmp; + }); tmp.scale(&worker, challenges[0]); @@ -3788,32 +3612,33 @@ mod test { } fn contribute_into_linearization<'a>( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, - _monomials_storage: & AssembledPolynomialStorageForMonomialForms<'a, E>, + _monomials_storage: &AssembledPolynomialStorageForMonomialForms<'a, E>, _challenges: &[E::Fr], - _worker: &Worker + _worker: &Worker, ) -> Result, SynthesisError> { unreachable!("this gate does not contribute into linearization"); } fn contribute_into_verification_equation( - &self, + &self, _domain_size: usize, _at: E::Fr, queried_values: &std::collections::HashMap, challenges: &[E::Fr], ) -> Result { assert_eq!(challenges.len(), 1); - // (A-1) * A - let a_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) + // (A-1) * A + let a_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) .ok_or(SynthesisError::AssignmentMissing)?; let mut result = a_value; result.sub_assign(&E::Fr::one()); result.mul_assign(&a_value); result.mul_assign(&challenges[0]); - + Ok(result) } @@ -3825,7 +3650,7 @@ mod test { Box::from(self.clone()) } fn contribute_into_linearization_commitment( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, diff --git a/crates/bellman/src/plonk/better_better_cs/data_structures.rs b/crates/bellman/src/plonk/better_better_cs/data_structures.rs index 948a922..29146f3 100644 --- a/crates/bellman/src/plonk/better_better_cs/data_structures.rs +++ b/crates/bellman/src/plonk/better_better_cs/data_structures.rs @@ -1,7 +1,7 @@ +use super::cs::GateInternal; use crate::pairing::ff::*; use crate::pairing::*; use crate::plonk::polynomials::*; -use super::cs::GateInternal; #[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize)] pub enum PolyIdentifier { @@ -20,23 +20,19 @@ impl PartialEq for PolyIdentifier { match (self, other) { (PolyIdentifier::VariablesPolynomial(a), PolyIdentifier::VariablesPolynomial(b)) => a.eq(&b), (PolyIdentifier::GateSetupPolynomial(a_id, a), PolyIdentifier::GateSetupPolynomial(b_id, b)) => { - if a.eq(&b) == true { + if a.eq(&b) == true { a == b } else { false } - }, - (PolyIdentifier::GateSelector(a_id), PolyIdentifier::GateSelector(b_id)) => { - *a_id == *b_id - }, + } + (PolyIdentifier::GateSelector(a_id), PolyIdentifier::GateSelector(b_id)) => *a_id == *b_id, (PolyIdentifier::LookupSelector, PolyIdentifier::LookupSelector) => true, (PolyIdentifier::LookupTableEntriesPolynomial(a), PolyIdentifier::LookupTableEntriesPolynomial(b)) => a.eq(&b), (PolyIdentifier::PermutationPolynomial(a), PolyIdentifier::PermutationPolynomial(b)) => a.eq(&b), - (PolyIdentifier::NamedSetupPolynomial(a_id), PolyIdentifier::NamedSetupPolynomial(b_id)) => { - *a_id == *b_id - }, + (PolyIdentifier::NamedSetupPolynomial(a_id), PolyIdentifier::NamedSetupPolynomial(b_id)) => *a_id == *b_id, (PolyIdentifier::WitnessPolynomial(a), PolyIdentifier::WitnessPolynomial(b)) => a.eq(&b), - _ => false + _ => false, } } } @@ -57,12 +53,11 @@ impl std::hash::Hash for PolyIdentifier { std::mem::discriminant(a).hash(state); state.write(str_id.as_bytes()); state.write_usize(*id); - }, - a @ PolyIdentifier::GateSelector(str_id) - | a @ PolyIdentifier::NamedSetupPolynomial(str_id) => { + } + a @ PolyIdentifier::GateSelector(str_id) | a @ PolyIdentifier::NamedSetupPolynomial(str_id) => { std::mem::discriminant(a).hash(state); state.write(str_id.as_bytes()); - }, + } a @ PolyIdentifier::LookupSelector => { std::mem::discriminant(a).hash(state); } @@ -75,10 +70,10 @@ pub const LOOKUP_TABLE_TYPE_POLYNOMIAL: &'static str = "LOOKUP_TABLE_TYPE_POLYNO #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct TimeDilation(pub usize); #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -#[serde(bound( deserialize = "'de: 'static"))] +#[serde(bound(deserialize = "'de: 'static"))] pub struct PolynomialInConstraint(pub PolyIdentifier, pub TimeDilation); -impl PolynomialInConstraint{ +impl PolynomialInConstraint { pub const fn from_id(id: PolyIdentifier) -> Self { Self(id, TimeDilation(0)) } @@ -106,23 +101,15 @@ impl<'a, F: PrimeField, P: PolynomialForm> PolynomialProxy<'a, F, P> { pub fn as_ref(&self) -> &Polynomial { match self { - PolynomialProxy::Borrowed(b) => { - &*b - }, - PolynomialProxy::Owned(o) => { - &o - } + PolynomialProxy::Borrowed(b) => &*b, + PolynomialProxy::Owned(o) => &o, } } pub fn as_data_ref(&self) -> &[F] { match self { - PolynomialProxy::Borrowed(b) => { - b.as_ref() - }, - PolynomialProxy::Owned(o) => { - o.as_ref() - } + PolynomialProxy::Borrowed(b) => b.as_ref(), + PolynomialProxy::Owned(o) => o.as_ref(), } } @@ -130,46 +117,30 @@ impl<'a, F: PrimeField, P: PolynomialForm> PolynomialProxy<'a, F, P> { match self { PolynomialProxy::Borrowed(..) => { unreachable!("Can not borrow mutable for non-owned proxy") - }, - PolynomialProxy::Owned(o) => { - o.as_mut() } + PolynomialProxy::Owned(o) => o.as_mut(), } } pub fn into_poly(self) -> Polynomial { match self { - PolynomialProxy::Borrowed(b) => { - b.clone() - }, - PolynomialProxy::Owned(o) => { - o - } + PolynomialProxy::Borrowed(b) => b.clone(), + PolynomialProxy::Owned(o) => o, } } pub fn clone_as_owned(&self) -> Self { match self { - PolynomialProxy::Borrowed(ref b) => { - PolynomialProxy::Owned((*b).clone()) - }, - PolynomialProxy::Owned(o) => { - PolynomialProxy::Owned(o.clone()) - } + PolynomialProxy::Borrowed(ref b) => PolynomialProxy::Owned((*b).clone()), + PolynomialProxy::Owned(o) => PolynomialProxy::Owned(o.clone()), } } } -pub fn clone_as_borrowed<'a, 'b: 'a, F: PrimeField, P: PolynomialForm>( - src: &'a PolynomialProxy<'b, F, P> -) -> PolynomialProxy<'a, F, P> { +pub fn clone_as_borrowed<'a, 'b: 'a, F: PrimeField, P: PolynomialForm>(src: &'a PolynomialProxy<'b, F, P>) -> PolynomialProxy<'a, F, P> { match src { - PolynomialProxy::Borrowed(ref b) => { - PolynomialProxy::Borrowed(*b) - }, - PolynomialProxy::Owned(ref o) => { - PolynomialProxy::Borrowed(o) - } + PolynomialProxy::Borrowed(ref b) => PolynomialProxy::Borrowed(*b), + PolynomialProxy::Owned(ref o) => PolynomialProxy::Borrowed(o), } } @@ -186,7 +157,6 @@ pub fn clone_as_borrowed<'a, 'b: 'a, F: PrimeField, P: PolynomialForm>( // } // } - pub struct AssembledPolynomialStorage<'a, E: Engine> { pub state_map: std::collections::HashMap>, pub witness_map: std::collections::HashMap>, @@ -195,7 +165,7 @@ pub struct AssembledPolynomialStorage<'a, E: Engine> { pub gate_selectors: std::collections::HashMap>, pub named_polys: std::collections::HashMap>, pub is_bitreversed: bool, - pub lde_factor: usize + pub lde_factor: usize, } pub struct AssembledPolynomialStorageForMonomialForms<'a, E: Engine> { @@ -209,30 +179,14 @@ pub struct AssembledPolynomialStorageForMonomialForms<'a, E: Engine> { impl<'a, E: Engine> AssembledPolynomialStorage<'a, E> { pub fn get_poly(&self, id: PolyIdentifier) -> &Polynomial { match id { - p @ PolyIdentifier::VariablesPolynomial(..) => { - self.state_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::WitnessPolynomial(..) => { - self.witness_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::GateSetupPolynomial(..) => { - self.setup_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::GateSelector(..) => { - self.gate_selectors.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::PermutationPolynomial(..) => { - self.setup_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::LookupSelector => { - self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::LookupTableEntriesPolynomial(..) => { - self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::NamedSetupPolynomial(..) => { - self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, + p @ PolyIdentifier::VariablesPolynomial(..) => self.state_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::WitnessPolynomial(..) => self.witness_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::GateSetupPolynomial(..) => self.setup_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::GateSelector(..) => self.gate_selectors.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::PermutationPolynomial(..) => self.setup_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::LookupSelector => self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::LookupTableEntriesPolynomial(..) => self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::NamedSetupPolynomial(..) => self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), _ => { unreachable!() } @@ -260,7 +214,7 @@ impl<'a, E: Engine> AssembledPolynomialStorage<'a, E> { scratch_space: std::collections::HashMap::new(), named_polys: std::collections::HashMap::new(), is_bitreversed: bitreversed, - lde_factor + lde_factor, } } @@ -272,22 +226,22 @@ impl<'a, E: Engine> AssembledPolynomialStorage<'a, E> { match id { p @ PolyIdentifier::GateSetupPolynomial(..) => { self.setup_map.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::GateSelector(..) => { self.setup_map.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::PermutationPolynomial(..) => { self.setup_map.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::LookupSelector => { self.named_polys.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::LookupTableEntriesPolynomial(..) => { self.named_polys.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::NamedSetupPolynomial(..) => { self.named_polys.insert(p.clone(), proxy); - }, + } _ => { unreachable!() } @@ -299,30 +253,14 @@ impl<'a, E: Engine> AssembledPolynomialStorage<'a, E> { impl<'a, E: Engine> AssembledPolynomialStorageForMonomialForms<'a, E> { pub fn get_poly(&self, id: PolyIdentifier) -> &Polynomial { match id { - p @ PolyIdentifier::VariablesPolynomial(..) => { - self.state_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::WitnessPolynomial(..) => { - self.witness_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::GateSetupPolynomial(..) => { - self.setup_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::GateSelector(..) => { - self.gate_selectors.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::PermutationPolynomial(..) => { - self.setup_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::LookupSelector => { - self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::LookupTableEntriesPolynomial(..) => { - self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, - p @ PolyIdentifier::NamedSetupPolynomial(..) => { - self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref() - }, + p @ PolyIdentifier::VariablesPolynomial(..) => self.state_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::WitnessPolynomial(..) => self.witness_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::GateSetupPolynomial(..) => self.setup_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::GateSelector(..) => self.gate_selectors.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::PermutationPolynomial(..) => self.setup_map.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::LookupSelector => self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::LookupTableEntriesPolynomial(..) => self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), + p @ PolyIdentifier::NamedSetupPolynomial(..) => self.named_polys.get(&p).expect(&format!("poly {:?} must exist", p)).as_ref(), } } @@ -350,19 +288,19 @@ impl<'a, E: Engine> AssembledPolynomialStorageForMonomialForms<'a, E> { match id { p @ PolyIdentifier::GateSetupPolynomial(..) => { self.setup_map.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::GateSelector(..) => { self.setup_map.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::PermutationPolynomial(..) => { self.setup_map.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::LookupSelector => { self.named_polys.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::LookupTableEntriesPolynomial(..) => { self.named_polys.insert(p.clone(), proxy); - }, + } p @ PolyIdentifier::NamedSetupPolynomial(..) => { self.named_polys.insert(p.clone(), proxy); } @@ -385,4 +323,4 @@ pub struct LookupDataHolder<'a, E: Engine> { pub s_poly_monomial: Option>, pub selector_poly_monomial: Option>, pub table_type_poly_monomial: Option>, -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_better_cs/gates/main_gate_with_d_next.rs b/crates/bellman/src/plonk/better_better_cs/gates/main_gate_with_d_next.rs index dcb3efb..605c3b2 100644 --- a/crates/bellman/src/plonk/better_better_cs/gates/main_gate_with_d_next.rs +++ b/crates/bellman/src/plonk/better_better_cs/gates/main_gate_with_d_next.rs @@ -34,12 +34,10 @@ impl GateInternal for Width4MainGateWithDNext { PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(GATE_NAME, 4)), PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(GATE_NAME, 5)), PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(GATE_NAME, 6)), - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), - PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), ]; @@ -95,12 +93,11 @@ impl GateInternal for Width4MainGateWithDNext { #[inline] fn needs_opened_for_linearization(&self) -> &'static [PolynomialInConstraint] { - const ALL_OPENED_FOR_LINEARIZATION: [PolynomialInConstraint; 5] = [ + const ALL_OPENED_FOR_LINEARIZATION: [PolynomialInConstraint; 5] = [ PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), - PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), ]; @@ -129,18 +126,16 @@ impl GateInternal for Width4MainGateWithDNext { let c_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(2), row); let d_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row); let d_next_value = if last_row == false { - Some(poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row+1)) + Some(poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row + 1)) } else { None - }; + }; // println!("A = {}, B = {}, C = {}, D = {}, D_Next = {:?}", a_value, b_value, c_value, d_value, d_next_value); let mut total = E::Fr::zero(); - for (q, v) in [a_value, b_value, c_value, d_value].iter() - .zip([q_a, q_b, q_c, q_d].iter()) - { + for (q, v) in [a_value, b_value, c_value, d_value].iter().zip([q_a, q_b, q_c, q_d].iter()) { let mut tmp = *q; tmp.mul_assign(v); total.add_assign(&tmp); @@ -166,31 +161,31 @@ impl GateInternal for Width4MainGateWithDNext { } fn contribute_into_quotient( - &self, + &self, _domain_size: usize, _poly_storage: &mut AssembledPolynomialStorage, - _monomial_storage: & AssembledPolynomialStorageForMonomialForms, + _monomial_storage: &AssembledPolynomialStorageForMonomialForms, _challenges: &[E::Fr], _omegas_bitreversed: &BitReversedOmegas, _omegas_inv_bitreversed: &OmegasInvBitreversed, - _worker: &Worker + _worker: &Worker, ) -> Result, SynthesisError> { unreachable!("this type of gate can only be used as a main gate"); } fn contribute_into_linearization( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, - _monomials_storage: & AssembledPolynomialStorageForMonomialForms, + _monomials_storage: &AssembledPolynomialStorageForMonomialForms, _challenges: &[E::Fr], - _worker: &Worker + _worker: &Worker, ) -> Result, SynthesisError> { unreachable!("this gate is indended to be the main gate and should use main gate functions") } fn contribute_into_verification_equation( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, @@ -207,7 +202,7 @@ impl GateInternal for Width4MainGateWithDNext { Box::from(self.clone()) } fn contribute_into_linearization_commitment( - &self, + &self, domain_size: usize, at: E::Fr, queried_values: &std::collections::HashMap, @@ -218,9 +213,7 @@ impl GateInternal for Width4MainGateWithDNext { } } -impl Gate for Width4MainGateWithDNext { - -} +impl Gate for Width4MainGateWithDNext {} impl MainGate for Width4MainGateWithDNext { const NUM_LINEAR_TERMS: usize = 4; @@ -253,19 +246,19 @@ impl MainGate for Width4MainGateWithDNext { let mut used_in_multiplication = [padding; 2]; - debug_assert!(instance.num_constant_terms <= allowed_constants, "must not containt more constants than allowed"); - debug_assert!(instance.num_multiplicative_terms <= allowed_multiplications, "must not containt more multiplications than allowed"); - debug_assert!(instance.terms.len() <= allowed_constants + allowed_multiplications + allowed_linear, "gate can not fit that many terms"); + debug_assert!(instance.num_constant_terms <= allowed_constants, "must not containt more constants than allowed"); + debug_assert!(instance.num_multiplicative_terms <= allowed_multiplications, "must not containt more multiplications than allowed"); + debug_assert!(instance.terms.len() <= allowed_constants + allowed_multiplications + allowed_linear, "gate can not fit that many terms"); if instance.num_multiplicative_terms != 0 { - let index = instance.terms.iter().position( - |t| { - match t { - ArithmeticTerm::Product(_, _) => true, - _ => false, - } - } - ).unwrap(); + let index = instance + .terms + .iter() + .position(|t| match t { + ArithmeticTerm::Product(_, _) => true, + _ => false, + }) + .unwrap(); let term = instance.terms.swap_remove(index); match term { @@ -279,7 +272,7 @@ impl MainGate for Width4MainGateWithDNext { flattened_coefficients[4] = coeff; bitmap.set(0); bitmap.set(1); - }, + } _ => { unreachable!("must be multiplicative term"); } @@ -287,20 +280,20 @@ impl MainGate for Width4MainGateWithDNext { } if instance.num_constant_terms != 0 { - let index = instance.terms.iter().position( - |t| { - match t { - ArithmeticTerm::Constant(_) => true, - _ => false, - } - } - ).unwrap(); + let index = instance + .terms + .iter() + .position(|t| match t { + ArithmeticTerm::Constant(_) => true, + _ => false, + }) + .unwrap(); let term = instance.terms.swap_remove(index); match term { ArithmeticTerm::Constant(coeff) => { flattened_coefficients[5] = coeff; - }, + } _ => { unreachable!("must be constant term"); } @@ -311,13 +304,13 @@ impl MainGate for Width4MainGateWithDNext { for term in instance.terms.into_iter() { match term { ArithmeticTerm::SingleVariable(var, coeff) => { - let index = flattened_variables.iter().position( - |&t| t == var - ); + let index = flattened_variables.iter().position(|&t| t == var); if let Some(index) = index { // there is some variable there already, so it must have come from multiplication - assert!(used_in_multiplication[0] == var || used_in_multiplication[1] == var, - "variable in linear term must only happen already if it was in multiplication"); + assert!( + used_in_multiplication[0] == var || used_in_multiplication[1] == var, + "variable in linear term must only happen already if it was in multiplication" + ); flattened_coefficients[index] = coeff; } else { let idx = bitmap.get_next_unused(); @@ -325,7 +318,7 @@ impl MainGate for Width4MainGateWithDNext { flattened_coefficients[idx] = coeff; bitmap.set(idx); } - }, + } _ => { unreachable!("must be additive term"); } @@ -335,7 +328,10 @@ impl MainGate for Width4MainGateWithDNext { Ok((flattened_variables, flattened_coefficients)) } - fn format_linear_term_with_duplicates(mut instance: MainGateTerm, padding: Variable) -> Result<(SmallVec<[Variable; DEFAULT_SMALLVEC_CAPACITY]>, SmallVec<[E::Fr; DEFAULT_SMALLVEC_CAPACITY]>), SynthesisError> { + fn format_linear_term_with_duplicates( + mut instance: MainGateTerm, + padding: Variable, + ) -> Result<(SmallVec<[Variable; DEFAULT_SMALLVEC_CAPACITY]>, SmallVec<[E::Fr; DEFAULT_SMALLVEC_CAPACITY]>), SynthesisError> { let mut flattened_variables = smallvec::smallvec![padding; 4]; let mut flattened_coefficients = smallvec::smallvec![E::Fr::zero(); 7]; let mut bitmap = SimpleBitmap::new(); @@ -344,25 +340,25 @@ impl MainGate for Width4MainGateWithDNext { let allowed_multiplications = 0; let allowed_constants = 1; - debug_assert!(instance.num_constant_terms <= allowed_constants, "must not containt more constants than allowed"); - assert!(instance.num_multiplicative_terms <= allowed_multiplications, "must not containt multiplications"); - debug_assert!(instance.terms.len() <= allowed_constants + allowed_multiplications + allowed_linear, "gate can not fit that many terms"); + debug_assert!(instance.num_constant_terms <= allowed_constants, "must not containt more constants than allowed"); + assert!(instance.num_multiplicative_terms <= allowed_multiplications, "must not containt multiplications"); + debug_assert!(instance.terms.len() <= allowed_constants + allowed_multiplications + allowed_linear, "gate can not fit that many terms"); if instance.num_constant_terms != 0 { - let index = instance.terms.iter().position( - |t| { - match t { - ArithmeticTerm::Constant(_) => true, - _ => false, - } - } - ).unwrap(); + let index = instance + .terms + .iter() + .position(|t| match t { + ArithmeticTerm::Constant(_) => true, + _ => false, + }) + .unwrap(); let term = instance.terms.swap_remove(index); match term { ArithmeticTerm::Constant(coeff) => { flattened_coefficients[5] = coeff; - }, + } _ => { unreachable!("must be multiplicative term"); } @@ -376,7 +372,7 @@ impl MainGate for Width4MainGateWithDNext { flattened_variables[idx] = var; flattened_coefficients[idx] = coeff; bitmap.set(idx); - }, + } _ => { unreachable!("must be multiplicative term"); } @@ -395,15 +391,15 @@ impl MainGate for Width4MainGateWithDNext { } fn contribute_into_quotient_for_public_inputs<'a, 'b>( - &self, + &self, domain_size: usize, public_inputs: &[E::Fr], poly_storage: &mut AssembledPolynomialStorage<'a, E>, - monomials_storage: & AssembledPolynomialStorageForMonomialForms<'b, E>, + monomials_storage: &AssembledPolynomialStorageForMonomialForms<'b, E>, challenges: &[E::Fr], omegas_bitreversed: &BitReversedOmegas, omegas_inv_bitreversed: &OmegasInvBitreversed, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { assert!(domain_size.is_power_of_two()); assert_eq!(challenges.len(), >::num_quotient_terms(&self)); @@ -432,40 +428,21 @@ impl MainGate for Width4MainGateWithDNext { drop(constants_poly_ref); // LDE - let mut t_1 = inputs_poly.bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - omegas_bitreversed, - &coset_factor - )?; + let mut t_1 = inputs_poly.bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, omegas_bitreversed, &coset_factor)?; for &p in >::all_queried_polynomials(&self).into_iter() { // skip public constants poly (was used in public inputs) if p == PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 5)) { continue; } - ensure_in_map_or_create(&worker, - p, - domain_size, - omegas_bitreversed, - lde_factor, - coset_factor, - monomials_storage, - poly_storage - )?; + ensure_in_map_or_create(&worker, p, domain_size, omegas_bitreversed, lde_factor, coset_factor, monomials_storage, poly_storage)?; } let ldes_storage = &*poly_storage; // Q_A * A - let q_a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 0)), - ldes_storage - ); - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); + let q_a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 0)), ldes_storage); + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); let mut tmp = q_a_ref.clone(); tmp.mul_assign(&worker, a_ref); t_1.add_assign(&worker, &tmp); @@ -473,14 +450,8 @@ impl MainGate for Width4MainGateWithDNext { drop(a_ref); // Q_B * B - let q_b_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 1)), - ldes_storage - ); - let b_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), - ldes_storage - ); + let q_b_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 1)), ldes_storage); + let b_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), ldes_storage); tmp.reuse_allocation(q_b_ref); tmp.mul_assign(&worker, b_ref); t_1.add_assign(&worker, &tmp); @@ -488,14 +459,8 @@ impl MainGate for Width4MainGateWithDNext { drop(b_ref); // // Q_C * C - let q_c_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 2)), - ldes_storage - ); - let c_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), - ldes_storage - ); + let q_c_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 2)), ldes_storage); + let c_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), ldes_storage); tmp.reuse_allocation(q_c_ref); tmp.mul_assign(&worker, c_ref); t_1.add_assign(&worker, &tmp); @@ -503,14 +468,8 @@ impl MainGate for Width4MainGateWithDNext { drop(c_ref); // // Q_D * D - let q_d_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 3)), - ldes_storage - ); - let d_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), - ldes_storage - ); + let q_d_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 3)), ldes_storage); + let d_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), ldes_storage); tmp.reuse_allocation(q_d_ref); tmp.mul_assign(&worker, d_ref); t_1.add_assign(&worker, &tmp); @@ -518,18 +477,9 @@ impl MainGate for Width4MainGateWithDNext { drop(d_ref); // Q_M * A * B - let q_m_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 4)), - ldes_storage - ); - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); - let b_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), - ldes_storage - ); + let q_m_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 4)), ldes_storage); + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); + let b_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), ldes_storage); tmp.reuse_allocation(q_m_ref); tmp.mul_assign(&worker, a_ref); tmp.mul_assign(&worker, b_ref); @@ -539,14 +489,8 @@ impl MainGate for Width4MainGateWithDNext { drop(b_ref); // Q_D_next * D_next - let q_d_next_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 6)), - ldes_storage - ); - let d_next_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), - ldes_storage - ); + let q_d_next_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 6)), ldes_storage); + let d_next_ref = get_from_map_unchecked(PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), ldes_storage); tmp.reuse_allocation(q_d_next_ref); tmp.mul_assign(&worker, d_next_ref); t_1.add_assign(&worker, &tmp); @@ -559,28 +503,33 @@ impl MainGate for Width4MainGateWithDNext { } fn contribute_into_linearization_for_public_inputs( - &self, + &self, _domain_size: usize, _public_inputs: &[E::Fr], _at: E::Fr, queried_values: &std::collections::HashMap, - monomials_storage: & AssembledPolynomialStorageForMonomialForms, + monomials_storage: &AssembledPolynomialStorageForMonomialForms, challenges: &[E::Fr], - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { // we actually do not depend on public inputs, but we use this form for consistency assert_eq!(challenges.len(), 1); - let a_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) - .ok_or(SynthesisError::AssignmentMissing)?; - let b_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) - .ok_or(SynthesisError::AssignmentMissing)?; - let c_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) - .ok_or(SynthesisError::AssignmentMissing)?; - let d_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) - .ok_or(SynthesisError::AssignmentMissing)?; - let d_next_value = *queried_values.get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) - .ok_or(SynthesisError::AssignmentMissing)?; + let a_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) + .ok_or(SynthesisError::AssignmentMissing)?; + let b_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) + .ok_or(SynthesisError::AssignmentMissing)?; + let c_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) + .ok_or(SynthesisError::AssignmentMissing)?; + let d_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) + .ok_or(SynthesisError::AssignmentMissing)?; + let d_next_value = *queried_values + .get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) + .ok_or(SynthesisError::AssignmentMissing)?; let name = >::name(&self); @@ -618,13 +567,7 @@ impl MainGate for Width4MainGateWithDNext { Ok(result) } - fn add_inputs_into_quotient( - &self, - domain_size: usize, - public_inputs: &[E::Fr], - at: E::Fr, - challenges: &[E::Fr], - ) -> Result { + fn add_inputs_into_quotient(&self, domain_size: usize, public_inputs: &[E::Fr], at: E::Fr, challenges: &[E::Fr]) -> Result { if public_inputs.len() == 0 { return Ok(E::Fr::zero()); } @@ -644,7 +587,7 @@ impl MainGate for Width4MainGateWithDNext { Ok(contribution) } fn contribute_into_linearization_commitment_for_public_inputs<'a>( - &self, + &self, _domain_size: usize, _public_inputs: &[E::Fr], _at: E::Fr, @@ -657,16 +600,21 @@ impl MainGate for Width4MainGateWithDNext { let mut aggregate = E::G1::zero(); - let a_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) - .ok_or(SynthesisError::AssignmentMissing)?; - let b_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) - .ok_or(SynthesisError::AssignmentMissing)?; - let c_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) - .ok_or(SynthesisError::AssignmentMissing)?; - let d_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) - .ok_or(SynthesisError::AssignmentMissing)?; - let d_next_value = *queried_values.get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) - .ok_or(SynthesisError::AssignmentMissing)?; + let a_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) + .ok_or(SynthesisError::AssignmentMissing)?; + let b_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) + .ok_or(SynthesisError::AssignmentMissing)?; + let c_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) + .ok_or(SynthesisError::AssignmentMissing)?; + let d_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) + .ok_or(SynthesisError::AssignmentMissing)?; + let d_next_value = *queried_values + .get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) + .ok_or(SynthesisError::AssignmentMissing)?; let name = >::name(&self); @@ -710,4 +658,4 @@ impl MainGate for Width4MainGateWithDNext { Ok(aggregate) } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_better_cs/gates/mod.rs b/crates/bellman/src/plonk/better_better_cs/gates/mod.rs index 15a9414..1a95750 100644 --- a/crates/bellman/src/plonk/better_better_cs/gates/mod.rs +++ b/crates/bellman/src/plonk/better_better_cs/gates/mod.rs @@ -1,21 +1,21 @@ -use super::*; use super::cs::*; +use super::*; use crate::smallvec::SmallVec; -use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use crate::pairing::{Engine, CurveAffine, CurveProjective}; use crate::bit_vec::BitVec; +use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; -use crate::worker::Worker; use crate::plonk::domains::*; use crate::plonk::polynomials::*; +use crate::worker::Worker; -use crate::plonk::cs::variable::*; use crate::plonk::better_cs::utils::*; +use crate::plonk::cs::variable::*; use crate::plonk::fft::cooley_tukey_ntt::*; +pub mod main_gate_with_d_next; pub mod selector_optimized_with_d_next; -pub mod main_gate_with_d_next; \ No newline at end of file diff --git a/crates/bellman/src/plonk/better_better_cs/gates/selector_optimized_with_d_next.rs b/crates/bellman/src/plonk/better_better_cs/gates/selector_optimized_with_d_next.rs index 1b57542..1b9defa 100644 --- a/crates/bellman/src/plonk/better_better_cs/gates/selector_optimized_with_d_next.rs +++ b/crates/bellman/src/plonk/better_better_cs/gates/selector_optimized_with_d_next.rs @@ -36,12 +36,10 @@ impl GateInternal for SelectorOptimizedWidth4MainGateWithDNext { PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(GATE_NAME, 5)), PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(GATE_NAME, 6)), PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(GATE_NAME, 7)), - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), - PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), ]; @@ -50,7 +48,7 @@ impl GateInternal for SelectorOptimizedWidth4MainGateWithDNext { #[inline] fn setup_polynomials(&self) -> &'static [PolyIdentifier] { - const SETUP_POLYS: [PolyIdentifier; 8] =[ + const SETUP_POLYS: [PolyIdentifier; 8] = [ PolyIdentifier::GateSetupPolynomial(GATE_NAME, 0), PolyIdentifier::GateSetupPolynomial(GATE_NAME, 1), PolyIdentifier::GateSetupPolynomial(GATE_NAME, 2), @@ -99,12 +97,11 @@ impl GateInternal for SelectorOptimizedWidth4MainGateWithDNext { #[inline] fn needs_opened_for_linearization(&self) -> &'static [PolynomialInConstraint] { - const ALL_OPENED_FOR_LINEARIZATION: [PolynomialInConstraint; 5] = [ + const ALL_OPENED_FOR_LINEARIZATION: [PolynomialInConstraint; 5] = [ PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), - PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), ]; @@ -134,18 +131,16 @@ impl GateInternal for SelectorOptimizedWidth4MainGateWithDNext { let c_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(2), row); let d_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row); let d_next_value = if last_row == false { - Some(poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row+1)) + Some(poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row + 1)) } else { None - }; + }; // println!("A = {}, B = {}, C = {}, D = {}, D_Next = {:?}", a_value, b_value, c_value, d_value, d_next_value); let mut total = E::Fr::zero(); - for (q, v) in [a_value, b_value, c_value, d_value].iter() - .zip([q_a, q_b, q_c, q_d].iter()) - { + for (q, v) in [a_value, b_value, c_value, d_value].iter().zip([q_a, q_b, q_c, q_d].iter()) { let mut tmp = *q; tmp.mul_assign(v); total.add_assign(&tmp); @@ -181,31 +176,31 @@ impl GateInternal for SelectorOptimizedWidth4MainGateWithDNext { } fn contribute_into_quotient( - &self, + &self, _domain_size: usize, _poly_storage: &mut AssembledPolynomialStorage, - _monomial_storage: & AssembledPolynomialStorageForMonomialForms, + _monomial_storage: &AssembledPolynomialStorageForMonomialForms, _challenges: &[E::Fr], _omegas_bitreversed: &BitReversedOmegas, _omegas_inv_bitreversed: &OmegasInvBitreversed, - _worker: &Worker + _worker: &Worker, ) -> Result, SynthesisError> { unreachable!("this type of gate can only be used as a main gate"); } fn contribute_into_linearization( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, - _monomials_storage: & AssembledPolynomialStorageForMonomialForms, + _monomials_storage: &AssembledPolynomialStorageForMonomialForms, _challenges: &[E::Fr], - _worker: &Worker + _worker: &Worker, ) -> Result, SynthesisError> { unreachable!("this gate is indended to be the main gate and should use main gate functions") } fn contribute_into_verification_equation( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, @@ -222,7 +217,7 @@ impl GateInternal for SelectorOptimizedWidth4MainGateWithDNext { Box::from(self.clone()) } fn contribute_into_linearization_commitment( - &self, + &self, domain_size: usize, at: E::Fr, queried_values: &std::collections::HashMap, @@ -233,9 +228,7 @@ impl GateInternal for SelectorOptimizedWidth4MainGateWithDNext { } } -impl Gate for SelectorOptimizedWidth4MainGateWithDNext { - -} +impl Gate for SelectorOptimizedWidth4MainGateWithDNext {} impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { const NUM_LINEAR_TERMS: usize = 4; @@ -258,7 +251,8 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { } fn format_term(mut instance: MainGateTerm, padding: Variable) -> Result<(SmallVec<[Variable; DEFAULT_SMALLVEC_CAPACITY]>, SmallVec<[E::Fr; DEFAULT_SMALLVEC_CAPACITY]>), SynthesisError> { - assert!(instance.num_multiplicative_terms <= 1, + assert!( + instance.num_multiplicative_terms <= 1, "should not use term formatting by this gate if you are using it for optimized selector with 2 multiplicative terms" ); let mut flattened_variables = smallvec::smallvec![padding; 4]; @@ -271,19 +265,19 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { let mut used_in_multiplication = [padding; 2]; - debug_assert!(instance.num_constant_terms <= allowed_constants, "must not containt more constants than allowed"); - debug_assert!(instance.num_multiplicative_terms <= allowed_multiplications, "must not containt more multiplications than allowed"); - debug_assert!(instance.terms.len() <= allowed_constants + allowed_multiplications + allowed_linear, "gate can not fit that many terms"); + debug_assert!(instance.num_constant_terms <= allowed_constants, "must not containt more constants than allowed"); + debug_assert!(instance.num_multiplicative_terms <= allowed_multiplications, "must not containt more multiplications than allowed"); + debug_assert!(instance.terms.len() <= allowed_constants + allowed_multiplications + allowed_linear, "gate can not fit that many terms"); if instance.num_multiplicative_terms != 0 { - let index = instance.terms.iter().position( - |t| { - match t { - ArithmeticTerm::Product(_, _) => true, - _ => false, - } - } - ).unwrap(); + let index = instance + .terms + .iter() + .position(|t| match t { + ArithmeticTerm::Product(_, _) => true, + _ => false, + }) + .unwrap(); let term = instance.terms.swap_remove(index); match term { @@ -297,7 +291,7 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { flattened_coefficients[Self::AB_MULTIPLICATION_TERM_COEFF_INDEX] = coeff; bitmap.set(0); bitmap.set(1); - }, + } _ => { unreachable!("must be multiplicative term"); } @@ -305,20 +299,20 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { } if instance.num_constant_terms != 0 { - let index = instance.terms.iter().position( - |t| { - match t { - ArithmeticTerm::Constant(_) => true, - _ => false, - } - } - ).unwrap(); + let index = instance + .terms + .iter() + .position(|t| match t { + ArithmeticTerm::Constant(_) => true, + _ => false, + }) + .unwrap(); let term = instance.terms.swap_remove(index); match term { ArithmeticTerm::Constant(coeff) => { flattened_coefficients[Self::CONSTANT_TERM_COEFF_INDEX] = coeff; - }, + } _ => { unreachable!("must be constant term"); } @@ -329,13 +323,13 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { for term in instance.terms.into_iter() { match term { ArithmeticTerm::SingleVariable(var, coeff) => { - let index = flattened_variables.iter().position( - |&t| t == var - ); + let index = flattened_variables.iter().position(|&t| t == var); if let Some(index) = index { // there is some variable there already, so it must have come from multiplication - assert!(used_in_multiplication[0] == var || used_in_multiplication[1] == var, - "variable in linear term must only happen already if it was in multiplication"); + assert!( + used_in_multiplication[0] == var || used_in_multiplication[1] == var, + "variable in linear term must only happen already if it was in multiplication" + ); flattened_coefficients[index] = coeff; } else { let idx = bitmap.get_next_unused(); @@ -343,7 +337,7 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { flattened_coefficients[idx] = coeff; bitmap.set(idx); } - }, + } _ => { unreachable!("must be additive term"); } @@ -353,8 +347,12 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { Ok((flattened_variables, flattened_coefficients)) } - fn format_linear_term_with_duplicates(mut instance: MainGateTerm, padding: Variable) -> Result<(SmallVec<[Variable; DEFAULT_SMALLVEC_CAPACITY]>, SmallVec<[E::Fr; DEFAULT_SMALLVEC_CAPACITY]>), SynthesisError> { - assert!(instance.num_multiplicative_terms <= 1, + fn format_linear_term_with_duplicates( + mut instance: MainGateTerm, + padding: Variable, + ) -> Result<(SmallVec<[Variable; DEFAULT_SMALLVEC_CAPACITY]>, SmallVec<[E::Fr; DEFAULT_SMALLVEC_CAPACITY]>), SynthesisError> { + assert!( + instance.num_multiplicative_terms <= 1, "should not use term formatting by this gate if you are using it for optimized selector with 2 multiplicative terms" ); @@ -366,25 +364,25 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { let allowed_multiplications = 0; let allowed_constants = 1; - debug_assert!(instance.num_constant_terms <= allowed_constants, "must not containt more constants than allowed"); - assert!(instance.num_multiplicative_terms <= allowed_multiplications, "must not containt multiplications"); - debug_assert!(instance.terms.len() <= allowed_constants + allowed_multiplications + allowed_linear, "gate can not fit that many terms"); + debug_assert!(instance.num_constant_terms <= allowed_constants, "must not containt more constants than allowed"); + assert!(instance.num_multiplicative_terms <= allowed_multiplications, "must not containt multiplications"); + debug_assert!(instance.terms.len() <= allowed_constants + allowed_multiplications + allowed_linear, "gate can not fit that many terms"); if instance.num_constant_terms != 0 { - let index = instance.terms.iter().position( - |t| { - match t { - ArithmeticTerm::Constant(_) => true, - _ => false, - } - } - ).unwrap(); + let index = instance + .terms + .iter() + .position(|t| match t { + ArithmeticTerm::Constant(_) => true, + _ => false, + }) + .unwrap(); let term = instance.terms.swap_remove(index); match term { ArithmeticTerm::Constant(coeff) => { flattened_coefficients[Self::CONSTANT_TERM_COEFF_INDEX] = coeff; - }, + } _ => { unreachable!("must be multiplicative term"); } @@ -398,7 +396,7 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { flattened_variables[idx] = var; flattened_coefficients[idx] = coeff; bitmap.set(idx); - }, + } _ => { unreachable!("must be multiplicative term"); } @@ -417,15 +415,15 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { } fn contribute_into_quotient_for_public_inputs<'a, 'b>( - &self, + &self, domain_size: usize, public_inputs: &[E::Fr], poly_storage: &mut AssembledPolynomialStorage<'a, E>, - monomials_storage: & AssembledPolynomialStorageForMonomialForms<'b, E>, + monomials_storage: &AssembledPolynomialStorageForMonomialForms<'b, E>, challenges: &[E::Fr], omegas_bitreversed: &BitReversedOmegas, omegas_inv_bitreversed: &OmegasInvBitreversed, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { assert!(domain_size.is_power_of_two()); assert_eq!(challenges.len(), >::num_quotient_terms(&self)); @@ -454,40 +452,21 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { drop(constants_poly_ref); // LDE - let mut t_1 = inputs_poly.bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - omegas_bitreversed, - &coset_factor - )?; + let mut t_1 = inputs_poly.bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, omegas_bitreversed, &coset_factor)?; for &p in >::all_queried_polynomials(&self).into_iter() { // skip public constants poly (was used in public inputs) if p == PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, Self::CONSTANT_TERM_COEFF_INDEX)) { continue; } - ensure_in_map_or_create(&worker, - p, - domain_size, - omegas_bitreversed, - lde_factor, - coset_factor, - monomials_storage, - poly_storage - )?; + ensure_in_map_or_create(&worker, p, domain_size, omegas_bitreversed, lde_factor, coset_factor, monomials_storage, poly_storage)?; } let ldes_storage = &*poly_storage; // Q_A * A - let q_a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 0)), - ldes_storage - ); - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); + let q_a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 0)), ldes_storage); + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); let mut tmp = q_a_ref.clone(); tmp.mul_assign(&worker, a_ref); t_1.add_assign(&worker, &tmp); @@ -495,14 +474,8 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { drop(a_ref); // Q_B * B - let q_b_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 1)), - ldes_storage - ); - let b_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), - ldes_storage - ); + let q_b_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 1)), ldes_storage); + let b_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), ldes_storage); tmp.reuse_allocation(q_b_ref); tmp.mul_assign(&worker, b_ref); t_1.add_assign(&worker, &tmp); @@ -510,14 +483,8 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { drop(b_ref); // // Q_C * C - let q_c_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 2)), - ldes_storage - ); - let c_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), - ldes_storage - ); + let q_c_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 2)), ldes_storage); + let c_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), ldes_storage); tmp.reuse_allocation(q_c_ref); tmp.mul_assign(&worker, c_ref); t_1.add_assign(&worker, &tmp); @@ -525,14 +492,8 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { drop(c_ref); // // Q_D * D - let q_d_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 3)), - ldes_storage - ); - let d_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), - ldes_storage - ); + let q_d_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 3)), ldes_storage); + let d_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), ldes_storage); tmp.reuse_allocation(q_d_ref); tmp.mul_assign(&worker, d_ref); t_1.add_assign(&worker, &tmp); @@ -542,16 +503,10 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { // Q_M_AB * A * B let q_m_ab_ref = get_from_map_unchecked( PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, Self::AB_MULTIPLICATION_TERM_COEFF_INDEX)), - ldes_storage - ); - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); - let b_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), - ldes_storage + ldes_storage, ); + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); + let b_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), ldes_storage); tmp.reuse_allocation(q_m_ab_ref); tmp.mul_assign(&worker, a_ref); tmp.mul_assign(&worker, b_ref); @@ -563,16 +518,10 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { // Q_M_AC * A * C let q_m_ac_ref = get_from_map_unchecked( PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, Self::AC_MULTIPLICATION_TERM_COEFF_INDEX)), - ldes_storage - ); - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); - let c_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), - ldes_storage + ldes_storage, ); + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); + let c_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), ldes_storage); tmp.reuse_allocation(q_m_ac_ref); tmp.mul_assign(&worker, a_ref); tmp.mul_assign(&worker, c_ref); @@ -582,14 +531,8 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { drop(c_ref); // Q_D_next * D_next - let q_d_next_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 7)), - ldes_storage - ); - let d_next_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), - ldes_storage - ); + let q_d_next_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::GateSetupPolynomial(name, 7)), ldes_storage); + let d_next_ref = get_from_map_unchecked(PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), ldes_storage); tmp.reuse_allocation(q_d_next_ref); tmp.mul_assign(&worker, d_next_ref); t_1.add_assign(&worker, &tmp); @@ -602,28 +545,33 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { } fn contribute_into_linearization_for_public_inputs( - &self, + &self, _domain_size: usize, _public_inputs: &[E::Fr], _at: E::Fr, queried_values: &std::collections::HashMap, - monomials_storage: & AssembledPolynomialStorageForMonomialForms, + monomials_storage: &AssembledPolynomialStorageForMonomialForms, challenges: &[E::Fr], - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { // we actually do not depend on public inputs, but we use this form for consistency assert_eq!(challenges.len(), 1); - let a_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) - .ok_or(SynthesisError::AssignmentMissing)?; - let b_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) - .ok_or(SynthesisError::AssignmentMissing)?; - let c_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) - .ok_or(SynthesisError::AssignmentMissing)?; - let d_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) - .ok_or(SynthesisError::AssignmentMissing)?; - let d_next_value = *queried_values.get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) - .ok_or(SynthesisError::AssignmentMissing)?; + let a_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) + .ok_or(SynthesisError::AssignmentMissing)?; + let b_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) + .ok_or(SynthesisError::AssignmentMissing)?; + let c_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) + .ok_or(SynthesisError::AssignmentMissing)?; + let d_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) + .ok_or(SynthesisError::AssignmentMissing)?; + let d_next_value = *queried_values + .get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) + .ok_or(SynthesisError::AssignmentMissing)?; let name = >::name(&self); @@ -667,13 +615,7 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { Ok(result) } - fn add_inputs_into_quotient( - &self, - domain_size: usize, - public_inputs: &[E::Fr], - at: E::Fr, - challenges: &[E::Fr], - ) -> Result { + fn add_inputs_into_quotient(&self, domain_size: usize, public_inputs: &[E::Fr], at: E::Fr, challenges: &[E::Fr]) -> Result { if public_inputs.len() == 0 { return Ok(E::Fr::zero()); } @@ -693,7 +635,7 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { Ok(contribution) } fn contribute_into_linearization_commitment_for_public_inputs<'a>( - &self, + &self, _domain_size: usize, _public_inputs: &[E::Fr], _at: E::Fr, @@ -706,16 +648,21 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { let mut aggregate = E::G1::zero(); - let a_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) - .ok_or(SynthesisError::AssignmentMissing)?; - let b_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) - .ok_or(SynthesisError::AssignmentMissing)?; - let c_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) - .ok_or(SynthesisError::AssignmentMissing)?; - let d_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) - .ok_or(SynthesisError::AssignmentMissing)?; - let d_next_value = *queried_values.get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) - .ok_or(SynthesisError::AssignmentMissing)?; + let a_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) + .ok_or(SynthesisError::AssignmentMissing)?; + let b_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) + .ok_or(SynthesisError::AssignmentMissing)?; + let c_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) + .ok_or(SynthesisError::AssignmentMissing)?; + let d_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) + .ok_or(SynthesisError::AssignmentMissing)?; + let d_next_value = *queried_values + .get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) + .ok_or(SynthesisError::AssignmentMissing)?; let name = >::name(&self); @@ -742,19 +689,25 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { // Q_m_AB * A*B let mut tmp = a_value; tmp.mul_assign(&b_value); - let commitment = commitments_storage.get(&PolyIdentifier::GateSetupPolynomial(name, Self::AB_MULTIPLICATION_TERM_COEFF_INDEX)).ok_or(SynthesisError::AssignmentMissing)?; + let commitment = commitments_storage + .get(&PolyIdentifier::GateSetupPolynomial(name, Self::AB_MULTIPLICATION_TERM_COEFF_INDEX)) + .ok_or(SynthesisError::AssignmentMissing)?; let scaled = commitment.mul(tmp.into_repr()); aggregate.add_assign(&scaled); // Q_m_AC * A*B let mut tmp = a_value; tmp.mul_assign(&c_value); - let commitment = commitments_storage.get(&PolyIdentifier::GateSetupPolynomial(name, Self::AC_MULTIPLICATION_TERM_COEFF_INDEX)).ok_or(SynthesisError::AssignmentMissing)?; + let commitment = commitments_storage + .get(&PolyIdentifier::GateSetupPolynomial(name, Self::AC_MULTIPLICATION_TERM_COEFF_INDEX)) + .ok_or(SynthesisError::AssignmentMissing)?; let scaled = commitment.mul(tmp.into_repr()); aggregate.add_assign(&scaled); // Q_const - let commitment = commitments_storage.get(&PolyIdentifier::GateSetupPolynomial(name, Self::CONSTANT_TERM_COEFF_INDEX)).ok_or(SynthesisError::AssignmentMissing)?; + let commitment = commitments_storage + .get(&PolyIdentifier::GateSetupPolynomial(name, Self::CONSTANT_TERM_COEFF_INDEX)) + .ok_or(SynthesisError::AssignmentMissing)?; aggregate.add_assign_mixed(&commitment); // Q_dNext * D_next @@ -766,4 +719,4 @@ impl MainGate for SelectorOptimizedWidth4MainGateWithDNext { Ok(aggregate) } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_better_cs/lookup_tables.rs b/crates/bellman/src/plonk/better_better_cs/lookup_tables.rs index afb1c58..aee808c 100644 --- a/crates/bellman/src/plonk/better_better_cs/lookup_tables.rs +++ b/crates/bellman/src/plonk/better_better_cs/lookup_tables.rs @@ -1,42 +1,41 @@ -use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; use crate::bit_vec::BitVec; +use crate::pairing::ff::{Field, PrimeField}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; -use crate::worker::Worker; use crate::plonk::domains::*; use crate::plonk::polynomials::*; +use crate::worker::Worker; -pub use crate::plonk::cs::variable::*; -use crate::plonk::better_cs::utils::*; use super::cs::*; use super::data_structures::*; +use crate::plonk::better_cs::utils::*; +pub use crate::plonk::cs::variable::*; pub const RANGE_CHECK_SINGLE_APPLICATION_TABLE_NAME: &'static str = "Range check table for a single column"; -pub trait LookupTableInternal: Send - + Sync - + 'static - + std::any::Any - + std::fmt::Debug { - fn name(&self) -> &'static str; - fn table_size(&self) -> usize; - fn num_keys(&self) -> usize; - fn num_values(&self) -> usize; - fn allows_combining(&self) -> bool; - fn is_valid_entry(&self, keys: &[E::Fr], values: &[E::Fr]) -> bool; - fn query(&self, keys: &[E::Fr]) -> Result, SynthesisError>; - fn get_table_values_for_polys(&self) -> Vec>; - fn table_id(&self) -> E::Fr; - fn sort(&self, values: &[E::Fr], column: usize) -> Result, SynthesisError>; - fn box_clone(&self) -> Box>; - fn column_is_trivial(&self, column_num: usize) -> bool; - } +pub trait LookupTableInternal: Send + Sync + 'static + std::any::Any + std::fmt::Debug { + fn name(&self) -> &'static str; + fn table_size(&self) -> usize; + fn num_keys(&self) -> usize; + fn num_values(&self) -> usize; + fn allows_combining(&self) -> bool; + fn is_valid_entry(&self, keys: &[E::Fr], values: &[E::Fr]) -> bool; + fn query(&self, keys: &[E::Fr]) -> Result, SynthesisError>; + fn get_table_values_for_polys(&self) -> Vec>; + fn table_id(&self) -> E::Fr; + fn sort(&self, values: &[E::Fr], column: usize) -> Result, SynthesisError>; + fn box_clone(&self) -> Box>; + fn column_is_trivial(&self, column_num: usize) -> bool; +} impl std::hash::Hash for dyn LookupTableInternal { - fn hash(&self, state: &mut H) where H: std::hash::Hasher { + fn hash(&self, state: &mut H) + where + H: std::hash::Hasher, + { self.type_id().hash(state); self.name().hash(state); self.table_size().hash(state); @@ -47,11 +46,7 @@ impl std::hash::Hash for dyn LookupTableInternal { impl PartialEq for dyn LookupTableInternal { fn eq(&self, other: &Self) -> bool { - self.type_id() == other.type_id() && - self.name() == other.name() && - self.table_size() == other.table_size() && - self.num_keys() == other.num_keys() && - self.num_values() == other.num_values() + self.type_id() == other.type_id() && self.name() == other.name() && self.table_size() == other.table_size() && self.num_keys() == other.num_keys() && self.num_values() == other.num_values() } } @@ -66,7 +61,7 @@ pub struct LookupTableApplication { table_to_apply: Box>, #[serde(skip)] name_generator: Option String) + 'static + Send + Sync>>, - can_be_combined: bool + can_be_combined: bool, } impl std::fmt::Debug for LookupTableApplication { @@ -82,10 +77,7 @@ impl std::fmt::Debug for LookupTableApplication { impl PartialEq for LookupTableApplication { fn eq(&self, other: &Self) -> bool { - self.name == other.name && - self.apply_over == other.apply_over && - &self.table_to_apply == &other.table_to_apply && - self.can_be_combined == other.can_be_combined + self.name == other.name && self.apply_over == other.apply_over && &self.table_to_apply == &other.table_to_apply && self.can_be_combined == other.can_be_combined } } @@ -97,14 +89,14 @@ impl LookupTableApplication { table: L, apply_over: Vec, name_generator: Option String) + 'static + Send + Sync>>, - can_be_combined: bool + can_be_combined: bool, ) -> Self { Self { name, apply_over, table_to_apply: Box::from(table) as Box>, name_generator, - can_be_combined + can_be_combined, } } @@ -118,7 +110,7 @@ impl LookupTableApplication { apply_over: over, table_to_apply: table.box_clone(), name_generator: None, - can_be_combined: true + can_be_combined: true, }) } @@ -142,7 +134,7 @@ impl LookupTableApplication { apply_over: over, table_to_apply: table.box_clone(), name_generator: None, - can_be_combined: true + can_be_combined: true, }) } @@ -207,15 +199,12 @@ pub struct MultiTableApplication { apply_over: Vec, tables_to_apply: Vec>>, table_size: usize, - id: E::Fr + id: E::Fr, } impl PartialEq for MultiTableApplication { fn eq(&self, other: &Self) -> bool { - self.name == other.name && - self.apply_over == other.apply_over && - &self.tables_to_apply == &other.tables_to_apply && - self.table_size == other.table_size + self.name == other.name && self.apply_over == other.apply_over && &self.tables_to_apply == &other.tables_to_apply && self.table_size == other.table_size } } @@ -240,7 +229,7 @@ impl MultiTableApplication { apply_over: over, tables_to_apply: vec![table.box_clone(), table.box_clone(), table.box_clone()], table_size: 1 << width, - id: table_id_from_string::(name) + id: table_id_from_string::(name), }) } @@ -286,13 +275,13 @@ impl MultiTableApplication { pub struct RangeCheckTableOverSingleColumn { table_entries: Vec, entries_map: std::collections::HashMap, - bits: usize + bits: usize, } impl RangeCheckTableOverSingleColumn { pub fn new(bits: usize) -> Self { let mut entries = Vec::with_capacity(1 << bits); - let mut map = std::collections::HashMap::with_capacity(1 << bits); + let mut map = std::collections::HashMap::with_capacity(1 << bits); for i in 0..(1 << bits) { let value = E::Fr::from_str(&i.to_string()).unwrap(); entries.push(value); @@ -302,16 +291,14 @@ impl RangeCheckTableOverSingleColumn { Self { table_entries: entries, entries_map: map, - bits + bits, } } } impl std::fmt::Debug for RangeCheckTableOverSingleColumn { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("RangeCheckTableOverSingleColumn") - .field("bits", &self.bits) - .finish() + f.debug_struct("RangeCheckTableOverSingleColumn").field("bits", &self.bits).finish() } } @@ -370,7 +357,7 @@ impl LookupTableInternal for RangeCheckTableOverSingleColumn { pub struct RangeCheckTableOverOneColumnOfWidth3 { table_entries: Vec, dummy_entries: Vec, - bits: usize + bits: usize, } impl RangeCheckTableOverOneColumnOfWidth3 { @@ -385,16 +372,14 @@ impl RangeCheckTableOverOneColumnOfWidth3 { Self { table_entries: entries, dummy_entries, - bits + bits, } } } impl std::fmt::Debug for RangeCheckTableOverOneColumnOfWidth3 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("RangeCheckTableOverOneColumnOfWidth3") - .field("bits", &self.bits) - .finish() + f.debug_struct("RangeCheckTableOverOneColumnOfWidth3").field("bits", &self.bits).finish() } } @@ -481,7 +466,7 @@ impl Binop for XorBinop { pub struct AndBinop; impl Binop for AndBinop { - const NAME: &'static str = "AND binop"; + const NAME: &'static str = "AND binop"; fn apply(x: usize, y: usize) -> usize { x & y @@ -505,7 +490,7 @@ pub struct TwoKeysOneValueBinopTable { table_lookup_map: std::collections::HashMap<(E::Fr, E::Fr), E::Fr>, bits: usize, name: &'static str, - _binop_marker: std::marker::PhantomData + _binop_marker: std::marker::PhantomData, } impl TwoKeysOneValueBinopTable { @@ -516,7 +501,7 @@ impl TwoKeysOneValueBinopTable { let mut map = std::collections::HashMap::with_capacity(1 << (bits * 2)); for x in 0..(1 << bits) { - for y in 0..(1< TwoKeysOneValueBinopTable { map.insert((x, y), z); } - } Self { @@ -536,17 +520,14 @@ impl TwoKeysOneValueBinopTable { table_lookup_map: map, bits, name, - _binop_marker: std::marker::PhantomData + _binop_marker: std::marker::PhantomData, } } } impl std::fmt::Debug for TwoKeysOneValueBinopTable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("TwoKeysOneValueBinopTable") - .field("bits", &self.bits) - .field("binop", &B::NAME) - .finish() + f.debug_struct("TwoKeysOneValueBinopTable").field("bits", &self.bits).field("binop", &B::NAME).finish() } } @@ -555,8 +536,8 @@ impl LookupTableInternal for TwoKeysOneValueBinopTable usize { - debug_assert_eq!(1usize << (self.bits*2), self.table_entries[0].len()); - 1usize << (self.bits*2) + debug_assert_eq!(1usize << (self.bits * 2), self.table_entries[0].len()); + 1usize << (self.bits * 2) } fn num_keys(&self) -> usize { 2 @@ -581,7 +562,7 @@ impl LookupTableInternal for TwoKeysOneValueBinopTable LookupTableInternal for TwoKeysOneValueBinopTable bool { assert!(column_num < 3); - false + false } } - -pub fn table_id_from_string( - s: &str -) -> F { +pub fn table_id_from_string(s: &str) -> F { let mut h = tiny_keccak::keccak256(s.as_bytes()); for i in 0..4 { h[i] = 0u8; @@ -626,16 +604,14 @@ pub fn table_id_from_string( #[derive(Clone)] pub struct KeyValueSet { - pub inner: [E::Fr; 3] + pub inner: [E::Fr; 3], } -impl Copy for KeyValueSet{} +impl Copy for KeyValueSet {} impl KeyValueSet { pub fn new(set: [E::Fr; 3]) -> Self { - Self { - inner: set - } + Self { inner: set } } pub fn from_slice(input: &[E::Fr]) -> Self { @@ -643,9 +619,7 @@ impl KeyValueSet { let mut inner = [E::Fr::zero(); 3]; inner.copy_from_slice(input); - Self { - inner - } + Self { inner } } } @@ -684,7 +658,7 @@ impl std::cmp::Ord for KeyValueSet { return ord; } } - }, + } ord @ _ => { return ord; } @@ -700,9 +674,7 @@ impl std::cmp::PartialOrd for KeyValueSet { impl std::fmt::Debug for KeyValueSet { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("KeyValueSet") - .field("inner", &self.inner) - .finish() + f.debug_struct("KeyValueSet").field("inner", &self.inner).finish() } } @@ -728,4 +700,4 @@ pub(crate) struct LookupQuery { pub(crate) t_at_z_omega: E::Fr, pub(crate) selector_at_z: E::Fr, pub(crate) table_type_at_z: E::Fr, -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_better_cs/mod.rs b/crates/bellman/src/plonk/better_better_cs/mod.rs index 30e0d94..d94fd8a 100644 --- a/crates/bellman/src/plonk/better_better_cs/mod.rs +++ b/crates/bellman/src/plonk/better_better_cs/mod.rs @@ -1,12 +1,12 @@ -pub mod cs; -pub mod lookup_tables; -pub mod utils; +pub mod cs; pub mod data_structures; -pub mod setup; +pub mod gates; +pub mod lookup_tables; pub mod proof; -pub mod verifier; +pub mod setup; pub mod trees; -pub mod gates; +pub mod utils; +pub mod verifier; #[cfg(feature = "redshift")] -pub mod redshift; \ No newline at end of file +pub mod redshift; diff --git a/crates/bellman/src/plonk/better_better_cs/proof/mod.rs b/crates/bellman/src/plonk/better_better_cs/proof/mod.rs index 44cc02d..2ac0bea 100644 --- a/crates/bellman/src/plonk/better_better_cs/proof/mod.rs +++ b/crates/bellman/src/plonk/better_better_cs/proof/mod.rs @@ -1,7 +1,7 @@ use super::cs::*; use super::data_structures::{self, *}; use crate::pairing::ff::*; -use crate::pairing::{Engine, CurveAffine, CurveProjective}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; use crate::plonk::polynomials::*; use std::collections::HashMap; @@ -24,10 +24,7 @@ use std::io::{Read, Write}; use crate::plonk::better_cs::keys::*; -pub fn write_tuple_with_one_index( - tuple: &(usize, F), - mut writer: W -) -> std::io::Result<()> { +pub fn write_tuple_with_one_index(tuple: &(usize, F), mut writer: W) -> std::io::Result<()> { writer.write_u64::(tuple.0 as u64)?; write_fr(&tuple.1, &mut writer)?; @@ -60,10 +57,7 @@ pub fn read_tuple_with_one_index_vec(mut reader: R) -> s Ok(elements) } -pub fn write_tuple_with_two_indexes( - tuple: &(usize, usize, F), - mut writer: W -) -> std::io::Result<()> { +pub fn write_tuple_with_two_indexes(tuple: &(usize, usize, F), mut writer: W) -> std::io::Result<()> { writer.write_u64::(tuple.0 as u64)?; writer.write_u64::(tuple.1 as u64)?; write_fr(&tuple.2, &mut writer)?; @@ -141,7 +135,7 @@ pub struct Proof> { #[serde(skip_serializing, default)] #[serde(bound(serialize = ""))] #[serde(bound(deserialize = ""))] - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl> Proof { @@ -174,7 +168,7 @@ impl> Proof { lookup_t_poly_opening_at_z: None, lookup_t_poly_opening_at_z_omega: None, - + lookup_selector_poly_opening_at_z: None, lookup_table_type_poly_opening_at_z: None, @@ -185,10 +179,10 @@ impl> Proof { opening_proof_at_z: E::G1Affine::zero(), opening_proof_at_z_omega: E::G1Affine::zero(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } - + pub fn write(&self, mut writer: W) -> std::io::Result<()> { writer.write_u64::(self.n as u64)?; @@ -263,7 +257,7 @@ impl> Proof { lookup_t_poly_opening_at_z: read_optional_fr(&mut reader)?, lookup_t_poly_opening_at_z_omega: read_optional_fr(&mut reader)?, - + lookup_selector_poly_opening_at_z: read_optional_fr(&mut reader)?, lookup_table_type_poly_opening_at_z: read_optional_fr(&mut reader)?, @@ -274,7 +268,7 @@ impl> Proof { opening_proof_at_z: read_curve_affine(&mut reader)?, opening_proof_at_z_omega: read_curve_affine(&mut reader)?, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok(new) @@ -313,7 +307,7 @@ impl> Proof { new.lookup_t_poly_opening_at_z = std::mem::replace(&mut self.lookup_t_poly_opening_at_z, None); new.lookup_t_poly_opening_at_z_omega = std::mem::replace(&mut self.lookup_t_poly_opening_at_z_omega, None); - + new.lookup_selector_poly_opening_at_z = std::mem::replace(&mut self.lookup_selector_poly_opening_at_z, None); new.lookup_table_type_poly_opening_at_z = std::mem::replace(&mut self.lookup_table_type_poly_opening_at_z, None); @@ -333,7 +327,7 @@ use crate::plonk::commitments::transcript::*; impl, MG: MainGate, S: SynthesisMode> Assembly { pub fn create_proof, T: Transcript>( - self, + self, worker: &Worker, setup: &Setup, mon_crs: &Crs, @@ -341,9 +335,9 @@ impl, MG: MainGate, S: Synthesis ) -> Result, SynthesisError> { self.create_proof_by_ref::<_, T>(worker, setup, mon_crs, transcript_params) } - + pub fn create_proof_by_ref, T: Transcript>( - &self, + &self, worker: &Worker, setup: &Setup, mon_crs: &Crs, @@ -352,11 +346,7 @@ impl, MG: MainGate, S: Synthesis assert!(S::PRODUCE_WITNESS); assert!(self.is_finalized); - let mut transcript = if let Some(params) = transcript_params { - T::new_from_params(params) - } else { - T::new() - }; + let mut transcript = if let Some(params) = transcript_params { T::new_from_params(params) } else { T::new() }; let mut proof = Proof::::empty(); @@ -378,7 +368,7 @@ impl, MG: MainGate, S: Synthesis assert!(required_domain_size.is_power_of_two()); let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(required_domain_size); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(required_domain_size); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(required_domain_size); // if we simultaneously produce setup then grab permutation polys in values forms if S::PRODUCE_SETUP { @@ -395,28 +385,19 @@ impl, MG: MainGate, S: Synthesis for idx in 0..num_state_polys { let key = PolyIdentifier::PermutationPolynomial(idx); // let vals = setup.permutation_monomials[idx].clone().fft(&worker).into_coeffs(); - let vals = setup.permutation_monomials[idx].clone().fft_using_bitreversed_ntt( - &worker, - &omegas_bitreversed, - &E::Fr::one() - )?.into_coeffs(); + let vals = setup.permutation_monomials[idx] + .clone() + .fft_using_bitreversed_ntt(&worker, &omegas_bitreversed, &E::Fr::one())? + .into_coeffs(); let poly = Polynomial::from_values_unpadded(vals)?; let poly = PolynomialProxy::from_owned(poly); values_storage.setup_map.insert(key, poly); } } - let mut ldes_storage = AssembledPolynomialStorage::::new( - true, - self.max_constraint_degree.next_power_of_two() - ); + let mut ldes_storage = AssembledPolynomialStorage::::new(true, self.max_constraint_degree.next_power_of_two()); - let mut monomials_storage = Self::create_monomial_storage( - &worker, - &omegas_inv_bitreversed, - &values_storage, - true - )?; + let mut monomials_storage = Self::create_monomial_storage(&worker, &omegas_inv_bitreversed, &values_storage, true)?; monomials_storage.extend_from_setup(setup)?; @@ -424,16 +405,9 @@ impl, MG: MainGate, S: Synthesis for i in 0..num_state_polys { let key = PolyIdentifier::VariablesPolynomial(i); let poly_ref = monomials_storage.get_poly(key); - let commitment = commit_using_monomials( - poly_ref, - mon_crs, - &worker - )?; + let commitment = commit_using_monomials(poly_ref, mon_crs, &worker)?; - commit_point_as_xy::( - &mut transcript, - &commitment - ); + commit_point_as_xy::(&mut transcript, &commitment); proof.state_polys_commitments.push(commitment); } @@ -441,16 +415,9 @@ impl, MG: MainGate, S: Synthesis for i in 0..num_witness_polys { let key = PolyIdentifier::VariablesPolynomial(i); let poly_ref = monomials_storage.get_poly(key); - let commitment = commit_using_monomials( - poly_ref, - mon_crs, - &worker - )?; + let commitment = commit_using_monomials(poly_ref, mon_crs, &worker)?; - commit_point_as_xy::( - &mut transcript, - &commitment - ); + commit_point_as_xy::(&mut transcript, &commitment); proof.witness_polys_commitments.push(commitment); } @@ -472,20 +439,12 @@ impl, MG: MainGate, S: Synthesis let table_type_poly_monomial = { let mon = Polynomial::from_values(table_type_values.clone())?; - let mon = mon.ifft_using_bitreversed_ntt( - &worker, - &omegas_inv_bitreversed, - &E::Fr::one() - )?; - + let mon = mon.ifft_using_bitreversed_ntt(&worker, &omegas_inv_bitreversed, &E::Fr::one())?; + mon }; - let selector_poly = Polynomial::::from_values(selector_for_lookup_values)?.ifft_using_bitreversed_ntt( - &worker, - &omegas_inv_bitreversed, - &E::Fr::one() - )?; + let selector_poly = Polynomial::::from_values(selector_for_lookup_values)?.ifft_using_bitreversed_ntt(&worker, &omegas_inv_bitreversed, &E::Fr::one())?; let selector_poly = PolynomialProxy::from_owned(selector_poly); let table_type_poly = PolynomialProxy::from_owned(table_type_poly_monomial); @@ -499,11 +458,7 @@ impl, MG: MainGate, S: Synthesis let table_type_poly = PolynomialProxy::from_borrowed(table_type_poly_ref); // let mut table_type_values = table_type_poly_ref.clone().fft(&worker).into_coeffs(); - let mut table_type_values = table_type_poly_ref.clone().fft_using_bitreversed_ntt( - &worker, - &omegas_bitreversed, - &E::Fr::one() - )?.into_coeffs(); + let mut table_type_values = table_type_poly_ref.clone().fft_using_bitreversed_ntt(&worker, &omegas_bitreversed, &E::Fr::one())?.into_coeffs(); table_type_values.pop().unwrap(); @@ -520,28 +475,21 @@ impl, MG: MainGate, S: Synthesis let masked_entries_using_bookkept_bitmasks = self.calculate_masked_lookup_entries(&values_storage)?; let typical_len = masked_entries_using_bookkept_bitmasks[0].len(); - assert!((typical_len+1).is_power_of_two()); + assert!((typical_len + 1).is_power_of_two()); masked_entries_using_bookkept_bitmasks } else { assert!(S::PRODUCE_WITNESS); // let selector_values = PolynomialProxy::from_owned(selector_poly.as_ref().clone().fft(&worker)); - let selector_values = selector_poly.as_ref().clone().fft_using_bitreversed_ntt( - &worker, - &omegas_bitreversed, - &E::Fr::one() - )?; + let selector_values = selector_poly.as_ref().clone().fft_using_bitreversed_ntt(&worker, &omegas_bitreversed, &E::Fr::one())?; let selector_values = PolynomialProxy::from_owned(selector_values); - self.calculate_masked_lookup_entries_using_selector( - &values_storage, - &selector_values - )? + self.calculate_masked_lookup_entries_using_selector(&values_storage, &selector_values)? }; assert_eq!(table_type_values.len(), table_contributions_values[0].len()); - + assert_eq!(table_contributions_values.len(), 3); assert_eq!(witness_len, table_contributions_values[0].len()); @@ -552,14 +500,14 @@ impl, MG: MainGate, S: Synthesis for t in table_contributions_values.into_iter() { let op = BinopAddAssignScaled::new(current); binop_over_slices(&worker, &op, &mut f_poly_values_aggregated, &t); - + current.mul_assign(&eta); } // add table type marker let op = BinopAddAssignScaled::new(current); binop_over_slices(&worker, &op, &mut f_poly_values_aggregated, &table_type_values); - + Polynomial::from_values_unpadded(f_poly_values_aggregated)? }; @@ -573,7 +521,7 @@ impl, MG: MainGate, S: Synthesis for t in t_poly_ends.into_iter() { let op = BinopAddAssignScaled::new(current); binop_over_slices(&worker, &op, &mut t_poly_values_aggregated, &t); - + current.mul_assign(&eta); } @@ -582,47 +530,35 @@ impl, MG: MainGate, S: Synthesis let mut full_t_poly_values_shifted = full_t_poly_values.clone(); full_t_poly_values[copy_start..].copy_from_slice(&t_poly_values_aggregated); - full_t_poly_values_shifted[(copy_start - 1)..(witness_len-1)].copy_from_slice(&t_poly_values_aggregated); + full_t_poly_values_shifted[(copy_start - 1)..(witness_len - 1)].copy_from_slice(&t_poly_values_aggregated); assert!(full_t_poly_values[0].is_zero()); let t_poly_monomial = { let mon = Polynomial::from_values(full_t_poly_values.clone())?; - let mon = mon.ifft_using_bitreversed_ntt( - &worker, - &omegas_inv_bitreversed, - &E::Fr::one() - )?; - + let mon = mon.ifft_using_bitreversed_ntt(&worker, &omegas_inv_bitreversed, &E::Fr::one())?; + mon }; ( - PolynomialProxy::from_owned(Polynomial::from_values_unpadded(full_t_poly_values)?), + PolynomialProxy::from_owned(Polynomial::from_values_unpadded(full_t_poly_values)?), PolynomialProxy::from_owned(Polynomial::from_values_unpadded(full_t_poly_values_shifted)?), - PolynomialProxy::from_owned(t_poly_monomial) + PolynomialProxy::from_owned(t_poly_monomial), ) } else { let mut t_poly_values_monomial_aggregated = setup.lookup_tables_monomials[0].clone(); let mut current = eta; for idx in 1..4 { let to_aggregate_ref = &setup.lookup_tables_monomials[idx]; - t_poly_values_monomial_aggregated.add_assign_scaled( - &worker, - to_aggregate_ref, - ¤t - ); + t_poly_values_monomial_aggregated.add_assign_scaled(&worker, to_aggregate_ref, ¤t); current.mul_assign(&eta); } assert!(t_poly_values_monomial_aggregated.size().is_power_of_two()); - let mut t_poly_values = t_poly_values_monomial_aggregated.clone().fft_using_bitreversed_ntt( - &worker, - &omegas_bitreversed, - &E::Fr::one() - )?; + let mut t_poly_values = t_poly_values_monomial_aggregated.clone().fft_using_bitreversed_ntt(&worker, &omegas_bitreversed, &E::Fr::one())?; assert!(t_poly_values.as_ref().last().unwrap().is_zero()); assert!(t_poly_values.size().is_power_of_two()); @@ -642,9 +578,9 @@ impl, MG: MainGate, S: Synthesis assert_eq!(witness_len, t_poly_values_shifted.size()); ( - PolynomialProxy::from_owned(t_poly_values), + PolynomialProxy::from_owned(t_poly_values), PolynomialProxy::from_owned(t_poly_values_shifted), - PolynomialProxy::from_owned(t_poly_values_monomial_aggregated) + PolynomialProxy::from_owned(t_poly_values_monomial_aggregated), ) }; @@ -657,38 +593,27 @@ impl, MG: MainGate, S: Synthesis let mut full_s_poly_values_shifted = full_s_poly_values.clone(); full_s_poly_values[sorted_copy_start..].copy_from_slice(&s_poly_values_aggregated); - full_s_poly_values_shifted[(sorted_copy_start - 1)..(witness_len-1)].copy_from_slice(&s_poly_values_aggregated); + full_s_poly_values_shifted[(sorted_copy_start - 1)..(witness_len - 1)].copy_from_slice(&s_poly_values_aggregated); assert!(full_s_poly_values[0].is_zero()); let s_poly_monomial = { let mon = Polynomial::from_values(full_s_poly_values.clone())?; - let mon = mon.ifft_using_bitreversed_ntt( - &worker, - &omegas_inv_bitreversed, - &E::Fr::one() - )?; - + let mon = mon.ifft_using_bitreversed_ntt(&worker, &omegas_inv_bitreversed, &E::Fr::one())?; + mon }; ( s_poly_monomial, - Polynomial::from_values_unpadded(full_s_poly_values)?, - Polynomial::from_values_unpadded(full_s_poly_values_shifted)? + Polynomial::from_values_unpadded(full_s_poly_values)?, + Polynomial::from_values_unpadded(full_s_poly_values_shifted)?, ) }; - let s_poly_commitment = commit_using_monomials( - &s_poly_monomial, - mon_crs, - &worker - )?; + let s_poly_commitment = commit_using_monomials(&s_poly_monomial, mon_crs, &worker)?; - commit_point_as_xy::( - &mut transcript, - &s_poly_commitment - ); + commit_point_as_xy::(&mut transcript, &s_poly_commitment); proof.lookup_s_poly_commitment = Some(s_poly_commitment); @@ -731,15 +656,12 @@ impl, MG: MainGate, S: Synthesis grand_products_protos_with_gamma.push(p); } - + let required_domain_size = required_domain_size; let domain = Domain::new_for_size(required_domain_size as u64)?; - let mut domain_elements = materialize_domain_elements_with_natural_enumeration( - &domain, - &worker - ); + let mut domain_elements = materialize_domain_elements_with_natural_enumeration(&domain, &worker); domain_elements.pop().expect("must pop last element for omega^i"); @@ -767,7 +689,7 @@ impl, MG: MainGate, S: Synthesis // we take A, B, C, ... values and form (A + beta * perm_a + gamma), etc and calculate their grand product let mut permutation_polynomials_values_of_size_n_minus_one = vec![]; - + for idx in 0..num_state_polys { let key = PolyIdentifier::PermutationPolynomial(idx); @@ -779,19 +701,15 @@ impl, MG: MainGate, S: Synthesis } let z_den = { - assert_eq!( - permutation_polynomials_values_of_size_n_minus_one.len(), - grand_products_protos_with_gamma.len() - ); + assert_eq!(permutation_polynomials_values_of_size_n_minus_one.len(), grand_products_protos_with_gamma.len()); let mut grand_products_proto_it = grand_products_protos_with_gamma.into_iter(); let mut permutation_polys_it = permutation_polynomials_values_of_size_n_minus_one.iter(); let mut z_2 = grand_products_proto_it.next().unwrap(); z_2.add_assign_scaled(&worker, permutation_polys_it.next().unwrap(), &beta_for_copy_permutation); - for (mut p, perm) in grand_products_proto_it - .zip(permutation_polys_it) { - // permutation polynomials + for (mut p, perm) in grand_products_proto_it.zip(permutation_polys_it) { + // permutation polynomials p.add_assign_scaled(&worker, &perm, &beta_for_copy_permutation); z_2.mul_assign(&worker, &p); } @@ -811,26 +729,15 @@ impl, MG: MainGate, S: Synthesis assert!(z.as_ref()[0] == E::Fr::one()); - let copy_permutation_z_in_monomial_form = z.ifft_using_bitreversed_ntt( - &worker, - &omegas_inv_bitreversed, - &E::Fr::one() - )?; + let copy_permutation_z_in_monomial_form = z.ifft_using_bitreversed_ntt(&worker, &omegas_inv_bitreversed, &E::Fr::one())?; - let copy_permutation_z_poly_commitment = commit_using_monomials( - ©_permutation_z_in_monomial_form, - mon_crs, - &worker - )?; + let copy_permutation_z_poly_commitment = commit_using_monomials(©_permutation_z_in_monomial_form, mon_crs, &worker)?; - commit_point_as_xy::( - &mut transcript, - ©_permutation_z_poly_commitment - ); + commit_point_as_xy::(&mut transcript, ©_permutation_z_poly_commitment); proof.copy_permutation_grand_product_commitment = copy_permutation_z_poly_commitment; - let mut beta_for_lookup = None; + let mut beta_for_lookup = None; let mut gamma_for_lookup = None; let lookup_z_poly_in_monomial_form = if let Some(data) = lookup_data.as_mut() { @@ -848,17 +755,17 @@ impl, MG: MainGate, S: Synthesis let mut gamma_beta = gamma_for_lookup_permutation; gamma_beta.mul_assign(&beta_plus_one); - let expected = gamma_beta.pow([(required_domain_size-1) as u64]); - + let expected = gamma_beta.pow([(required_domain_size - 1) as u64]); + let f_poly_unpadded_values = data.f_poly_unpadded_values.take().unwrap(); let t_poly_unpadded_values = data.t_poly_unpadded_values.take().unwrap(); let t_shifted_unpadded_values = data.t_shifted_unpadded_values.take().unwrap(); let s_poly_unpadded_values = data.s_poly_unpadded_values.take().unwrap(); let s_shifted_unpadded_values = data.s_shifted_unpadded_values.take().unwrap(); - // Z(x*omega) = Z(x) * - // (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) / - // (\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) + // Z(x*omega) = Z(x) * + // (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) / + // (\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) let mut z_num = { // (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) @@ -915,23 +822,12 @@ impl, MG: MainGate, S: Synthesis // data.t_poly_monomial = Some(t_poly_monomial); // data.s_poly_monomial = Some(s_poly_monomial); - let z = z.ifft_using_bitreversed_ntt( - &worker, - &omegas_inv_bitreversed, - &E::Fr::one() - )?; + let z = z.ifft_using_bitreversed_ntt(&worker, &omegas_inv_bitreversed, &E::Fr::one())?; + + let lookup_z_poly_commitment = commit_using_monomials(&z, mon_crs, &worker)?; + + commit_point_as_xy::(&mut transcript, &lookup_z_poly_commitment); - let lookup_z_poly_commitment = commit_using_monomials( - &z, - mon_crs, - &worker - )?; - - commit_point_as_xy::( - &mut transcript, - &lookup_z_poly_commitment - ); - proof.lookup_grand_product_commitment = Some(lookup_z_poly_commitment); Some(z) @@ -943,7 +839,7 @@ impl, MG: MainGate, S: Synthesis let alpha = transcript.get_challenge(); // let alpha = E::Fr::from_str("1234567890").unwrap(); - + let mut total_powers_of_alpha_for_gates = 0; for g in self.sorted_gates.iter() { total_powers_of_alpha_for_gates += g.num_quotient_terms(); @@ -996,19 +892,16 @@ impl, MG: MainGate, S: Synthesis for_gate, &omegas_bitreversed, &omegas_inv_bitreversed, - &worker + &worker, )?; if num_different_gates > 1 { // we have to multiply by the masking poly (selector) let key = PolyIdentifier::GateSelector(gate.name()); let monomial_selector = monomials_storage.gate_selectors.get(&key).unwrap().as_ref(); - let selector_lde = monomial_selector.clone_padded_to_domain()?.bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let selector_lde = monomial_selector + .clone_padded_to_domain()? + .bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; t.mul_assign(&worker, &selector_lde); drop(selector_lde); @@ -1031,19 +924,16 @@ impl, MG: MainGate, S: Synthesis for_gate, &omegas_bitreversed, &omegas_inv_bitreversed, - &worker + &worker, )?; { // we have to multiply by the masking poly (selector) let key = PolyIdentifier::GateSelector(gate.name()); let monomial_selector = monomials_storage.gate_selectors.get(&key).unwrap().as_ref(); - let selector_lde = monomial_selector.clone_padded_to_domain()?.bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let selector_lde = monomial_selector + .clone_padded_to_domain()? + .bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; contribution.mul_assign(&worker, &selector_lde); drop(selector_lde); @@ -1063,12 +953,7 @@ impl, MG: MainGate, S: Synthesis // z(omega^0) - 1 == 0 let l_0 = calculate_lagrange_poly::(&worker, required_domain_size.next_power_of_two(), 0)?; - let l_0_coset_lde_bitreversed = l_0.bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let l_0_coset_lde_bitreversed = l_0.bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; let mut copy_grand_product_alphas = None; let x_poly_lde_bitreversed = { @@ -1078,34 +963,25 @@ impl, MG: MainGate, S: Synthesis current_alpha.mul_assign(&alpha); let alpha_0 = current_alpha; - let z_coset_lde_bitreversed = copy_permutation_z_in_monomial_form.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let z_coset_lde_bitreversed = copy_permutation_z_in_monomial_form + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; - assert!(z_coset_lde_bitreversed.size() == required_domain_size*lde_factor); + assert!(z_coset_lde_bitreversed.size() == required_domain_size * lde_factor); - let z_shifted_coset_lde_bitreversed = z_coset_lde_bitreversed.clone_shifted_assuming_bitreversed( - lde_factor, - &worker, - )?; + let z_shifted_coset_lde_bitreversed = z_coset_lde_bitreversed.clone_shifted_assuming_bitreversed(lde_factor, &worker)?; - assert!(z_shifted_coset_lde_bitreversed.size() == required_domain_size*lde_factor); + assert!(z_shifted_coset_lde_bitreversed.size() == required_domain_size * lde_factor); // For both Z_1 and Z_2 we first check for grand products - // z*(X)(A + beta*X + gamma)(B + beta*k_1*X + gamma)(C + beta*K_2*X + gamma) - + // z*(X)(A + beta*X + gamma)(B + beta*k_1*X + gamma)(C + beta*K_2*X + gamma) - // - (A + beta*perm_a(X) + gamma)(B + beta*perm_b(X) + gamma)(C + beta*perm_c(X) + gamma)*Z(X*Omega)== 0 // we use evaluations of the polynomial X and K_i * X on a large domain's coset let mut contrib_z = z_coset_lde_bitreversed.clone(); // precompute x poly - let mut x_poly = Polynomial::from_values(vec![ - coset_factor; - required_domain_size*lde_factor - ])?; + let mut x_poly = Polynomial::from_values(vec![coset_factor; required_domain_size * lde_factor])?; x_poly.distribute_powers(&worker, z_shifted_coset_lde_bitreversed.omega); x_poly.bitreverse_enumeration(&worker); @@ -1146,12 +1022,10 @@ impl, MG: MainGate, S: Synthesis tmp.add_constant(&worker, &gamma_for_copy_permutation); let key = PolyIdentifier::PermutationPolynomial(idx); - let perm = monomials_storage.get_poly(key).clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let perm = monomials_storage + .get_poly(key) + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; tmp.add_assign_scaled(&worker, &perm, &beta_for_copy_permutation); contrib_z.mul_assign(&worker, &tmp); drop(perm); @@ -1194,7 +1068,7 @@ impl, MG: MainGate, S: Synthesis let mut gamma_beta = gamma_for_lookup_permutation; gamma_beta.mul_assign(&beta_plus_one); - let expected = gamma_beta.pow([(required_domain_size-1) as u64]); + let expected = gamma_beta.pow([(required_domain_size - 1) as u64]); current_alpha.mul_assign(&alpha); @@ -1202,39 +1076,30 @@ impl, MG: MainGate, S: Synthesis // same grand product argument for lookup permutation except divisor is now with one point cut - let z_lde = z_poly_in_monomial_form.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let z_lde = z_poly_in_monomial_form + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; - let z_lde_shifted = z_lde.clone_shifted_assuming_bitreversed( - lde_factor, - &worker - )?; + let z_lde_shifted = z_lde.clone_shifted_assuming_bitreversed(lde_factor, &worker)?; // We make an small ad-hoc modification here and instead of dividing some contributions by // (X^n - 1)/(X - omega^{n-1}) we move (X - omega^{n-1}) to the numerator and join the divisions // Numerator degree is at max 4n, so it's < 4n after division - // ( Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - + // ( Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - // - Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) )*(X - omega^{n-1}) let data = lookup_data.as_ref().unwrap(); - let s_lde = data.s_poly_monomial.as_ref().unwrap().clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let s_lde = data + .s_poly_monomial + .as_ref() + .unwrap() + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; - let s_lde_shifted = s_lde.clone_shifted_assuming_bitreversed( - lde_factor, - &worker - )?; + let s_lde_shifted = s_lde.clone_shifted_assuming_bitreversed(lde_factor, &worker)?; // Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) @@ -1246,25 +1111,20 @@ impl, MG: MainGate, S: Synthesis drop(s_lde_shifted); drop(z_lde_shifted); - let t_lde = data.t_poly_monomial.as_ref().unwrap().as_ref().clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let t_lde = data + .t_poly_monomial + .as_ref() + .unwrap() + .as_ref() + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; - let t_lde_shifted = t_lde.clone_shifted_assuming_bitreversed( - lde_factor, - &worker - )?; + let t_lde_shifted = t_lde.clone_shifted_assuming_bitreversed(lde_factor, &worker)?; let f_lde = { // add up ldes of a,b,c and table_type poly and multiply by selector - - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - &ldes_storage - ); + + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), &ldes_storage); let mut tmp = a_ref.clone(); drop(a_ref); @@ -1272,52 +1132,49 @@ impl, MG: MainGate, S: Synthesis let mut current = eta; - let b_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), - &ldes_storage - ); + let b_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), &ldes_storage); tmp.add_assign_scaled(&worker, b_ref, ¤t); drop(b_ref); current.mul_assign(&eta); - let c_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), - &ldes_storage - ); + let c_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), &ldes_storage); tmp.add_assign_scaled(&worker, c_ref, ¤t); drop(c_ref); current.mul_assign(&eta); - let table_type_lde = lookup_data.as_ref().unwrap().table_type_poly_monomial.as_ref().unwrap().as_ref().clone() - .bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let table_type_lde = lookup_data + .as_ref() + .unwrap() + .table_type_poly_monomial + .as_ref() + .unwrap() + .as_ref() + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; tmp.add_assign_scaled(&worker, &table_type_lde, ¤t); drop(table_type_lde); - let lookup_selector_lde = lookup_data.as_ref().unwrap().selector_poly_monomial.as_ref().unwrap().as_ref().clone() - .bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let lookup_selector_lde = lookup_data + .as_ref() + .unwrap() + .selector_poly_monomial + .as_ref() + .unwrap() + .as_ref() + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; tmp.mul_assign(&worker, &lookup_selector_lde); drop(lookup_selector_lde); tmp - }; // - Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) @@ -1332,7 +1189,7 @@ impl, MG: MainGate, S: Synthesis t.add_constant(&worker, &gamma_beta); tmp.mul_assign(&worker, &t); - + drop(t); drop(t_lde_shifted); @@ -1356,7 +1213,7 @@ impl, MG: MainGate, S: Synthesis current_alpha.mul_assign(&alpha); let alpha_1 = current_alpha; - + tmp.reuse_allocation(&z_lde); tmp.sub_constant(&worker, &E::Fr::one()); tmp.mul_assign(&worker, &l_0_coset_lde_bitreversed); @@ -1373,12 +1230,7 @@ impl, MG: MainGate, S: Synthesis let l_last = calculate_lagrange_poly::(&worker, required_domain_size.next_power_of_two(), required_domain_size - 1)?; - let l_last_coset_lde_bitreversed = l_last.bitreversed_lde_using_bitreversed_ntt( - &worker, - lde_factor, - &omegas_bitreversed, - &coset_factor - )?; + let l_last_coset_lde_bitreversed = l_last.bitreversed_lde_using_bitreversed_ntt(&worker, lde_factor, &omegas_bitreversed, &coset_factor)?; tmp.reuse_allocation(&z_lde); tmp.sub_constant(&worker, &expected); @@ -1405,12 +1257,7 @@ impl, MG: MainGate, S: Synthesis let inverse_divisor_on_coset_lde_natural_ordering = { let mut vanishing_poly_inverse_bitreversed = - evaluate_vanishing_polynomial_of_degree_on_domain_size::( - required_domain_size as u64, - &E::Fr::multiplicative_generator(), - (required_domain_size * lde_factor) as u64, - &worker, - )?; + evaluate_vanishing_polynomial_of_degree_on_domain_size::(required_domain_size as u64, &E::Fr::multiplicative_generator(), (required_domain_size * lde_factor) as u64, &worker)?; vanishing_poly_inverse_bitreversed.batch_inversion(&worker)?; // vanishing_poly_inverse_bitreversed.bitreverse_enumeration(&worker)?; @@ -1424,7 +1271,7 @@ impl, MG: MainGate, S: Synthesis t_poly.mul_assign(&worker, &inverse_divisor_on_coset_lde_natural_ordering); drop(inverse_divisor_on_coset_lde_natural_ordering); - + let t_poly = t_poly.icoset_fft_for_generator(&worker, &coset_factor); // println!("Lde factor = {}", lde_factor); @@ -1435,8 +1282,8 @@ impl, MG: MainGate, S: Synthesis // degree is 4n-4 let l = t_poly.as_ref().len(); // assert_eq!(&t_poly.as_ref()[(l-4)..], &[E::Fr::zero(); 4][..], "quotient degree is too large"); - if &t_poly.as_ref()[(l-4)..] != &[E::Fr::zero(); 4][..] { - println!("End coeffs are {:?}", &t_poly.as_ref()[(l-4)..]); + if &t_poly.as_ref()[(l - 4)..] != &[E::Fr::zero(); 4][..] { + println!("End coeffs are {:?}", &t_poly.as_ref()[(l - 4)..]); return Err(SynthesisError::Unsatisfiable); } } @@ -1446,16 +1293,9 @@ impl, MG: MainGate, S: Synthesis let mut t_poly_parts = t_poly.break_into_multiples(required_domain_size)?; for part in t_poly_parts.iter() { - let commitment = commit_using_monomials( - part, - mon_crs, - &worker - )?; + let commitment = commit_using_monomials(part, mon_crs, &worker)?; - commit_point_as_xy::( - &mut transcript, - &commitment - ); + commit_point_as_xy::(&mut transcript, &commitment); proof.quotient_poly_parts_commitments.push(commitment); } @@ -1504,8 +1344,7 @@ impl, MG: MainGate, S: Synthesis for id in ids.into_iter() { let (poly_ref, poly_idx) = if let PolyIdentifier::VariablesPolynomial(idx) = id { (monomials_storage.state_map.get(&id).unwrap().as_ref(), idx) - } - else { + } else { unreachable!(); }; @@ -1534,8 +1373,7 @@ impl, MG: MainGate, S: Synthesis for id in ids.into_iter() { let (poly_ref, poly_idx) = if let PolyIdentifier::WitnessPolynomial(idx) = id { (monomials_storage.witness_map.get(&id).unwrap().as_ref(), idx) - } - else { + } else { unreachable!(); }; @@ -1565,8 +1403,7 @@ impl, MG: MainGate, S: Synthesis for id in ids.into_iter() { let (poly_ref, poly_idx) = if let PolyIdentifier::GateSetupPolynomial(_, idx) = id { (monomials_storage.setup_map.get(&id).unwrap().as_ref(), idx) - } - else { + } else { unreachable!(); }; @@ -1589,7 +1426,7 @@ impl, MG: MainGate, S: Synthesis query_values_map.insert(key, value); } - } + } } // also open selectors @@ -1613,7 +1450,7 @@ impl, MG: MainGate, S: Synthesis let mut copy_permutation_queries = vec![]; - for idx in 0..(num_state_polys-1) { + for idx in 0..(num_state_polys - 1) { let key = PolyIdentifier::PermutationPolynomial(idx); let value = monomials_storage.get_poly(key).evaluate_at(&worker, z); @@ -1649,15 +1486,7 @@ impl, MG: MainGate, S: Synthesis let input_values = self.input_assingments.clone(); - let mut r = gate.contribute_into_linearization_for_public_inputs( - required_domain_size, - &input_values, - z, - &query_values_map, - &monomials_storage, - for_gate, - &worker - )?; + let mut r = gate.contribute_into_linearization_for_public_inputs(required_domain_size, &input_values, z, &query_values_map, &monomials_storage, for_gate, &worker)?; let mut selectors_it = selector_values.clone().into_iter(); @@ -1674,26 +1503,14 @@ impl, MG: MainGate, S: Synthesis if gate.benefits_from_linearization() { // gate benefits from linearization, so make temporary value - let tmp = gate.contribute_into_linearization( - required_domain_size, - z, - &query_values_map, - &monomials_storage, - for_gate, - &worker - )?; + let tmp = gate.contribute_into_linearization(required_domain_size, z, &query_values_map, &monomials_storage, for_gate, &worker)?; let selector_value = selectors_it.next().unwrap(); r.add_assign_scaled(&worker, &tmp, &selector_value); } else { // we linearize over the selector, so take a selector and scale it - let gate_value_at_z = gate.contribute_into_verification_equation( - required_domain_size, - z, - &query_values_map, - for_gate - )?; + let gate_value_at_z = gate.contribute_into_verification_equation(required_domain_size, z, &query_values_map, for_gate)?; let key = PolyIdentifier::GateSelector(gate.name()); let gate_selector_ref = monomials_storage.gate_selectors.get(&key).expect("must get monomial form of gate selector").as_ref(); @@ -1723,8 +1540,7 @@ impl, MG: MainGate, S: Synthesis for idx in 0..num_state_polys { let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(idx)); - let wire_value = query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let wire_value = query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; let mut t = z; let non_res = non_residues_iterator.next().unwrap(); t.mul_assign(&non_res); @@ -1745,13 +1561,12 @@ impl, MG: MainGate, S: Synthesis factor.mul_assign(&beta_for_copy_permutation); factor.mul_assign(©_permutation_z_at_z_omega); - for idx in 0..(num_state_polys-1) { + for idx in 0..(num_state_polys - 1) { let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(idx)); - let wire_value = query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let wire_value = query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; let permutation_at_z = copy_permutation_queries[idx]; let mut t = permutation_at_z; - + t.mul_assign(&beta_for_copy_permutation); t.add_assign(&wire_value); t.add_assign(&gamma_for_copy_permutation); @@ -1777,7 +1592,7 @@ impl, MG: MainGate, S: Synthesis // due to separate divisor it's not obvious if this is beneficial without some tricks // like multiplication by (1 - L_{n-1}) or by (x - omega^{n-1}) - // Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - + // Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - // Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) == 0 // check that (Z(x) - 1) * L_{0} == 0 // check that (Z(x) - expected) * L_{n-1} == 0, or (Z(x*omega) - expected)* L_{n-2} == 0 @@ -1809,7 +1624,7 @@ impl, MG: MainGate, S: Synthesis let mut gamma_beta = gamma_for_lookup_permutation; gamma_beta.mul_assign(&beta_plus_one); - // (Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - + // (Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - // Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)))*(X - omega^{n-1}) let last_omega = domain.generator.pow(&[(required_domain_size - 1) as u64]); @@ -1823,7 +1638,7 @@ impl, MG: MainGate, S: Synthesis r_poly.add_assign_scaled(&worker, lookup_data.as_ref().unwrap().s_poly_monomial.as_ref().unwrap(), &factor); - // Z(x) from - alpha_0 * Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) + // Z(x) from - alpha_0 * Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) // + alpha_1 * Z(x) * L_{0}(z) + alpha_2 * Z(x) * L_{n-1}(z) // accumulate coefficient @@ -1838,10 +1653,9 @@ impl, MG: MainGate, S: Synthesis let mut current = E::Fr::one(); let eta = lookup_data.as_ref().unwrap().eta; // a,b,c - for idx in 0..(num_state_polys-1) { + for idx in 0..(num_state_polys - 1) { let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(idx)); - let mut value = *query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let mut value = *query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; value.mul_assign(¤t); f_reconstructed.add_assign(&value); @@ -1949,12 +1763,7 @@ impl, MG: MainGate, S: Synthesis let input_values = self.input_assingments.clone(); - let mut inputs_term = gate.add_inputs_into_quotient( - required_domain_size, - &input_values, - z, - for_gate, - )?; + let mut inputs_term = gate.add_inputs_into_quotient(required_domain_size, &input_values, z, for_gate)?; if num_different_gates > 1 { let selector_value = selector_values[0]; @@ -1964,7 +1773,7 @@ impl, MG: MainGate, S: Synthesis tmp.add_assign(&inputs_term); t_num_on_full_domain.add_assign(&tmp); - } + } // now aggregate leftovers from grand product for copy permutation { @@ -1974,13 +1783,12 @@ impl, MG: MainGate, S: Synthesis let mut factor = alpha_0; factor.mul_assign(©_permutation_z_at_z_omega); - for idx in 0..(num_state_polys-1) { + for idx in 0..(num_state_polys - 1) { let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(idx)); - let wire_value = query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let wire_value = query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; let permutation_at_z = copy_permutation_queries[idx]; let mut t = permutation_at_z; - + t.mul_assign(&beta_for_copy_permutation); t.add_assign(&wire_value); t.add_assign(&gamma_for_copy_permutation); @@ -1988,9 +1796,8 @@ impl, MG: MainGate, S: Synthesis factor.mul_assign(&t); } - let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(num_state_polys-1)); - let mut tmp = *query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(num_state_polys - 1)); + let mut tmp = *query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; tmp.add_assign(&gamma_for_copy_permutation); factor.mul_assign(&tmp); @@ -2009,7 +1816,6 @@ impl, MG: MainGate, S: Synthesis { if lookup_queries.is_some() { - let [alpha_0, alpha_1, alpha_2] = lookup_grand_product_alphas.expect("there must be powers of alpha for lookup permutation"); let lookup_queries = lookup_queries.clone().expect("lookup queries must be made"); @@ -2020,12 +1826,12 @@ impl, MG: MainGate, S: Synthesis beta_plus_one.add_assign(&E::Fr::one()); let mut gamma_beta = gamma_for_lookup_permutation; gamma_beta.mul_assign(&beta_plus_one); - - let expected = gamma_beta.pow([(required_domain_size-1) as u64]); + + let expected = gamma_beta.pow([(required_domain_size - 1) as u64]); // in a linearization we've taken terms: // - s(x) from the alpha_0 * Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - // - and Z(x) from - alpha_0 * Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) (term in full) + + // - and Z(x) from - alpha_0 * Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) (term in full) + // + alpha_1 * (Z(x) - 1) * L_{0}(z) + alpha_2 * (Z(x) - expected) * L_{n-1}(z) // first make alpha_0 * Z(x*omega)*(\gamma*(1 + \beta) + \beta * s(x*omega))) @@ -2049,7 +1855,7 @@ impl, MG: MainGate, S: Synthesis let mut l_0_at_z = evaluate_l0_at_point(required_domain_size as u64, z)?; l_0_at_z.mul_assign(&alpha_1); - + t_num_on_full_domain.sub_assign(&l_0_at_z); // // - alpha_2 * expected L_{n-1}(z) @@ -2113,7 +1919,7 @@ impl, MG: MainGate, S: Synthesis multiopening_challenge.mul_assign(&v); let poly_ref = monomials_storage.get_poly(*id); poly_to_divide_at_z.add_assign_scaled(&worker, poly_ref, &multiopening_challenge); - } + } } // also open selectors at z @@ -2124,14 +1930,14 @@ impl, MG: MainGate, S: Synthesis poly_to_divide_at_z.add_assign_scaled(&worker, poly_ref, &multiopening_challenge); } - for idx in 0..(num_state_polys-1) { + for idx in 0..(num_state_polys - 1) { multiopening_challenge.mul_assign(&v); let key = PolyIdentifier::PermutationPolynomial(idx); let poly_ref = monomials_storage.get_poly(key); poly_to_divide_at_z.add_assign_scaled(&worker, poly_ref, &multiopening_challenge); } - // if lookup is present - add it + // if lookup is present - add it if let Some(data) = lookup_data.as_ref() { // we need to add t(x), selector(x) and table type(x) multiopening_challenge.mul_assign(&v); @@ -2171,7 +1977,7 @@ impl, MG: MainGate, S: Synthesis multiopening_challenge.mul_assign(&v); let poly_ref = monomials_storage.get_poly(*id); poly_to_divide_at_z_omega.add_assign_scaled(&worker, poly_ref, &multiopening_challenge); - } + } } if let Some(data) = lookup_data { @@ -2210,17 +2016,9 @@ impl, MG: MainGate, S: Synthesis let open_at_z_omega = polys.pop().unwrap().0; let open_at_z = polys.pop().unwrap().0; - let opening_at_z = commit_using_monomials( - &open_at_z, - &mon_crs, - &worker - )?; + let opening_at_z = commit_using_monomials(&open_at_z, &mon_crs, &worker)?; - let opening_at_z_omega = commit_using_monomials( - &open_at_z_omega, - &mon_crs, - &worker - )?; + let opening_at_z_omega = commit_using_monomials(&open_at_z_omega, &mon_crs, &worker)?; proof.opening_proof_at_z = opening_at_z; proof.opening_proof_at_z_omega = opening_at_z_omega; @@ -2230,7 +2028,7 @@ impl, MG: MainGate, S: Synthesis } #[derive(Debug)] -pub struct SortedGateQueries{ +pub struct SortedGateQueries { pub state_polys: Vec>, pub witness_polys: Vec>, pub gate_selectors: Vec>>, @@ -2242,10 +2040,10 @@ pub struct SortedGateQueries{ /// - gate selectors /// - gate setups in order of gates appearing /// - additionally we split them into buckets of different dilation -pub fn sort_queries_for_linearization(gates: & Vec>>, max_dilation: usize) -> SortedGateQueries{ - let state_polys_sorted_by_dilation = vec![vec![]; max_dilation+1]; - let witness_polys_sorted_by_dilation = vec![vec![]; max_dilation+1]; - let gate_setup_polys_by_gate_and_dilation = vec![vec![vec![]; max_dilation+1]; gates.len()]; +pub fn sort_queries_for_linearization(gates: &Vec>>, max_dilation: usize) -> SortedGateQueries { + let state_polys_sorted_by_dilation = vec![vec![]; max_dilation + 1]; + let witness_polys_sorted_by_dilation = vec![vec![]; max_dilation + 1]; + let gate_setup_polys_by_gate_and_dilation = vec![vec![vec![]; max_dilation + 1]; gates.len()]; let mut queries = SortedGateQueries:: { state_polys: state_polys_sorted_by_dilation, @@ -2296,26 +2094,24 @@ pub fn sort_queries_for_linearization(gates: & Vec { queries.state_polys[dilation_value].push(p); - }, + } p @ PolyIdentifier::WitnessPolynomial(..) => { queries.witness_polys[dilation_value].push(p); - }, + } p @ PolyIdentifier::GateSetupPolynomial(..) => { queries.gate_setup_polys[gate_idx][dilation_value].push(p); - }, + } _ => { unreachable!(); } }; - sorted_opening_requests.push(q); - } } } - // Sanity check: we open everything either in linearization or in plain text! + // Sanity check: we open everything either in linearization or in plain text! { let must_open_without_linearization: Vec<_> = all_queries.difference(&polys_in_linearization).collect(); @@ -2328,4 +2124,4 @@ pub fn sort_queries_for_linearization(gates: & Vec > { +pub struct Multioracle<'a, E: Engine, H: BinaryTreeHasher> { pub polynomial_values_refs: Vec<&'a [E::Fr]>, - pub tree: BinaryTree + pub tree: BinaryTree, } impl<'a, E: Engine, H: BinaryTreeHasher> Multioracle<'a, E, H> { - pub fn combine_leafs<'p>( - polynomials: &'p [Polynomial], - num_values_from_one_poly_into_leaf: usize, - worker: &Worker - ) -> Vec> { + pub fn combine_leafs<'p>(polynomials: &'p [Polynomial], num_values_from_one_poly_into_leaf: usize, worker: &Worker) -> Vec> { let num_polys = polynomials.len(); let num_leafs = polynomials[0].size() / num_values_from_one_poly_into_leaf; println!("{} leafs total", num_leafs); @@ -35,12 +31,11 @@ impl<'a, E: Engine, H: BinaryTreeHasher> Multioracle<'a, E, H> { println!("Start combining leafs"); worker.scope(leaf_refs_combined.len(), |scope, chunk| { - for (i, lh) in leaf_refs_combined.chunks_mut(chunk) - .enumerate() { + for (i, lh) in leaf_refs_combined.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { // we take `values_per_leaf` values from each of the polynomial // and push them into the conbinations - let base_idx = i*chunk; + let base_idx = i * chunk; for (j, lh) in lh.iter_mut().enumerate() { let idx = base_idx + j; let start = idx * num_values_from_one_poly_into_leaf; @@ -60,39 +55,23 @@ impl<'a, E: Engine, H: BinaryTreeHasher> Multioracle<'a, E, H> { leaf_refs_combined } - pub fn new_from_polynomials( - polynomials: &'a [Polynomial], - tree_hasher: H, - num_values_from_one_poly_into_leaf: usize, - worker: &Worker - ) -> Self { + pub fn new_from_polynomials(polynomials: &'a [Polynomial], tree_hasher: H, num_values_from_one_poly_into_leaf: usize, worker: &Worker) -> Self { // first make combinations of leaf values // expect polynomials to be in bitreverse enumeration let num_polys = polynomials.len(); let values_per_leaf = num_polys * num_values_from_one_poly_into_leaf; println!("Placing {} values into single leaf", values_per_leaf); - let tree_params = BinaryTreeParams { - values_per_leaf: values_per_leaf - }; + let tree_params = BinaryTreeParams { values_per_leaf: values_per_leaf }; // we need vector (over leafs) // of vectors(over individual polys) // of references - let leaf_refs_combined = Self::combine_leafs( - polynomials, - num_values_from_one_poly_into_leaf, - &worker - ); + let leaf_refs_combined = Self::combine_leafs(polynomials, num_values_from_one_poly_into_leaf, &worker); println!("Start making a tree"); - let tree = BinaryTree::create_from_combined_leafs( - &leaf_refs_combined, - num_polys, - tree_hasher, - &tree_params - ); + let tree = BinaryTree::create_from_combined_leafs(&leaf_refs_combined, num_polys, tree_hasher, &tree_params); println!("Done making a tree"); @@ -100,7 +79,7 @@ impl<'a, E: Engine, H: BinaryTreeHasher> Multioracle<'a, E, H> { Self { polynomial_values_refs: poly_refs, - tree + tree, } } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_better_cs/redshift/prover.rs b/crates/bellman/src/plonk/better_better_cs/redshift/prover.rs index 0af603d..fb71869 100644 --- a/crates/bellman/src/plonk/better_better_cs/redshift/prover.rs +++ b/crates/bellman/src/plonk/better_better_cs/redshift/prover.rs @@ -1,49 +1,33 @@ -use crate::pairing::{Engine}; -use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use crate::worker::Worker; -use crate::plonk::commitments::transparent::utils::log2_floor; -use super::*; -use super::tree_hash::BinaryTreeHasher; +use super::super::cs_old::*; use super::binary_tree::{BinaryTree, BinaryTreeParams}; -use crate::plonk::polynomials::*; use super::multioracle::Multioracle; -use super::super::cs_old::*; -use crate::SynthesisError; use super::setup::*; +use super::tree_hash::BinaryTreeHasher; +use super::*; +use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; +use crate::pairing::Engine; use crate::plonk::better_cs::utils::*; +use crate::plonk::commitments::transcript::Prng; +use crate::plonk::commitments::transparent::utils::log2_floor; use crate::plonk::domains::*; use crate::plonk::fft::cooley_tukey_ntt::*; +use crate::plonk::polynomials::*; +use crate::worker::Worker; +use crate::SynthesisError; use simple_fri::*; -use crate::plonk::commitments::transcript::Prng; -pub(crate) fn get_precomputed_x_lde( - domain_size: usize, - worker: &Worker -) -> Result, SynthesisError> { +pub(crate) fn get_precomputed_x_lde(domain_size: usize, worker: &Worker) -> Result, SynthesisError> { let coset_factor = E::Fr::multiplicative_generator(); - let mut x_poly = Polynomial::from_values(vec![ - coset_factor; - domain_size - ])?; + let mut x_poly = Polynomial::from_values(vec![coset_factor; domain_size])?; x_poly.distribute_powers(&worker, x_poly.omega); x_poly.bitreverse_enumeration(&worker); Ok(x_poly) } -pub(crate) fn get_precomputed_inverse_divisor( - vanishing_size: usize, - domain_size: usize, - worker: &Worker -) -> Result, SynthesisError> { +pub(crate) fn get_precomputed_inverse_divisor(vanishing_size: usize, domain_size: usize, worker: &Worker) -> Result, SynthesisError> { let coset_factor = E::Fr::multiplicative_generator(); - let mut vanishing_poly_inverse_bitreversed = - evaluate_vanishing_polynomial_of_degree_on_domain_size::( - vanishing_size as u64, - &coset_factor, - domain_size as u64, - &worker, - )?; + let mut vanishing_poly_inverse_bitreversed = evaluate_vanishing_polynomial_of_degree_on_domain_size::(vanishing_size as u64, &coset_factor, domain_size as u64, &worker)?; vanishing_poly_inverse_bitreversed.batch_inversion(&worker)?; vanishing_poly_inverse_bitreversed.bitreverse_enumeration(&worker); @@ -86,7 +70,7 @@ pub(crate) struct SecondPartialProverState pub(crate) struct SecondProverMessage> { pub(crate) grand_product_oracle_commitment: H::Output, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } pub(crate) struct SecondVerifierMessage { @@ -113,7 +97,7 @@ pub(crate) struct ThirdPartialProverState> pub(crate) struct ThirdProverMessage> { pub(crate) quotient_poly_oracle_commitment: H::Output, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } pub(crate) struct ThirdVerifierMessage { @@ -126,7 +110,7 @@ pub(crate) struct ThirdVerifierMessage { pub(crate) struct FourthPartialProverState> { required_domain_size: usize, non_residues: Vec, - input_values: Vec, + input_values: Vec, witness_polys_ldes: Vec>, witness_polys_in_monomial_form: Vec>, witness_multioracle_tree: BinaryTree, @@ -173,7 +157,7 @@ pub(crate) struct FifthProverMessage> { struct WitnessOpeningRequest<'a, F: PrimeField> { polynomials: Vec<&'a Polynomial>, opening_point: F, - opening_values: Vec + opening_values: Vec, } struct SetupOpeningRequest<'a, F: PrimeField> { @@ -181,7 +165,7 @@ struct SetupOpeningRequest<'a, F: PrimeField> { setup_point: F, setup_values: Vec, opening_point: F, - opening_values: Vec + opening_values: Vec, } pub struct RedshiftProver> { @@ -197,13 +181,8 @@ impl> RedshiftProver { pub(crate) fn first_step, MG: MainGateEquation>( assembly: TrivialAssembly, tree_hasher: H, - worker: &Worker, - ) -> Result<( - Self, - FirstPartialProverState, - FirstProverMessage - ), SynthesisError> - { + worker: &Worker, + ) -> Result<(Self, FirstPartialProverState, FirstProverMessage), SynthesisError> { assert!(assembly.is_finalized); let input_values = assembly.input_assingments.clone(); @@ -215,25 +194,23 @@ impl> RedshiftProver { let required_domain_size = n + 1; assert!(required_domain_size.is_power_of_two()); - let non_residues = make_non_residues::( - P::STATE_WIDTH - 1 - ); + let non_residues = make_non_residues::(P::STATE_WIDTH - 1); let (full_assignments, _) = assembly.make_state_and_witness_polynomials(&worker)?; let gate_constants = assembly.sorted_gate_constants; let sorted_gates = assembly.sorted_gates; - // Commit wire polynomials + // Commit wire polynomials let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); let mut first_message = FirstProverMessage:: { n: n, num_inputs: num_inputs, input_values: input_values.clone(), - witness_multioracle_commitment: H::placeholder_output() + witness_multioracle_commitment: H::placeholder_output(), }; let s = Self { @@ -251,17 +228,8 @@ impl> RedshiftProver { for wire_poly in full_assignments.iter() { let lde = Polynomial::from_values(wire_poly.clone())? - .ifft_using_bitreversed_ntt( - &worker, - &s.precomputed_omegas_inv, - &E::Fr::one() - )? - .bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - &s.precomputed_omegas, - &coset_factor - )?; + .ifft_using_bitreversed_ntt(&worker, &s.precomputed_omegas_inv, &E::Fr::one())? + .bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, &s.precomputed_omegas, &coset_factor)?; witness_polys_ldes.push(lde); } @@ -275,23 +243,18 @@ impl> RedshiftProver { witness_polys_unpadded_values.push(p); } - let multioracle = Multioracle::new_from_polynomials( - &witness_polys_ldes, - tree_hasher, - FRI_VALUES_PER_LEAF, - &worker - ); + let multioracle = Multioracle::new_from_polynomials(&witness_polys_ldes, tree_hasher, FRI_VALUES_PER_LEAF, &worker); let tree = multioracle.tree; first_message.witness_multioracle_commitment = tree.get_commitment(); let first_state = FirstPartialProverState:: { - required_domain_size: n+1, + required_domain_size: n + 1, non_residues: non_residues, input_values: input_values.clone(), witness_polys_ldes: witness_polys_ldes, witness_polys_unpadded_values: witness_polys_unpadded_values, - witness_multioracle_tree: tree + witness_multioracle_tree: tree, }; Ok((s, first_state, first_message)) @@ -302,13 +265,9 @@ impl> RedshiftProver { first_state: FirstPartialProverState, first_verifier_message: FirstVerifierMessage, permutation_polynomials: &Vec>, - worker: &Worker - ) -> Result<( - SecondPartialProverState, - SecondProverMessage - ), SynthesisError> - { - let FirstVerifierMessage { beta, gamma, ..} = first_verifier_message; + worker: &Worker, + ) -> Result<(SecondPartialProverState, SecondProverMessage), SynthesisError> { + let FirstVerifierMessage { beta, gamma, .. } = first_verifier_message; assert_eq!(first_state.witness_polys_unpadded_values.len(), self.state_width, "first state must containt assignment poly values"); @@ -323,10 +282,7 @@ impl> RedshiftProver { let domain = Domain::new_for_size(required_domain_size as u64)?; - let mut domain_elements = materialize_domain_elements_with_natural_enumeration( - &domain, - &worker - ); + let mut domain_elements = materialize_domain_elements_with_natural_enumeration(&domain, &worker); domain_elements.pop().expect("must pop last element for omega^i"); @@ -352,19 +308,15 @@ impl> RedshiftProver { // we take A, B, C, ... values and form (A + beta * perm_a + gamma), etc and calculate their grand product let z_den = { - assert_eq!( - permutation_polynomials.len(), - grand_products_protos_with_gamma.len() - ); + assert_eq!(permutation_polynomials.len(), grand_products_protos_with_gamma.len()); let mut grand_products_proto_it = grand_products_protos_with_gamma.into_iter(); let mut permutation_polys_it = permutation_polynomials.iter(); let mut z_2 = grand_products_proto_it.next().unwrap(); z_2.add_assign_scaled(&worker, permutation_polys_it.next().unwrap(), &beta); - for (mut p, perm) in grand_products_proto_it - .zip(permutation_polys_it) { - // permutation polynomials + for (mut p, perm) in grand_products_proto_it.zip(permutation_polys_it) { + // permutation polynomials p.add_assign_scaled(&worker, perm, &beta); z_2.mul_assign(&worker, &p); } @@ -389,21 +341,13 @@ impl> RedshiftProver { let coset_factor = E::Fr::multiplicative_generator(); - let grand_product_lde = grand_product_in_monomial_form.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - &self.precomputed_omegas, - &coset_factor - )?; + let grand_product_lde = grand_product_in_monomial_form + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, &self.precomputed_omegas, &coset_factor)?; let grand_product_ldes = vec![grand_product_lde]; - let multioracle = Multioracle::new_from_polynomials( - &grand_product_ldes, - self.tree_hasher.clone(), - FRI_VALUES_PER_LEAF, - &worker - ); + let multioracle = Multioracle::new_from_polynomials(&grand_product_ldes, self.tree_hasher.clone(), FRI_VALUES_PER_LEAF, &worker); let mut witness_polys_in_monomial_form = vec![]; for mut p in first_state.witness_polys_unpadded_values.into_iter() { @@ -429,8 +373,7 @@ impl> RedshiftProver { let message = SecondProverMessage:: { grand_product_oracle_commitment: commitment, - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok((state, message)) @@ -441,12 +384,8 @@ impl> RedshiftProver { second_state: SecondPartialProverState, second_verifier_message: SecondVerifierMessage, setup: &SetupMultioracle, - worker: &Worker - ) -> Result<( - ThirdPartialProverState, - ThirdProverMessage - ), SynthesisError> - { + worker: &Worker, + ) -> Result<(ThirdPartialProverState, ThirdProverMessage), SynthesisError> { use std::sync::Arc; let mut quotient_linearization_challenge = E::Fr::one(); @@ -501,11 +440,7 @@ impl> RedshiftProver { println!("Have {} gate selector indexes", selectors_indexes.len()); let mut selectors_range_it = selectors_indexes.into_iter(); - let mut local_scratch_space = if use_gate_selectors { - Some(global_scratch_space.clone()) - } else { - None - }; + let mut local_scratch_space = if use_gate_selectors { Some(global_scratch_space.clone()) } else { None }; for (i, (gate, constants)) in self.sorted_gates.iter().zip(self.gate_constants.iter()).enumerate() { let mut constants_iter = constants.iter(); @@ -519,23 +454,15 @@ impl> RedshiftProver { let mut base = match term.0 { Coefficient::PlusOne => one, Coefficient::MinusOne => minus_one, - Coefficient::Other => *constants_iter.next().unwrap() + Coefficient::Other => *constants_iter.next().unwrap(), }; for poly in term.1.iter() { match poly { - PolynomialInConstraint::VariablesPolynomial( - poly_num, TimeDilation(0) - ) => { + PolynomialInConstraint::VariablesPolynomial(poly_num, TimeDilation(0)) => { let poly_lde_ref = &second_state.witness_polys_ldes[*poly_num]; - let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed( - partition_factor - )?; - let scratch_space = if use_gate_selectors { - local_scratch_space.as_mut().unwrap() - } else { - &mut global_scratch_space - }; + let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed(partition_factor)?; + let scratch_space = if use_gate_selectors { local_scratch_space.as_mut().unwrap() } else { &mut global_scratch_space }; if must_refill_scratch { must_refill_scratch = false; @@ -543,31 +470,23 @@ impl> RedshiftProver { } else { scratch_space.mul_assign(&worker, &poly_lde_part); } - }, - PolynomialInConstraint::VariablesPolynomial( - poly_num, TimeDilation(dilation) - ) => { + } + PolynomialInConstraint::VariablesPolynomial(poly_num, TimeDilation(dilation)) => { let dilated_poly = if let Some(dilated_poly) = extra_precomputations_storage_by_time_dilation.get(&(*poly_num, TimeDilation(*dilation))) { dilated_poly } else { let poly_lde_ref = &second_state.witness_polys_ldes[*poly_num]; - let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed( - partition_factor - )?; + let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed(partition_factor)?; let shift = quotient_degree_factor * (*dilation); let dilated_poly = poly_lde_part.clone_shifted_assuming_bitreversed(shift, &worker)?; - + extra_precomputations_storage_by_time_dilation.insert((*poly_num, TimeDilation(*dilation)), dilated_poly); extra_precomputations_storage_by_time_dilation.get(&(*poly_num, TimeDilation(*dilation))).unwrap() }; - let scratch_space = if use_gate_selectors { - local_scratch_space.as_mut().unwrap() - } else { - &mut global_scratch_space - }; + let scratch_space = if use_gate_selectors { local_scratch_space.as_mut().unwrap() } else { &mut global_scratch_space }; if must_refill_scratch { must_refill_scratch = false; @@ -575,16 +494,12 @@ impl> RedshiftProver { } else { scratch_space.mul_assign(&worker, dilated_poly); } - }, - PolynomialInConstraint::SetupPolynomial( - str_id, poly_num, TimeDilation(0) - ) => { + } + PolynomialInConstraint::SetupPolynomial(str_id, poly_num, TimeDilation(0)) => { let id = PolyIdentifier::SetupPolynomial(str_id, *poly_num); let idx = setup.setup_ids.iter().position(|el| el == &id).unwrap(); let poly_lde_ref = &setup.polynomial_ldes[idx]; - let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed( - partition_factor - )?; + let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed(partition_factor)?; let process_public_inputs = if constant_term_index.is_some() { public_inputs_processed == false && constant_term_index.unwrap() == *poly_num @@ -592,11 +507,7 @@ impl> RedshiftProver { false }; - let scratch_space = if use_gate_selectors { - local_scratch_space.as_mut().unwrap() - } else { - &mut global_scratch_space - }; + let scratch_space = if use_gate_selectors { local_scratch_space.as_mut().unwrap() } else { &mut global_scratch_space }; if process_public_inputs { public_inputs_processed = true; @@ -608,23 +519,14 @@ impl> RedshiftProver { inputs_poly.as_mut()[idx] = input; } // go into monomial form - - let inputs_poly = inputs_poly.ifft_using_bitreversed_ntt( - &worker, - &self.precomputed_omegas_inv, - &E::Fr::one() - )?; - - let mut inputs_poly = inputs_poly.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR / partition_factor, - &self.precomputed_omegas, - &coset_factor - )?; - + + let inputs_poly = inputs_poly.ifft_using_bitreversed_ntt(&worker, &self.precomputed_omegas_inv, &E::Fr::one())?; + + let mut inputs_poly = inputs_poly.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR / partition_factor, &self.precomputed_omegas, &coset_factor)?; + // add constants selectors vector inputs_poly.add_assign(&worker, &poly_lde_part); - + if must_refill_scratch { must_refill_scratch = false; scratch_space.reuse_allocation(&inputs_poly); @@ -639,7 +541,7 @@ impl> RedshiftProver { scratch_space.mul_assign(&worker, &poly_lde_part); } } - }, + } _ => { unimplemented!() } @@ -673,9 +575,7 @@ impl> RedshiftProver { if use_gate_selectors { let selector_idx = (&mut selectors_range_it).next().expect(&format!("must get gate selector for gate {}", i)); let poly_lde_ref = &setup.polynomial_ldes[selector_idx]; - let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed( - partition_factor - )?; + let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed(partition_factor)?; global_scratch_space.mul_assign(&worker, &poly_lde_part); t.add_assign(&worker, &global_scratch_space); } @@ -683,9 +583,7 @@ impl> RedshiftProver { let mut scratch_space = global_scratch_space; - let grand_product_lde_bitreversed = second_state.grand_product_polynomial_lde[0].clone_subset_assuming_bitreversed( - partition_factor - )?; + let grand_product_lde_bitreversed = second_state.grand_product_polynomial_lde[0].clone_subset_assuming_bitreversed(partition_factor)?; let shift = quotient_degree_factor; @@ -694,7 +592,7 @@ impl> RedshiftProver { let non_residues = second_state.non_residues.clone(); // For both Z_1 and Z_2 we first check for grand products - // z*(X)(A + beta*X + gamma)(B + beta*k_1*X + gamma)(C + beta*K_2*X + gamma) - + // z*(X)(A + beta*X + gamma)(B + beta*k_1*X + gamma)(C + beta*K_2*X + gamma) - // - (A + beta*perm_a(X) + gamma)(B + beta*perm_b(X) + gamma)(C + beta*perm_c(X) + gamma)*Z(X*Omega)== 0 // we use evaluations of the polynomial X and K_i * X on a large domain's coset @@ -705,18 +603,13 @@ impl> RedshiftProver { // A + beta*X + gamma let poly_lde_ref = &second_state.witness_polys_ldes[0]; - let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed( - partition_factor - )?; + let poly_lde_part = poly_lde_ref.clone_subset_assuming_bitreversed(partition_factor)?; scratch_space.reuse_allocation(&poly_lde_part); drop(poly_lde_ref); scratch_space.add_constant(&worker, &gamma); - let x_precomp = get_precomputed_x_lde::( - quotient_degree, - &worker - )?; + let x_precomp = get_precomputed_x_lde::(quotient_degree, &worker)?; scratch_space.add_assign_scaled(&worker, &x_precomp, &beta); contrib_z.mul_assign(&worker, &scratch_space); @@ -727,9 +620,7 @@ impl> RedshiftProver { let mut factor = beta; factor.mul_assign(&non_res); - let poly_lde_part = w.clone_subset_assuming_bitreversed( - partition_factor - )?; + let poly_lde_part = w.clone_subset_assuming_bitreversed(partition_factor)?; scratch_space.reuse_allocation(&poly_lde_part); scratch_space.add_constant(&worker, &gamma); @@ -746,19 +637,15 @@ impl> RedshiftProver { // A + beta*perm_a + gamma for (w, perm_idx) in second_state.witness_polys_ldes.iter().zip(setup.permutations_ranges[0].clone()) { - let poly_lde_part = w.clone_subset_assuming_bitreversed( - partition_factor - )?; - - let perm_part = setup.polynomial_ldes[perm_idx].clone_subset_assuming_bitreversed( - partition_factor - )?; - - scratch_space.reuse_allocation(&poly_lde_part); - scratch_space.add_constant(&worker, &gamma); - scratch_space.add_assign_scaled(&worker, &perm_part, &beta); - contrib_z.mul_assign(&worker, &scratch_space); - } + let poly_lde_part = w.clone_subset_assuming_bitreversed(partition_factor)?; + + let perm_part = setup.polynomial_ldes[perm_idx].clone_subset_assuming_bitreversed(partition_factor)?; + + scratch_space.reuse_allocation(&poly_lde_part); + scratch_space.add_constant(&worker, &gamma); + scratch_space.add_assign_scaled(&worker, &perm_part, &beta); + contrib_z.mul_assign(&worker, &scratch_space); + } t.sub_assign_scaled(&worker, &contrib_z, "ient_linearization_challenge); @@ -775,12 +662,7 @@ impl> RedshiftProver { let mut z_minus_one_by_l_0 = grand_product_lde_bitreversed; z_minus_one_by_l_0.sub_constant(&worker, &E::Fr::one()); - let l_coset_lde_bitreversed = l_0.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR / partition_factor, - &self.precomputed_omegas, - &coset_factor - )?; + let l_coset_lde_bitreversed = l_0.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR / partition_factor, &self.precomputed_omegas, &coset_factor)?; z_minus_one_by_l_0.mul_assign(&worker, &l_coset_lde_bitreversed); @@ -791,19 +673,12 @@ impl> RedshiftProver { drop(scratch_space); - let divisor_inversed = get_precomputed_inverse_divisor::( - required_domain_size, - quotient_degree, - &worker - )?; + let divisor_inversed = get_precomputed_inverse_divisor::(required_domain_size, quotient_degree, &worker)?; t.mul_assign(&worker, &divisor_inversed); t.bitreverse_enumeration(&worker); - let t_poly_in_monomial_form = t.icoset_fft_for_generator( - &worker, - &E::Fr::multiplicative_generator() - ); + let t_poly_in_monomial_form = t.icoset_fft_for_generator(&worker, &E::Fr::multiplicative_generator()); fn get_degree(poly: &Polynomial) -> usize { let mut degree = poly.as_ref().len() - 1; @@ -814,7 +689,7 @@ impl> RedshiftProver { break; } } - + degree } @@ -824,22 +699,12 @@ impl> RedshiftProver { let mut t_poly_parts_ldes = vec![]; for p in t_poly_parts.iter() { - let lde = p.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - &self.precomputed_omegas, - &coset_factor - )?; + let lde = p.clone().bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, &self.precomputed_omegas, &coset_factor)?; t_poly_parts_ldes.push(lde); } - let multioracle = Multioracle::new_from_polynomials( - &t_poly_parts_ldes, - self.tree_hasher.clone(), - FRI_VALUES_PER_LEAF, - &worker - ); + let multioracle = Multioracle::new_from_polynomials(&t_poly_parts_ldes, self.tree_hasher.clone(), FRI_VALUES_PER_LEAF, &worker); let tree = multioracle.tree; let commitment = tree.get_commitment(); @@ -861,8 +726,7 @@ impl> RedshiftProver { let message = ThirdProverMessage:: { quotient_poly_oracle_commitment: commitment, - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok((state, message)) @@ -873,12 +737,8 @@ impl> RedshiftProver { third_state: ThirdPartialProverState, third_verifier_message: ThirdVerifierMessage, setup: &SetupMultioracle, - worker: &Worker - ) -> Result<( - FourthPartialProverState, - FourthProverMessage - ), SynthesisError> - { + worker: &Worker, + ) -> Result<(FourthPartialProverState, FourthProverMessage), SynthesisError> { let ThirdVerifierMessage { z, .. } = third_verifier_message; let required_domain_size = third_state.required_domain_size; @@ -919,26 +779,22 @@ impl> RedshiftProver { for term in constraint.0.iter() { for poly in term.1.iter() { match poly { - PolynomialInConstraint::VariablesPolynomial( - poly_num, TimeDilation(dilation) - ) => { - let poly_id = PolyIdentifier::VariablesPolynomial(*poly_num); + PolynomialInConstraint::VariablesPolynomial(poly_num, TimeDilation(dilation)) => { + let poly_id = PolyIdentifier::VariablesPolynomial(*poly_num); let key = TimeDilation(*dilation); let entry = dilation_maps.entry(key).or_insert(vec![]); if !entry.contains(&poly_id) { entry.push(poly_id); - } - }, - PolynomialInConstraint::SetupPolynomial( - str_id, poly_num, TimeDilation(0) - ) => { - let poly_id = PolyIdentifier::SetupPolynomial(str_id, *poly_num); + } + } + PolynomialInConstraint::SetupPolynomial(str_id, poly_num, TimeDilation(0)) => { + let poly_id = PolyIdentifier::SetupPolynomial(str_id, *poly_num); let key = TimeDilation(0); let entry = dilation_maps.entry(key).or_insert(vec![]); if !entry.contains(&poly_id) { entry.push(poly_id); } - }, + } _ => { unimplemented!() } @@ -1025,186 +881,171 @@ impl> RedshiftProver { Ok((state, message)) } - fn perform_fri> - ( - &self, - aggregation_challenge: E::Fr, - witness_opening_requests: Vec>, - setup_opening_requests: Vec>, - worker: &Worker, - prng: &mut P - ) -> Result, SynthesisError> { - let mut len = 0; - for r in witness_opening_requests.iter() { - for p in r.polynomials.iter() { - if len == 0 { - len = p.size(); - } else { - assert_eq!(p.size(), len, "poly lengths are different!"); - } + fn perform_fri>( + &self, + aggregation_challenge: E::Fr, + witness_opening_requests: Vec>, + setup_opening_requests: Vec>, + worker: &Worker, + prng: &mut P, + ) -> Result, SynthesisError> { + let mut len = 0; + for r in witness_opening_requests.iter() { + for p in r.polynomials.iter() { + if len == 0 { + len = p.size(); + } else { + assert_eq!(p.size(), len, "poly lengths are different!"); } } + } - for r in setup_opening_requests.iter() { - for p in r.polynomials.iter() { - if len == 0 { - len = p.size(); - } else { - assert_eq!(p.size(), len, "poly lengths are different!"); - } + for r in setup_opening_requests.iter() { + for p in r.polynomials.iter() { + if len == 0 { + len = p.size(); + } else { + assert_eq!(p.size(), len, "poly lengths are different!"); } } + } - assert!(len != 0); - let required_divisor_size = len; - - let mut final_aggregate = Polynomial::from_values(vec![E::Fr::zero(); required_divisor_size])?; - - let mut precomputed_bitreversed_coset_divisor = Polynomial::from_values(vec![E::Fr::one(); required_divisor_size])?; - precomputed_bitreversed_coset_divisor.distribute_powers(&worker, precomputed_bitreversed_coset_divisor.omega); - precomputed_bitreversed_coset_divisor.scale(&worker, E::Fr::multiplicative_generator()); - precomputed_bitreversed_coset_divisor.bitreverse_enumeration(&worker); - - let mut scratch_space_numerator = final_aggregate.clone(); - let mut scratch_space_denominator = final_aggregate.clone(); - - let mut alpha = E::Fr::one(); - - for witness_request in witness_opening_requests.iter() { - let z = witness_request.opening_point; - let mut minus_z = z; - minus_z.negate(); - scratch_space_denominator.reuse_allocation(&precomputed_bitreversed_coset_divisor); - scratch_space_denominator.add_constant(&worker, &minus_z); - scratch_space_denominator.batch_inversion(&worker)?; - for (poly, value) in witness_request.polynomials.iter().zip(witness_request.opening_values.iter()) { - scratch_space_numerator.reuse_allocation(&poly); - let mut v = *value; - v.negate(); - scratch_space_numerator.add_constant(&worker, &v); - scratch_space_numerator.mul_assign(&worker, &scratch_space_denominator); - if aggregation_challenge != E::Fr::one() { - scratch_space_numerator.scale(&worker, alpha); - } + assert!(len != 0); + let required_divisor_size = len; + + let mut final_aggregate = Polynomial::from_values(vec![E::Fr::zero(); required_divisor_size])?; + + let mut precomputed_bitreversed_coset_divisor = Polynomial::from_values(vec![E::Fr::one(); required_divisor_size])?; + precomputed_bitreversed_coset_divisor.distribute_powers(&worker, precomputed_bitreversed_coset_divisor.omega); + precomputed_bitreversed_coset_divisor.scale(&worker, E::Fr::multiplicative_generator()); + precomputed_bitreversed_coset_divisor.bitreverse_enumeration(&worker); + + let mut scratch_space_numerator = final_aggregate.clone(); + let mut scratch_space_denominator = final_aggregate.clone(); + + let mut alpha = E::Fr::one(); + + for witness_request in witness_opening_requests.iter() { + let z = witness_request.opening_point; + let mut minus_z = z; + minus_z.negate(); + scratch_space_denominator.reuse_allocation(&precomputed_bitreversed_coset_divisor); + scratch_space_denominator.add_constant(&worker, &minus_z); + scratch_space_denominator.batch_inversion(&worker)?; + for (poly, value) in witness_request.polynomials.iter().zip(witness_request.opening_values.iter()) { + scratch_space_numerator.reuse_allocation(&poly); + let mut v = *value; + v.negate(); + scratch_space_numerator.add_constant(&worker, &v); + scratch_space_numerator.mul_assign(&worker, &scratch_space_denominator); + if aggregation_challenge != E::Fr::one() { + scratch_space_numerator.scale(&worker, alpha); + } - final_aggregate.add_assign(&worker, &scratch_space_numerator); + final_aggregate.add_assign(&worker, &scratch_space_numerator); - alpha.mul_assign(&aggregation_challenge); - } + alpha.mul_assign(&aggregation_challenge); } + } - for setup_request in setup_opening_requests.iter() { - // for now assume a single setup point per poly and setup point is the same for all polys - // (omega - y)(omega - z) = omega^2 - (z+y)*omega + zy - - let setup_point = setup_request.setup_point; - let opening_point = setup_request.opening_point; + for setup_request in setup_opening_requests.iter() { + // for now assume a single setup point per poly and setup point is the same for all polys + // (omega - y)(omega - z) = omega^2 - (z+y)*omega + zy - let mut t0 = setup_point; - t0.add_assign(&opening_point); - t0.negate(); + let setup_point = setup_request.setup_point; + let opening_point = setup_request.opening_point; - let mut t1 = setup_point; - t1.mul_assign(&opening_point); + let mut t0 = setup_point; + t0.add_assign(&opening_point); + t0.negate(); - scratch_space_denominator.reuse_allocation(&precomputed_bitreversed_coset_divisor); - worker.scope(scratch_space_denominator.as_ref().len(), |scope, chunk| { - for den in scratch_space_denominator.as_mut().chunks_mut(chunk) { - scope.spawn(move |_| { - for d in den.iter_mut() { - let mut result = *d; - result.square(); - result.add_assign(&t1); + let mut t1 = setup_point; + t1.mul_assign(&opening_point); - let mut tmp = t0; - tmp.mul_assign(&d); + scratch_space_denominator.reuse_allocation(&precomputed_bitreversed_coset_divisor); + worker.scope(scratch_space_denominator.as_ref().len(), |scope, chunk| { + for den in scratch_space_denominator.as_mut().chunks_mut(chunk) { + scope.spawn(move |_| { + for d in den.iter_mut() { + let mut result = *d; + result.square(); + result.add_assign(&t1); - result.add_assign(&tmp); + let mut tmp = t0; + tmp.mul_assign(&d); - *d = result; - } - }); - } - }); + result.add_assign(&tmp); + + *d = result; + } + }); + } + }); - scratch_space_denominator.batch_inversion(&worker)?; + scratch_space_denominator.batch_inversion(&worker)?; - // each numerator must have a value removed of the polynomial that interpolates the following points: - // (setup_x, setup_y) - // (opening_x, opening_y) - // such polynomial is linear and has a form e.g setup_y + (X - setup_x) * (witness_y - setup_y) / (witness_x - setup_x) + // each numerator must have a value removed of the polynomial that interpolates the following points: + // (setup_x, setup_y) + // (opening_x, opening_y) + // such polynomial is linear and has a form e.g setup_y + (X - setup_x) * (witness_y - setup_y) / (witness_x - setup_x) - for ((poly, value), setup_value) in setup_request.polynomials.iter().zip(setup_request.opening_values.iter()).zip(setup_request.setup_values.iter()) { - scratch_space_numerator.reuse_allocation(&poly); + for ((poly, value), setup_value) in setup_request.polynomials.iter().zip(setup_request.opening_values.iter()).zip(setup_request.setup_values.iter()) { + scratch_space_numerator.reuse_allocation(&poly); - let intercept = setup_value; - let mut t0 = opening_point; - t0.sub_assign(&setup_point); + let intercept = setup_value; + let mut t0 = opening_point; + t0.sub_assign(&setup_point); - let mut slope = t0.inverse().expect("must exist"); - - let mut t1 = *value; - t1.sub_assign(&setup_value); + let mut slope = t0.inverse().expect("must exist"); - slope.mul_assign(&t1); + let mut t1 = *value; + t1.sub_assign(&setup_value); - worker.scope(scratch_space_numerator.as_ref().len(), |scope, chunk| { - for (num, omega) in scratch_space_numerator.as_mut().chunks_mut(chunk). - zip(precomputed_bitreversed_coset_divisor.as_ref().chunks(chunk)) { - scope.spawn(move |_| { - for (n, omega) in num.iter_mut().zip(omega.iter()) { - let mut result = *omega; - result.sub_assign(&setup_point); - result.mul_assign(&slope); - result.add_assign(&intercept); + slope.mul_assign(&t1); - n.sub_assign(&result); - } - }); - } - }); + worker.scope(scratch_space_numerator.as_ref().len(), |scope, chunk| { + for (num, omega) in scratch_space_numerator.as_mut().chunks_mut(chunk).zip(precomputed_bitreversed_coset_divisor.as_ref().chunks(chunk)) { + scope.spawn(move |_| { + for (n, omega) in num.iter_mut().zip(omega.iter()) { + let mut result = *omega; + result.sub_assign(&setup_point); + result.mul_assign(&slope); + result.add_assign(&intercept); - scratch_space_numerator.mul_assign(&worker, &scratch_space_denominator); - if aggregation_challenge != E::Fr::one() { - scratch_space_numerator.scale(&worker, alpha); + n.sub_assign(&result); + } + }); } + }); - final_aggregate.add_assign(&worker, &scratch_space_numerator); - - alpha.mul_assign(&aggregation_challenge); + scratch_space_numerator.mul_assign(&worker, &scratch_space_denominator); + if aggregation_challenge != E::Fr::one() { + scratch_space_numerator.scale(&worker, alpha); } + + final_aggregate.add_assign(&worker, &scratch_space_numerator); + + alpha.mul_assign(&aggregation_challenge); } + } - let fri_combiner = FriCombiner::initialize_for_domain_size( - required_divisor_size, - LDE_FACTOR, - 1, - E::Fr::multiplicative_generator(), - FRI_VALUES_PER_LEAF, - self.tree_hasher.clone(), - ); + let fri_combiner = FriCombiner::initialize_for_domain_size(required_divisor_size, LDE_FACTOR, 1, E::Fr::multiplicative_generator(), FRI_VALUES_PER_LEAF, self.tree_hasher.clone()); - println!("Start making FRI oracles"); + println!("Start making FRI oracles"); - let oracles = fri_combiner.perform_fri_assuming_bitreversed( - &final_aggregate.as_ref(), - prng, - &worker - )?; + let oracles = fri_combiner.perform_fri_assuming_bitreversed(&final_aggregate.as_ref(), prng, &worker)?; - Ok(oracles) + Ok(oracles) } - pub(crate) fn fifth_step_from_fourth_step>( &self, fourth_state: FourthPartialProverState, fourth_verifier_message: FourthVerifierMessage, setup: &SetupMultioracle, prng: &mut P, - worker: &Worker - ) -> Result, SynthesisError> - { + worker: &Worker, + ) -> Result, SynthesisError> { let FourthVerifierMessage { z, v, .. } = fourth_verifier_message; let required_domain_size = fourth_state.required_domain_size; @@ -1236,8 +1077,9 @@ impl> RedshiftProver { let range_of_permutation_polys = setup.permutations_ranges[0].clone(); - for (value, perm_ref) in setup.setup_poly_values[range_of_permutation_polys.clone()].iter() - .zip(setup.polynomial_ldes[range_of_permutation_polys].iter()) + for (value, perm_ref) in setup.setup_poly_values[range_of_permutation_polys.clone()] + .iter() + .zip(setup.polynomial_ldes[range_of_permutation_polys].iter()) { setup_values.push(*value); setup_poly_refs.push(perm_ref); @@ -1263,7 +1105,7 @@ impl> RedshiftProver { setup_point: setup.setup_point, setup_values: setup_values, opening_point: z, - opening_values: opening_values + opening_values: opening_values, }; setup_opening_requests.push(request); @@ -1283,15 +1125,13 @@ impl> RedshiftProver { for term in constraint.0.iter() { for poly in term.1.iter() { match poly { - PolynomialInConstraint::VariablesPolynomial( - poly_num, TimeDilation(dil) - ) => { + PolynomialInConstraint::VariablesPolynomial(poly_num, TimeDilation(dil)) => { if dil == &dilation { if !per_dilation_set.contains(poly_num) { per_dilation_set.push(*poly_num) } } - }, + } _ => {} } } @@ -1306,9 +1146,7 @@ impl> RedshiftProver { for id in per_dilation_set.into_iter() { let poly_ref = &fourth_state.witness_polys_ldes[id]; - let mut tmp: Vec<_> = storage.iter().filter( - |el| el.0 == id - ).collect(); + let mut tmp: Vec<_> = storage.iter().filter(|el| el.0 == id).collect(); assert_eq!(tmp.len(), 1); let value = tmp.pop().unwrap().1; @@ -1328,19 +1166,13 @@ impl> RedshiftProver { let request = WitnessOpeningRequest { polynomials: opening_refs, opening_point: open_at, - opening_values: opening_values + opening_values: opening_values, }; witness_opening_requests.push(request); } - let fri_oracles_set = self.perform_fri( - v, - witness_opening_requests, - setup_opening_requests, - &worker, - prng - )?; + let fri_oracles_set = self.perform_fri(v, witness_opening_requests, setup_opening_requests, &worker, prng)?; let commitments = fri_oracles_set.intermediate_roots.clone(); let coeffs = fri_oracles_set.final_coefficients.clone(); @@ -1356,7 +1188,7 @@ impl> RedshiftProver { { let idx_start = 0; - let indexes: Vec = (idx_start..(idx_start+FRI_VALUES_PER_LEAF)).collect(); + let indexes: Vec = (idx_start..(idx_start + FRI_VALUES_PER_LEAF)).collect(); let setup_tree_params = setup.tree.params.clone(); let witness_tree_params = fourth_state.witness_multioracle_tree.params.clone(); @@ -1369,100 +1201,55 @@ impl> RedshiftProver { let setup_query = setup.tree.produce_multiquery( indexes.clone(), - setup.polynomial_ldes.len(), - &Multioracle::::combine_leafs( - &setup.polynomial_ldes, - FRI_VALUES_PER_LEAF, - &worker, - ) + setup.polynomial_ldes.len(), + &Multioracle::::combine_leafs(&setup.polynomial_ldes, FRI_VALUES_PER_LEAF, &worker), ); let witness_query = fourth_state.witness_multioracle_tree.produce_multiquery( indexes.clone(), - fourth_state.witness_polys_ldes.len(), - &Multioracle::::combine_leafs( - &fourth_state.witness_polys_ldes, - FRI_VALUES_PER_LEAF, - &worker, - ) + fourth_state.witness_polys_ldes.len(), + &Multioracle::::combine_leafs(&fourth_state.witness_polys_ldes, FRI_VALUES_PER_LEAF, &worker), ); let grand_product_query = fourth_state.grand_product_polynomial_multioracle_tree.produce_multiquery( indexes.clone(), - fourth_state.grand_product_polynomial_lde.len(), - &Multioracle::::combine_leafs( - &fourth_state.grand_product_polynomial_lde, - FRI_VALUES_PER_LEAF, - &worker, - ) + fourth_state.grand_product_polynomial_lde.len(), + &Multioracle::::combine_leafs(&fourth_state.grand_product_polynomial_lde, FRI_VALUES_PER_LEAF, &worker), ); let quotient_query = fourth_state.t_poly_parts_multioracle_tree.produce_multiquery( indexes.clone(), - fourth_state.t_poly_parts_ldes.len(), - &Multioracle::::combine_leafs( - &fourth_state.t_poly_parts_ldes, - FRI_VALUES_PER_LEAF, - &worker, - ) + fourth_state.t_poly_parts_ldes.len(), + &Multioracle::::combine_leafs(&fourth_state.t_poly_parts_ldes, FRI_VALUES_PER_LEAF, &worker), ); let mut fri_queries = vec![]; - for ((vals, tree), params) in fri_oracles_set.intermediate_leaf_values.iter() + for ((vals, tree), params) in fri_oracles_set + .intermediate_leaf_values + .iter() .zip(fri_oracles_set.intermediate_oracles.iter()) - .zip(fri_subtrees_params.iter()) - { - - let idx_start = 0; - let indexes: Vec = (idx_start..(idx_start + params.values_per_leaf)).collect(); - - let query = tree.produce_query( - indexes, - &vals - ); - - fri_queries.push(query); + .zip(fri_subtrees_params.iter()) + { + let idx_start = 0; + let indexes: Vec = (idx_start..(idx_start + params.values_per_leaf)).collect(); + + let query = tree.produce_query(indexes, &vals); + + fri_queries.push(query); } let hasher = setup.tree.tree_hasher.clone(); - let _ = BinaryTree::verify_multiquery( - &setup.tree.get_commitment(), - &setup_query, - &setup_tree_params, - &hasher - ); + let _ = BinaryTree::verify_multiquery(&setup.tree.get_commitment(), &setup_query, &setup_tree_params, &hasher); - let _ = BinaryTree::verify_multiquery( - &setup.tree.get_commitment(), - &witness_query, - &witness_tree_params, - &hasher - ); + let _ = BinaryTree::verify_multiquery(&setup.tree.get_commitment(), &witness_query, &witness_tree_params, &hasher); - let _ = BinaryTree::verify_multiquery( - &setup.tree.get_commitment(), - &grand_product_query, - &grand_product_tree_params, - &hasher - ); + let _ = BinaryTree::verify_multiquery(&setup.tree.get_commitment(), &grand_product_query, &grand_product_tree_params, &hasher); + let _ = BinaryTree::verify_multiquery(&setup.tree.get_commitment(), "ient_query, &t_poly_tree_params, &hasher); - let _ = BinaryTree::verify_multiquery( - &setup.tree.get_commitment(), - "ient_query, - &t_poly_tree_params, - &hasher - ); - - for (query, params) in fri_queries.into_iter() - .zip(fri_subtrees_params.iter()) { - let _ = BinaryTree::verify_query( - &setup.tree.get_commitment(), - &query, - ¶ms, - &hasher - ); + for (query, params) in fri_queries.into_iter().zip(fri_subtrees_params.iter()) { + let _ = BinaryTree::verify_query(&setup.tree.get_commitment(), &query, ¶ms, &hasher); } } diff --git a/crates/bellman/src/plonk/better_better_cs/redshift/setup.rs b/crates/bellman/src/plonk/better_better_cs/redshift/setup.rs index b86ac77..37dad4f 100644 --- a/crates/bellman/src/plonk/better_better_cs/redshift/setup.rs +++ b/crates/bellman/src/plonk/better_better_cs/redshift/setup.rs @@ -1,13 +1,13 @@ -use crate::pairing::{Engine}; +use super::super::cs_old::*; +use super::binary_tree::{BinaryTree, BinaryTreeParams}; +use super::multioracle::Multioracle; +use super::tree_hash::*; +use super::*; use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use crate::worker::Worker; +use crate::pairing::Engine; use crate::plonk::commitments::transparent::utils::log2_floor; -use super::*; -use super::tree_hash::*; -use super::binary_tree::{BinaryTree, BinaryTreeParams}; use crate::plonk::polynomials::*; -use super::multioracle::Multioracle; -use super::super::cs_old::*; +use crate::worker::Worker; use crate::SynthesisError; pub struct SetupMultioracle> { @@ -18,7 +18,7 @@ pub struct SetupMultioracle> { pub setup_ids: Vec, pub permutations_ranges: Vec>, pub gate_selectors_indexes: Vec, - pub tree: BinaryTree + pub tree: BinaryTree, } pub const LDE_FACTOR: usize = 16; @@ -28,7 +28,7 @@ impl> SetupMultioracle { pub fn from_assembly, MG: MainGateEquation>( assembly: TrivialAssembly, tree_hasher: H, - worker: &Worker + worker: &Worker, ) -> Result<(Self, Vec>), SynthesisError> { use crate::plonk::fft::cooley_tukey_ntt::*; @@ -46,8 +46,8 @@ impl> SetupMultioracle { let mut mononial_forms = vec![]; let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); - + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); + for id in ids.iter() { let mut setup_poly = storage.remove(&id).expect(&format!("must contain a poly for id {:?}", id)); setup_poly.pad_to_domain()?; @@ -96,12 +96,7 @@ impl> SetupMultioracle { println!("Gate selectors LDEs completed"); - let multioracle = Multioracle::::new_from_polynomials( - &setup_polys, - tree_hasher, - FRI_VALUES_PER_LEAF, - &worker - ); + let multioracle = Multioracle::::new_from_polynomials(&setup_polys, tree_hasher, FRI_VALUES_PER_LEAF, &worker); let tree = multioracle.tree; @@ -128,4 +123,3 @@ impl> SetupMultioracle { Ok((setup, permutations)) } } - diff --git a/crates/bellman/src/plonk/better_better_cs/redshift/simple_fri/mod.rs b/crates/bellman/src/plonk/better_better_cs/redshift/simple_fri/mod.rs index 111b82f..8b23287 100644 --- a/crates/bellman/src/plonk/better_better_cs/redshift/simple_fri/mod.rs +++ b/crates/bellman/src/plonk/better_better_cs/redshift/simple_fri/mod.rs @@ -3,19 +3,19 @@ // pub mod verifier; // pub mod precomputation; -use crate::SynthesisError; -use crate::worker::Worker; use crate::pairing::ff::{Field, PrimeField}; use crate::pairing::Engine; use crate::plonk::commitments::transcript::*; +use crate::worker::Worker; +use crate::SynthesisError; use crate::plonk::better_better_cs::redshift::binary_tree::*; use crate::plonk::better_better_cs::redshift::tree_hash::*; -use crate::plonk::polynomials::*; use crate::plonk::commitments::transcript::Prng; use crate::plonk::fft::cooley_tukey_ntt::*; +use crate::plonk::polynomials::*; -pub struct FriCombiner> { +pub struct FriCombiner> { precomputations: OmegasInvBitreversed, fri_domain_size: usize, lde_factor: usize, @@ -26,23 +26,16 @@ pub struct FriCombiner> { coset_factor: E::Fr, } -pub struct FriOraclesSet> { +pub struct FriOraclesSet> { pub intermediate_oracles: Vec>, pub intermediate_roots: Vec, pub intermediate_leaf_values: Vec>, pub intermediate_challenges: Vec>, - pub final_coefficients: Vec + pub final_coefficients: Vec, } impl> FriCombiner { - pub fn initialize_for_domain_size( - size: usize, - lde_factor: usize, - output_coeffs_at_degree_plus_one: usize, - coset_factor: E::Fr, - optimal_values_per_leaf: usize, - hasher: H - ) -> Self { + pub fn initialize_for_domain_size(size: usize, lde_factor: usize, output_coeffs_at_degree_plus_one: usize, coset_factor: E::Fr, optimal_values_per_leaf: usize, hasher: H) -> Self { assert!(output_coeffs_at_degree_plus_one.is_power_of_two()); assert!(lde_factor.is_power_of_two()); @@ -74,16 +67,11 @@ impl> FriCombiner { folding_schedule: schedule, tree_hasher: hasher, optimal_values_per_leaf, - coset_factor + coset_factor, } } - pub fn perform_fri_assuming_bitreversed>( - &self, - lde_values: &[E::Fr], - prng: &mut P, - worker: &Worker, - ) -> Result, SynthesisError> { + pub fn perform_fri_assuming_bitreversed>(&self, lde_values: &[E::Fr], prng: &mut P, worker: &Worker) -> Result, SynthesisError> { let mut coset_schedule_index = 0; let coset_factor = self.folding_schedule[coset_schedule_index]; @@ -102,9 +90,15 @@ impl> FriCombiner { let two_inv = two.inverse().expect("should exist"); let initial_degree_plus_one = initial_domain_size / self.lde_factor; - assert_eq!(initial_degree_plus_one / total_wrap_factor, self.output_coeffs_at_degree_plus_one, - "number of FRI round does not match the ouput degree: initial degree+1 = {}, wrapping factor {}, output at degree+1 = {}", - initial_degree_plus_one, total_wrap_factor, self.output_coeffs_at_degree_plus_one); + assert_eq!( + initial_degree_plus_one / total_wrap_factor, + self.output_coeffs_at_degree_plus_one, + "number of FRI round does not match the ouput degree: \ + initial degree+1 = {}, wrapping factor {}, output at degree+1 = {}", + initial_degree_plus_one, + total_wrap_factor, + self.output_coeffs_at_degree_plus_one + ); let mut intermediate_oracles = vec![]; let mut intermediate_values = vec![]; @@ -141,7 +135,7 @@ impl> FriCombiner { let num_steps = self.folding_schedule.len(); // we do NOT need to make the first (largest) tree cause it's values are simulated - // so we will cover the first step later on separately + // so we will cover the first step later on separately for (fri_step, coset_factor) in self.folding_schedule.iter().enumerate() { let coset_factor = *coset_factor; let wrapping_factor = 1 << coset_factor; @@ -154,12 +148,12 @@ impl> FriCombiner { // intermediate(omega*) intermediate(-omega*) // / \ / \ // this(omega) this(-omega) this(omega') this(-omega') - // + // // so omega* = omega^2i. omega' = sqrt(-omega^2i) = sqrt(omega^(N/2 + 2i)) = omega^N/4 + i - // + // // we expect values to come bitreversed, so this(omega) and this(-omega) are always adjustent to each other // because in normal emumeration it would be elements b0XYZ and b1XYZ, and now it's bZYX0 and bZYX1 - // + // // this(omega^(N/4 + i)) for b00YZ has a form b01YZ, so bitreversed it's bZY00 and bZY10 // this(-omega^(N/4 + i)) obviously has bZY11, so they are all near in initial values @@ -167,12 +161,12 @@ impl> FriCombiner { for (i, v) in next_values.chunks_mut(chunk).enumerate() { let next_domain_challenges = next_domain_challenges.clone(); scope.spawn(move |_| { - let initial_k = i*chunk; + let initial_k = i * chunk; let mut this_level_values = Vec::with_capacity(wrapping_factor); let mut next_level_values = vec![E::Fr::zero(); wrapping_factor]; for (j, v) in v.iter_mut().enumerate() { let batch_id = initial_k + j; - let values_offset = batch_id*wrapping_factor; + let values_offset = batch_id * wrapping_factor; for (wrapping_step, challenge) in next_domain_challenges.iter().enumerate() { let base_omega_idx = (batch_id * wrapping_factor) >> (1 + wrapping_step); let expected_this_level_values = wrapping_factor >> wrapping_step; @@ -235,15 +229,9 @@ impl> FriCombiner { this_domain_size = next_domain_size; let coset_factor = self.folding_schedule[coset_schedule_index]; - let tree_params = BinaryTreeParams { - values_per_leaf: (1 << coset_factor) - }; + let tree_params = BinaryTreeParams { values_per_leaf: (1 << coset_factor) }; - let intermediate_oracle = BinaryTree::create( - &next_values, - self.tree_hasher.clone(), - &tree_params - ); + let intermediate_oracle = BinaryTree::create(&next_values, self.tree_hasher.clone(), &tree_params); let root = intermediate_oracle.get_commitment(); let num_challenges = coset_factor; @@ -260,16 +248,16 @@ impl> FriCombiner { challenges.push(next_domain_challenges.clone()); intermediate_roots.push(root); intermediate_oracles.push(intermediate_oracle); - } + } intermediate_values.push(next_values); - values_slice = intermediate_values.last().expect("is something").as_ref(); + values_slice = intermediate_values.last().expect("is something").as_ref(); } assert_eq!(challenges.len(), num_steps); - assert_eq!(intermediate_roots.len(), num_steps-1); - assert_eq!(intermediate_oracles.len(), num_steps-1); + assert_eq!(intermediate_roots.len(), num_steps - 1); + assert_eq!(intermediate_oracles.len(), num_steps - 1); assert_eq!(intermediate_values.len(), num_steps); let mut final_poly_values = Polynomial::from_values(values_slice.to_vec())?; @@ -287,7 +275,7 @@ impl> FriCombiner { if c.is_zero() { degree -= 1; } else { - break + break; } } @@ -300,7 +288,7 @@ impl> FriCombiner { intermediate_roots, intermediate_leaf_values: intermediate_values, intermediate_challenges: challenges, - final_coefficients: final_poly_coeffs + final_coefficients: final_poly_coeffs, }; Ok(set) diff --git a/crates/bellman/src/plonk/better_better_cs/setup/mod.rs b/crates/bellman/src/plonk/better_better_cs/setup/mod.rs index e1fdf0f..c6dc4ac 100644 --- a/crates/bellman/src/plonk/better_better_cs/setup/mod.rs +++ b/crates/bellman/src/plonk/better_better_cs/setup/mod.rs @@ -38,10 +38,10 @@ pub struct Setup> { pub non_residues: Vec, - #[serde(skip_serializing,skip_deserializing, default)] + #[serde(skip_serializing, skip_deserializing, default)] #[serde(bound(serialize = ""))] #[serde(bound(deserialize = ""))] - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl> std::fmt::Debug for Setup { @@ -70,14 +70,14 @@ impl> Setup { gate_setup_monomials: vec![], gate_selectors_monomials: vec![], permutation_monomials: vec![], - + total_lookup_entries_length: 0, lookup_selector_monomial: None, lookup_tables_monomials: vec![], lookup_table_type_monomial: None, non_residues: vec![], - - _marker: std::marker::PhantomData + + _marker: std::marker::PhantomData, } } @@ -161,10 +161,10 @@ pub struct VerificationKey> { pub non_residues: Vec, pub g2_elements: [E::G2Affine; 2], - #[serde(skip_serializing,skip_deserializing, default)] + #[serde(skip_serializing, skip_deserializing, default)] #[serde(bound(serialize = ""))] #[serde(bound(deserialize = ""))] - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl> std::fmt::Debug for VerificationKey { @@ -206,11 +206,7 @@ impl> VerificationKey { } } - pub fn from_setup( - setup: &Setup, - worker: &Worker, - crs: &Crs, - ) -> Result { + pub fn from_setup(setup: &Setup, worker: &Worker, crs: &Crs) -> Result { let mut new = Self { n: setup.n, num_inputs: setup.num_inputs, @@ -224,7 +220,7 @@ impl> VerificationKey { lookup_selector_commitment: None, lookup_tables_commitments: vec![], lookup_table_type_commitment: None, - + non_residues: vec![], g2_elements: [crs.g2_monomial_bases[0], crs.g2_monomial_bases[1]], @@ -236,7 +232,9 @@ impl> VerificationKey { (&setup.gate_selectors_monomials, &mut new.gate_selectors_commitments), (&setup.permutation_monomials, &mut new.permutation_commitments), (&setup.lookup_tables_monomials, &mut new.lookup_tables_commitments), - ].into_iter() { + ] + .into_iter() + { for p in p.iter() { let commitment = commit_using_monomials(p, &crs, &worker)?; c.push(commitment); @@ -369,5 +367,5 @@ impl<'a, E: Engine> AssembledPolynomialStorageForMonomialForms<'a, E> { } Ok(()) - } -} \ No newline at end of file + } +} diff --git a/crates/bellman/src/plonk/better_better_cs/trees/binary_tree.rs b/crates/bellman/src/plonk/better_better_cs/trees/binary_tree.rs index b2efede..6b53bc8 100644 --- a/crates/bellman/src/plonk/better_better_cs/trees/binary_tree.rs +++ b/crates/bellman/src/plonk/better_better_cs/trees/binary_tree.rs @@ -1,24 +1,24 @@ -use crate::pairing::{Engine}; +use super::tree_hash::*; +use super::*; use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; -use crate::worker::Worker; +use crate::pairing::Engine; use crate::plonk::commitments::transparent::utils::log2_floor; -use super::*; -use super::tree_hash::*; +use crate::worker::Worker; #[derive(Debug)] pub struct BinaryTree> { - pub (crate) size: usize, - pub (crate) num_leafs: usize, - pub (crate) num_combined: usize, - pub (crate) nodes: Vec, - pub (crate) params: BinaryTreeParams, - pub (crate) tree_hasher: H, - _marker: std::marker::PhantomData + pub(crate) size: usize, + pub(crate) num_leafs: usize, + pub(crate) num_combined: usize, + pub(crate) nodes: Vec, + pub(crate) params: BinaryTreeParams, + pub(crate) tree_hasher: H, + _marker: std::marker::PhantomData, } #[derive(Clone, PartialEq, Eq, Debug)] pub struct BinaryTreeParams { - pub values_per_leaf: usize + pub values_per_leaf: usize, } use std::time::Instant; @@ -58,12 +58,7 @@ impl> BinaryTree { self.num_leafs } - pub fn create_from_combined_leafs( - leafs: &[Vec<&[E::Fr]>], - num_combined: usize, - tree_hasher: H, - params: &BinaryTreeParams - ) -> Self { + pub fn create_from_combined_leafs(leafs: &[Vec<&[E::Fr]>], num_combined: usize, tree_hasher: H, params: &BinaryTreeParams) -> Self { let values_per_leaf = params.values_per_leaf; let num_leafs = leafs.len(); let values_per_leaf_supplied = leafs[0].len() * leafs[0][0].len(); @@ -85,11 +80,10 @@ impl> BinaryTree { { worker.scope(leaf_hashes.len(), |scope, chunk| { - for (i, lh) in leaf_hashes.chunks_mut(chunk) - .enumerate() { + for (i, lh) in leaf_hashes.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { let mut scratch_space = Vec::with_capacity(values_per_leaf); - let base_idx = i*chunk; + let base_idx = i * chunk; for (j, lh) in lh.iter_mut().enumerate() { // idx is index of the leaf let idx = base_idx + j; @@ -115,15 +109,14 @@ impl> BinaryTree { // separately hash last level, which hashes leaf hashes into first nodes { - let _level = num_levels-1; + let _level = num_levels - 1; let inputs = &mut leaf_hashes[..]; - let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { let mut hash_input = [H::placeholder_output(); 2]; for (o, i) in o.iter_mut().zip(i.chunks(2)) { @@ -136,16 +129,15 @@ impl> BinaryTree { }); } - for _level in (0..(num_levels-1)).rev() { + for _level in (0..(num_levels - 1)).rev() { // do the trick - split - let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); let (_, outputs) = next_levels.split_at_mut(next_levels.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { let mut hash_input = [H::placeholder_output(); 2]; for (o, i) in o.iter_mut().zip(i.chunks(2)) { @@ -167,9 +159,8 @@ impl> BinaryTree { num_combined, tree_hasher: tree_hasher, params: params.clone(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } - } pub(crate) fn create(values: &[E::Fr], tree_hasher: H, params: &BinaryTreeParams) -> Self { @@ -194,10 +185,9 @@ impl> BinaryTree { { worker.scope(leaf_hashes.len(), |scope, chunk| { - for (i, lh) in leaf_hashes.chunks_mut(chunk) - .enumerate() { + for (i, lh) in leaf_hashes.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let base_idx = i*chunk; + let base_idx = i * chunk; for (j, lh) in lh.iter_mut().enumerate() { let idx = base_idx + j; let values_start = idx * values_per_leaf; @@ -216,15 +206,14 @@ impl> BinaryTree { // separately hash last level, which hashes leaf hashes into first nodes { - let _level = num_levels-1; + let _level = num_levels - 1; let inputs = &mut leaf_hashes[..]; - let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { let mut hash_input = [H::placeholder_output(); 2]; for (o, i) in o.iter_mut().zip(i.chunks(2)) { @@ -237,16 +226,15 @@ impl> BinaryTree { }); } - for _level in (0..(num_levels-1)).rev() { + for _level in (0..(num_levels - 1)).rev() { // do the trick - split - let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); let (_, outputs) = next_levels.split_at_mut(next_levels.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { let mut hash_input = [H::placeholder_output(); 2]; for (o, i) in o.iter_mut().zip(i.chunks(2)) { @@ -268,7 +256,7 @@ impl> BinaryTree { num_combined: 1, tree_hasher: tree_hasher, params: params.clone(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } @@ -280,17 +268,19 @@ impl> BinaryTree { // we never expect that query is mis-alligned, so check it debug_assert!(indexes[0] % self.params.values_per_leaf == 0); debug_assert!(indexes.len() == self.params.values_per_leaf); - debug_assert!(indexes == (indexes[0]..(indexes[0]+self.params.values_per_leaf)).collect::>()); + debug_assert!(indexes == (indexes[0]..(indexes[0] + self.params.values_per_leaf)).collect::>()); debug_assert!(*indexes.last().expect("is some") < self.size()); debug_assert!(*indexes.last().expect("is some") < values.len()); - let query_values = Vec::from(&values[indexes[0]..(indexes[0]+self.params.values_per_leaf)]); + let query_values = Vec::from(&values[indexes[0]..(indexes[0] + self.params.values_per_leaf)]); let leaf_index = indexes[0] / self.params.values_per_leaf; let pair_index = leaf_index ^ 1; - let leaf_pair_hash = self.tree_hasher.leaf_hash(&values[(pair_index*self.params.values_per_leaf)..((pair_index+1)*self.params.values_per_leaf)]); + let leaf_pair_hash = self + .tree_hasher + .leaf_hash(&values[(pair_index * self.params.values_per_leaf)..((pair_index + 1) * self.params.values_per_leaf)]); let path = self.make_full_path(leaf_index, leaf_pair_hash); @@ -301,15 +291,10 @@ impl> BinaryTree { } } - pub fn produce_multiquery( - &self, - indexes: Vec, - num_combined: usize, - leafs: &[Vec<&[E::Fr]>] - ) -> MultiQuery { + pub fn produce_multiquery(&self, indexes: Vec, num_combined: usize, leafs: &[Vec<&[E::Fr]>]) -> MultiQuery { // debug_assert!(indexes[0] % self.params.values_per_leaf == 0); // debug_assert!(indexes.len() == self.params.values_per_leaf); - debug_assert!(indexes == (indexes[0]..(indexes[0]+(self.params.values_per_leaf/self.num_combined))).collect::>()); + debug_assert!(indexes == (indexes[0]..(indexes[0] + (self.params.values_per_leaf / self.num_combined))).collect::>()); debug_assert!(*indexes.last().expect("is some") < self.size()); debug_assert!(leafs[0].len() == num_combined); @@ -345,12 +330,7 @@ impl> BinaryTree { } } - pub fn verify_query( - commitment: &H::Output, - query: &Query, - params: &BinaryTreeParams, - tree_hasher: &H - ) -> bool { + pub fn verify_query(commitment: &H::Output, query: &Query, params: &BinaryTreeParams, tree_hasher: &H) -> bool { if query.values().len() != params.values_per_leaf { return false; } @@ -376,12 +356,7 @@ impl> BinaryTree { &hash == commitment } - pub fn verify_multiquery( - commitment: &H::Output, - query: &MultiQuery, - params: &BinaryTreeParams, - tree_hasher: &H - ) -> bool { + pub fn verify_multiquery(commitment: &H::Output, query: &MultiQuery, params: &BinaryTreeParams, tree_hasher: &H) -> bool { let values = query.values_flattened(); if values.len() != params.values_per_leaf { return false; @@ -467,4 +442,4 @@ impl> MultiQuery { self.num_combined } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_better_cs/trees/mod.rs b/crates/bellman/src/plonk/better_better_cs/trees/mod.rs index 940ffbb..b98eaec 100644 --- a/crates/bellman/src/plonk/better_better_cs/trees/mod.rs +++ b/crates/bellman/src/plonk/better_better_cs/trees/mod.rs @@ -1,2 +1,2 @@ +pub mod binary_tree; pub mod tree_hash; -pub mod binary_tree; \ No newline at end of file diff --git a/crates/bellman/src/plonk/better_better_cs/trees/tree_hash.rs b/crates/bellman/src/plonk/better_better_cs/trees/tree_hash.rs index d0cc19b..78a61df 100644 --- a/crates/bellman/src/plonk/better_better_cs/trees/tree_hash.rs +++ b/crates/bellman/src/plonk/better_better_cs/trees/tree_hash.rs @@ -1,7 +1,7 @@ use crate::pairing::ff::{Field, PrimeField}; pub trait BinaryTreeHasher: Sized + Send + Sync + Clone { - type Output: Sized + Clone + Copy + Send + Sync + PartialEq + Eq; + type Output: Sized + Clone + Copy + Send + Sync + PartialEq + Eq; fn placeholder_output() -> Self::Output; fn leaf_hash(&self, input: &[F]) -> Self::Output; diff --git a/crates/bellman/src/plonk/better_better_cs/utils.rs b/crates/bellman/src/plonk/better_better_cs/utils.rs index 202f423..8454640 100644 --- a/crates/bellman/src/plonk/better_better_cs/utils.rs +++ b/crates/bellman/src/plonk/better_better_cs/utils.rs @@ -1,6 +1,6 @@ use crate::pairing::ff::PrimeField; -use crate::worker::Worker; use crate::plonk::domains::*; +use crate::worker::Worker; use crate::SynthesisError; use crate::plonk::polynomials::*; @@ -12,8 +12,7 @@ pub trait FieldBinop: 'static + Copy + Clone + Send + Sync + std: pub(crate) fn binop_over_slices>(worker: &Worker, binop: &B, dest: &mut [F], source: &[F]) { assert_eq!(dest.len(), source.len()); worker.scope(dest.len(), |scope, chunk| { - for (dest, source) in dest.chunks_mut(chunk) - .zip(source.chunks(chunk)) { + for (dest, source) in dest.chunks_mut(chunk).zip(source.chunks(chunk)) { scope.spawn(move |_| { for (dest, source) in dest.iter_mut().zip(source.iter()) { binop.apply(dest, source); @@ -30,19 +29,17 @@ impl FieldBinop for BinopAddAssign { #[inline(always)] fn apply(&self, dest: &mut F, source: &F) { dest.add_assign(source); - } + } } #[derive(Clone, Copy, Debug)] -pub struct BinopAddAssignScaled{ - pub scale: F +pub struct BinopAddAssignScaled { + pub scale: F, } impl BinopAddAssignScaled { pub fn new(scale: F) -> Self { - Self { - scale - } + Self { scale } } } @@ -53,7 +50,7 @@ impl FieldBinop for BinopAddAssignScaled { tmp.mul_assign(&source); dest.add_assign(&tmp); - } + } } pub(crate) fn get_degree(poly: &Polynomial) -> usize { @@ -69,9 +66,9 @@ pub(crate) fn get_degree(poly: &Polynomial) -> u degree } -pub (crate) fn calculate_inverse_vanishing_polynomial_with_last_point_cut( - worker: &Worker, - poly_size:usize, +pub(crate) fn calculate_inverse_vanishing_polynomial_with_last_point_cut( + worker: &Worker, + poly_size: usize, vahisning_size: usize, coset_factor: F, ) -> Result, SynthesisError> { @@ -101,7 +98,7 @@ pub (crate) fn calculate_inverse_vanishing_polynomial_with_last_point_cut::from_values(vec![shift; poly_size])?; // elements are h^size - 1, (hg)^size - 1, (hg^2)^size - 1, ... @@ -114,4 +111,4 @@ pub (crate) fn calculate_inverse_vanishing_polynomial_with_last_point_cut, T: Transcript>( - vk: &VerificationKey, - proof: &Proof, - transcript_params: Option, -) -> Result { +pub fn verify, T: Transcript>(vk: &VerificationKey, proof: &Proof, transcript_params: Option) -> Result { let ((pair_with_generator, pair_with_x), success) = aggregate::<_, _, T>(vk, proof, transcript_params)?; if !success { - return Ok(false) + return Ok(false); } use crate::pairing::CurveAffine; - let valid = E::final_exponentiation( - &E::miller_loop(&[ - (&pair_with_generator.prepare(), &vk.g2_elements[0].prepare()), - (&pair_with_x.prepare(), &vk.g2_elements[1].prepare()) - ]) - ).ok_or(SynthesisError::Unsatisfiable)? == E::Fqk::one(); + let valid = E::final_exponentiation(&E::miller_loop(&[ + (&pair_with_generator.prepare(), &vk.g2_elements[0].prepare()), + (&pair_with_x.prepare(), &vk.g2_elements[1].prepare()), + ])) + .ok_or(SynthesisError::Unsatisfiable)? + == E::Fqk::one(); Ok(valid) } @@ -49,24 +45,20 @@ fn safe_assert(must_be_true: bool) -> Result<(), SynthesisError> { } fn safe_assert_eq(a: T, b: T) -> Result<(), SynthesisError> { - safe_assert(a==b) + safe_assert(a == b) } pub fn aggregate, T: Transcript>( - vk: &VerificationKey, + vk: &VerificationKey, proof: &Proof, transcript_params: Option, ) -> Result<((E::G1Affine, E::G1Affine), bool), SynthesisError> { - let mut transcript = if let Some(params) = transcript_params { - T::new_from_params(params) - } else { - T::new() - }; + let mut transcript = if let Some(params) = transcript_params { T::new_from_params(params) } else { T::new() }; let sorted_gates = C::declare_used_gates()?; let num_different_gates = sorted_gates.len(); - safe_assert((vk.n+1).is_power_of_two())?; + safe_assert((vk.n + 1).is_power_of_two())?; let required_domain_size = vk.n.next_power_of_two(); let domain = Domain::::new_for_size(required_domain_size as u64)?; @@ -78,12 +70,12 @@ pub fn aggregate, T: Transcript>( for idx in 0..vk.state_width { let commitment = proof.state_polys_commitments.get(idx).ok_or(SynthesisError::AssignmentMissing)?; commit_point_as_xy::(&mut transcript, commitment); - } + } for idx in 0..vk.num_witness_polys { let commitment = proof.witness_polys_commitments.get(idx).ok_or(SynthesisError::AssignmentMissing)?; commit_point_as_xy::(&mut transcript, commitment); - } + } let mut eta = E::Fr::zero(); if vk.total_lookup_entries_length > 0 { @@ -99,7 +91,7 @@ pub fn aggregate, T: Transcript>( let commitment = &proof.copy_permutation_grand_product_commitment; commit_point_as_xy::(&mut transcript, commitment); - let mut beta_for_lookup = None; + let mut beta_for_lookup = None; let mut gamma_for_lookup = None; if vk.total_lookup_entries_length > 0 { @@ -181,7 +173,6 @@ pub fn aggregate, T: Transcript>( { let mut gate_setup_polys_commitments_iter = vk.gate_setup_commitments.iter(); - if sorted_gates.len() == 1 { // there is no selector let gate = sorted_gates.last().unwrap(); @@ -199,11 +190,11 @@ pub fn aggregate, T: Transcript>( let key = PolyIdentifier::GateSelector(gate.name()); let commitment = *gate_selectors_polys_commitments_iter.next().ok_or(SynthesisError::AssignmentMissing)?; gate_selectors_commitments_storage.insert(key, commitment); - + let setup_polys = gate.setup_polynomials(); for &id in setup_polys.into_iter() { let commitment = *gate_setup_polys_commitments_iter.next().ok_or(SynthesisError::AssignmentMissing)?; - + setup_commitments_storage.insert(id, commitment); } } @@ -252,7 +243,7 @@ pub fn aggregate, T: Transcript>( all_values_queried_at_z_omega.push(value); all_commitments_queried_at_z_omega.push(commitment); - + value }; @@ -293,10 +284,10 @@ pub fn aggregate, T: Transcript>( safe_assert_eq(dilation, dilation_value)?; safe_assert_eq(*poly_idx, witness_poly_idx)?; safe_assert(witness_poly_idx < vk.num_witness_polys)?; - + all_values_queried_at_z_omega.push(value); all_commitments_queried_at_z_omega.push(commitment); - + value }; @@ -332,7 +323,7 @@ pub fn aggregate, T: Transcript>( all_values_queried_at_z.push(value); all_commitments_queried_at_z.push(commitment); - + value } else { unimplemented!("gate setup polynomials can not be time dilated"); @@ -344,7 +335,7 @@ pub fn aggregate, T: Transcript>( query_values_map.insert(key, value); } - } + } } safe_assert(gate_setup_openings_at_z_iter.next().is_none())?; @@ -378,7 +369,7 @@ pub fn aggregate, T: Transcript>( let mut copy_permutation_queries = vec![]; - for _ in 0..(vk.state_width-1) { + for _ in 0..(vk.state_width - 1) { let value = *copy_permutation_polys_openings_at_z_iter.next().ok_or(SynthesisError::AssignmentMissing)?; transcript.commit_field_element(&value); @@ -391,7 +382,7 @@ pub fn aggregate, T: Transcript>( } safe_assert(copy_permutation_polys_openings_at_z_iter.next().is_none())?; - + // copy-permutation grand product query let mut z_omega = z; @@ -447,12 +438,7 @@ pub fn aggregate, T: Transcript>( let input_values = proof.inputs.clone(); - let mut inputs_term = gate.add_inputs_into_quotient( - required_domain_size, - &input_values, - z, - for_gate, - )?; + let mut inputs_term = gate.add_inputs_into_quotient(required_domain_size, &input_values, z, for_gate)?; if num_different_gates > 1 { let selector_value = selector_values[0]; @@ -462,7 +448,7 @@ pub fn aggregate, T: Transcript>( tmp.add_assign(&inputs_term); t_num_on_full_domain.add_assign(&tmp); - } + } // now aggregate leftovers from grand product for copy permutation { @@ -472,13 +458,12 @@ pub fn aggregate, T: Transcript>( let mut factor = alpha_0; factor.mul_assign(©_permutation_z_at_z_omega); - for idx in 0..(vk.state_width-1) { + for idx in 0..(vk.state_width - 1) { let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(idx)); - let wire_value = query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let wire_value = query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; let permutation_at_z = copy_permutation_queries[idx]; let mut t = permutation_at_z; - + t.mul_assign(&beta_for_copy_permutation); t.add_assign(&wire_value); t.add_assign(&gamma_for_copy_permutation); @@ -486,9 +471,8 @@ pub fn aggregate, T: Transcript>( factor.mul_assign(&t); } - let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(vk.state_width-1)); - let mut tmp = *query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(vk.state_width - 1)); + let mut tmp = *query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; tmp.add_assign(&gamma_for_copy_permutation); factor.mul_assign(&tmp); @@ -506,7 +490,6 @@ pub fn aggregate, T: Transcript>( // and if exists - grand product for lookup permutation { if vk.total_lookup_entries_length > 0 { - let [alpha_0, alpha_1, alpha_2] = lookup_grand_product_alphas.expect("there must be powers of alpha for lookup permutation"); let lookup_queries = LookupQuery:: { @@ -525,11 +508,11 @@ pub fn aggregate, T: Transcript>( let mut gamma_beta = gamma_for_lookup_permutation; gamma_beta.mul_assign(&beta_plus_one); - let expected = gamma_beta.pow([(required_domain_size-1) as u64]); + let expected = gamma_beta.pow([(required_domain_size - 1) as u64]); // in a linearization we've taken terms: // - s(x) from the alpha_0 * Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - // - and Z(x) from - alpha_0 * Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) (term in full) + + // - and Z(x) from - alpha_0 * Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) (term in full) + // + alpha_1 * (Z(x) - 1) * L_{0}(z) + alpha_2 * (Z(x) - expected) * L_{n-1}(z) // first make alpha_0 * Z(x*omega)*(\gamma*(1 + \beta) + \beta * s(x*omega))) @@ -553,7 +536,7 @@ pub fn aggregate, T: Transcript>( let mut l_0_at_z = evaluate_l0_at_point(required_domain_size as u64, z)?; l_0_at_z.mul_assign(&alpha_1); - + t_num_on_full_domain.sub_assign(&l_0_at_z); // // - alpha_2 * expected L_{n-1}(z) @@ -580,7 +563,6 @@ pub fn aggregate, T: Transcript>( // now we need to reconstruct the effective linearization poly with homomorphic properties let linearization_commitment = { - let mut challenges_slice = &powers_of_alpha_for_gates[..]; let mut all_gates = sorted_gates.clone(); @@ -595,14 +577,7 @@ pub fn aggregate, T: Transcript>( let input_values = proof.inputs.clone(); - let mut r = gate.contribute_into_linearization_commitment_for_public_inputs( - required_domain_size, - &input_values, - z, - &query_values_map, - &setup_commitments_storage, - for_gate, - )?; + let mut r = gate.contribute_into_linearization_commitment_for_public_inputs(required_domain_size, &input_values, z, &query_values_map, &setup_commitments_storage, for_gate)?; let mut selectors_it = selector_values.clone().into_iter(); @@ -619,13 +594,7 @@ pub fn aggregate, T: Transcript>( if gate.benefits_from_linearization() { // gate benefits from linearization, so make temporary value - let tmp = gate.contribute_into_linearization_commitment( - required_domain_size, - z, - &query_values_map, - &setup_commitments_storage, - for_gate, - )?; + let tmp = gate.contribute_into_linearization_commitment(required_domain_size, z, &query_values_map, &setup_commitments_storage, for_gate)?; let selector_value = selectors_it.next().ok_or(SynthesisError::AssignmentMissing)?; let mut scaled = tmp; @@ -634,12 +603,7 @@ pub fn aggregate, T: Transcript>( r.add_assign(&scaled); } else { // we linearize over the selector, so take a selector and scale it - let gate_value_at_z = gate.contribute_into_verification_equation( - required_domain_size, - z, - &query_values_map, - for_gate - )?; + let gate_value_at_z = gate.contribute_into_verification_equation(required_domain_size, z, &query_values_map, for_gate)?; let key = PolyIdentifier::GateSelector(gate.name()); let gate_selector = gate_selectors_commitments_storage.get(&key).ok_or(SynthesisError::AssignmentMissing)?; @@ -667,8 +631,7 @@ pub fn aggregate, T: Transcript>( for idx in 0..vk.state_width { let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(idx)); - let wire_value = query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let wire_value = query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; let mut t = z; let non_res = non_residues_iterator.next().ok_or(SynthesisError::AssignmentMissing)?; t.mul_assign(&non_res); @@ -691,13 +654,12 @@ pub fn aggregate, T: Transcript>( factor.mul_assign(&beta_for_copy_permutation); factor.mul_assign(©_permutation_z_at_z_omega); - for idx in 0..(vk.state_width-1) { + for idx in 0..(vk.state_width - 1) { let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(idx)); - let wire_value = query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let wire_value = query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; let permutation_at_z = copy_permutation_queries[idx]; let mut t = permutation_at_z; - + t.mul_assign(&beta_for_copy_permutation); t.add_assign(&wire_value); t.add_assign(&gamma_for_copy_permutation); @@ -706,7 +668,7 @@ pub fn aggregate, T: Transcript>( } let scaled = vk.permutation_commitments.get(vk.state_width - 1).ok_or(SynthesisError::AssignmentMissing)?.mul(factor.into_repr()); - + r.sub_assign(&scaled); // + L_0(z) * Z(x) @@ -724,7 +686,7 @@ pub fn aggregate, T: Transcript>( // due to separate divisor it's not obvious if this is beneficial without some tricks // like multiplication by (1 - L_{n-1}) or by (x - omega^{n-1}) - // Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - + // Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - // Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) == 0 // check that (Z(x) - 1) * L_{0} == 0 // check that (Z(x) - expected) * L_{n-1} == 0, or (Z(x*omega) - expected)* L_{n-2} == 0 @@ -758,7 +720,7 @@ pub fn aggregate, T: Transcript>( let mut gamma_beta = gamma_for_lookup_permutation; gamma_beta.mul_assign(&beta_plus_one); - // (Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - + // (Z(x*omega)*(\gamma*(1 + \beta) + s(x) + \beta * s(x*omega))) - // Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)))*(X - omega^{n-1}) let last_omega = domain.generator.pow(&[(required_domain_size - 1) as u64]); @@ -774,7 +736,7 @@ pub fn aggregate, T: Transcript>( r.add_assign(&scaled); - // Z(x) from - alpha_0 * Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) + // Z(x) from - alpha_0 * Z(x) * (\beta + 1) * (\gamma + f(x)) * (\gamma(1 + \beta) + t(x) + \beta * t(x*omega)) // + alpha_1 * Z(x) * L_{0}(z) + alpha_2 * Z(x) * L_{n-1}(z) // accumulate coefficient @@ -790,10 +752,9 @@ pub fn aggregate, T: Transcript>( let eta = eta; // a,b,c safe_assert_eq(vk.state_width, 4)?; - for idx in 0..(vk.state_width-1) { + for idx in 0..(vk.state_width - 1) { let key = PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(idx)); - let mut value = *query_values_map.get(&key) - .ok_or(SynthesisError::AssignmentMissing)?; + let mut value = *query_values_map.get(&key).ok_or(SynthesisError::AssignmentMissing)?; value.mul_assign(¤t); f_reconstructed.add_assign(&value); @@ -891,16 +852,16 @@ pub fn aggregate, T: Transcript>( let lookup_t_poly_commitment_aggregated = { let mut commitments_iter = vk.lookup_tables_commitments.iter(); let mut result = commitments_iter.next().ok_or(SynthesisError::AssignmentMissing)?.into_projective(); - + let mut current = eta; for part in commitments_iter { let tmp = *part; let tmp = tmp.mul(current.into_repr()); - + result.add_assign(&tmp); current.mul_assign(&eta); } - + result.into_affine() }; @@ -950,7 +911,11 @@ pub fn aggregate, T: Transcript>( aggregation_challenge.mul_assign(&v); - let mut aggregated_commitment_at_z_omega = commitments_queried_at_z_omega.drain(0..1).next().ok_or(SynthesisError::AssignmentMissing)?.mul(aggregation_challenge.into_repr()); + let mut aggregated_commitment_at_z_omega = commitments_queried_at_z_omega + .drain(0..1) + .next() + .ok_or(SynthesisError::AssignmentMissing)? + .mul(aggregation_challenge.into_repr()); let mut aggregated_opening_at_z_omega = values_queried_at_z_omega.drain(0..1).next().ok_or(SynthesisError::AssignmentMissing)?; aggregated_opening_at_z_omega.mul_assign(&aggregation_challenge); @@ -995,6 +960,6 @@ pub fn aggregate, T: Transcript>( pair_with_x.negate(); let pair_with_generator = pair_with_generator.into_affine(); - + Ok(((pair_with_generator, pair_with_x), true)) } diff --git a/crates/bellman/src/plonk/better_cs/adaptor.rs b/crates/bellman/src/plonk/better_cs/adaptor.rs index 11eb30f..d5e9954 100644 --- a/crates/bellman/src/plonk/better_cs/adaptor.rs +++ b/crates/bellman/src/plonk/better_cs/adaptor.rs @@ -1,18 +1,18 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; use crate::SynthesisError; use super::cs::{PlonkConstraintSystemParams, StateVariablesSet, TraceStepCoefficients}; -use crate::plonk::cs::gates::Variable as PlonkVariable; use crate::plonk::cs::gates::Index as PlonkIndex; +use crate::plonk::cs::gates::Variable as PlonkVariable; use super::cs::Circuit as PlonkCircuit; use super::cs::ConstraintSystem as PlonkConstraintSystem; use std::marker::PhantomData; -use std::collections::{HashSet, HashMap}; +use std::collections::{HashMap, HashSet}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MergeLcVariant { @@ -47,7 +47,7 @@ impl MergeLcVariant { _ => { use std::io::{Error, ErrorKind}; let custom_error = Error::new(ErrorKind::Other, "unknown LC merging variant"); - + return Err(custom_error); } }; @@ -83,7 +83,7 @@ impl LcTransformationVariant { _ => { use std::io::{Error, ErrorKind}; let custom_error = Error::new(ErrorKind::Other, "unknown LC transformation variant"); - + return Err(custom_error); } }; @@ -120,13 +120,13 @@ pub enum TranspilationVariant { IntoQuadraticGate, IntoAdditionGate(LcTransformationVariant), MergeLinearCombinations(MergeLcVariant, LcTransformationVariant), - IntoMultiplicationGate((LcTransformationVariant, LcTransformationVariant, LcTransformationVariant)) + IntoMultiplicationGate((LcTransformationVariant, LcTransformationVariant, LcTransformationVariant)), } -use std::io::{Read, Write}; +use crate::byteorder::BigEndian; use crate::byteorder::ReadBytesExt; use crate::byteorder::WriteBytesExt; -use crate::byteorder::BigEndian; +use std::io::{Read, Write}; impl TranspilationVariant { pub fn into_u8(&self) -> u8 { @@ -138,11 +138,7 @@ impl TranspilationVariant { } } - pub fn write( - &self, - mut writer: W - ) -> std::io::Result<()> - { + pub fn write(&self, mut writer: W) -> std::io::Result<()> { let prefix = self.into_u8(); writer.write_u8(prefix)?; match self { @@ -156,46 +152,44 @@ impl TranspilationVariant { let subhint = subhint.into_u8(); writer.write_u8(subhint)?; - }, + } TranspilationVariant::IntoMultiplicationGate(hints) => { let (h_a, h_b, h_c) = hints; writer.write_u8(h_a.into_u8())?; writer.write_u8(h_b.into_u8())?; writer.write_u8(h_c.into_u8())?; - }, - _ => { } + _ => {} } Ok(()) } - pub fn read( - mut reader: R - ) -> std::io::Result - { + pub fn read(mut reader: R) -> std::io::Result { let prefix = reader.read_u8()?; match prefix { - 1u8 => {return Ok(TranspilationVariant::IntoQuadraticGate); }, + 1u8 => { + return Ok(TranspilationVariant::IntoQuadraticGate); + } 2u8 => { let subhint = LcTransformationVariant::from_u8(reader.read_u8()?)?; - + return Ok(TranspilationVariant::IntoAdditionGate(subhint)); - }, + } 3u8 => { let variant = MergeLcVariant::from_u8(reader.read_u8()?)?; let subhint = LcTransformationVariant::from_u8(reader.read_u8()?)?; - + return Ok(TranspilationVariant::MergeLinearCombinations(variant, subhint)); - }, + } 4u8 => { let subhint_a = LcTransformationVariant::from_u8(reader.read_u8()?)?; let subhint_b = LcTransformationVariant::from_u8(reader.read_u8()?)?; let subhint_c = LcTransformationVariant::from_u8(reader.read_u8()?)?; - + return Ok(TranspilationVariant::IntoMultiplicationGate((subhint_a, subhint_b, subhint_c))); - }, + } _ => {} } @@ -203,12 +197,10 @@ impl TranspilationVariant { let custom_error = Error::new(ErrorKind::Other, "unknown transpilation variant"); Err(custom_error) - } + } } -pub fn read_transpilation_hints( - mut reader: R -) -> std::io::Result> { +pub fn read_transpilation_hints(mut reader: R) -> std::io::Result> { let num_hints = reader.read_u64::()?; let mut hints = Vec::with_capacity(num_hints as usize); @@ -221,10 +213,7 @@ pub fn read_transpilation_hints( Ok(hints) } -pub fn write_transpilation_hints( - hints: &Vec<(usize, TranspilationVariant)>, - mut writer: W -) -> std::io::Result<()> { +pub fn write_transpilation_hints(hints: &Vec<(usize, TranspilationVariant)>, mut writer: W) -> std::io::Result<()> { writer.write_u64::(hints.len() as u64)?; for (idx, h) in hints.iter() { writer.write_u64::(*idx as u64)?; @@ -239,19 +228,19 @@ impl std::fmt::Debug for TranspilationVariant { match self { TranspilationVariant::IntoQuadraticGate => { writeln!(f, "Variant: into quadratic gate")?; - }, + } TranspilationVariant::IntoAdditionGate(_) => { writeln!(f, "Variant: make an addition gate")?; - }, + } TranspilationVariant::MergeLinearCombinations(merge_type, _) => { writeln!(f, "Variant: merge linear combinations as {:?}", merge_type)?; - }, + } TranspilationVariant::IntoMultiplicationGate(b) => { writeln!(f, "Variant: into combinatoric multiplication gate")?; writeln!(f, "A: {:?}", b.0)?; writeln!(f, "B: {:?}", b.1)?; writeln!(f, "C: {:?}", b.2)?; - }, + } } Ok(()) @@ -269,33 +258,33 @@ pub struct Transpiler> { hints: Vec<(usize, TranspilationVariant)>, n: usize, _marker_e: std::marker::PhantomData, - _marker_p: std::marker::PhantomData

+ _marker_p: std::marker::PhantomData

, } // by convention last coefficient is a coefficient for a jump to the next step -fn allocate_into_cs, CS: PlonkConstraintSystem> ( +fn allocate_into_cs, CS: PlonkConstraintSystem>( cs: &mut CS, needs_next_step: bool, variables: &[PlonkVariable], - coefficients: &[E::Fr] + coefficients: &[E::Fr], ) -> Result<(), SynthesisError> { if needs_next_step { debug_assert!(coefficients.len() == P::STATE_WIDTH + 1 + 1 + 1); debug_assert!(P::CAN_ACCESS_NEXT_TRACE_STEP); cs.new_gate( - P::StateVariables::from_variables(variables), - P::ThisTraceStepCoefficients::from_coeffs(&coefficients[0..(P::STATE_WIDTH+2)]), - P::NextTraceStepCoefficients::from_coeffs(&coefficients[(P::STATE_WIDTH+2)..]) + P::StateVariables::from_variables(variables), + P::ThisTraceStepCoefficients::from_coeffs(&coefficients[0..(P::STATE_WIDTH + 2)]), + P::NextTraceStepCoefficients::from_coeffs(&coefficients[(P::STATE_WIDTH + 2)..]), )?; } else { debug_assert!(coefficients.len() >= P::STATE_WIDTH + 1 + 1); debug_assert!(coefficients.last().unwrap().is_zero()); cs.new_gate( - P::StateVariables::from_variables(variables), - P::ThisTraceStepCoefficients::from_coeffs(&coefficients[0..(P::STATE_WIDTH+2)]), - P::NextTraceStepCoefficients::from_coeffs(&coefficients[(P::STATE_WIDTH+2)..]) + P::StateVariables::from_variables(variables), + P::ThisTraceStepCoefficients::from_coeffs(&coefficients[0..(P::STATE_WIDTH + 2)]), + P::NextTraceStepCoefficients::from_coeffs(&coefficients[(P::STATE_WIDTH + 2)..]), )?; } @@ -304,9 +293,9 @@ fn allocate_into_cs, CS: PlonkConst fn evaluate_lc, CS: PlonkConstraintSystem>( cs: &CS, - lc: &LinearCombination, - // multiplier: E::Fr, - free_term_constant: E::Fr + lc: &LinearCombination, + // multiplier: E::Fr, + free_term_constant: E::Fr, ) -> Result { let mut final_value = E::Fr::zero(); for (var, coeff) in lc.as_ref().iter() { @@ -323,7 +312,7 @@ fn evaluate_lc, CS: PlonkConstraint fn evaluate_over_variables, CS: PlonkConstraintSystem>( cs: &CS, variables: &[(Variable, E::Fr)], - free_term_constant: E::Fr + free_term_constant: E::Fr, ) -> Result { let mut final_value = E::Fr::zero(); for (var, coeff) in variables.iter() { @@ -340,7 +329,7 @@ fn evaluate_over_variables, CS: Plo fn evaluate_over_plonk_variables, CS: PlonkConstraintSystem>( cs: &CS, variables: &[(PlonkVariable, E::Fr)], - free_term_constant: E::Fr + free_term_constant: E::Fr, ) -> Result { let mut final_value = E::Fr::zero(); for (var, coeff) in variables.iter() { @@ -358,7 +347,7 @@ fn evaluate_over_plonk_variables_and_coeffs Result { debug_assert_eq!(variables.len(), coeffs.len()); let mut final_value = E::Fr::zero(); @@ -374,9 +363,9 @@ fn evaluate_over_plonk_variables_and_coeffs, CS: PlonkConstraintSystem>( - cs: &mut CS, - mut lc: LinearCombination, - multiplier: E::Fr, + cs: &mut CS, + mut lc: LinearCombination, + multiplier: E::Fr, free_term_constant: E::Fr, collapse_into_single_variable: bool, scratch_space: &mut TranspilationScratchSpace, @@ -399,14 +388,14 @@ fn enforce_lc_as_gates, CS: PlonkCo if lc.0.len() == 1 { if free_term_constant.is_zero() { // this linear combination contains only one variable and no constant - // term, so we just leave it as is, + // term, so we just leave it as is, // but ONLY if we just need to collapse LC into a variable if collapse_into_single_variable { let (var, coeff) = lc.0[0]; return Ok((Some(convert_variable(var)), coeff, LcTransformationVariant::IsSingleVariable)); } - } + } } // everything else should be handled here by making a new variable @@ -424,15 +413,13 @@ fn enforce_lc_as_gates, CS: PlonkCo } } - // if we need to collaplse an LC into a single variable for + // if we need to collaplse an LC into a single variable for // future use we allocate it and then subtract it from linear combination // to have an enforcement LC == 0 in all the cases let final_variable = if collapse_into_single_variable { let may_be_new_value = evaluate_lc::(&*cs, &lc, free_term_constant); - let new_var = cs.alloc(|| { - may_be_new_value - })?; + let new_var = cs.alloc(|| may_be_new_value)?; Some(new_var) } else { @@ -445,11 +432,11 @@ fn enforce_lc_as_gates, CS: PlonkCo let num_terms = lc.0.len(); - // we have two options: + // we have two options: // - fit everything into a single gate (in case of number terms in the linear combination // smaller than a width of the state) // - make a required number of extra variables and chain it - + if num_terms <= P::STATE_WIDTH { // we can just make a single gate @@ -477,12 +464,7 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(free_term_constant); scratch_space.scratch_space_for_coeffs.push(zero_fr); - allocate_into_cs( - cs, - false, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs - )?; + allocate_into_cs(cs, false, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs)?; scratch_space.clear(); @@ -495,18 +477,18 @@ fn enforce_lc_as_gates, CS: PlonkCo // - every time take STATE_WIDTH-1 variables and place their sum + last wire into the next gate last wire // we have also made a final variable already, so there is NO difference - let cycles = ((lc.0.len() - P::STATE_WIDTH) + (P::STATE_WIDTH - 2)) / (P::STATE_WIDTH - 1); // ceil + let cycles = ((lc.0.len() - P::STATE_WIDTH) + (P::STATE_WIDTH - 2)) / (P::STATE_WIDTH - 1); // ceil let mut it = lc.0.into_iter(); - // this is a placeholder variable that must go into the - // corresponding trace polynomial at the NEXT time step + // this is a placeholder variable that must go into the + // corresponding trace polynomial at the NEXT time step let mut next_step_var_in_chain = { scratch_space.scratch_space_for_vars.resize(P::STATE_WIDTH, cs.get_dummy_variable()); scratch_space.scratch_space_for_booleans.resize(P::STATE_WIDTH, false); scratch_space.scratch_space_for_coeffs.resize(P::STATE_WIDTH, zero_fr); - + // we can consume and never have leftovers - + let mut idx = 0; for (var, coeff) in &mut it { if scratch_space.scratch_space_for_booleans[idx] == false { @@ -522,17 +504,11 @@ fn enforce_lc_as_gates, CS: PlonkCo // for a P::STATE_WIDTH variables we make a corresponding LC // ~ a + b + c + d + constant. That will be equal to d_next - let may_be_new_intermediate_value = evaluate_over_plonk_variables_and_coeffs::( - &*cs, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs, - free_term_constant - ); + let may_be_new_intermediate_value = + evaluate_over_plonk_variables_and_coeffs::(&*cs, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs, free_term_constant); // we manually allocate the new variable - let new_intermediate_var = cs.alloc(|| { - may_be_new_intermediate_value - })?; + let new_intermediate_var = cs.alloc(|| may_be_new_intermediate_value)?; // no multiplication coefficient, // but -1 to link to the next trace step (we enforce == 0) @@ -540,12 +516,7 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(free_term_constant); // add constant scratch_space.scratch_space_for_coeffs.push(minus_one_fr); // -1 for a d_next - allocate_into_cs( - cs, - true, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs - )?; + allocate_into_cs(cs, true, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs)?; scratch_space.clear(); @@ -554,16 +525,16 @@ fn enforce_lc_as_gates, CS: PlonkCo // run over the rest - // we can only take one less cause + // we can only take one less cause // we've already used one of the variable - let consume_from_lc = P::STATE_WIDTH - 1; - for _ in 0..(cycles-1) { + let consume_from_lc = P::STATE_WIDTH - 1; + for _ in 0..(cycles - 1) { scratch_space.scratch_space_for_vars.resize(consume_from_lc, cs.get_dummy_variable()); scratch_space.scratch_space_for_booleans.resize(consume_from_lc, false); scratch_space.scratch_space_for_coeffs.resize(consume_from_lc, zero_fr); - + // we can consume and never have leftovers - + let mut idx = 0; for (var, coeff) in &mut it { if scratch_space.scratch_space_for_booleans[idx] == false { @@ -582,16 +553,9 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(one_fr); scratch_space.scratch_space_for_vars.push(next_step_var_in_chain); - let may_be_new_intermediate_value = evaluate_over_plonk_variables_and_coeffs::( - &*cs, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs, - zero_fr - ); + let may_be_new_intermediate_value = evaluate_over_plonk_variables_and_coeffs::(&*cs, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs, zero_fr); - let new_intermediate_var = cs.alloc(|| { - may_be_new_intermediate_value - })?; + let new_intermediate_var = cs.alloc(|| may_be_new_intermediate_value)?; // no multiplication coefficient and no constant now, // but -1 to link to the next trace step @@ -599,12 +563,7 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(zero_fr); scratch_space.scratch_space_for_coeffs.push(minus_one_fr); - allocate_into_cs( - cs, - true, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs - )?; + allocate_into_cs(cs, true, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs)?; scratch_space.clear(); @@ -613,12 +572,12 @@ fn enforce_lc_as_gates, CS: PlonkCo // final step - we just make a single gate, last one { - scratch_space.scratch_space_for_vars.resize(P::STATE_WIDTH-1, cs.get_dummy_variable()); - scratch_space.scratch_space_for_booleans.resize(P::STATE_WIDTH-1, false); - scratch_space.scratch_space_for_coeffs.resize(P::STATE_WIDTH-1, zero_fr); - + scratch_space.scratch_space_for_vars.resize(P::STATE_WIDTH - 1, cs.get_dummy_variable()); + scratch_space.scratch_space_for_booleans.resize(P::STATE_WIDTH - 1, false); + scratch_space.scratch_space_for_coeffs.resize(P::STATE_WIDTH - 1, zero_fr); + // we can consume and never have leftovers - + let mut idx = 0; for (var, coeff) in &mut it { if scratch_space.scratch_space_for_booleans[idx] == false { @@ -639,12 +598,7 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(zero_fr); scratch_space.scratch_space_for_coeffs.push(zero_fr); - allocate_into_cs( - cs, - false, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs - )?; + allocate_into_cs(cs, false, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs)?; scratch_space.clear(); } @@ -653,7 +607,7 @@ fn enforce_lc_as_gates, CS: PlonkCo let hint = LcTransformationVariant::IntoMultipleGates; - return Ok((final_variable, one_fr, hint)); + return Ok((final_variable, one_fr, hint)); } } @@ -669,7 +623,7 @@ impl> Transpiler { hints: vec![], n: 0usize, _marker_e: std::marker::PhantomData, - _marker_p: std::marker::PhantomData + _marker_p: std::marker::PhantomData, } } @@ -696,12 +650,9 @@ impl> Transpiler { impl> PlonkConstraintSystem for Transpiler { fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - let var = crate::ConstraintSystem::::alloc( - self, - || "alloc aux var", - value)?; + let var = crate::ConstraintSystem::::alloc(self, || "alloc aux var", value)?; Ok(convert_variable(var)) } @@ -709,23 +660,16 @@ impl> PlonkConstraintSystem f // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - let var = crate::ConstraintSystem::::alloc_input( - self, - || "alloc input var", - value)?; + let var = crate::ConstraintSystem::::alloc_input(self, || "alloc input var", value)?; self.n += 1; Ok(convert_variable(var)) } - fn new_gate(&mut self, - _variables: P::StateVariables, - _this_step_coeffs: P::ThisTraceStepCoefficients, - _next_step_coeffs: P::NextTraceStepCoefficients - ) -> Result<(), SynthesisError> { + fn new_gate(&mut self, _variables: P::StateVariables, _this_step_coeffs: P::ThisTraceStepCoefficients, _next_step_coeffs: P::NextTraceStepCoefficients) -> Result<(), SynthesisError> { // Transpiler does NOT allocate any gates himself self.n += 1; @@ -740,12 +684,9 @@ impl> PlonkConstraintSystem f impl<'a, E: Engine, P: PlonkConstraintSystemParams> PlonkConstraintSystem for &'a mut Transpiler { fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - let var = crate::ConstraintSystem::::alloc( - self, - || "alloc aux var", - value)?; + let var = crate::ConstraintSystem::::alloc(self, || "alloc aux var", value)?; Ok(convert_variable(var)) } @@ -753,23 +694,16 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams> PlonkConstraintSystem(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - let var = crate::ConstraintSystem::::alloc_input( - self, - || "alloc input var", - value)?; + let var = crate::ConstraintSystem::::alloc_input(self, || "alloc input var", value)?; self.n += 1; Ok(convert_variable(var)) } - fn new_gate(&mut self, - _variables: P::StateVariables, - _this_step_coeffs: P::ThisTraceStepCoefficients, - _next_step_coeffs: P::NextTraceStepCoefficients - ) -> Result<(), SynthesisError> { + fn new_gate(&mut self, _variables: P::StateVariables, _this_step_coeffs: P::ThisTraceStepCoefficients, _next_step_coeffs: P::NextTraceStepCoefficients) -> Result<(), SynthesisError> { // Transpiler does NOT allocate any gates himself self.n += 1; @@ -781,8 +715,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams> PlonkConstraintSystem> crate::ConstraintSystem for Transpiler -{ +impl> crate::ConstraintSystem for Transpiler { type Root = Self; fn one() -> crate::Variable { @@ -800,11 +733,7 @@ impl> crate::ConstraintSystem fo Ok(crate::Variable::new_unchecked(crate::Index::Aux(self.current_plonk_aux_idx))) } - fn alloc_input( - &mut self, - _: A, - _f: F, - ) -> Result + fn alloc_input(&mut self, _: A, _f: F) -> Result where F: FnOnce() -> Result, A: FnOnce() -> AR, @@ -850,7 +779,7 @@ impl> crate::ConstraintSystem fo match (a_is_constant, b_is_constant, c_is_constant) { (true, true, true) => { unreachable!("R1CS has a gate 1 * 1 = 1"); - }, + } (true, false, true) | (false, true, true) => { // println!("C * LC = C"); // we have something like c0 * LC = c1 @@ -885,14 +814,7 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_, _, hint) = enforce_lc_as_gates( - self, - lc, - multiplier, - free_constant_term, - false, - &mut space - ).expect("must allocate LCs as gates for constraint like c0 * LC = c1"); + let (_, _, hint) = enforce_lc_as_gates(self, lc, multiplier, free_constant_term, false, &mut space).expect("must allocate LCs as gates for constraint like c0 * LC = c1"); self.transpilation_scratch_space = Some(space); @@ -903,19 +825,12 @@ impl> crate::ConstraintSystem fo self.hints.push((current_lc_number, TranspilationVariant::IntoAdditionGate(hint))); return; - }, + } (false, false, true) => { - // println!("LC * LC = C"); + // println!("LC * LC = C"); // potential quadatic gate, but ig general // it's a full multiplication gate - let (is_quadratic_gate, _coeffs) = check_for_quadratic_gate::( - &a_lc, - &b_lc, - &c_lc, - a_constant_term, - b_constant_term, - c_constant_term - ); + let (is_quadratic_gate, _coeffs) = check_for_quadratic_gate::(&a_lc, &b_lc, &c_lc, a_constant_term, b_constant_term, c_constant_term); if is_quadratic_gate { let current_lc_number = self.increment_lc_number(); // we don't pass a call to any function that allocates a gate, @@ -933,23 +848,9 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_new_a_var, _, hint_a) = enforce_lc_as_gates( - self, - a_lc, - one_fr, - a_constant_term, - true, - &mut space - ).expect("must allocate A LC as gates for constraint like LC * LC = c1"); - - let (_new_b_var, _, hint_b) = enforce_lc_as_gates( - self, - b_lc, - one_fr, - b_constant_term, - true, - &mut space - ).expect("must allocate B LC as gates for constraint like LC * LC = c1"); + let (_new_a_var, _, hint_a) = enforce_lc_as_gates(self, a_lc, one_fr, a_constant_term, true, &mut space).expect("must allocate A LC as gates for constraint like LC * LC = c1"); + + let (_new_b_var, _, hint_b) = enforce_lc_as_gates(self, b_lc, one_fr, b_constant_term, true, &mut space).expect("must allocate B LC as gates for constraint like LC * LC = c1"); self.transpilation_scratch_space = Some(space); @@ -965,8 +866,7 @@ impl> crate::ConstraintSystem fo // println!("Hint = {:?}", hint); self.hints.push((current_lc_number, hint)); - - }, + } (true, false, false) | (false, true, false) => { // sometihng like LC * const = LC // so we can merge them into one long linear combination @@ -991,14 +891,7 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_, _, hint_c) = enforce_lc_as_gates( - self, - c_lc, - one_fr, - c_constant_term, - false, - &mut space - ).expect("must allocate LCs as gates for constraint like 0 = LC_C"); + let (_, _, hint_c) = enforce_lc_as_gates(self, c_lc, one_fr, c_constant_term, false, &mut space).expect("must allocate LCs as gates for constraint like 0 = LC_C"); self.transpilation_scratch_space = Some(space); @@ -1042,14 +935,7 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_, _, hint_lc) = enforce_lc_as_gates( - self, - final_lc, - one_fr, - free_constant_term, - false, - &mut space - ).expect("must allocate LCs as gates for constraint like c0 * LC = LC"); + let (_, _, hint_lc) = enforce_lc_as_gates(self, final_lc, one_fr, free_constant_term, false, &mut space).expect("must allocate LCs as gates for constraint like c0 * LC = LC"); self.transpilation_scratch_space = Some(space); @@ -1062,8 +948,7 @@ impl> crate::ConstraintSystem fo self.hints.push((current_lc_number, hint)); return; - - }, + } (true, true, false) => { // const * const = LC // A and B are some constants @@ -1076,14 +961,7 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_, _, hint_lc) = enforce_lc_as_gates( - self, - c_lc, - one_fr, - free_constant_term, - false, - &mut space - ).expect("must allocate LCs as gates for constraint like c0 * c1 = LC"); + let (_, _, hint_lc) = enforce_lc_as_gates(self, c_lc, one_fr, free_constant_term, false, &mut space).expect("must allocate LCs as gates for constraint like c0 * c1 = LC"); self.transpilation_scratch_space = Some(space); @@ -1094,15 +972,11 @@ impl> crate::ConstraintSystem fo // println!("Hint = {:?}", hint); self.hints.push((current_lc_number, hint)); - - }, + } (false, false, false) => { // LC * LC = LC // potentially it can still be quadratic - let (is_quadratic_gate, _coeffs) = is_quadratic_gate::( - &a_lc, - &b_lc, - &c_lc, &mut self.scratch); + let (is_quadratic_gate, _coeffs) = is_quadratic_gate::(&a_lc, &b_lc, &c_lc, &mut self.scratch); if is_quadratic_gate { let current_lc_number = self.increment_lc_number(); @@ -1121,31 +995,10 @@ impl> crate::ConstraintSystem fo // rewrite into addition gates and multiplication gates let mut space = self.transpilation_scratch_space.take().unwrap(); - - let (_new_a_var, _, hint_a) = enforce_lc_as_gates( - self, - a_lc, - one_fr, - a_constant_term, - true, - &mut space - ).expect("must allocate A LC as gates for constraint like LC * LC = LC"); - let (_new_b_var, _, hint_b) = enforce_lc_as_gates( - self, - b_lc, - one_fr, - b_constant_term, - true, - &mut space - ).expect("must allocate B LC as gates for constraint like LC * LC = LC"); - let (_new_c_var, _, hint_c) = enforce_lc_as_gates( - self, - c_lc, - one_fr, - c_constant_term, - true, - &mut space - ).expect("must allocate C LC as gates for constraint like LC * LC = LC"); + + let (_new_a_var, _, hint_a) = enforce_lc_as_gates(self, a_lc, one_fr, a_constant_term, true, &mut space).expect("must allocate A LC as gates for constraint like LC * LC = LC"); + let (_new_b_var, _, hint_b) = enforce_lc_as_gates(self, b_lc, one_fr, b_constant_term, true, &mut space).expect("must allocate B LC as gates for constraint like LC * LC = LC"); + let (_new_c_var, _, hint_c) = enforce_lc_as_gates(self, c_lc, one_fr, c_constant_term, true, &mut space).expect("must allocate C LC as gates for constraint like LC * LC = LC"); self.transpilation_scratch_space = Some(space); @@ -1160,7 +1013,7 @@ impl> crate::ConstraintSystem fo self.hints.push((current_lc_number, hint)); } - } + } } fn push_namespace(&mut self, _: N) @@ -1182,16 +1035,16 @@ impl> crate::ConstraintSystem fo // List of heuristics -use crate::{LinearCombination, ConstraintSystem, Variable}; +use crate::{ConstraintSystem, LinearCombination, Variable}; fn is_quadratic_gate>( - a: &LinearCombination, - b: &LinearCombination, + a: &LinearCombination, + b: &LinearCombination, c: &LinearCombination, - scratch: &mut HashSet:: + scratch: &mut HashSet, ) -> (bool, (E::Fr, E::Fr, E::Fr)) { let zero = E::Fr::zero(); - + let (_a_containts_constant, a_constant_coeff) = get_constant_term::(&a); let (_b_containts_constant, b_constant_coeff) = get_constant_term::(&b); let (_c_containts_constant, c_constant_coeff) = get_constant_term::(&c); @@ -1240,14 +1093,14 @@ fn is_quadratic_gate>( } return (true, (constant_term, linear_term, quadratic_term)); - } + } (false, (zero, zero, zero)) } fn check_for_quadratic_gate( - a: &LinearCombination, - b: &LinearCombination, + a: &LinearCombination, + b: &LinearCombination, c: &LinearCombination, a_constant_term: E::Fr, b_constant_term: E::Fr, @@ -1316,7 +1169,7 @@ fn check_for_quadratic_gate( } return (true, (constant_term, linear_term, quadratic_term)); - } + } (false, (zero, zero, zero)) } @@ -1326,7 +1179,7 @@ fn is_constant>(lc: &LinearCombination) -> if lc.as_ref().len() == 0 { return (true, E::Fr::zero()); } - + let result = get_constant_term::(&lc); if result.0 && lc.as_ref().len() == 1 { @@ -1338,7 +1191,7 @@ fn is_constant>(lc: &LinearCombination) -> fn get_constant_term>(lc: &LinearCombination) -> (bool, E::Fr) { let cs_one = CS::one(); - + for (var, coeff) in lc.as_ref().iter() { if var == &cs_one { return (true, *coeff); @@ -1350,7 +1203,7 @@ fn get_constant_term>(lc: &LinearCombination< fn get_first_variable>(lc: &LinearCombination) -> (bool, Variable) { let cs_one = CS::one(); - + for (var, _) in lc.as_ref().iter() { if var != &cs_one { return (true, *var); @@ -1362,7 +1215,7 @@ fn get_first_variable>(lc: &LinearCombination fn get_first_variable_with_coeff>(lc: &LinearCombination) -> (bool, Variable, E::Fr) { let cs_one = CS::one(); - + for (var, coeff) in lc.as_ref().iter() { if var != &cs_one { return (true, *var, *coeff); @@ -1372,11 +1225,11 @@ fn get_first_variable_with_coeff>(lc: &Linear (false, cs_one, E::Fr::zero()) } -fn num_unique_values>(lc: &LinearCombination, scratch: &mut HashSet::) -> (bool, usize) { +fn num_unique_values>(lc: &LinearCombination, scratch: &mut HashSet) -> (bool, usize) { let cs_one = CS::one(); debug_assert!(scratch.is_empty()); - + let mut contains_constant = false; for (var, _) in lc.as_ref().iter() { @@ -1394,11 +1247,11 @@ fn num_unique_values>(lc: &LinearCombination< (contains_constant, num_unique_without_constant) } -fn is_linear_term>(lc: &LinearCombination, scratch: &mut HashSet::) -> (bool, Variable, E::Fr) { +fn is_linear_term>(lc: &LinearCombination, scratch: &mut HashSet) -> (bool, Variable, E::Fr) { let cs_one = CS::one(); debug_assert!(scratch.is_empty()); - + let mut linear_coeff = E::Fr::zero(); for (var, coeff) in lc.as_ref().iter() { @@ -1414,18 +1267,15 @@ fn is_linear_term>(lc: &LinearCombination, let terms: Vec<_> = scratch.drain().collect(); let term = terms[0]; - return (true, term, linear_coeff) + return (true, term, linear_coeff); } else { scratch.clear(); - return (false, cs_one, E::Fr::zero()) - } + return (false, cs_one, E::Fr::zero()); + } } -fn deduplicate_stable>( - lc: LinearCombination, - scratch: &mut HashMap -) -> LinearCombination { +fn deduplicate_stable>(lc: LinearCombination, scratch: &mut HashMap) -> LinearCombination { assert!(scratch.is_empty()); if lc.as_ref().len() == 0 { @@ -1462,10 +1312,7 @@ fn deduplicate_stable>( LinearCombination(deduped_vec) } -fn deduplicate_and_split_linear_term>( - lc: LinearCombination, - scratch: &mut HashMap -) -> (bool, E::Fr, bool, LinearCombination) { +fn deduplicate_and_split_linear_term>(lc: LinearCombination, scratch: &mut HashMap) -> (bool, E::Fr, bool, LinearCombination) { assert!(scratch.is_empty()); if lc.as_ref().len() == 0 { @@ -1505,11 +1352,11 @@ fn deduplicate_and_split_linear_term>( fn subtract_lcs_with_dedup_stable>( lc_0: LinearCombination, lc_1: LinearCombination, - scratch: &mut HashMap + scratch: &mut HashMap, ) -> LinearCombination { assert!(scratch.is_empty()); - if lc_0.as_ref().len() == 0 && lc_1.as_ref().len() == 0{ + if lc_0.as_ref().len() == 0 && lc_1.as_ref().len() == 0 { return lc_0; } @@ -1546,19 +1393,14 @@ fn subtract_lcs_with_dedup_stable>( LinearCombination(deduped_vec) } -fn subtract_variable_unchecked( - lc: &mut LinearCombination, - variable: Variable -) { +fn subtract_variable_unchecked(lc: &mut LinearCombination, variable: Variable) { let mut minus_one = E::Fr::one(); minus_one.negate(); lc.0.push((variable, minus_one)); } -fn split_constant_term>( - mut lc: LinearCombination, -) -> (LinearCombination, E::Fr) { +fn split_constant_term>(mut lc: LinearCombination) -> (LinearCombination, E::Fr) { if lc.as_ref().len() == 0 { return (lc, E::Fr::zero()); } @@ -1583,7 +1425,6 @@ fn split_constant_term>( } } - pub struct Adaptor<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem + 'a> { cs: &'a mut CS, hints: &'a Vec<(usize, TranspilationVariant)>, @@ -1613,9 +1454,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem } } -impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem - for Adaptor<'a, E, P, CS> -{ +impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem for Adaptor<'a, E, P, CS> { type Root = Self; fn one() -> crate::Variable { @@ -1628,9 +1467,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem A: FnOnce() -> AR, AR: Into, { - let var = self.cs.alloc(|| { - f().map_err(|_| crate::SynthesisError::AssignmentMissing) - })?; + let var = self.cs.alloc(|| f().map_err(|_| crate::SynthesisError::AssignmentMissing))?; Ok(match var { PlonkVariable(PlonkIndex::Aux(index)) => crate::Variable::new_unchecked(crate::Index::Aux(index)), @@ -1638,19 +1475,13 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem }) } - fn alloc_input( - &mut self, - _: A, - f: F, - ) -> Result + fn alloc_input(&mut self, _: A, f: F) -> Result where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into, { - let var = self.cs.alloc_input(|| { - f().map_err(|_| crate::SynthesisError::AssignmentMissing) - })?; + let var = self.cs.alloc_input(|| f().map_err(|_| crate::SynthesisError::AssignmentMissing))?; Ok(match var { PlonkVariable(PlonkIndex::Input(index)) => crate::Variable::new_unchecked(crate::Index::Input(index)), @@ -1671,9 +1502,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem let mut minus_one_fr = E::Fr::one(); minus_one_fr.negate(); - let (_, hint) = { - self.get_next_hint() - }; + let (_, hint) = { self.get_next_hint() }; let _hint = hint.clone(); @@ -1710,14 +1539,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem unreachable!(); }; - let (is_quadratic, coeffs) = check_for_quadratic_gate( - &a_lc, - &b_lc, - &c_lc, - a_constant_term, - b_constant_term, - c_constant_term - ); + let (is_quadratic, coeffs) = check_for_quadratic_gate(&a_lc, &b_lc, &c_lc, a_constant_term, b_constant_term, c_constant_term); debug_assert!(is_quadratic); @@ -1735,105 +1557,82 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem space.scratch_space_for_vars[0] = var; space.scratch_space_for_vars[1] = var; - allocate_into_cs( - self.cs, - false, - &*space.scratch_space_for_vars, - &*space.scratch_space_for_coeffs - ).expect("must make a quadratic gate"); - }, + allocate_into_cs(self.cs, false, &*space.scratch_space_for_vars, &*space.scratch_space_for_coeffs).expect("must make a quadratic gate"); + } TranspilationVariant::IntoMultiplicationGate(hints) => { - let (t_a, t_b, t_c) = hints; let mut q_m = one_fr; let mut q_c = one_fr; let a_var = match t_a { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_a_var, a_coeff, _variant) = enforce_lc_as_gates( - self.cs, - a_lc, - one_fr, - a_constant_term, - true, - &mut space - ).expect("must allocate A variable to transpile A LC for multiplication gate"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_a_var, a_coeff, _variant) = + enforce_lc_as_gates(self.cs, a_lc, one_fr, a_constant_term, true, &mut space).expect("must allocate A variable to transpile A LC for multiplication gate"); assert!(a_coeff == one_fr); assert!(_variant == hint); new_a_var.expect("transpiler must create a new variable for LC A") - }, + } LcTransformationVariant::IsSingleVariable => { assert!(!a_lc_is_empty); let (var, coeff) = a_lc.0[0]; q_m.mul_assign(&coeff); // collapse coeff before A*B convert_variable(var) - }, - _ => {unreachable!("{:?}", t_a)} + } + _ => { + unreachable!("{:?}", t_a) + } }; let b_var = match t_b { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_b_var, b_coeff, _variant) = enforce_lc_as_gates( - self.cs, - b_lc, - one_fr, - b_constant_term, - true, - &mut space - ).expect("must allocate B variable to transpile B LC for multiplication gate"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_b_var, b_coeff, _variant) = + enforce_lc_as_gates(self.cs, b_lc, one_fr, b_constant_term, true, &mut space).expect("must allocate B variable to transpile B LC for multiplication gate"); assert!(b_coeff == one_fr); assert!(_variant == hint); new_b_var.expect("transpiler must create a new variable for LC B") - }, + } LcTransformationVariant::IsSingleVariable => { assert!(!b_lc_is_empty); let (var, coeff) = b_lc.0[0]; q_m.mul_assign(&coeff); // collapse coeffs before A*B convert_variable(var) - }, - _ => {unreachable!("{:?}", t_b)} + } + _ => { + unreachable!("{:?}", t_b) + } }; let (c_is_just_a_constant, c_var) = match t_c { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_c_var, c_coeff, _variant) = enforce_lc_as_gates( - self.cs, - c_lc, - one_fr, - c_constant_term, - true, - &mut space - ).expect("must allocate C variable to transpile C LC for multiplication gate"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_c_var, c_coeff, _variant) = + enforce_lc_as_gates(self.cs, c_lc, one_fr, c_constant_term, true, &mut space).expect("must allocate C variable to transpile C LC for multiplication gate"); assert!(c_coeff == one_fr); assert!(_variant == hint); (false, Some(new_c_var.expect("transpiler must create a new variable for LC C"))) - }, + } LcTransformationVariant::IsSingleVariable => { assert!(!c_lc_is_empty); let (var, coeff) = c_lc.0[0]; q_c = coeff; (false, Some(convert_variable(var))) - }, + } LcTransformationVariant::IsConstant => { assert!(c_lc_is_empty); assert!(c_has_constant); (true, None) - }, + } }; if c_is_just_a_constant { @@ -1851,12 +1650,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem space.scratch_space_for_vars[0] = a_var; space.scratch_space_for_vars[1] = b_var; - allocate_into_cs( - self.cs, - false, - &*space.scratch_space_for_vars, - &*space.scratch_space_for_coeffs - ).expect("must make a multiplication gate with C being constant"); + allocate_into_cs(self.cs, false, &*space.scratch_space_for_vars, &*space.scratch_space_for_coeffs).expect("must make a multiplication gate with C being constant"); } else { // Plain multiplication gate @@ -1877,14 +1671,9 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem space.scratch_space_for_vars[1] = b_var; space.scratch_space_for_vars[2] = c_var; - allocate_into_cs( - self.cs, - false, - &*space.scratch_space_for_vars, - &*space.scratch_space_for_coeffs - ).expect("must make a plain multiplication gate"); + allocate_into_cs(self.cs, false, &*space.scratch_space_for_vars, &*space.scratch_space_for_coeffs).expect("must make a plain multiplication gate"); } - }, + } // make an addition gate TranspilationVariant::IntoAdditionGate(hint) => { // these are simple enforcements that are not a part of multiplication gate @@ -1898,7 +1687,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem } else { unreachable!("Either A or B LCs are constant"); }; - + let multiplier = if a_is_constant { a_constant_term } else if b_is_constant { @@ -1906,7 +1695,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem } else { unreachable!("Must take multiplier from A or B"); }; - + let mut free_constant_term = if a_is_constant { b_constant_term } else if b_is_constant { @@ -1914,25 +1703,18 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem } else { unreachable!("Either A or B LCs are constant"); }; - + free_constant_term.mul_assign(&multiplier); free_constant_term.sub_assign(&c_constant_term); - - let (_, _, _variant) = enforce_lc_as_gates( - self.cs, - lc, - multiplier, - free_constant_term, - false, - &mut space - ).expect("must allocate variable to transpile LC == 0 gate"); + + let (_, _, _variant) = enforce_lc_as_gates(self.cs, lc, multiplier, free_constant_term, false, &mut space).expect("must allocate variable to transpile LC == 0 gate"); assert!(hint == _variant); } else { // c is not a constant and it's handled by MergeLCs unreachable!(); } - }, + } TranspilationVariant::MergeLinearCombinations(merge_variant, merge_hint) => { let multiplier = if a_is_constant { a_constant_term @@ -1960,7 +1742,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem subtract_lcs_with_dedup_stable::(final_lc, c_lc, &mut self.deduplication_scratch) // final_lc - &c - }, + } MergeLcVariant::MergeBCThroughConstantA => { assert!(a_is_constant); let mut final_lc = b_lc; @@ -1976,7 +1758,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem subtract_lcs_with_dedup_stable::(final_lc, c_lc, &mut self.deduplication_scratch) // final_lc - &c - }, + } MergeLcVariant::CIsTheOnlyMeaningful => { free_constant_term = a_constant_term; free_constant_term.mul_assign(&b_constant_term); @@ -1984,7 +1766,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem free_constant_term.add_assign(&c_constant_term); c_lc - }, + } _ => { unreachable!() } @@ -1993,29 +1775,22 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem let h = merge_hint; match h { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_c_var, _coeff, _variant) = enforce_lc_as_gates( - self.cs, - lc_into_rewriting, - one_fr, - free_constant_term, - false, - &mut space - ).expect("must allocate gates to transpile merging of LCs"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_c_var, _coeff, _variant) = + enforce_lc_as_gates(self.cs, lc_into_rewriting, one_fr, free_constant_term, false, &mut space).expect("must allocate gates to transpile merging of LCs"); assert!(_coeff == one_fr); assert!(new_c_var.is_none()); assert!(_variant == hint); - }, + } _ => { unreachable!("{:?}", h); } }; } } - + space.clear(); self.transpilation_scratch_space = Some(space); } @@ -2039,8 +1814,12 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem fn convert_variable(r1cs_variable: crate::Variable) -> PlonkVariable { let var = match r1cs_variable.get_unchecked() { - crate::Index::Input(0) => {unreachable!("can not convert input variable number 0 (CS::one)")}, - crate::Index::Aux(0) => {unreachable!("can not convert aux variable labeled as 0 (taken by Plonk CS)")}, + crate::Index::Input(0) => { + unreachable!("can not convert input variable number 0 (CS::one)") + } + crate::Index::Aux(0) => { + unreachable!("can not convert aux variable labeled as 0 (taken by Plonk CS)") + } crate::Index::Input(i) => PlonkVariable(PlonkIndex::Input(i)), crate::Index::Aux(i) => PlonkVariable(PlonkIndex::Aux(i)), }; @@ -2050,8 +1829,12 @@ fn convert_variable(r1cs_variable: crate::Variable) -> PlonkVariable { fn convert_variable_back(plonk_variable: PlonkVariable) -> crate::Variable { let var = match plonk_variable.get_unchecked() { - crate::plonk::cs::variable::Index::Input(0) => {unreachable!("can not convert input variable number 0 (does not exist in plonk)")}, - crate::plonk::cs::variable::Index::Aux(0) => {unreachable!("can not convert aux variable labeled as 0 (does not exist in plonk, dummy gate)")}, + crate::plonk::cs::variable::Index::Input(0) => { + unreachable!("can not convert input variable number 0 (does not exist in plonk)") + } + crate::plonk::cs::variable::Index::Aux(0) => { + unreachable!("can not convert aux variable labeled as 0 (does not exist in plonk, dummy gate)") + } crate::plonk::cs::variable::Index::Input(i) => crate::Variable(crate::Index::Input(i)), crate::plonk::cs::variable::Index::Aux(i) => crate::Variable(crate::Index::Aux(i)), }; @@ -2061,22 +1844,23 @@ fn convert_variable_back(plonk_variable: PlonkVariable) -> crate::Variable { use std::cell::Cell; -pub struct AdaptorCircuit<'a, E:Engine, P: PlonkConstraintSystemParams, C: crate::Circuit>{ +pub struct AdaptorCircuit<'a, E: Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> { circuit: Cell>, hints: &'a Vec<(usize, TranspilationVariant)>, _marker_e: std::marker::PhantomData, _marker_p: std::marker::PhantomData

, } -impl<'a, E:Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> AdaptorCircuit<'a, E, P, C> { - pub fn new<'b>(circuit: C, hints: &'b Vec<(usize, TranspilationVariant)>) -> Self - where 'b: 'a +impl<'a, E: Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> AdaptorCircuit<'a, E, P, C> { + pub fn new<'b>(circuit: C, hints: &'b Vec<(usize, TranspilationVariant)>) -> Self + where + 'b: 'a, { Self { circuit: Cell::new(Some(circuit)), hints: hints, _marker_e: std::marker::PhantomData, - _marker_p: std::marker::PhantomData + _marker_p: std::marker::PhantomData, } } } @@ -2092,7 +1876,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> Plo deduplication_scratch: HashMap::with_capacity((E::Fr::NUM_BITS * 2) as usize), transpilation_scratch_space: Some(TranspilationScratchSpace::new(P::STATE_WIDTH * 2)), _marker_e: std::marker::PhantomData, - _marker_p: std::marker::PhantomData + _marker_p: std::marker::PhantomData, }; let c = self.circuit.replace(None).expect("Must replace a circuit out from cell"); @@ -2103,27 +1887,27 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> Plo #[test] fn transpile_xor_using_new_adaptor() { - use crate::tests::XORDemo; - use crate::cs::Circuit; - use crate::pairing::bn256::{Bn256, Fr}; - use super::test_assembly::*; use super::cs::PlonkCsWidth4WithNextStepParams; use super::generator::*; + use super::keys::*; use super::prover::*; - use crate::worker::Worker; + use super::test_assembly::*; + use super::utils::make_non_residues; use super::verifier::*; + use crate::cs::Circuit; use crate::kate_commitment::*; - use crate::plonk::commitments::transcript::*; + use crate::pairing::bn256::{Bn256, Fr}; use crate::plonk::commitments::transcript::keccak_transcript::*; - use crate::plonk::fft::cooley_tukey_ntt::*; - use super::keys::*; + use crate::plonk::commitments::transcript::*; use crate::plonk::domains::Domain; - use super::utils::make_non_residues; + use crate::plonk::fft::cooley_tukey_ntt::*; + use crate::tests::XORDemo; + use crate::worker::Worker; let c = XORDemo:: { a: None, b: None, - _marker: PhantomData + _marker: PhantomData, }; let mut transpiler = Transpiler::::new(); @@ -2145,7 +1929,7 @@ fn transpile_xor_using_new_adaptor() { let c = XORDemo:: { a: Some(true), b: Some(false), - _marker: PhantomData + _marker: PhantomData, }; let adapted_curcuit = AdaptorCircuit::::new(c.clone(), &hints); @@ -2167,16 +1951,9 @@ fn transpile_xor_using_new_adaptor() { let crs_mons = Crs::::crs_42(setup.permutation_polynomials[0].size(), &worker); let crs_vals = Crs::::crs_42(setup.permutation_polynomials[0].size(), &worker); - let verification_key = VerificationKey::from_setup( - &setup, - &worker, - &crs_mons - ).unwrap(); + let verification_key = VerificationKey::from_setup(&setup, &worker, &crs_mons).unwrap(); - let precomputations = SetupPolynomialsPrecomputations::from_setup( - &setup, - &worker - ).unwrap(); + let precomputations = SetupPolynomialsPrecomputations::from_setup(&setup, &worker).unwrap(); let mut assembly = ProverAssembly4WithNextStep::::new(); @@ -2195,18 +1972,11 @@ fn transpile_xor_using_new_adaptor() { type Transcr = RollingKeccakTranscript; let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); - - let proof = assembly.prove::( - &worker, - &setup, - &precomputations, - &crs_vals, - &crs_mons, - &omegas_bitreversed, - &omegas_inv_bitreversed, - None - ).unwrap(); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); + + let proof = assembly + .prove::(&worker, &setup, &precomputations, &crs_vals, &crs_mons, &omegas_bitreversed, &omegas_inv_bitreversed, None) + .unwrap(); let is_valid = verify::(&proof, &verification_key, None).unwrap(); @@ -2215,42 +1985,36 @@ fn transpile_xor_using_new_adaptor() { // println!("Verification key = {:?}", verification_key); // println!("Proof = {:?}", proof); - let mut key_writer = std::io::BufWriter::with_capacity( - 1<<24, - std::fs::File::create("./xor_vk.key").unwrap() - ); + let mut key_writer = std::io::BufWriter::with_capacity(1 << 24, std::fs::File::create("./xor_vk.key").unwrap()); verification_key.write(&mut key_writer).unwrap(); - let mut proof_writer = std::io::BufWriter::with_capacity( - 1<<24, - std::fs::File::create("./xor_proof.proof").unwrap() - ); + let mut proof_writer = std::io::BufWriter::with_capacity(1 << 24, std::fs::File::create("./xor_proof.proof").unwrap()); proof.write(&mut proof_writer).unwrap(); } #[test] fn transpile_xor_and_prove_with_no_precomputations() { - use crate::tests::XORDemo; - use crate::cs::Circuit; - use crate::pairing::bn256::{Bn256, Fr}; - use super::test_assembly::*; use super::cs::PlonkCsWidth4WithNextStepParams; use super::generator::*; + use super::keys::*; use super::prover::*; - use crate::worker::Worker; + use super::test_assembly::*; + use super::utils::make_non_residues; use super::verifier::*; + use crate::cs::Circuit; use crate::kate_commitment::*; - use crate::plonk::commitments::transcript::*; + use crate::pairing::bn256::{Bn256, Fr}; use crate::plonk::commitments::transcript::keccak_transcript::*; - use crate::plonk::fft::cooley_tukey_ntt::*; - use super::keys::*; + use crate::plonk::commitments::transcript::*; use crate::plonk::domains::Domain; - use super::utils::make_non_residues; + use crate::plonk::fft::cooley_tukey_ntt::*; + use crate::tests::XORDemo; + use crate::worker::Worker; let c = XORDemo:: { a: None, b: None, - _marker: PhantomData + _marker: PhantomData, }; let mut transpiler = Transpiler::::new(); @@ -2272,7 +2036,7 @@ fn transpile_xor_and_prove_with_no_precomputations() { let c = XORDemo:: { a: Some(true), b: Some(false), - _marker: PhantomData + _marker: PhantomData, }; let adapted_curcuit = AdaptorCircuit::::new(c.clone(), &hints); @@ -2293,11 +2057,7 @@ fn transpile_xor_and_prove_with_no_precomputations() { let crs_mons = Crs::::crs_42(setup.permutation_polynomials[0].size(), &worker); - let verification_key = VerificationKey::from_setup( - &setup, - &worker, - &crs_mons - ).unwrap(); + let verification_key = VerificationKey::from_setup(&setup, &worker, &crs_mons).unwrap(); let size = setup.permutation_polynomials[0].size(); @@ -2307,14 +2067,7 @@ fn transpile_xor_and_prove_with_no_precomputations() { type Transcr = RollingKeccakTranscript; - let proof = super::super::prove_by_steps::<_, _, Transcr>( - c, - &hints, - &setup, - None, - &crs_mons, - None - ).unwrap(); + let proof = super::super::prove_by_steps::<_, _, Transcr>(c, &hints, &setup, None, &crs_mons, None).unwrap(); let is_valid = verify::(&proof, &verification_key, None).unwrap(); @@ -2323,15 +2076,9 @@ fn transpile_xor_and_prove_with_no_precomputations() { // println!("Verification key = {:?}", verification_key); // println!("Proof = {:?}", proof); - let mut key_writer = std::io::BufWriter::with_capacity( - 1<<24, - std::fs::File::create("./xor_vk.key").unwrap() - ); + let mut key_writer = std::io::BufWriter::with_capacity(1 << 24, std::fs::File::create("./xor_vk.key").unwrap()); verification_key.write(&mut key_writer).unwrap(); - let mut proof_writer = std::io::BufWriter::with_capacity( - 1<<24, - std::fs::File::create("./xor_proof.proof").unwrap() - ); + let mut proof_writer = std::io::BufWriter::with_capacity(1 << 24, std::fs::File::create("./xor_proof.proof").unwrap()); proof.write(&mut proof_writer).unwrap(); -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_cs/cs.rs b/crates/bellman/src/plonk/better_cs/cs.rs index 9965b26..59307c3 100644 --- a/crates/bellman/src/plonk/better_cs/cs.rs +++ b/crates/bellman/src/plonk/better_cs/cs.rs @@ -1,7 +1,7 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine}; +use crate::pairing::ff::Field; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; pub use crate::plonk::cs::variable::*; @@ -12,12 +12,12 @@ pub trait Circuit> { pub trait CustomGateMarker: Sized {} -// pub trait TraceStepCoefficients<'a, E: Engine>: Sized -// + AsRef<[E::Fr]> -// + Copy -// + Clone -// + PartialEq -// + Eq +// pub trait TraceStepCoefficients<'a, E: Engine>: Sized +// + AsRef<[E::Fr]> +// + Copy +// + Clone +// + PartialEq +// + Eq // + ExactSizeIterator { } // pub trait PlonkConstraintSystemParams where @@ -30,17 +30,12 @@ pub trait CustomGateMarker: Sized {} // type CustomGateType: CustomGateMarker; // } -pub trait TraceStepCoefficients: Sized - + AsRef<[E::Fr]> - + Copy - + Clone - + PartialEq - + Eq { - fn empty() -> Self; - fn identity() -> Self; - fn negate(&mut self); - fn from_coeffs(coeffs: &[E::Fr]) -> Self; - } +pub trait TraceStepCoefficients: Sized + AsRef<[E::Fr]> + Copy + Clone + PartialEq + Eq { + fn empty() -> Self; + fn identity() -> Self; + fn negate(&mut self); + fn from_coeffs(coeffs: &[E::Fr]) -> Self; +} pub trait StateVariablesSet: Sized + AsRef<[Variable]> + Copy + Clone + PartialEq + Eq { fn from_variable_and_padding(variable: Variable, padding: Variable) -> Self; @@ -70,20 +65,15 @@ pub trait ConstraintSystem> { where F: FnOnce() -> Result; - fn new_gate(&mut self, - variables: P::StateVariables, - this_step_coeffs: P::ThisTraceStepCoefficients, - next_step_coeffs: P::NextTraceStepCoefficients - ) -> Result<(), SynthesisError>; + fn new_gate(&mut self, variables: P::StateVariables, this_step_coeffs: P::ThisTraceStepCoefficients, next_step_coeffs: P::NextTraceStepCoefficients) -> Result<(), SynthesisError>; - fn get_value(&self, _variable: Variable) -> Result { + fn get_value(&self, _variable: Variable) -> Result { Err(SynthesisError::AssignmentMissing) } fn get_dummy_variable(&self) -> Variable; } - pub struct NoCustomGate; impl CustomGateMarker for NoCustomGate {} @@ -136,9 +126,7 @@ impl TraceStepCoefficients for [E::Fr; 0] { fn identity() -> Self { [] } - fn negate(&mut self) { - - } + fn negate(&mut self) {} fn from_coeffs(coeffs: &[E::Fr]) -> Self { debug_assert_eq!(coeffs.len(), 0); @@ -244,9 +232,9 @@ impl TraceStepCoefficients for [E::Fr; 6] { #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct PlonkCsWidth3WithNextStepParams; impl PlonkConstraintSystemParams for PlonkCsWidth3WithNextStepParams { - const STATE_WIDTH: usize = 3; - const HAS_CUSTOM_GATES: bool = false; - const CAN_ACCESS_NEXT_TRACE_STEP: bool = true; + const STATE_WIDTH: usize = 3; + const HAS_CUSTOM_GATES: bool = false; + const CAN_ACCESS_NEXT_TRACE_STEP: bool = true; type StateVariables = [Variable; 3]; type ThisTraceStepCoefficients = [E::Fr; 5]; @@ -258,9 +246,9 @@ impl PlonkConstraintSystemParams for PlonkCsWidth3WithNextStepPara #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct PlonkCsWidth4WithNextStepParams; impl PlonkConstraintSystemParams for PlonkCsWidth4WithNextStepParams { - const STATE_WIDTH: usize = 4; - const HAS_CUSTOM_GATES: bool = false; - const CAN_ACCESS_NEXT_TRACE_STEP: bool = true; + const STATE_WIDTH: usize = 4; + const HAS_CUSTOM_GATES: bool = false; + const CAN_ACCESS_NEXT_TRACE_STEP: bool = true; type StateVariables = [Variable; 4]; type ThisTraceStepCoefficients = [E::Fr; 6]; diff --git a/crates/bellman/src/plonk/better_cs/fma_adaptor.rs b/crates/bellman/src/plonk/better_cs/fma_adaptor.rs index 87d9b34..e35a820 100644 --- a/crates/bellman/src/plonk/better_cs/fma_adaptor.rs +++ b/crates/bellman/src/plonk/better_cs/fma_adaptor.rs @@ -1,18 +1,18 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; use crate::SynthesisError; use super::cs::{PlonkConstraintSystemParams, StateVariablesSet, TraceStepCoefficients}; -use crate::plonk::cs::gates::Variable as PlonkVariable; use crate::plonk::cs::gates::Index as PlonkIndex; +use crate::plonk::cs::gates::Variable as PlonkVariable; use super::cs::Circuit as PlonkCircuit; use super::cs::ConstraintSystem as PlonkConstraintSystem; use std::marker::PhantomData; -use std::collections::{HashSet, HashMap}; +use std::collections::{HashMap, HashSet}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum MergeLcVariant { @@ -47,7 +47,7 @@ impl MergeLcVariant { _ => { use std::io::{Error, ErrorKind}; let custom_error = Error::new(ErrorKind::Other, "unknown LC merging variant"); - + return Err(custom_error); } }; @@ -83,7 +83,7 @@ impl LcTransformationVariant { _ => { use std::io::{Error, ErrorKind}; let custom_error = Error::new(ErrorKind::Other, "unknown LC transformation variant"); - + return Err(custom_error); } }; @@ -121,13 +121,13 @@ pub enum TranspilationVariant { IntoAdditionGate(LcTransformationVariant), MergeLinearCombinations(MergeLcVariant, LcTransformationVariant), IntoMultiplicationGate((LcTransformationVariant, LcTransformationVariant, LcTransformationVariant)), - IntoFMAGate((LcTransformationVariant, LcTransformationVariant, LcTransformationVariant)) + IntoFMAGate((LcTransformationVariant, LcTransformationVariant, LcTransformationVariant)), } -use std::io::{Read, Write}; +use crate::byteorder::BigEndian; use crate::byteorder::ReadBytesExt; use crate::byteorder::WriteBytesExt; -use crate::byteorder::BigEndian; +use std::io::{Read, Write}; impl TranspilationVariant { pub fn into_u8(&self) -> u8 { @@ -140,11 +140,7 @@ impl TranspilationVariant { } } - pub fn write( - &self, - mut writer: W - ) -> std::io::Result<()> - { + pub fn write(&self, mut writer: W) -> std::io::Result<()> { let prefix = self.into_u8(); writer.write_u8(prefix)?; match self { @@ -158,46 +154,44 @@ impl TranspilationVariant { let subhint = subhint.into_u8(); writer.write_u8(subhint)?; - }, + } TranspilationVariant::IntoMultiplicationGate(hints) => { let (h_a, h_b, h_c) = hints; writer.write_u8(h_a.into_u8())?; writer.write_u8(h_b.into_u8())?; writer.write_u8(h_c.into_u8())?; - }, - _ => { } + _ => {} } Ok(()) } - pub fn read( - mut reader: R - ) -> std::io::Result - { + pub fn read(mut reader: R) -> std::io::Result { let prefix = reader.read_u8()?; match prefix { - 1u8 => {return Ok(TranspilationVariant::IntoQuadraticGate); }, + 1u8 => { + return Ok(TranspilationVariant::IntoQuadraticGate); + } 2u8 => { let subhint = LcTransformationVariant::from_u8(reader.read_u8()?)?; - + return Ok(TranspilationVariant::IntoAdditionGate(subhint)); - }, + } 3u8 => { let variant = MergeLcVariant::from_u8(reader.read_u8()?)?; let subhint = LcTransformationVariant::from_u8(reader.read_u8()?)?; - + return Ok(TranspilationVariant::MergeLinearCombinations(variant, subhint)); - }, + } 4u8 => { let subhint_a = LcTransformationVariant::from_u8(reader.read_u8()?)?; let subhint_b = LcTransformationVariant::from_u8(reader.read_u8()?)?; let subhint_c = LcTransformationVariant::from_u8(reader.read_u8()?)?; - + return Ok(TranspilationVariant::IntoMultiplicationGate((subhint_a, subhint_b, subhint_c))); - }, + } _ => {} } @@ -205,12 +199,10 @@ impl TranspilationVariant { let custom_error = Error::new(ErrorKind::Other, "unknown transpilation variant"); Err(custom_error) - } + } } -pub fn read_transpilation_hints( - mut reader: R -) -> std::io::Result> { +pub fn read_transpilation_hints(mut reader: R) -> std::io::Result> { let num_hints = reader.read_u64::()?; let mut hints = Vec::with_capacity(num_hints as usize); @@ -223,10 +215,7 @@ pub fn read_transpilation_hints( Ok(hints) } -pub fn write_transpilation_hints( - hints: &Vec<(usize, TranspilationVariant)>, - mut writer: W -) -> std::io::Result<()> { +pub fn write_transpilation_hints(hints: &Vec<(usize, TranspilationVariant)>, mut writer: W) -> std::io::Result<()> { writer.write_u64::(hints.len() as u64)?; for (idx, h) in hints.iter() { writer.write_u64::(*idx as u64)?; @@ -241,25 +230,25 @@ impl std::fmt::Debug for TranspilationVariant { match self { TranspilationVariant::IntoQuadraticGate => { writeln!(f, "Variant: into quadratic gate")?; - }, + } TranspilationVariant::IntoAdditionGate(_) => { writeln!(f, "Variant: make an addition gate")?; - }, + } TranspilationVariant::MergeLinearCombinations(merge_type, _) => { writeln!(f, "Variant: merge linear combinations as {:?}", merge_type)?; - }, + } TranspilationVariant::IntoMultiplicationGate(b) => { writeln!(f, "Variant: into combinatoric multiplication gate")?; writeln!(f, "A: {:?}", b.0)?; writeln!(f, "B: {:?}", b.1)?; writeln!(f, "C: {:?}", b.2)?; - }, + } TranspilationVariant::IntoFMAGate(b) => { writeln!(f, "Variant: into FMA gate")?; writeln!(f, "A: {:?}", b.0)?; writeln!(f, "B: {:?}", b.1)?; writeln!(f, "C: {:?}", b.2)?; - }, + } } Ok(()) @@ -275,44 +264,40 @@ pub struct Transpiler> { transpilation_scratch_space: Option>, hints: Vec<(usize, TranspilationVariant)>, _marker_e: std::marker::PhantomData, - _marker_p: std::marker::PhantomData

+ _marker_p: std::marker::PhantomData

, } // by convention last coefficient is a coefficient for a jump to the next step -fn allocate_into_cs, CS: PlonkConstraintSystem> ( +fn allocate_into_cs, CS: PlonkConstraintSystem>( cs: &mut CS, needs_next_step: bool, variables: &[PlonkVariable], - coefficients: &[E::Fr] + coefficients: &[E::Fr], ) -> Result<(), SynthesisError> { if needs_next_step { debug_assert!(coefficients.len() == P::STATE_WIDTH + 1 + 1 + 1); debug_assert!(P::CAN_ACCESS_NEXT_TRACE_STEP); cs.new_gate( - P::StateVariables::from_variables(variables), - P::ThisTraceStepCoefficients::from_coeffs(&coefficients[0..(P::STATE_WIDTH+2)]), - P::NextTraceStepCoefficients::from_coeffs(&coefficients[(P::STATE_WIDTH+2)..]) + P::StateVariables::from_variables(variables), + P::ThisTraceStepCoefficients::from_coeffs(&coefficients[0..(P::STATE_WIDTH + 2)]), + P::NextTraceStepCoefficients::from_coeffs(&coefficients[(P::STATE_WIDTH + 2)..]), )?; } else { debug_assert!(coefficients.len() >= P::STATE_WIDTH + 1 + 1); debug_assert!(coefficients.last().unwrap().is_zero()); cs.new_gate( - P::StateVariables::from_variables(variables), - P::ThisTraceStepCoefficients::from_coeffs(&coefficients[0..(P::STATE_WIDTH+2)]), - P::NextTraceStepCoefficients::from_coeffs(&coefficients[(P::STATE_WIDTH+2)..]) + P::StateVariables::from_variables(variables), + P::ThisTraceStepCoefficients::from_coeffs(&coefficients[0..(P::STATE_WIDTH + 2)]), + P::NextTraceStepCoefficients::from_coeffs(&coefficients[(P::STATE_WIDTH + 2)..]), )?; } Ok(()) } -fn evaluate_lc, CS: PlonkConstraintSystem>( - cs: &CS, - lc: &LinearCombination, - free_term_constant: E::Fr -) -> Result { +fn evaluate_lc, CS: PlonkConstraintSystem>(cs: &CS, lc: &LinearCombination, free_term_constant: E::Fr) -> Result { let mut final_value = E::Fr::zero(); for (var, coeff) in lc.as_ref().iter() { let mut may_be_value = cs.get_value(convert_variable(*var))?; @@ -328,7 +313,7 @@ fn evaluate_lc, CS: PlonkConstraint fn evaluate_over_variables, CS: PlonkConstraintSystem>( cs: &CS, variables: &[(Variable, E::Fr)], - free_term_constant: E::Fr + free_term_constant: E::Fr, ) -> Result { let mut final_value = E::Fr::zero(); for (var, coeff) in variables.iter() { @@ -345,8 +330,8 @@ fn evaluate_over_variables, CS: Plo fn evaluate_over_plonk_variables, CS: PlonkConstraintSystem>( cs: &CS, variables: &[(PlonkVariable, E::Fr)], - // multiplier: E::Fr, - free_term_constant: E::Fr + // multiplier: E::Fr, + free_term_constant: E::Fr, ) -> Result { let mut final_value = E::Fr::zero(); for (var, coeff) in variables.iter() { @@ -364,7 +349,7 @@ fn evaluate_over_plonk_variables_and_coeffs Result { debug_assert_eq!(variables.len(), coeffs.len()); let mut final_value = E::Fr::zero(); @@ -380,12 +365,12 @@ fn evaluate_over_plonk_variables_and_coeffs, CS: PlonkConstraintSystem>( - cs: &mut CS, - mut lc: LinearCombination, - multiplier: E::Fr, + cs: &mut CS, + mut lc: LinearCombination, + multiplier: E::Fr, free_term_constant: E::Fr, collapse_into_single_variable: bool, // we use this when we later want to make a multiplication gate - try_fma: bool, // we indicate that we want to transpile C query + try_fma: bool, // we indicate that we want to transpile C query scratch_space: &mut TranspilationScratchSpace, ) -> Result<(Option, E::Fr, LcTransformationVariant, bool), SynthesisError> { assert!(P::CAN_ACCESS_NEXT_TRACE_STEP, "Transliper only works for proof systems with access to next step"); @@ -406,14 +391,14 @@ fn enforce_lc_as_gates, CS: PlonkCo if lc.0.len() == 1 { if free_term_constant.is_zero() { // this linear combination contains only one variable and no constant - // term, so we just leave it as is, + // term, so we just leave it as is, // but ONLY if we just need to collapse LC into a variable if collapse_into_single_variable { let (var, coeff) = lc.0[0]; return Ok((Some(convert_variable(var)), coeff, LcTransformationVariant::IsSingleVariable, false)); } - } + } } // everything else should be handled here by making a new variable @@ -431,15 +416,13 @@ fn enforce_lc_as_gates, CS: PlonkCo } } - // if we need to collaplse an LC into a single variable for + // if we need to collaplse an LC into a single variable for // future use we allocate it and then subtract it from linear combination // to have an enforcement LC == 0 in all the cases let final_variable = if collapse_into_single_variable { let may_be_new_value = evaluate_lc::(&*cs, &lc, free_term_constant); - let new_var = cs.alloc(|| { - may_be_new_value - })?; + let new_var = cs.alloc(|| may_be_new_value)?; Some(new_var) } else { @@ -452,7 +435,7 @@ fn enforce_lc_as_gates, CS: PlonkCo let num_terms = lc.0.len(); - // we have two options: + // we have two options: // - fit everything into a single gate (in case of number terms in the linear combination // smaller than a width of the state) // - make a required number of extra variables and chain it @@ -489,12 +472,7 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(free_term_constant); // add constant scratch_space.scratch_space_for_coeffs.push(minus_one_fr); // -1 for a d_next - allocate_into_cs( - cs, - true, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs - )?; + allocate_into_cs(cs, true, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs)?; scratch_space.clear(); @@ -502,7 +480,7 @@ fn enforce_lc_as_gates, CS: PlonkCo return Ok((Some(convert_variable(fma_variable)), one_fr, hint, true)); } - + if num_terms <= P::STATE_WIDTH { // we can just make a single gate @@ -530,12 +508,7 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(free_term_constant); scratch_space.scratch_space_for_coeffs.push(zero_fr); - allocate_into_cs( - cs, - false, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs - )?; + allocate_into_cs(cs, false, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs)?; scratch_space.clear(); @@ -548,18 +521,18 @@ fn enforce_lc_as_gates, CS: PlonkCo // - every time take STATE_WIDTH-1 variables and place their sum + last wire into the next gate last wire // we have also made a final variable already, so there is NO difference - let cycles = ((lc.0.len() - P::STATE_WIDTH) + (P::STATE_WIDTH - 2)) / (P::STATE_WIDTH - 1); // ceil + let cycles = ((lc.0.len() - P::STATE_WIDTH) + (P::STATE_WIDTH - 2)) / (P::STATE_WIDTH - 1); // ceil let mut it = lc.0.into_iter(); - // this is a placeholder variable that must go into the - // corresponding trace polynomial at the NEXT time step + // this is a placeholder variable that must go into the + // corresponding trace polynomial at the NEXT time step let mut next_step_var_in_chain = { scratch_space.scratch_space_for_vars.resize(P::STATE_WIDTH, cs.get_dummy_variable()); scratch_space.scratch_space_for_booleans.resize(P::STATE_WIDTH, false); scratch_space.scratch_space_for_coeffs.resize(P::STATE_WIDTH, zero_fr); - + // we can consume and never have leftovers - + let mut idx = 0; for (var, coeff) in &mut it { if scratch_space.scratch_space_for_booleans[idx] == false { @@ -575,17 +548,11 @@ fn enforce_lc_as_gates, CS: PlonkCo // for a P::STATE_WIDTH variables we make a corresponding LC // ~ a + b + c + d + constant. That will be equal to d_next - let may_be_new_intermediate_value = evaluate_over_plonk_variables_and_coeffs::( - &*cs, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs, - free_term_constant - ); + let may_be_new_intermediate_value = + evaluate_over_plonk_variables_and_coeffs::(&*cs, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs, free_term_constant); // we manually allocate the new variable - let new_intermediate_var = cs.alloc(|| { - may_be_new_intermediate_value - })?; + let new_intermediate_var = cs.alloc(|| may_be_new_intermediate_value)?; // no multiplication coefficient, // but -1 to link to the next trace step (we enforce == 0) @@ -593,12 +560,7 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(free_term_constant); // add constant scratch_space.scratch_space_for_coeffs.push(minus_one_fr); // -1 for a d_next - allocate_into_cs( - cs, - true, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs - )?; + allocate_into_cs(cs, true, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs)?; scratch_space.clear(); @@ -607,16 +569,16 @@ fn enforce_lc_as_gates, CS: PlonkCo // run over the rest - // we can only take one less cause + // we can only take one less cause // we've already used one of the variable - let consume_from_lc = P::STATE_WIDTH - 1; - for _ in 0..(cycles-1) { + let consume_from_lc = P::STATE_WIDTH - 1; + for _ in 0..(cycles - 1) { scratch_space.scratch_space_for_vars.resize(consume_from_lc, cs.get_dummy_variable()); scratch_space.scratch_space_for_booleans.resize(consume_from_lc, false); scratch_space.scratch_space_for_coeffs.resize(consume_from_lc, zero_fr); - + // we can consume and never have leftovers - + let mut idx = 0; for (var, coeff) in &mut it { if scratch_space.scratch_space_for_booleans[idx] == false { @@ -635,16 +597,9 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(one_fr); scratch_space.scratch_space_for_vars.push(next_step_var_in_chain); - let may_be_new_intermediate_value = evaluate_over_plonk_variables_and_coeffs::( - &*cs, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs, - zero_fr - ); + let may_be_new_intermediate_value = evaluate_over_plonk_variables_and_coeffs::(&*cs, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs, zero_fr); - let new_intermediate_var = cs.alloc(|| { - may_be_new_intermediate_value - })?; + let new_intermediate_var = cs.alloc(|| may_be_new_intermediate_value)?; // no multiplication coefficient and no constant now, // but -1 to link to the next trace step @@ -652,12 +607,7 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(zero_fr); scratch_space.scratch_space_for_coeffs.push(minus_one_fr); - allocate_into_cs( - cs, - true, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs - )?; + allocate_into_cs(cs, true, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs)?; scratch_space.clear(); @@ -666,12 +616,12 @@ fn enforce_lc_as_gates, CS: PlonkCo // final step - we just make a single gate, last one { - scratch_space.scratch_space_for_vars.resize(P::STATE_WIDTH-1, cs.get_dummy_variable()); - scratch_space.scratch_space_for_booleans.resize(P::STATE_WIDTH-1, false); - scratch_space.scratch_space_for_coeffs.resize(P::STATE_WIDTH-1, zero_fr); - + scratch_space.scratch_space_for_vars.resize(P::STATE_WIDTH - 1, cs.get_dummy_variable()); + scratch_space.scratch_space_for_booleans.resize(P::STATE_WIDTH - 1, false); + scratch_space.scratch_space_for_coeffs.resize(P::STATE_WIDTH - 1, zero_fr); + // we can consume and never have leftovers - + let mut idx = 0; for (var, coeff) in &mut it { if scratch_space.scratch_space_for_booleans[idx] == false { @@ -692,12 +642,7 @@ fn enforce_lc_as_gates, CS: PlonkCo scratch_space.scratch_space_for_coeffs.push(zero_fr); scratch_space.scratch_space_for_coeffs.push(zero_fr); - allocate_into_cs( - cs, - false, - &*scratch_space.scratch_space_for_vars, - &*scratch_space.scratch_space_for_coeffs - )?; + allocate_into_cs(cs, false, &*scratch_space.scratch_space_for_vars, &*scratch_space.scratch_space_for_coeffs)?; scratch_space.clear(); } @@ -706,7 +651,7 @@ fn enforce_lc_as_gates, CS: PlonkCo let hint = LcTransformationVariant::IntoMultipleGates; - return Ok((final_variable, one_fr, hint, false)); + return Ok((final_variable, one_fr, hint, false)); } } @@ -721,7 +666,7 @@ impl> Transpiler { transpilation_scratch_space: Some(TranspilationScratchSpace::::new(P::STATE_WIDTH * 2)), hints: vec![], _marker_e: std::marker::PhantomData, - _marker_p: std::marker::PhantomData + _marker_p: std::marker::PhantomData, } } @@ -740,12 +685,9 @@ impl> Transpiler { impl> PlonkConstraintSystem for Transpiler { fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - let var = crate::ConstraintSystem::::alloc( - self, - || "alloc aux var", - value)?; + let var = crate::ConstraintSystem::::alloc(self, || "alloc aux var", value)?; Ok(convert_variable(var)) } @@ -753,20 +695,13 @@ impl> PlonkConstraintSystem f // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - let var = crate::ConstraintSystem::::alloc_input( - self, - || "alloc input var", - value)?; + let var = crate::ConstraintSystem::::alloc_input(self, || "alloc input var", value)?; Ok(convert_variable(var)) } - fn new_gate(&mut self, - _variables: P::StateVariables, - _this_step_coeffs: P::ThisTraceStepCoefficients, - _next_step_coeffs: P::NextTraceStepCoefficients - ) -> Result<(), SynthesisError> { + fn new_gate(&mut self, _variables: P::StateVariables, _this_step_coeffs: P::ThisTraceStepCoefficients, _next_step_coeffs: P::NextTraceStepCoefficients) -> Result<(), SynthesisError> { // Transpiler does NOT allocate any gates himself Ok(()) } @@ -779,12 +714,9 @@ impl> PlonkConstraintSystem f impl<'a, E: Engine, P: PlonkConstraintSystemParams> PlonkConstraintSystem for &'a mut Transpiler { fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - let var = crate::ConstraintSystem::::alloc( - self, - || "alloc aux var", - value)?; + let var = crate::ConstraintSystem::::alloc(self, || "alloc aux var", value)?; Ok(convert_variable(var)) } @@ -792,20 +724,13 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams> PlonkConstraintSystem(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - let var = crate::ConstraintSystem::::alloc_input( - self, - || "alloc input var", - value)?; + let var = crate::ConstraintSystem::::alloc_input(self, || "alloc input var", value)?; Ok(convert_variable(var)) } - fn new_gate(&mut self, - _variables: P::StateVariables, - _this_step_coeffs: P::ThisTraceStepCoefficients, - _next_step_coeffs: P::NextTraceStepCoefficients - ) -> Result<(), SynthesisError> { + fn new_gate(&mut self, _variables: P::StateVariables, _this_step_coeffs: P::ThisTraceStepCoefficients, _next_step_coeffs: P::NextTraceStepCoefficients) -> Result<(), SynthesisError> { // Transpiler does NOT allocate any gates himself Ok(()) } @@ -815,8 +740,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams> PlonkConstraintSystem> crate::ConstraintSystem for Transpiler -{ +impl> crate::ConstraintSystem for Transpiler { type Root = Self; fn one() -> crate::Variable { @@ -834,11 +758,7 @@ impl> crate::ConstraintSystem fo Ok(crate::Variable::new_unchecked(crate::Index::Aux(self.current_plonk_aux_idx))) } - fn alloc_input( - &mut self, - _: A, - _f: F, - ) -> Result + fn alloc_input(&mut self, _: A, _f: F) -> Result where F: FnOnce() -> Result, A: FnOnce() -> AR, @@ -859,7 +779,7 @@ impl> crate::ConstraintSystem fo { // let ann: String = _ann().into(); // if ann.contains("y-coordinate lookup") { - // // + // // // let _t = E::Fr::one(); // }; // println!("Enforce {}", ann); @@ -891,7 +811,7 @@ impl> crate::ConstraintSystem fo match (a_is_constant, b_is_constant, c_is_constant) { (true, true, true) => { unreachable!("R1CS has a gate 1 * 1 = 1"); - }, + } (true, false, true) | (false, true, true) => { // println!("C * LC = C"); // we have something like c0 * LC = c1 @@ -926,15 +846,7 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_, _, hint, _) = enforce_lc_as_gates( - self, - lc, - multiplier, - free_constant_term, - false, - false, - &mut space - ).expect("must allocate LCs as gates for constraint like c0 * LC = c1"); + let (_, _, hint, _) = enforce_lc_as_gates(self, lc, multiplier, free_constant_term, false, false, &mut space).expect("must allocate LCs as gates for constraint like c0 * LC = c1"); self.transpilation_scratch_space = Some(space); @@ -945,19 +857,12 @@ impl> crate::ConstraintSystem fo self.hints.push((current_lc_number, TranspilationVariant::IntoAdditionGate(hint))); return; - }, + } (false, false, true) => { - // println!("LC * LC = C"); + // println!("LC * LC = C"); // potential quadatic gate, but ig general // it's a full multiplication gate - let (is_quadratic_gate, _coeffs) = check_for_quadratic_gate::( - &a_lc, - &b_lc, - &c_lc, - a_constant_term, - b_constant_term, - c_constant_term - ); + let (is_quadratic_gate, _coeffs) = check_for_quadratic_gate::(&a_lc, &b_lc, &c_lc, a_constant_term, b_constant_term, c_constant_term); if is_quadratic_gate { let current_lc_number = self.increment_lc_number(); @@ -972,25 +877,11 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_new_a_var, _, hint_a, _) = enforce_lc_as_gates( - self, - a_lc, - one_fr, - a_constant_term, - true, - false, - &mut space - ).expect("must allocate A LC as gates for constraint like LC * LC = c1"); - - let (_new_b_var, _, hint_b, _) = enforce_lc_as_gates( - self, - b_lc, - one_fr, - b_constant_term, - true, - false, - &mut space - ).expect("must allocate B LC as gates for constraint like LC * LC = c1"); + let (_new_a_var, _, hint_a, _) = + enforce_lc_as_gates(self, a_lc, one_fr, a_constant_term, true, false, &mut space).expect("must allocate A LC as gates for constraint like LC * LC = c1"); + + let (_new_b_var, _, hint_b, _) = + enforce_lc_as_gates(self, b_lc, one_fr, b_constant_term, true, false, &mut space).expect("must allocate B LC as gates for constraint like LC * LC = c1"); self.transpilation_scratch_space = Some(space); @@ -1003,8 +894,7 @@ impl> crate::ConstraintSystem fo // println!("Hint = {:?}", hint); self.hints.push((current_lc_number, hint)); - - }, + } (true, false, false) | (false, true, false) => { // sometihng like LC * const = LC // so we can merge them into one long linear combination @@ -1029,15 +919,7 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_, _, hint_c, _) = enforce_lc_as_gates( - self, - c_lc, - one_fr, - zero_fr, - false, - false, - &mut space - ).expect("must allocate LCs as gates for constraint like 0 = LC_C"); + let (_, _, hint_c, _) = enforce_lc_as_gates(self, c_lc, one_fr, zero_fr, false, false, &mut space).expect("must allocate LCs as gates for constraint like 0 = LC_C"); self.transpilation_scratch_space = Some(space); @@ -1075,15 +957,8 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_, _, hint_lc, _) = enforce_lc_as_gates( - self, - final_lc, - one_fr, - free_constant_term, - false, - false, - &mut space - ).expect("must allocate LCs as gates for constraint like c0 * LC = LC"); + let (_, _, hint_lc, _) = + enforce_lc_as_gates(self, final_lc, one_fr, free_constant_term, false, false, &mut space).expect("must allocate LCs as gates for constraint like c0 * LC = LC"); self.transpilation_scratch_space = Some(space); @@ -1096,8 +971,7 @@ impl> crate::ConstraintSystem fo self.hints.push((current_lc_number, hint)); return; - - }, + } (true, true, false) => { // const * const = LC // A and B are some constants @@ -1107,15 +981,7 @@ impl> crate::ConstraintSystem fo let mut space = self.transpilation_scratch_space.take().unwrap(); - let (_, _, hint_lc, _) = enforce_lc_as_gates( - self, - c_lc, - one_fr, - free_constant_term, - false, - false, - &mut space - ).expect("must allocate LCs as gates for constraint like c0 * c1 = LC"); + let (_, _, hint_lc, _) = enforce_lc_as_gates(self, c_lc, one_fr, free_constant_term, false, false, &mut space).expect("must allocate LCs as gates for constraint like c0 * c1 = LC"); self.transpilation_scratch_space = Some(space); @@ -1126,15 +992,11 @@ impl> crate::ConstraintSystem fo // println!("Hint = {:?}", hint); self.hints.push((current_lc_number, hint)); - - }, + } (false, false, false) => { // LC * LC = LC // potentially it can still be quadratic - let (is_quadratic_gate, _coeffs) = is_quadratic_gate::( - &a_lc, - &b_lc, - &c_lc, &mut self.scratch); + let (is_quadratic_gate, _coeffs) = is_quadratic_gate::(&a_lc, &b_lc, &c_lc, &mut self.scratch); if is_quadratic_gate { let current_lc_number = self.increment_lc_number(); @@ -1150,34 +1012,13 @@ impl> crate::ConstraintSystem fo // rewrite into addition gates and multiplication gates let mut space = self.transpilation_scratch_space.take().unwrap(); - - let (_new_a_var, _, hint_a, _) = enforce_lc_as_gates( - self, - a_lc, - one_fr, - a_constant_term, - true, - false, - &mut space - ).expect("must allocate A LC as gates for constraint like LC * LC = LC"); - let (_new_b_var, _, hint_b, _) = enforce_lc_as_gates( - self, - b_lc, - one_fr, - b_constant_term, - true, - false, - &mut space - ).expect("must allocate B LC as gates for constraint like LC * LC = LC"); - let (_new_c_var, _, hint_c, can_use_fma) = enforce_lc_as_gates( - self, - c_lc, - one_fr, - c_constant_term, - true, - true, - &mut space - ).expect("must allocate C LC as gates for constraint like LC * LC = LC"); + + let (_new_a_var, _, hint_a, _) = + enforce_lc_as_gates(self, a_lc, one_fr, a_constant_term, true, false, &mut space).expect("must allocate A LC as gates for constraint like LC * LC = LC"); + let (_new_b_var, _, hint_b, _) = + enforce_lc_as_gates(self, b_lc, one_fr, b_constant_term, true, false, &mut space).expect("must allocate B LC as gates for constraint like LC * LC = LC"); + let (_new_c_var, _, hint_c, can_use_fma) = + enforce_lc_as_gates(self, c_lc, one_fr, c_constant_term, true, true, &mut space).expect("must allocate C LC as gates for constraint like LC * LC = LC"); self.transpilation_scratch_space = Some(space); @@ -1189,10 +1030,9 @@ impl> crate::ConstraintSystem fo TranspilationVariant::IntoMultiplicationGate((hint_a, hint_b, hint_c)) }; - self.hints.push((current_lc_number, hint)); } - } + } } fn push_namespace(&mut self, _: N) @@ -1214,16 +1054,16 @@ impl> crate::ConstraintSystem fo // List of heuristics -use crate::{LinearCombination, ConstraintSystem, Variable}; +use crate::{ConstraintSystem, LinearCombination, Variable}; fn is_quadratic_gate>( - a: &LinearCombination, - b: &LinearCombination, + a: &LinearCombination, + b: &LinearCombination, c: &LinearCombination, - scratch: &mut HashSet:: + scratch: &mut HashSet, ) -> (bool, (E::Fr, E::Fr, E::Fr)) { let zero = E::Fr::zero(); - + let (_a_containts_constant, a_constant_coeff) = get_constant_term::(&a); let (_b_containts_constant, b_constant_coeff) = get_constant_term::(&b); let (_c_containts_constant, c_constant_coeff) = get_constant_term::(&c); @@ -1272,14 +1112,14 @@ fn is_quadratic_gate>( } return (true, (constant_term, linear_term, quadratic_term)); - } + } (false, (zero, zero, zero)) } fn check_for_quadratic_gate( - a: &LinearCombination, - b: &LinearCombination, + a: &LinearCombination, + b: &LinearCombination, c: &LinearCombination, a_constant_term: E::Fr, b_constant_term: E::Fr, @@ -1348,7 +1188,7 @@ fn check_for_quadratic_gate( } return (true, (constant_term, linear_term, quadratic_term)); - } + } (false, (zero, zero, zero)) } @@ -1358,7 +1198,7 @@ fn is_constant>(lc: &LinearCombination) -> if lc.as_ref().len() == 0 { return (true, E::Fr::zero()); } - + let result = get_constant_term::(&lc); if result.0 && lc.as_ref().len() == 1 { @@ -1370,7 +1210,7 @@ fn is_constant>(lc: &LinearCombination) -> fn get_constant_term>(lc: &LinearCombination) -> (bool, E::Fr) { let cs_one = CS::one(); - + for (var, coeff) in lc.as_ref().iter() { if var == &cs_one { return (true, *coeff); @@ -1382,7 +1222,7 @@ fn get_constant_term>(lc: &LinearCombination< fn get_first_variable>(lc: &LinearCombination) -> (bool, Variable) { let cs_one = CS::one(); - + for (var, _) in lc.as_ref().iter() { if var != &cs_one { return (true, *var); @@ -1394,7 +1234,7 @@ fn get_first_variable>(lc: &LinearCombination fn get_first_variable_with_coeff>(lc: &LinearCombination) -> (bool, Variable, E::Fr) { let cs_one = CS::one(); - + for (var, coeff) in lc.as_ref().iter() { if var != &cs_one { return (true, *var, *coeff); @@ -1404,11 +1244,11 @@ fn get_first_variable_with_coeff>(lc: &Linear (false, cs_one, E::Fr::zero()) } -fn num_unique_values>(lc: &LinearCombination, scratch: &mut HashSet::) -> (bool, usize) { +fn num_unique_values>(lc: &LinearCombination, scratch: &mut HashSet) -> (bool, usize) { let cs_one = CS::one(); debug_assert!(scratch.is_empty()); - + let mut contains_constant = false; for (var, _) in lc.as_ref().iter() { @@ -1426,11 +1266,11 @@ fn num_unique_values>(lc: &LinearCombination< (contains_constant, num_unique_without_constant) } -fn is_linear_term>(lc: &LinearCombination, scratch: &mut HashSet::) -> (bool, Variable, E::Fr) { +fn is_linear_term>(lc: &LinearCombination, scratch: &mut HashSet) -> (bool, Variable, E::Fr) { let cs_one = CS::one(); debug_assert!(scratch.is_empty()); - + let mut linear_coeff = E::Fr::zero(); for (var, coeff) in lc.as_ref().iter() { @@ -1446,18 +1286,15 @@ fn is_linear_term>(lc: &LinearCombination, let terms: Vec<_> = scratch.drain().collect(); let term = terms[0]; - return (true, term, linear_coeff) + return (true, term, linear_coeff); } else { scratch.clear(); - return (false, cs_one, E::Fr::zero()) - } + return (false, cs_one, E::Fr::zero()); + } } -fn deduplicate_stable>( - lc: LinearCombination, - scratch: &mut HashMap -) -> LinearCombination { +fn deduplicate_stable>(lc: LinearCombination, scratch: &mut HashMap) -> LinearCombination { assert!(scratch.is_empty()); if lc.as_ref().len() == 0 { @@ -1494,10 +1331,7 @@ fn deduplicate_stable>( LinearCombination(deduped_vec) } -fn deduplicate_and_split_linear_term>( - lc: LinearCombination, - scratch: &mut HashMap -) -> (bool, E::Fr, bool, LinearCombination) { +fn deduplicate_and_split_linear_term>(lc: LinearCombination, scratch: &mut HashMap) -> (bool, E::Fr, bool, LinearCombination) { assert!(scratch.is_empty()); if lc.as_ref().len() == 0 { @@ -1547,11 +1381,11 @@ fn deduplicate_and_split_linear_term>( fn subtract_lcs_with_dedup_stable>( lc_0: LinearCombination, lc_1: LinearCombination, - scratch: &mut HashMap + scratch: &mut HashMap, ) -> LinearCombination { assert!(scratch.is_empty()); - if lc_0.as_ref().len() == 0 && lc_1.as_ref().len() == 0{ + if lc_0.as_ref().len() == 0 && lc_1.as_ref().len() == 0 { return lc_0; } @@ -1598,19 +1432,14 @@ fn subtract_lcs_with_dedup_stable>( LinearCombination(deduped_vec) } -fn subtract_variable_unchecked( - lc: &mut LinearCombination, - variable: Variable -) { +fn subtract_variable_unchecked(lc: &mut LinearCombination, variable: Variable) { let mut minus_one = E::Fr::one(); minus_one.negate(); lc.0.push((variable, minus_one)); } -fn split_constant_term>( - mut lc: LinearCombination, -) -> (LinearCombination, E::Fr) { +fn split_constant_term>(mut lc: LinearCombination) -> (LinearCombination, E::Fr) { if lc.as_ref().len() == 0 { return (lc, E::Fr::zero()); } @@ -1635,7 +1464,6 @@ fn split_constant_term>( } } - pub struct Adaptor<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem + 'a> { cs: &'a mut CS, hints: &'a Vec<(usize, TranspilationVariant)>, @@ -1679,9 +1507,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem } } -impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem - for Adaptor<'a, E, P, CS> -{ +impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem + 'a> crate::ConstraintSystem for Adaptor<'a, E, P, CS> { type Root = Self; fn one() -> crate::Variable { @@ -1694,9 +1520,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem A: FnOnce() -> AR, AR: Into, { - let var = self.cs.alloc(|| { - f().map_err(|_| crate::SynthesisError::AssignmentMissing) - })?; + let var = self.cs.alloc(|| f().map_err(|_| crate::SynthesisError::AssignmentMissing))?; Ok(match var { PlonkVariable(PlonkIndex::Aux(index)) => crate::Variable::new_unchecked(crate::Index::Aux(index)), @@ -1704,19 +1528,13 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem }) } - fn alloc_input( - &mut self, - _: A, - f: F, - ) -> Result + fn alloc_input(&mut self, _: A, f: F) -> Result where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into, { - let var = self.cs.alloc_input(|| { - f().map_err(|_| crate::SynthesisError::AssignmentMissing) - })?; + let var = self.cs.alloc_input(|| f().map_err(|_| crate::SynthesisError::AssignmentMissing))?; Ok(match var { PlonkVariable(PlonkIndex::Input(index)) => crate::Variable::new_unchecked(crate::Index::Input(index)), @@ -1737,9 +1555,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem let mut minus_one_fr = E::Fr::one(); minus_one_fr.negate(); - let (_, hint) = { - self.get_next_hint() - }; + let (_, hint) = { self.get_next_hint() }; let _hint = hint.clone(); @@ -1795,14 +1611,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem unreachable!(); }; - let (is_quadratic, coeffs) = check_for_quadratic_gate( - &a_lc, - &b_lc, - &c_lc, - a_constant_term, - b_constant_term, - c_constant_term - ); + let (is_quadratic, coeffs) = check_for_quadratic_gate(&a_lc, &b_lc, &c_lc, a_constant_term, b_constant_term, c_constant_term); debug_assert!(is_quadratic); @@ -1820,18 +1629,13 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem space.scratch_space_for_vars[0] = var; space.scratch_space_for_vars[1] = var; - allocate_into_cs( - self.cs, - false, - &*space.scratch_space_for_vars, - &*space.scratch_space_for_coeffs - ).expect("must make a quadratic gate"); + allocate_into_cs(self.cs, false, &*space.scratch_space_for_vars, &*space.scratch_space_for_coeffs).expect("must make a quadratic gate"); // self.cs.new_gate( // (var, var, dummy_var), // [c1, zero_fr, zero_fr, c2, c0, zero_fr] // ).expect("must make a quadratic gate"); - }, + } TranspilationVariant::IntoMultiplicationGate(hints) => { // let ann: String = _ann().into(); // if ann.contains("(a - b) * x == r - 1") { @@ -1842,95 +1646,75 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem let mut q_m = one_fr; let mut q_c = one_fr; let a_var = match t_a { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_a_var, a_coeff, _variant, _) = enforce_lc_as_gates( - self.cs, - a_lc, - one_fr, - a_constant_term, - true, - false, - &mut space - ).expect("must allocate A variable to transpile A LC for multiplication gate"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_a_var, a_coeff, _variant, _) = + enforce_lc_as_gates(self.cs, a_lc, one_fr, a_constant_term, true, false, &mut space).expect("must allocate A variable to transpile A LC for multiplication gate"); assert!(a_coeff == one_fr); assert!(_variant == hint); new_a_var.expect("transpiler must create a new variable for LC A") - }, + } LcTransformationVariant::IsSingleVariable => { assert!(!a_lc_is_empty); let (var, coeff) = a_lc.0[0]; q_m.mul_assign(&coeff); // collapse coeff before A*B convert_variable(var) - }, - _ => {unreachable!("{:?}", t_a)} + } + _ => { + unreachable!("{:?}", t_a) + } }; let b_var = match t_b { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_b_var, b_coeff, _variant, _) = enforce_lc_as_gates( - self.cs, - b_lc, - one_fr, - b_constant_term, - true, - false, - &mut space - ).expect("must allocate B variable to transpile B LC for multiplication gate"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_b_var, b_coeff, _variant, _) = + enforce_lc_as_gates(self.cs, b_lc, one_fr, b_constant_term, true, false, &mut space).expect("must allocate B variable to transpile B LC for multiplication gate"); assert!(b_coeff == one_fr); assert!(_variant == hint); new_b_var.expect("transpiler must create a new variable for LC B") - }, + } LcTransformationVariant::IsSingleVariable => { assert!(!b_lc_is_empty); let (var, coeff) = b_lc.0[0]; q_m.mul_assign(&coeff); // collapse coeffs before A*B convert_variable(var) - }, - _ => {unreachable!("{:?}", t_b)} + } + _ => { + unreachable!("{:?}", t_b) + } }; let (c_is_just_a_constant, c_var) = match t_c { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_c_var, c_coeff, _variant, _) = enforce_lc_as_gates( - self.cs, - c_lc, - one_fr, - c_constant_term, - true, - false, - &mut space - ).expect("must allocate C variable to transpile C LC for multiplication gate"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_c_var, c_coeff, _variant, _) = + enforce_lc_as_gates(self.cs, c_lc, one_fr, c_constant_term, true, false, &mut space).expect("must allocate C variable to transpile C LC for multiplication gate"); assert!(c_coeff == one_fr); assert!(_variant == hint); (false, Some(new_c_var.expect("transpiler must create a new variable for LC C"))) - }, + } LcTransformationVariant::IsSingleVariable => { assert!(!c_lc_is_empty); let (var, coeff) = c_lc.0[0]; q_c = coeff; (false, Some(convert_variable(var))) - }, + } LcTransformationVariant::IsConstant => { assert!(c_lc_is_empty); assert!(c_has_constant); (true, None) - }, + } }; if c_is_just_a_constant { @@ -1948,16 +1732,11 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem space.scratch_space_for_vars[0] = a_var; space.scratch_space_for_vars[1] = b_var; - allocate_into_cs( - self.cs, - false, - &*space.scratch_space_for_vars, - &*space.scratch_space_for_coeffs - ).expect("must make a multiplication gate with C being constant"); + allocate_into_cs(self.cs, false, &*space.scratch_space_for_vars, &*space.scratch_space_for_coeffs).expect("must make a multiplication gate with C being constant"); // A*B == constant // let t = self.cs.new_gate( - // (a_var, b_var, dummy_var), + // (a_var, b_var, dummy_var), // [zero_fr, zero_fr, zero_fr, q_m, constant_term, zero_fr] // ); //.expect("must make a multiplication gate with C being constant"); @@ -1987,16 +1766,10 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem space.scratch_space_for_vars[1] = b_var; space.scratch_space_for_vars[2] = c_var; - allocate_into_cs( - self.cs, - false, - &*space.scratch_space_for_vars, - &*space.scratch_space_for_coeffs - ).expect("must make a plain multiplication gate"); - + allocate_into_cs(self.cs, false, &*space.scratch_space_for_vars, &*space.scratch_space_for_coeffs).expect("must make a plain multiplication gate"); // let t = self.cs.new_gate( - // (a_var, b_var, c_var), + // (a_var, b_var, c_var), // [zero_fr, zero_fr, q_c, q_m, zero_fr, zero_fr] // ); //.expect("must make a multiplication gate"); @@ -2010,87 +1783,70 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem // panic!("Unsatisfied multiplication gate"); // } } - }, + } TranspilationVariant::IntoFMAGate(hints) => { let (t_a, t_b, t_c) = hints; let mut q_m = one_fr; let a_var = match t_a { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_a_var, a_coeff, _variant, _) = enforce_lc_as_gates( - self.cs, - a_lc, - one_fr, - a_constant_term, - true, - false, - &mut space - ).expect("must allocate A variable to transpile A LC for multiplication gate"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_a_var, a_coeff, _variant, _) = + enforce_lc_as_gates(self.cs, a_lc, one_fr, a_constant_term, true, false, &mut space).expect("must allocate A variable to transpile A LC for multiplication gate"); assert!(a_coeff == one_fr); assert!(_variant == hint); new_a_var.expect("transpiler must create a new variable for LC A") - }, + } LcTransformationVariant::IsSingleVariable => { assert!(!a_lc_is_empty); let (var, coeff) = a_lc.0[0]; q_m.mul_assign(&coeff); // collapse coeff before A*B convert_variable(var) - }, - _ => {unreachable!("{:?}", t_a)} + } + _ => { + unreachable!("{:?}", t_a) + } }; let b_var = match t_b { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_b_var, b_coeff, _variant, _) = enforce_lc_as_gates( - self.cs, - b_lc, - one_fr, - b_constant_term, - true, - false, - &mut space - ).expect("must allocate B variable to transpile B LC for multiplication gate"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_b_var, b_coeff, _variant, _) = + enforce_lc_as_gates(self.cs, b_lc, one_fr, b_constant_term, true, false, &mut space).expect("must allocate B variable to transpile B LC for multiplication gate"); assert!(b_coeff == one_fr); assert!(_variant == hint); new_b_var.expect("transpiler must create a new variable for LC B") - }, + } LcTransformationVariant::IsSingleVariable => { assert!(!b_lc_is_empty); let (var, coeff) = b_lc.0[0]; q_m.mul_assign(&coeff); // collapse coeffs before A*B convert_variable(var) - }, - _ => {unreachable!("{:?}", t_b)} + } + _ => { + unreachable!("{:?}", t_b) + } }; let c_var = match t_c { hint @ LcTransformationVariant::IntoSingleGate => { - let (new_c_var, c_coeff, _variant, _) = enforce_lc_as_gates( - self.cs, - c_lc, - one_fr, - c_constant_term, - true, - true, - &mut space - ).expect("must allocate C variable to transpile C LC for multiplication gate"); + let (new_c_var, c_coeff, _variant, _) = + enforce_lc_as_gates(self.cs, c_lc, one_fr, c_constant_term, true, true, &mut space).expect("must allocate C variable to transpile C LC for multiplication gate"); assert!(c_coeff == one_fr); assert!(_variant == hint); Some(new_c_var.expect("transpiler must create a new variable for LC C")) - }, - _ => { unreachable!("{:?}", t_c)} + } + _ => { + unreachable!("{:?}", t_c) + } }; // Plain multiplication gate, but in a form A*B - D = 0 @@ -2112,13 +1868,8 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem space.scratch_space_for_vars[1] = b_var; space.scratch_space_for_vars[3] = d_var; - allocate_into_cs( - self.cs, - false, - &*space.scratch_space_for_vars, - &*space.scratch_space_for_coeffs - ).expect("must make a plain multiplication gate"); - }, + allocate_into_cs(self.cs, false, &*space.scratch_space_for_vars, &*space.scratch_space_for_coeffs).expect("must make a plain multiplication gate"); + } // make an addition gate TranspilationVariant::IntoAdditionGate(hint) => { // let ann: String = _ann().into(); @@ -2136,7 +1887,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem } else { unreachable!("Either A or B LCs are constant"); }; - + let multiplier = if a_is_constant { a_constant_term } else if b_is_constant { @@ -2144,7 +1895,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem } else { unreachable!("Must take multiplier from A or B"); }; - + let mut free_constant_term = if a_is_constant { b_constant_term } else if b_is_constant { @@ -2152,19 +1903,11 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem } else { unreachable!("Either A or B LCs are constant"); }; - + free_constant_term.mul_assign(&multiplier); free_constant_term.sub_assign(&c_constant_term); - - let (_, _, _variant, _) = enforce_lc_as_gates( - self.cs, - lc, - multiplier, - free_constant_term, - false, - false, - &mut space - ).expect("must allocate variable to transpile LC == 0 gate"); + + let (_, _, _variant, _) = enforce_lc_as_gates(self.cs, lc, multiplier, free_constant_term, false, false, &mut space).expect("must allocate variable to transpile LC == 0 gate"); assert!(hint == _variant); } else { @@ -2175,7 +1918,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem // c is not a constant and it's handled by MergeLCs unreachable!(); } - }, + } TranspilationVariant::MergeLinearCombinations(merge_variant, merge_hint) => { let multiplier = if a_is_constant { a_constant_term @@ -2203,7 +1946,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem subtract_lcs_with_dedup_stable::(final_lc, c_lc, &mut self.deduplication_scratch) // final_lc - &c - }, + } MergeLcVariant::MergeBCThroughConstantA => { assert!(a_is_constant); let mut final_lc = b_lc; @@ -2219,7 +1962,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem subtract_lcs_with_dedup_stable::(final_lc, c_lc, &mut self.deduplication_scratch) // final_lc - &c - }, + } MergeLcVariant::CIsTheOnlyMeaningful => { free_constant_term = a_constant_term; free_constant_term.mul_assign(&b_constant_term); @@ -2227,7 +1970,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem free_constant_term.add_assign(&c_constant_term); c_lc - }, + } _ => { unreachable!() } @@ -2236,30 +1979,22 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem let h = merge_hint; match h { - hint @ LcTransformationVariant::IntoSingleGate | - hint @ LcTransformationVariant::IntoMultipleGates => { - let (new_c_var, _coeff, _variant, _) = enforce_lc_as_gates( - self.cs, - lc_into_rewriting, - one_fr, - free_constant_term, - false, - false, - &mut space - ).expect("must allocate gates to transpile merging of LCs"); + hint @ LcTransformationVariant::IntoSingleGate | hint @ LcTransformationVariant::IntoMultipleGates => { + let (new_c_var, _coeff, _variant, _) = + enforce_lc_as_gates(self.cs, lc_into_rewriting, one_fr, free_constant_term, false, false, &mut space).expect("must allocate gates to transpile merging of LCs"); assert!(_coeff == one_fr); assert!(new_c_var.is_none()); assert!(_variant == hint); - }, + } _ => { unreachable!("{:?}", h); } }; } } - + space.clear(); self.transpilation_scratch_space = Some(space); } @@ -2283,8 +2018,12 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, CS: PlonkConstraintSystem fn convert_variable(r1cs_variable: crate::Variable) -> PlonkVariable { let var = match r1cs_variable.get_unchecked() { - crate::Index::Input(0) => {unreachable!("can not convert input variable number 0 (CS::one)")}, - crate::Index::Aux(0) => {unreachable!("can not convert aux variable labeled as 0 (taken by Plonk CS)")}, + crate::Index::Input(0) => { + unreachable!("can not convert input variable number 0 (CS::one)") + } + crate::Index::Aux(0) => { + unreachable!("can not convert aux variable labeled as 0 (taken by Plonk CS)") + } crate::Index::Input(i) => PlonkVariable(PlonkIndex::Input(i)), crate::Index::Aux(i) => PlonkVariable(PlonkIndex::Aux(i)), }; @@ -2294,8 +2033,12 @@ fn convert_variable(r1cs_variable: crate::Variable) -> PlonkVariable { fn convert_variable_back(plonk_variable: PlonkVariable) -> crate::Variable { let var = match plonk_variable.get_unchecked() { - crate::plonk::cs::variable::Index::Input(0) => {unreachable!("can not convert input variable number 0 (does not exist in plonk)")}, - crate::plonk::cs::variable::Index::Aux(0) => {unreachable!("can not convert aux variable labeled as 0 (does not exist in plonk, dummy gate)")}, + crate::plonk::cs::variable::Index::Input(0) => { + unreachable!("can not convert input variable number 0 (does not exist in plonk)") + } + crate::plonk::cs::variable::Index::Aux(0) => { + unreachable!("can not convert aux variable labeled as 0 (does not exist in plonk, dummy gate)") + } crate::plonk::cs::variable::Index::Input(i) => crate::Variable(crate::Index::Input(i)), crate::plonk::cs::variable::Index::Aux(i) => crate::Variable(crate::Index::Aux(i)), }; @@ -2305,22 +2048,23 @@ fn convert_variable_back(plonk_variable: PlonkVariable) -> crate::Variable { use std::cell::Cell; -pub struct AdaptorCircuit<'a, E:Engine, P: PlonkConstraintSystemParams, C: crate::Circuit>{ +pub struct AdaptorCircuit<'a, E: Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> { circuit: Cell>, hints: &'a Vec<(usize, TranspilationVariant)>, _marker_e: std::marker::PhantomData, _marker_p: std::marker::PhantomData

, } -impl<'a, E:Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> AdaptorCircuit<'a, E, P, C> { - pub fn new<'b>(circuit: C, hints: &'b Vec<(usize, TranspilationVariant)>) -> Self - where 'b: 'a +impl<'a, E: Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> AdaptorCircuit<'a, E, P, C> { + pub fn new<'b>(circuit: C, hints: &'b Vec<(usize, TranspilationVariant)>) -> Self + where + 'b: 'a, { Self { circuit: Cell::new(Some(circuit)), hints: hints, _marker_e: std::marker::PhantomData, - _marker_p: std::marker::PhantomData + _marker_p: std::marker::PhantomData, } } } @@ -2336,7 +2080,7 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> Plo deduplication_scratch: HashMap::with_capacity((E::Fr::NUM_BITS * 2) as usize), transpilation_scratch_space: Some(TranspilationScratchSpace::new(P::STATE_WIDTH * 2)), _marker_e: std::marker::PhantomData, - _marker_p: std::marker::PhantomData + _marker_p: std::marker::PhantomData, }; let c = self.circuit.replace(None).expect("Must replace a circuit out from cell"); @@ -2347,27 +2091,27 @@ impl<'a, E: Engine, P: PlonkConstraintSystemParams, C: crate::Circuit> Plo #[test] fn transpile_xor_using_fma_adaptor() { - use crate::tests::XORDemo; - use crate::cs::Circuit; - use crate::pairing::bn256::{Bn256, Fr}; - use super::test_assembly::*; use super::cs::PlonkCsWidth4WithNextStepParams; use super::generator::*; + use super::keys::*; use super::prover::*; - use crate::worker::Worker; + use super::test_assembly::*; + use super::utils::make_non_residues; use super::verifier::*; + use crate::cs::Circuit; use crate::kate_commitment::*; - use crate::plonk::commitments::transcript::*; + use crate::pairing::bn256::{Bn256, Fr}; use crate::plonk::commitments::transcript::keccak_transcript::*; - use crate::plonk::fft::cooley_tukey_ntt::*; - use super::keys::*; + use crate::plonk::commitments::transcript::*; use crate::plonk::domains::Domain; - use super::utils::make_non_residues; + use crate::plonk::fft::cooley_tukey_ntt::*; + use crate::tests::XORDemo; + use crate::worker::Worker; let c = XORDemo:: { a: None, b: None, - _marker: PhantomData + _marker: PhantomData, }; let mut transpiler = Transpiler::::new(); @@ -2389,7 +2133,7 @@ fn transpile_xor_using_fma_adaptor() { let c = XORDemo:: { a: Some(true), b: Some(false), - _marker: PhantomData + _marker: PhantomData, }; let adapted_curcuit = AdaptorCircuit::::new(c.clone(), &hints); @@ -2411,16 +2155,9 @@ fn transpile_xor_using_fma_adaptor() { let crs_mons = Crs::::crs_42(setup.permutation_polynomials[0].size(), &worker); let crs_vals = Crs::::crs_42(setup.permutation_polynomials[0].size(), &worker); - let verification_key = VerificationKey::from_setup( - &setup, - &worker, - &crs_mons - ).unwrap(); + let verification_key = VerificationKey::from_setup(&setup, &worker, &crs_mons).unwrap(); - let precomputations = SetupPolynomialsPrecomputations::from_setup( - &setup, - &worker - ).unwrap(); + let precomputations = SetupPolynomialsPrecomputations::from_setup(&setup, &worker).unwrap(); let mut assembly = ProverAssembly4WithNextStep::::new(); @@ -2439,18 +2176,11 @@ fn transpile_xor_using_fma_adaptor() { type Transcr = RollingKeccakTranscript; let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); - - let proof = assembly.prove::( - &worker, - &setup, - &precomputations, - &crs_vals, - &crs_mons, - &omegas_bitreversed, - &omegas_inv_bitreversed, - None, - ).unwrap(); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); + + let proof = assembly + .prove::(&worker, &setup, &precomputations, &crs_vals, &crs_mons, &omegas_bitreversed, &omegas_inv_bitreversed, None) + .unwrap(); let is_valid = verify::(&proof, &verification_key, None).unwrap(); @@ -2459,15 +2189,9 @@ fn transpile_xor_using_fma_adaptor() { // println!("Verification key = {:?}", verification_key); // println!("Proof = {:?}", proof); - let mut key_writer = std::io::BufWriter::with_capacity( - 1<<24, - std::fs::File::create("./xor_vk.key").unwrap() - ); + let mut key_writer = std::io::BufWriter::with_capacity(1 << 24, std::fs::File::create("./xor_vk.key").unwrap()); verification_key.write(&mut key_writer).unwrap(); - let mut proof_writer = std::io::BufWriter::with_capacity( - 1<<24, - std::fs::File::create("./xor_proof.proof").unwrap() - ); + let mut proof_writer = std::io::BufWriter::with_capacity(1 << 24, std::fs::File::create("./xor_proof.proof").unwrap()); proof.write(&mut proof_writer).unwrap(); -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_cs/generator.rs b/crates/bellman/src/plonk/better_cs/generator.rs index e7c62e7..0691062 100644 --- a/crates/bellman/src/plonk/better_cs/generator.rs +++ b/crates/bellman/src/plonk/better_cs/generator.rs @@ -1,16 +1,16 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::plonk::domains::*; use crate::plonk::polynomials::*; use crate::worker::Worker; -use crate::plonk::domains::*; +use crate::SynthesisError; use std::marker::PhantomData; use super::cs::*; use super::keys::SetupPolynomials; -pub use super::utils::{make_non_residues}; +pub use super::utils::make_non_residues; #[derive(Debug, Clone)] pub struct GeneratorAssembly> { @@ -24,16 +24,15 @@ pub struct GeneratorAssembly> { inputs_map: Vec, - is_finalized: bool + is_finalized: bool, } impl> ConstraintSystem for GeneratorAssembly { // allocate a variable fn alloc(&mut self, _value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - self.num_aux += 1; let index = self.num_aux; @@ -43,9 +42,8 @@ impl> ConstraintSystem for Ge // allocate an input variable fn alloc_input(&mut self, _value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { - self.num_inputs += 1; let index = self.num_inputs; @@ -65,12 +63,7 @@ impl> ConstraintSystem for Ge } // allocate an abstract gate - fn new_gate(&mut self, - variables: P::StateVariables, - this_step_coeffs: P::ThisTraceStepCoefficients, - next_step_coeffs: P::NextTraceStepCoefficients - ) -> Result<(), SynthesisError> - { + fn new_gate(&mut self, variables: P::StateVariables, this_step_coeffs: P::ThisTraceStepCoefficients, next_step_coeffs: P::NextTraceStepCoefficients) -> Result<(), SynthesisError> { self.aux_gates.push((variables, this_step_coeffs, next_step_coeffs)); self.n += 1; @@ -138,7 +131,7 @@ impl> GeneratorAssembly { } let n = self.input_gates.len() + self.aux_gates.len(); - if (n+1).is_power_of_two() { + if (n + 1).is_power_of_two() { self.is_finalized = true; return; } @@ -151,12 +144,12 @@ impl> GeneratorAssembly { let empty_gate = (vars, this_step_coeffs, next_step_coeffs); - let new_aux_len = (n+1).next_power_of_two() - 1 - self.input_gates.len(); + let new_aux_len = (n + 1).next_power_of_two() - 1 - self.input_gates.len(); self.aux_gates.resize(new_aux_len, empty_gate); let n = self.input_gates.len() + self.aux_gates.len(); - assert!((n+1).is_power_of_two()); + assert!((n + 1).is_power_of_two()); self.n = n; self.is_finalized = true; @@ -170,13 +163,7 @@ pub type GeneratorAssembly3WithNextStep = GeneratorAssembly = GeneratorAssembly; impl GeneratorAssembly4WithNextStep { - pub fn make_selector_polynomials( - &self, - worker: &Worker - ) -> Result< - ([Polynomial::; 6], [Polynomial::; 1]), - SynthesisError - > { + pub fn make_selector_polynomials(&self, worker: &Worker) -> Result<([Polynomial; 6], [Polynomial; 1]), SynthesisError> { assert!(self.is_finalized); let total_num_gates = self.input_gates.len() + self.aux_gates.len(); let mut q_a = vec![E::Fr::zero(); total_num_gates]; @@ -189,9 +176,7 @@ impl GeneratorAssembly4WithNextStep { let mut q_d_next = vec![E::Fr::zero(); total_num_gates]; // expect a small number of inputs - for (gate, q_a) in self.input_gates.iter() - .zip(q_a.iter_mut()) - { + for (gate, q_a) in self.input_gates.iter().zip(q_a.iter_mut()) { let mut tmp = gate.1[0]; tmp.negate(); // -a + const = 0, where const will come from verifier @@ -214,36 +199,37 @@ impl GeneratorAssembly4WithNextStep { debug_assert!(self.aux_gates.len() == q_a_aux.len()); worker.scope(self.aux_gates.len(), |scope, chunk| { - for (((((((gate, q_a), q_b), q_c), q_d), q_m), q_const), q_d_next) - in self.aux_gates.chunks(chunk) - .zip(q_a_aux.chunks_mut(chunk)) - .zip(q_b_aux.chunks_mut(chunk)) - .zip(q_c_aux.chunks_mut(chunk)) - .zip(q_d_aux.chunks_mut(chunk)) - .zip(q_m_aux.chunks_mut(chunk)) - .zip(q_const_aux.chunks_mut(chunk)) - .zip(q_d_next_aux.chunks_mut(chunk)) + for (((((((gate, q_a), q_b), q_c), q_d), q_m), q_const), q_d_next) in self + .aux_gates + .chunks(chunk) + .zip(q_a_aux.chunks_mut(chunk)) + .zip(q_b_aux.chunks_mut(chunk)) + .zip(q_c_aux.chunks_mut(chunk)) + .zip(q_d_aux.chunks_mut(chunk)) + .zip(q_m_aux.chunks_mut(chunk)) + .zip(q_const_aux.chunks_mut(chunk)) + .zip(q_d_next_aux.chunks_mut(chunk)) { scope.spawn(move |_| { - for (((((((gate, q_a), q_b), q_c), q_d), q_m), q_const), q_d_next) - in gate.iter() - .zip(q_a.iter_mut()) - .zip(q_b.iter_mut()) - .zip(q_c.iter_mut()) - .zip(q_d.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_const.iter_mut()) - .zip(q_d_next.iter_mut()) - { - *q_a = gate.1[0]; - *q_b = gate.1[1]; - *q_c = gate.1[2]; - *q_d = gate.1[3]; - *q_m = gate.1[4]; - *q_const = gate.1[5]; - - *q_d_next = gate.2[0]; - } + for (((((((gate, q_a), q_b), q_c), q_d), q_m), q_const), q_d_next) in gate + .iter() + .zip(q_a.iter_mut()) + .zip(q_b.iter_mut()) + .zip(q_c.iter_mut()) + .zip(q_d.iter_mut()) + .zip(q_m.iter_mut()) + .zip(q_const.iter_mut()) + .zip(q_d_next.iter_mut()) + { + *q_a = gate.1[0]; + *q_b = gate.1[1]; + *q_c = gate.1[2]; + *q_d = gate.1[3]; + *q_m = gate.1[4]; + *q_const = gate.1[5]; + + *q_d_next = gate.2[0]; + } }); } }); @@ -260,7 +246,7 @@ impl GeneratorAssembly4WithNextStep { Ok(([q_a, q_b, q_c, q_d, q_m, q_const], [q_d_next])) } - pub(crate) fn make_permutations(&self, worker: &Worker) -> [Polynomial::; 4] { + pub(crate) fn make_permutations(&self, worker: &Worker) -> [Polynomial; 4] { assert!(self.is_finalized); let num_gates = self.input_gates.len() + self.aux_gates.len(); @@ -270,24 +256,23 @@ impl GeneratorAssembly4WithNextStep { let mut partitions = vec![vec![]; num_partitions + 1]; // gate_idx is zero-enumerated here - for (gate_idx, (vars, _, _)) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (gate_idx, (vars, _, _)) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { for (var_index_in_gate, v) in vars.iter().enumerate() { match v { Variable(Index::Aux(0)) => { // Dummy variables do not participate in the permutation - }, + } Variable(Index::Input(0)) => { unreachable!("There must be no input with index 0"); - }, + } Variable(Index::Input(index)) => { let i = *index; // inputs are [1, num_inputs] - partitions[i].push((var_index_in_gate, gate_idx+1)); - }, + partitions[i].push((var_index_in_gate, gate_idx + 1)); + } Variable(Index::Aux(index)) => { let i = index + num_inputs; // aux are [num_inputs + 1, ..] - partitions[i].push((var_index_in_gate, gate_idx+1)); - }, + partitions[i].push((var_index_in_gate, gate_idx + 1)); + } } } } @@ -298,14 +283,12 @@ impl GeneratorAssembly4WithNextStep { let domain = Domain::new_for_size(num_gates as u64).expect("must have enough roots of unity to fit the circuit"); // now we need to make root at it's cosets - let domain_elements = materialize_domain_elements_with_natural_enumeration( - &domain, &worker - ); + let domain_elements = materialize_domain_elements_with_natural_enumeration(&domain, &worker); // domain_elements.pop().unwrap(); - use crate::ff::SqrtField; use crate::ff::LegendreSymbol; + use crate::ff::SqrtField; let mut non_residues = vec![]; non_residues.push(E::Fr::one()); @@ -349,9 +332,7 @@ impl GeneratorAssembly4WithNextStep { // let permutation = partition.clone(); // permutations[i] = permutation; - for (original, new) in partition.into_iter() - .zip(permutation.into_iter()) - { + for (original, new) in partition.into_iter().zip(permutation.into_iter()) { // (column_idx, trace_step_idx) let new_zero_enumerated = new.1 - 1; let mut new_value = domain_elements[new_zero_enumerated]; @@ -363,18 +344,10 @@ impl GeneratorAssembly4WithNextStep { // check to what witness polynomial the variable belongs let place_into = match original.0 { - 0 => { - sigma_1.as_mut() - }, - 1 => { - sigma_2.as_mut() - }, - 2 => { - sigma_3.as_mut() - }, - 3 => { - sigma_4.as_mut() - }, + 0 => sigma_1.as_mut(), + 1 => sigma_2.as_mut(), + 2 => sigma_3.as_mut(), + 3 => sigma_4.as_mut(), _ => { unreachable!() } @@ -401,8 +374,7 @@ impl GeneratorAssembly4WithNextStep { let [sigma_1, sigma_2, sigma_3, sigma_4] = self.make_permutations(&worker); - let ([q_a, q_b, q_c, q_d, q_m, q_const], - [q_d_next]) = self.make_selector_polynomials(&worker)?; + let ([q_a, q_b, q_c, q_d, q_m, q_const], [q_d_next]) = self.make_selector_polynomials(&worker)?; drop(self); @@ -426,8 +398,8 @@ impl GeneratorAssembly4WithNextStep { selector_polynomials: vec![q_a, q_b, q_c, q_d, q_m, q_const], next_step_selector_polynomials: vec![q_d_next], permutation_polynomials: vec![sigma_1, sigma_2, sigma_3, sigma_4], - - _marker: std::marker::PhantomData + + _marker: std::marker::PhantomData, }; Ok(setup) @@ -463,33 +435,25 @@ mod test { use crate::pairing::Engine; - struct TestCircuit4{ - _marker: PhantomData + struct TestCircuit4 { + _marker: PhantomData, } impl Circuit for TestCircuit4 { - fn synthesize >(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let a = cs.alloc(|| { - Ok(E::Fr::from_str("10").unwrap()) - })?; + fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { + let a = cs.alloc(|| Ok(E::Fr::from_str("10").unwrap()))?; println!("A = {:?}", a); - let b = cs.alloc(|| { - Ok(E::Fr::from_str("20").unwrap()) - })?; + let b = cs.alloc(|| Ok(E::Fr::from_str("20").unwrap()))?; println!("B = {:?}", b); - let c = cs.alloc(|| { - Ok(E::Fr::from_str("200").unwrap()) - })?; + let c = cs.alloc(|| Ok(E::Fr::from_str("200").unwrap()))?; println!("C = {:?}", c); - let d = cs.alloc(|| { - Ok(E::Fr::from_str("100").unwrap()) - })?; + let d = cs.alloc(|| Ok(E::Fr::from_str("100").unwrap()))?; println!("D = {:?}", d); @@ -506,37 +470,20 @@ mod test { let dummy = cs.get_dummy_variable(); // 2a - b == 0 - cs.new_gate( - [a, b, dummy, dummy], - [two, negative_one, zero, zero, zero, zero], - [zero] - )?; + cs.new_gate([a, b, dummy, dummy], [two, negative_one, zero, zero, zero, zero], [zero])?; // 10b - c = 0 let ten = E::Fr::from_str("10").unwrap(); - cs.new_gate( - [b, c, dummy, dummy], - [ten, negative_one, zero, zero, zero, zero], - [zero] - )?; + cs.new_gate([b, c, dummy, dummy], [ten, negative_one, zero, zero, zero, zero], [zero])?; - // c - a*b == 0 + // c - a*b == 0 - cs.new_gate( - [a, b, dummy, c], - [zero, zero, zero, negative_one, one, zero], - [zero] - )?; + cs.new_gate([a, b, dummy, c], [zero, zero, zero, negative_one, one, zero], [zero])?; // 10a + 10b - c - d == 0 - cs.new_gate( - [a, b, c, d], - [ten, ten, negative_one, negative_one, zero, zero], - [zero] - )?; - + cs.new_gate([a, b, c, d], [ten, ten, negative_one, negative_one, zero, zero], [zero])?; Ok(()) } @@ -549,9 +496,7 @@ mod test { let mut assembly = GeneratorAssembly4WithNextStep::::new(); - let circuit = TestCircuit4:: { - _marker: PhantomData - }; + let circuit = TestCircuit4:: { _marker: PhantomData }; circuit.synthesize(&mut assembly).expect("must work"); @@ -591,19 +536,12 @@ mod test { let mut non_res = vec![Fr::one()]; non_res.extend(make_non_residues::(3)); - let p = vec![ - (a, sigma_1, non_res[0]), - (b, sigma_2, non_res[1]), - (c, sigma_3, non_res[2]), - (d, sigma_4, non_res[3]), - ]; + let p = vec![(a, sigma_1, non_res[0]), (b, sigma_2, non_res[1]), (c, sigma_3, non_res[2]), (d, sigma_4, non_res[3])]; let mut subproducts: Vec> = vec![vec![]; 4]; let mut permuted_subproducts: Vec> = vec![vec![]; 4]; - for (((wit, perm, non_res), subprod), permuted_subprod) in p.into_iter() - .zip(subproducts.iter_mut()) - .zip(permuted_subproducts.iter_mut()) { + for (((wit, perm, non_res), subprod), permuted_subprod) in p.into_iter().zip(subproducts.iter_mut()).zip(permuted_subproducts.iter_mut()) { let mut current = non_res; // omega^0 * k for (el, sig) in wit.iter().zip(perm.as_ref().iter()) { let mut tmp = current; @@ -662,4 +600,4 @@ mod test { let _setup = assembly.setup(&worker).unwrap(); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_cs/keys.rs b/crates/bellman/src/plonk/better_cs/keys.rs index 6a62d18..c7db764 100644 --- a/crates/bellman/src/plonk/better_cs/keys.rs +++ b/crates/bellman/src/plonk/better_cs/keys.rs @@ -1,7 +1,7 @@ use super::cs::*; use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine, CurveAffine, EncodedPoint}; +use crate::pairing::{CurveAffine, EncodedPoint, Engine}; use crate::plonk::domains::*; use crate::plonk::polynomials::*; @@ -30,9 +30,8 @@ use crate::byteorder::ReadBytesExt; use crate::byteorder::WriteBytesExt; use std::io::{Read, Write}; - // pub trait EngineDataSerializationRead: Sized { -// fn read(reader: R) -> std::io::Result; +// fn read(reader: R) -> std::io::Result; // } // pub trait EngineDataSerializationWrite: Sized { @@ -76,9 +75,7 @@ pub fn read_curve_affine(mut reader: R) -> std::io::Res let mut repr = G::Uncompressed::empty(); reader.read_exact(repr.as_mut())?; - let e = repr - .into_affine() - .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; + let e = repr.into_affine().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; Ok(e) } @@ -215,7 +212,7 @@ pub fn read_optional_flag(mut reader: R) -> std::io::Result { } else if value == 0 { return Ok(false); } - + panic!("invalid encoding of optional flag"); } @@ -225,7 +222,7 @@ pub fn write_optional_flag(is_some: bool, mut writer: W) -> std::io::R } else { writer.write_u64::(0u64)?; } - + Ok(()) } @@ -383,8 +380,7 @@ impl> SetupPolynomials { pub struct SetupPolynomialsPrecomputations> { pub selector_polynomials_on_coset_of_size_4n_bitreversed: Vec>, - pub next_step_selector_polynomials_on_coset_of_size_4n_bitreversed: - Vec>, + pub next_step_selector_polynomials_on_coset_of_size_4n_bitreversed: Vec>, pub permutation_polynomials_on_coset_of_size_4n_bitreversed: Vec>, pub permutation_polynomials_values_of_size_n_minus_one: Vec>, pub inverse_divisor_on_coset_of_size_4n_bitreversed: Polynomial, @@ -396,20 +392,13 @@ pub struct SetupPolynomialsPrecomputations> SetupPolynomialsPrecomputations { - pub fn from_setup_and_precomputations>( - setup: &SetupPolynomials, - worker: &Worker, - omegas_bitreversed: &CP, - ) -> Result { + pub fn from_setup_and_precomputations>(setup: &SetupPolynomials, worker: &Worker, omegas_bitreversed: &CP) -> Result { let mut new = Self { selector_polynomials_on_coset_of_size_4n_bitreversed: vec![], next_step_selector_polynomials_on_coset_of_size_4n_bitreversed: vec![], permutation_polynomials_on_coset_of_size_4n_bitreversed: vec![], permutation_polynomials_values_of_size_n_minus_one: vec![], - inverse_divisor_on_coset_of_size_4n_bitreversed: Polynomial::from_values(vec![ - E::Fr::one(), - ]) - .unwrap(), + inverse_divisor_on_coset_of_size_4n_bitreversed: Polynomial::from_values(vec![E::Fr::one()]).unwrap(), x_on_coset_of_size_4n_bitreversed: Polynomial::from_values(vec![E::Fr::one()]).unwrap(), _marker: std::marker::PhantomData, @@ -424,71 +413,39 @@ impl> SetupPolynomialsPrecomputatio // we do not precompute q_const as we need to use it for public inputs; for p in setup.selector_polynomials[0..(setup.selector_polynomials.len() - 1)].iter() { - let ext = p.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - omegas_bitreversed, - &coset_generator, - )?; + let ext = p.clone().bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, omegas_bitreversed, &coset_generator)?; - new.selector_polynomials_on_coset_of_size_4n_bitreversed - .push(ext); + new.selector_polynomials_on_coset_of_size_4n_bitreversed.push(ext); } for p in setup.next_step_selector_polynomials.iter() { - let ext = p.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - omegas_bitreversed, - &coset_generator, - )?; + let ext = p.clone().bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, omegas_bitreversed, &coset_generator)?; - new.next_step_selector_polynomials_on_coset_of_size_4n_bitreversed - .push(ext); + new.next_step_selector_polynomials_on_coset_of_size_4n_bitreversed.push(ext); } for p in setup.permutation_polynomials.iter() { - let lde = p.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - omegas_bitreversed, - &coset_generator, - )?; - new.permutation_polynomials_on_coset_of_size_4n_bitreversed - .push(lde); + let lde = p.clone().bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, omegas_bitreversed, &coset_generator)?; + new.permutation_polynomials_on_coset_of_size_4n_bitreversed.push(lde); let as_values = p.clone().fft(&worker); let mut as_values = as_values.into_coeffs(); - as_values - .pop() - .expect("must shorted permutation polynomial values by one"); + as_values.pop().expect("must shorted permutation polynomial values by one"); let p = Polynomial::from_values_unpadded(as_values)?; - new.permutation_polynomials_values_of_size_n_minus_one - .push(p); + new.permutation_polynomials_values_of_size_n_minus_one.push(p); } let mut vanishing_poly_inverse_bitreversed = - evaluate_vanishing_polynomial_of_degree_on_domain_size::( - required_domain_size as u64, - &E::Fr::multiplicative_generator(), - (required_domain_size * LDE_FACTOR) as u64, - &worker, - )?; + evaluate_vanishing_polynomial_of_degree_on_domain_size::(required_domain_size as u64, &E::Fr::multiplicative_generator(), (required_domain_size * LDE_FACTOR) as u64, &worker)?; vanishing_poly_inverse_bitreversed.batch_inversion(&worker)?; vanishing_poly_inverse_bitreversed.bitreverse_enumeration(&worker); - assert_eq!( - vanishing_poly_inverse_bitreversed.size(), - required_domain_size * LDE_FACTOR - ); + assert_eq!(vanishing_poly_inverse_bitreversed.size(), required_domain_size * LDE_FACTOR); // evaluate polynomial X on the coset - let mut x_poly = Polynomial::from_values(vec![ - coset_generator; - vanishing_poly_inverse_bitreversed.size() - ])?; + let mut x_poly = Polynomial::from_values(vec![coset_generator; vanishing_poly_inverse_bitreversed.size()])?; x_poly.distribute_powers(&worker, x_poly.omega); x_poly.bitreverse_enumeration(&worker); @@ -500,17 +457,12 @@ impl> SetupPolynomialsPrecomputatio Ok(new) } - pub fn from_setup( - setup: &SetupPolynomials, - worker: &Worker, - ) -> Result { - let precomps = - BitReversedOmegas::new_for_domain_size(setup.permutation_polynomials[0].size()); + pub fn from_setup(setup: &SetupPolynomials, worker: &Worker) -> Result { + let precomps = BitReversedOmegas::new_for_domain_size(setup.permutation_polynomials[0].size()); Self::from_setup_and_precomputations(setup, worker, &precomps) } - pub fn write(&self, mut writer: W) -> std::io::Result<()> { writer.write_u64::(self.selector_polynomials_on_coset_of_size_4n_bitreversed.len() as u64)?; for p in &self.selector_polynomials_on_coset_of_size_4n_bitreversed { @@ -535,24 +487,21 @@ impl> SetupPolynomialsPrecomputatio pub fn read(mut reader: R) -> std::io::Result { let num_selectors = reader.read_u64::()?; - let mut selector_polynomials_on_coset_of_size_4n_bitreversed = - Vec::with_capacity(num_selectors as usize); + let mut selector_polynomials_on_coset_of_size_4n_bitreversed = Vec::with_capacity(num_selectors as usize); for _ in 0..num_selectors { let poly = read_polynomial_values_unpadded(&mut reader)?; selector_polynomials_on_coset_of_size_4n_bitreversed.push(poly); } let num_next_step_selectors = reader.read_u64::()?; - let mut next_step_selector_polynomials_on_coset_of_size_4n_bitreversed = - Vec::with_capacity(num_next_step_selectors as usize); + let mut next_step_selector_polynomials_on_coset_of_size_4n_bitreversed = Vec::with_capacity(num_next_step_selectors as usize); for _ in 0..num_next_step_selectors { let poly = read_polynomial_values_unpadded(&mut reader)?; next_step_selector_polynomials_on_coset_of_size_4n_bitreversed.push(poly); } let num_permutation_polys = reader.read_u64::()?; - let mut permutation_polynomials_on_coset_of_size_4n_bitreversed = - Vec::with_capacity(num_permutation_polys as usize); + let mut permutation_polynomials_on_coset_of_size_4n_bitreversed = Vec::with_capacity(num_permutation_polys as usize); for _ in 0..num_permutation_polys { let poly = read_polynomial_values_unpadded(&mut reader)?; permutation_polynomials_on_coset_of_size_4n_bitreversed.push(poly); @@ -688,9 +637,7 @@ impl> Proof { let mut repr = ::Uncompressed::empty(); reader.read_exact(repr.as_mut())?; - let e = repr - .into_affine() - .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; + let e = repr.into_affine().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; Ok(e) }; @@ -784,11 +731,7 @@ pub struct VerificationKey> { } impl> VerificationKey { - pub fn from_setup( - setup: &SetupPolynomials, - worker: &Worker, - crs: &Crs, - ) -> Result { + pub fn from_setup(setup: &SetupPolynomials, worker: &Worker, crs: &Crs) -> Result { assert_eq!(setup.selector_polynomials.len(), P::STATE_WIDTH + 2); if P::CAN_ACCESS_NEXT_TRACE_STEP == false { assert_eq!(setup.next_step_selector_polynomials.len(), 0); @@ -823,8 +766,7 @@ impl> VerificationKey { new.permutation_commitments.push(commitment); } - new.non_residues - .extend(super::utils::make_non_residues::(P::STATE_WIDTH - 1)); + new.non_residues.extend(super::utils::make_non_residues::(P::STATE_WIDTH - 1)); Ok(new) } @@ -872,9 +814,7 @@ impl> VerificationKey { let mut repr = ::Uncompressed::empty(); reader.read_exact(repr.as_mut())?; - let e = repr - .into_affine() - .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; + let e = repr.into_affine().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?; Ok(e) }; @@ -883,19 +823,13 @@ impl> VerificationKey { let mut repr = ::Uncompressed::empty(); reader.read_exact(repr.as_mut())?; - let e = repr - .into_affine() - .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e)) - .and_then(|e| { - if e.is_zero() { - Err(std::io::Error::new( - std::io::ErrorKind::InvalidData, - "point at infinity", - ))? - } else { - Ok(e) - } - }); + let e = repr.into_affine().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "point at infinity"))? + } else { + Ok(e) + } + }); e }; @@ -928,10 +862,7 @@ impl> VerificationKey { non_residues.push(p); } - let g2_points = [ - read_g2_not_zero(&mut reader)?, - read_g2_not_zero(&mut reader)?, - ]; + let g2_points = [read_g2_not_zero(&mut reader)?, read_g2_not_zero(&mut reader)?]; let new = Self { n: n as usize, @@ -948,4 +879,4 @@ impl> VerificationKey { Ok(new) } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_cs/mod.rs b/crates/bellman/src/plonk/better_cs/mod.rs index 7e6bd69..c1b9ad7 100644 --- a/crates/bellman/src/plonk/better_cs/mod.rs +++ b/crates/bellman/src/plonk/better_cs/mod.rs @@ -1,13 +1,13 @@ -pub mod cs; -pub mod test_assembly; pub mod adaptor; +pub mod cs; +pub mod fma_adaptor; pub mod generator; pub mod keys; +pub mod one_shot_test_assembly; pub mod prover; +pub mod test_assembly; pub mod verifier; -pub mod one_shot_test_assembly; -pub mod fma_adaptor; pub(crate) mod utils; -const LDE_FACTOR: usize = 4; \ No newline at end of file +const LDE_FACTOR: usize = 4; diff --git a/crates/bellman/src/plonk/better_cs/one_shot_test_assembly.rs b/crates/bellman/src/plonk/better_cs/one_shot_test_assembly.rs index 6bccec2..22ebe93 100644 --- a/crates/bellman/src/plonk/better_cs/one_shot_test_assembly.rs +++ b/crates/bellman/src/plonk/better_cs/one_shot_test_assembly.rs @@ -1,7 +1,7 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use super::cs::*; @@ -26,14 +26,14 @@ pub struct OneShotTestAssembly> { next_step_leftover_from_previous_gate: Option<(E::Fr, P::NextTraceStepCoefficients)>, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } impl> ConstraintSystem for OneShotTestAssembly { // allocate a variable fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -49,7 +49,7 @@ impl> ConstraintSystem for On // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -70,17 +70,12 @@ impl> ConstraintSystem for On self.n += 1; Ok(input_var) - } // allocate an abstract gate - fn new_gate(&mut self, - variables: P::StateVariables, - this_step_coeffs: P::ThisTraceStepCoefficients, - next_step_coeffs: P::NextTraceStepCoefficients - ) -> Result<(), SynthesisError> { + fn new_gate(&mut self, variables: P::StateVariables, this_step_coeffs: P::ThisTraceStepCoefficients, next_step_coeffs: P::NextTraceStepCoefficients) -> Result<(), SynthesisError> { self.aux_gates.push((variables, this_step_coeffs, next_step_coeffs)); - + self.n += 1; Ok(()) @@ -95,12 +90,8 @@ impl> ConstraintSystem for On Variable(Index::Input(0)) => { return Err(SynthesisError::AssignmentMissing); } - Variable(Index::Input(input)) => { - self.input_assingments[input - 1] - }, - Variable(Index::Aux(aux)) => { - self.aux_assingments[aux - 1] - } + Variable(Index::Input(input)) => self.input_assingments[input - 1], + Variable(Index::Aux(aux)) => self.aux_assingments[aux - 1], }; Ok(value) @@ -125,7 +116,6 @@ impl> OneShotTestAssembly { input_gates: vec![], aux_gates: vec![], - inputs_map: vec![], @@ -133,7 +123,7 @@ impl> OneShotTestAssembly { next_step_leftover_from_previous_gate: None, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; tmp @@ -150,7 +140,7 @@ impl> OneShotTestAssembly { input_assingments: Vec::with_capacity(num_inputs), aux_assingments: Vec::with_capacity(num_aux), - input_gates:Vec::with_capacity(num_inputs), + input_gates: Vec::with_capacity(num_inputs), aux_gates: Vec::with_capacity(num_aux), inputs_map: Vec::with_capacity(num_inputs), @@ -159,7 +149,7 @@ impl> OneShotTestAssembly { next_step_leftover_from_previous_gate: None, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; tmp @@ -183,8 +173,7 @@ impl> OneShotTestAssembly { impl OneShotTestAssembly { pub fn is_satisfied(&self, in_a_middle: bool) -> bool { // expect a small number of inputs - for (_i, (_vars, this_step_coeffs, next_step_coeffs)) in self.input_gates.iter().enumerate() - { + for (_i, (_vars, this_step_coeffs, next_step_coeffs)) in self.input_gates.iter().enumerate() { for c in this_step_coeffs.as_ref().iter().skip(1) { assert!(c.is_zero(), "input gate must contatain only one coefficient"); } @@ -193,8 +182,7 @@ impl OneShotTestAssembly { } } - for (i, gate_pair) in self.aux_gates.windows(2).enumerate() - { + for (i, gate_pair) in self.aux_gates.windows(2).enumerate() { let this_gate = &gate_pair[0]; let next_gate = &gate_pair[1]; @@ -203,9 +191,7 @@ impl OneShotTestAssembly { let mut coeffs_iter = this_gate.1.as_ref().iter(); // addition - for (&this_var, this_coeff) in this_gate.0.as_ref().iter() - .zip(&mut coeffs_iter) - { + for (&this_var, this_coeff) in this_gate.0.as_ref().iter().zip(&mut coeffs_iter) { let mut tmp = self.get_value(this_var).expect("must get a variable value"); tmp.mul_assign(&this_coeff); @@ -220,24 +206,21 @@ impl OneShotTestAssembly { this_gate_value.add_assign(&tmp); - // constant + // constant this_gate_value.add_assign(&(&mut coeffs_iter.next().unwrap())); // next step part - for (&next_var, next_step_coeffs_coeff) in next_gate.0.as_ref().iter().rev() - .zip(this_gate.2.as_ref().iter()) - { + for (&next_var, next_step_coeffs_coeff) in next_gate.0.as_ref().iter().rev().zip(this_gate.2.as_ref().iter()) { let mut tmp = self.get_value(next_var).expect("must get a variable value"); tmp.mul_assign(&next_step_coeffs_coeff); this_gate_value.add_assign(&tmp); } - if !this_gate_value.is_zero() { - println!("Unsatisfied at aux gate {}", i+1); + println!("Unsatisfied at aux gate {}", i + 1); println!("Gate {:?}", this_gate); // println!("A = {}, B = {}, C = {}", a_value, b_value, c_value); return false; @@ -255,9 +238,7 @@ impl OneShotTestAssembly { let mut coeffs_iter = this_gate.1.as_ref().iter(); // addition - for (&this_var, this_coeff) in this_gate.0.as_ref().iter() - .zip(&mut coeffs_iter) - { + for (&this_var, this_coeff) in this_gate.0.as_ref().iter().zip(&mut coeffs_iter) { let mut tmp = self.get_value(this_var).expect("must get a variable value"); tmp.mul_assign(&this_coeff); @@ -272,7 +253,7 @@ impl OneShotTestAssembly { this_gate_value.add_assign(&tmp); - // constant + // constant this_gate_value.add_assign(&(&mut coeffs_iter.next().unwrap())); @@ -283,7 +264,7 @@ impl OneShotTestAssembly { } if !this_gate_value.is_zero() { - println!("Unsatisfied at last aux gate {}", i+1); + println!("Unsatisfied at last aux gate {}", i + 1); println!("Gate {:?}", this_gate); // println!("A = {}, B = {}, C = {}", a_value, b_value, c_value); return false; diff --git a/crates/bellman/src/plonk/better_cs/prover/mod.rs b/crates/bellman/src/plonk/better_cs/prover/mod.rs index efe0175..24dd444 100644 --- a/crates/bellman/src/plonk/better_cs/prover/mod.rs +++ b/crates/bellman/src/plonk/better_cs/prover/mod.rs @@ -1,20 +1,20 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::plonk::domains::*; use crate::plonk::polynomials::*; use crate::worker::Worker; -use crate::plonk::domains::*; +use crate::SynthesisError; use std::marker::PhantomData; use super::cs::*; -use super::keys::{SetupPolynomials, Proof, SetupPolynomialsPrecomputations}; +use super::keys::{Proof, SetupPolynomials, SetupPolynomialsPrecomputations}; use crate::source::{DensityTracker, DensityTrackerersChain}; -use crate::kate_commitment::*; use super::utils::*; +use crate::kate_commitment::*; use crate::plonk::commitments::transcript::*; use crate::plonk::fft::cooley_tukey_ntt::*; @@ -29,7 +29,6 @@ pub struct ProverAssembly> { n: usize, // input_gates: Vec<(P::StateVariables, P::ThisTraceStepCoefficients, P::NextTraceStepCoefficients)>, // aux_gates: Vec<(P::StateVariables, P::ThisTraceStepCoefficients, P::NextTraceStepCoefficients)>, - num_inputs: usize, num_aux: usize, @@ -39,20 +38,19 @@ pub struct ProverAssembly> { wire_assignments: Vec>, // aux_densities: Vec, - inputs_map: Vec, dummy_var: Variable, is_finalized: bool, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } impl> ConstraintSystem for ProverAssembly { // allocate a variable fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -66,7 +64,7 @@ impl> ConstraintSystem for Pr // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -77,20 +75,14 @@ impl> ConstraintSystem for Pr let input_var = Variable(Index::Input(index)); // there is an implicit gate to constraint the input - // and it's handled during the proving - self.n += 1; + // and it's handled during the proving + self.n += 1; Ok(input_var) - } // allocate an abstract gate - fn new_gate(&mut self, - variables: P::StateVariables, - _this_step_coeffs: P::ThisTraceStepCoefficients, - _next_step_coeffs: P::NextTraceStepCoefficients - ) -> Result<(), SynthesisError> - { + fn new_gate(&mut self, variables: P::StateVariables, _this_step_coeffs: P::ThisTraceStepCoefficients, _next_step_coeffs: P::NextTraceStepCoefficients) -> Result<(), SynthesisError> { for (idx, &v) in variables.as_ref().iter().enumerate() { let val = self.get_value(v)?; self.wire_assignments[idx].push(val); @@ -110,12 +102,8 @@ impl> ConstraintSystem for Pr unreachable!(); // return Err(SynthesisError::AssignmentMissing); } - Variable(Index::Input(input)) => { - self.input_assingments[input - 1] - }, - Variable(Index::Aux(aux)) => { - self.aux_assingments[aux - 1] - } + Variable(Index::Input(input)) => self.input_assingments[input - 1], + Variable(Index::Aux(aux)) => self.aux_assingments[aux - 1], }; Ok(value) @@ -139,15 +127,14 @@ impl> ProverAssembly { aux_assingments: vec![], wire_assignments: vec![vec![]; P::STATE_WIDTH], - - // aux_densities: vec![DensityTracker::new(); P::STATE_WIDTH], + // aux_densities: vec![DensityTracker::new(); P::STATE_WIDTH], inputs_map: vec![], dummy_var: Variable(Index::Aux(0)), is_finalized: false, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; tmp @@ -165,15 +152,14 @@ impl> ProverAssembly { aux_assingments: Vec::with_capacity(num_aux), wire_assignments: vec![Vec::with_capacity(num_inputs + num_aux); P::STATE_WIDTH], - - // aux_densities: vec![DensityTracker::new(); P::STATE_WIDTH], + // aux_densities: vec![DensityTracker::new(); P::STATE_WIDTH], inputs_map: Vec::with_capacity(num_inputs), dummy_var: Variable(Index::Aux(0)), is_finalized: false, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; tmp @@ -194,12 +180,12 @@ impl> ProverAssembly { } let n = self.n; - if (n+1).is_power_of_two() { + if (n + 1).is_power_of_two() { self.is_finalized = true; return; } - self.n = (n+1).next_power_of_two() - 1; + self.n = (n + 1).next_power_of_two() - 1; self.is_finalized = true; } @@ -238,13 +224,10 @@ impl> ProverAssembly { // Ok((full_assignments, aux_densities)) // } - pub fn make_witness_polynomials( - self - ) -> Result>, SynthesisError> - { + pub fn make_witness_polynomials(self) -> Result>, SynthesisError> { assert!(self.is_finalized); - let mut full_assignments = vec![Vec::with_capacity((self.n+1).next_power_of_two()); self.wire_assignments.len()]; + let mut full_assignments = vec![Vec::with_capacity((self.n + 1).next_power_of_two()); self.wire_assignments.len()]; for inp in self.input_assingments.into_iter() { // inputs will always go into A wire @@ -256,11 +239,11 @@ impl> ProverAssembly { for (idx, aux) in self.wire_assignments.into_iter().enumerate() { full_assignments[idx].extend(aux); - full_assignments[idx].resize((self.n+1).next_power_of_two() - 1, E::Fr::zero()); + full_assignments[idx].resize((self.n + 1).next_power_of_two() - 1, E::Fr::zero()); } for a in full_assignments.iter() { - assert_eq!(a.len(), (self.n+1).next_power_of_two() - 1); + assert_eq!(a.len(), (self.n + 1).next_power_of_two() - 1); } Ok(full_assignments) @@ -275,25 +258,21 @@ pub type ProverAssembly4WithNextStep = ProverAssembly ProverAssembly4WithNextStep { pub fn prove, CP: CTPrecomputations, CPI: CTPrecomputations>( - self, - worker: &Worker, + self, + worker: &Worker, setup: &SetupPolynomials, setup_precomputations: &SetupPolynomialsPrecomputations, - crs_vals: &Crs, + crs_vals: &Crs, crs_mon: &Crs, omegas_bitreversed: &CP, omegas_inv_bitreversed: &CPI, - transcript_init_params: Option< >:: InitializationParameters>, + transcript_init_params: Option<>::InitializationParameters>, ) -> Result, SynthesisError> { use crate::pairing::CurveAffine; use std::sync::Arc; - let mut transcript = if let Some(p) = transcript_init_params { - T::new_from_params(p) - } else { - T::new() - }; - + let mut transcript = if let Some(p) = transcript_init_params { T::new_from_params(p) } else { T::new() }; + assert!(self.is_finalized); let input_values = self.input_assingments.clone(); @@ -319,14 +298,10 @@ impl ProverAssembly4WithNextStep { // let coset_factor = E::Fr::one(); - // Commit wire polynomials + // Commit wire polynomials for wire_poly in full_assignments.iter() { - let commitment = commit_using_raw_values( - &wire_poly, - &crs_vals, - &worker - )?; + let commitment = commit_using_raw_values(&wire_poly, &crs_vals, &worker)?; commit_point_as_xy::(&mut transcript, &commitment); @@ -357,19 +332,14 @@ impl ProverAssembly4WithNextStep { let domain = Domain::new_for_size(required_domain_size as u64)?; - let mut domain_elements = materialize_domain_elements_with_natural_enumeration( - &domain, - &worker - ); + let mut domain_elements = materialize_domain_elements_with_natural_enumeration(&domain, &worker); domain_elements.pop().expect("must pop last element for omega^i"); let mut domain_elements_poly_by_beta = Polynomial::from_values_unpadded(domain_elements)?; domain_elements_poly_by_beta.scale(&worker, beta); - let non_residues = make_non_residues::( - >::STATE_WIDTH - 1 - ); + let non_residues = make_non_residues::(>::STATE_WIDTH - 1); // we take A, B, C, ... values and form (A + beta * X * non_residue + gamma), etc and calculate their grand product @@ -390,19 +360,15 @@ impl ProverAssembly4WithNextStep { // we take A, B, C, ... values and form (A + beta * perm_a + gamma), etc and calculate their grand product let z_den = { - assert_eq!( - setup_precomputations.permutation_polynomials_values_of_size_n_minus_one.len(), - grand_products_protos_with_gamma.len() - ); + assert_eq!(setup_precomputations.permutation_polynomials_values_of_size_n_minus_one.len(), grand_products_protos_with_gamma.len()); let mut grand_products_proto_it = grand_products_protos_with_gamma.into_iter(); let mut permutation_polys_it = setup_precomputations.permutation_polynomials_values_of_size_n_minus_one.iter(); let mut z_2 = grand_products_proto_it.next().unwrap(); z_2.add_assign_scaled(&worker, &permutation_polys_it.next().unwrap(), &beta); - for (mut p, perm) in grand_products_proto_it - .zip(permutation_polys_it) { - // permutation polynomials + for (mut p, perm) in grand_products_proto_it.zip(permutation_polys_it) { + // permutation polynomials p.add_assign_scaled(&worker, &perm, &beta); z_2.mul_assign(&worker, &p); } @@ -423,11 +389,7 @@ impl ProverAssembly4WithNextStep { // println!("Z last = {}", z.as_ref().last().unwrap()); // assert!(z.as_ref().last().expect("must exist") == &E::Fr::one()); - let z_commitment = commit_using_values( - &z, - &crs_vals, - &worker - )?; + let z_commitment = commit_using_values(&z, &crs_vals, &worker)?; proof.grand_product_commitment = z_commitment; commit_point_as_xy::(&mut transcript, &proof.grand_product_commitment); @@ -438,7 +400,7 @@ impl ProverAssembly4WithNextStep { // those are z(x*Omega) formally let mut z_shifted_in_monomial_form = z_in_monomial_form.clone(); z_shifted_in_monomial_form.distribute_powers(&worker, z_in_monomial_form.omega); - + // now we have to LDE everything and compute quotient polynomial // also to save on openings that we will have to do from the monomial form anyway @@ -456,22 +418,12 @@ impl ProverAssembly4WithNextStep { let mut d_next = monomial.clone(); d_next.distribute_powers(&worker, d_next.omega); - let lde = d_next.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - omegas_bitreversed, - &coset_factor - )?; + let lde = d_next.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, omegas_bitreversed, &coset_factor)?; witness_next_ldes_on_coset.push(lde); } - let lde = monomial.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - omegas_bitreversed, - &coset_factor - )?; + let lde = monomial.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, omegas_bitreversed, &coset_factor)?; witness_ldes_on_coset.push(lde); } @@ -496,12 +448,7 @@ impl ProverAssembly4WithNextStep { inputs_poly.add_assign(&worker, setup.selector_polynomials.last().unwrap()); // LDE - let mut t_1 = inputs_poly.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - omegas_bitreversed, - &coset_factor - )?; + let mut t_1 = inputs_poly.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, omegas_bitreversed, &coset_factor)?; // Q_A * A let mut tmp = setup_precomputations.selector_polynomials_on_coset_of_size_4n_bitreversed[0].clone(); @@ -541,26 +488,18 @@ impl ProverAssembly4WithNextStep { // now compute the permutation argument - let z_coset_lde_bitreversed = z_in_monomial_form.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - omegas_bitreversed, - &coset_factor - )?; + let z_coset_lde_bitreversed = z_in_monomial_form + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, omegas_bitreversed, &coset_factor)?; - assert!(z_coset_lde_bitreversed.size() == required_domain_size*LDE_FACTOR); + assert!(z_coset_lde_bitreversed.size() == required_domain_size * LDE_FACTOR); - let z_shifted_coset_lde_bitreversed = z_shifted_in_monomial_form.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - omegas_bitreversed, - &coset_factor - )?; + let z_shifted_coset_lde_bitreversed = z_shifted_in_monomial_form.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, omegas_bitreversed, &coset_factor)?; - assert!(z_shifted_coset_lde_bitreversed.size() == required_domain_size*LDE_FACTOR); + assert!(z_shifted_coset_lde_bitreversed.size() == required_domain_size * LDE_FACTOR); // For both Z_1 and Z_2 we first check for grand products - // z*(X)(A + beta*X + gamma)(B + beta*k_1*X + gamma)(C + beta*K_2*X + gamma) - + // z*(X)(A + beta*X + gamma)(B + beta*k_1*X + gamma)(C + beta*K_2*X + gamma) - // - (A + beta*perm_a(X) + gamma)(B + beta*perm_b(X) + gamma)(C + beta*perm_c(X) + gamma)*Z(X*Omega)== 0 // we use evaluations of the polynomial X and K_i * X on a large domain's coset @@ -597,12 +536,9 @@ impl ProverAssembly4WithNextStep { // A + beta*perm_a + gamma - assert_eq!( - setup_precomputations.permutation_polynomials_on_coset_of_size_4n_bitreversed.len(), witness_ldes_on_coset.len() - ); + assert_eq!(setup_precomputations.permutation_polynomials_on_coset_of_size_4n_bitreversed.len(), witness_ldes_on_coset.len()); - for (w, perm) in witness_ldes_on_coset.iter() - .zip(setup_precomputations.permutation_polynomials_on_coset_of_size_4n_bitreversed.iter()) { + for (w, perm) in witness_ldes_on_coset.iter().zip(setup_precomputations.permutation_polynomials_on_coset_of_size_4n_bitreversed.iter()) { tmp.reuse_allocation(&w); tmp.add_constant(&worker, &gamma); tmp.add_assign_scaled(&worker, &perm, &beta); @@ -624,12 +560,7 @@ impl ProverAssembly4WithNextStep { let mut z_minus_one_by_l_0 = z_coset_lde_bitreversed; z_minus_one_by_l_0.sub_constant(&worker, &E::Fr::one()); - let l_coset_lde_bitreversed = l_0.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - omegas_bitreversed, - &coset_factor - )?; + let l_coset_lde_bitreversed = l_0.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, omegas_bitreversed, &coset_factor)?; z_minus_one_by_l_0.mul_assign(&worker, &l_coset_lde_bitreversed); @@ -649,11 +580,7 @@ impl ProverAssembly4WithNextStep { let mut t_poly_parts = t_poly_in_monomial_form.break_into_multiples(required_domain_size)?; for t_part in t_poly_parts.iter() { - let t_part_commitment = commit_using_monomials( - &t_part, - &crs_mon, - &worker - )?; + let t_part_commitment = commit_using_monomials(&t_part, &crs_mon, &worker)?; commit_point_as_xy::(&mut transcript, &t_part_commitment); @@ -747,9 +674,7 @@ impl ProverAssembly4WithNextStep { // + (a(z) + beta*z + gamma)*()*()*()*Z(x) let mut factor = quotient_linearization_challenge; - for (wire_at_z, non_residue) in proof.wire_values_at_z.iter() - .zip(Some(E::Fr::one()).iter().chain(&non_residues)) - { + for (wire_at_z, non_residue) in proof.wire_values_at_z.iter().zip(Some(E::Fr::one()).iter().chain(&non_residues)) { let mut t = z; t.mul_assign(&non_residue); t.mul_assign(&beta); @@ -767,9 +692,7 @@ impl ProverAssembly4WithNextStep { factor.mul_assign(&beta); factor.mul_assign(&z_at_z_omega); - for (wire_at_z, perm_at_z) in proof.wire_values_at_z.iter() - .zip(proof.permutation_polynomials_at_z.iter()) - { + for (wire_at_z, perm_at_z) in proof.wire_values_at_z.iter().zip(proof.permutation_polynomials_at_z.iter()) { let mut t = *perm_at_z; t.mul_assign(&beta); t.add_assign(&wire_at_z); @@ -804,7 +727,7 @@ impl ProverAssembly4WithNextStep { // sanity check - verification { let mut lhs = t_at_z; - let vanishing_at_z = evaluate_vanishing_for_size(&z ,required_domain_size as u64); + let vanishing_at_z = evaluate_vanishing_for_size(&z, required_domain_size as u64); lhs.mul_assign(&vanishing_at_z); let mut quotient_linearization_challenge = E::Fr::one(); @@ -834,9 +757,9 @@ impl ProverAssembly4WithNextStep { tmp.mul_assign(&beta); tmp.add_assign(&gamma); tmp.add_assign(&w); - + z_part.mul_assign(&tmp); - } + } // last poly value and gamma let mut tmp = gamma; @@ -848,7 +771,7 @@ impl ProverAssembly4WithNextStep { rhs.sub_assign(&z_part); quotient_linearization_challenge.mul_assign(&alpha); - + // - L_0(z) * \alpha^2 let mut l_0_at_z = evaluate_l0_at_point(required_domain_size as u64, z)?; @@ -938,60 +861,44 @@ impl ProverAssembly4WithNextStep { let open_at_z_omega = polys.pop().unwrap().0; let open_at_z = polys.pop().unwrap().0; - let opening_at_z = commit_using_monomials( - &open_at_z, - &crs_mon, - &worker - )?; + let opening_at_z = commit_using_monomials(&open_at_z, &crs_mon, &worker)?; - let opening_at_z_omega = commit_using_monomials( - &open_at_z_omega, - &crs_mon, - &worker - )?; + let opening_at_z_omega = commit_using_monomials(&open_at_z_omega, &crs_mon, &worker)?; proof.opening_at_z_proof = opening_at_z; proof.opening_at_z_omega_proof = opening_at_z_omega; - + Ok(proof) } } #[cfg(test)] mod test { - use super::*; use super::super::verifier::verify; + use super::*; use crate::pairing::Engine; #[derive(Clone)] - struct TestCircuit4{ - _marker: PhantomData + struct TestCircuit4 { + _marker: PhantomData, } impl Circuit for TestCircuit4 { - fn synthesize >(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let a = cs.alloc_input(|| { - Ok(E::Fr::from_str("10").unwrap()) - })?; + fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { + let a = cs.alloc_input(|| Ok(E::Fr::from_str("10").unwrap()))?; println!("A = {:?}", a); - let b = cs.alloc_input(|| { - Ok(E::Fr::from_str("20").unwrap()) - })?; + let b = cs.alloc_input(|| Ok(E::Fr::from_str("20").unwrap()))?; println!("B = {:?}", b); - let c = cs.alloc(|| { - Ok(E::Fr::from_str("200").unwrap()) - })?; + let c = cs.alloc(|| Ok(E::Fr::from_str("200").unwrap()))?; println!("C = {:?}", c); - let d = cs.alloc(|| { - Ok(E::Fr::from_str("100").unwrap()) - })?; + let d = cs.alloc(|| Ok(E::Fr::from_str("100").unwrap()))?; println!("D = {:?}", d); @@ -1008,114 +915,54 @@ mod test { let dummy = cs.get_dummy_variable(); // 2a - b == 0 - cs.new_gate( - [a, b, dummy, dummy], - [two, negative_one, zero, zero, zero, zero], - [zero] - )?; + cs.new_gate([a, b, dummy, dummy], [two, negative_one, zero, zero, zero, zero], [zero])?; // try various combinations - cs.new_gate( - [dummy, b, dummy, a], - [zero, negative_one, zero, two, zero, zero], - [zero] - )?; - - cs.new_gate( - [dummy, b, a, dummy], - [zero, negative_one, two, zero, zero, zero], - [zero] - )?; + cs.new_gate([dummy, b, dummy, a], [zero, negative_one, zero, two, zero, zero], [zero])?; + + cs.new_gate([dummy, b, a, dummy], [zero, negative_one, two, zero, zero, zero], [zero])?; // 10b - c = 0 let ten = E::Fr::from_str("10").unwrap(); - cs.new_gate( - [b, c, dummy, dummy], - [ten, negative_one, zero, zero, zero, zero], - [zero] - )?; + cs.new_gate([b, c, dummy, dummy], [ten, negative_one, zero, zero, zero, zero], [zero])?; // same, try various combinations - cs.new_gate( - [dummy, c, dummy, b], - [zero, negative_one, zero, ten, zero, zero], - [zero] - )?; + cs.new_gate([dummy, c, dummy, b], [zero, negative_one, zero, ten, zero, zero], [zero])?; - cs.new_gate( - [dummy, c, b, dummy], - [zero, negative_one, ten, zero, zero, zero], - [zero] - )?; + cs.new_gate([dummy, c, b, dummy], [zero, negative_one, ten, zero, zero, zero], [zero])?; - // c - a*b == 0 + // c - a*b == 0 - cs.new_gate( - [a, b, dummy, c], - [zero, zero, zero, negative_one, one, zero], - [zero] - )?; + cs.new_gate([a, b, dummy, c], [zero, zero, zero, negative_one, one, zero], [zero])?; - cs.new_gate( - [a, b, c, dummy], - [zero, zero, negative_one, zero, one, zero], - [zero] - )?; + cs.new_gate([a, b, c, dummy], [zero, zero, negative_one, zero, one, zero], [zero])?; // 10a + 10b - c - d == 0 - cs.new_gate( - [a, b, c, d], - [ten, ten, negative_one, negative_one, zero, zero], - [zero] - )?; + cs.new_gate([a, b, c, d], [ten, ten, negative_one, negative_one, zero, zero], [zero])?; - cs.new_gate( - [a, d, b, c], - [ten, negative_one, ten, negative_one, zero, zero], - [zero] - )?; + cs.new_gate([a, d, b, c], [ten, negative_one, ten, negative_one, zero, zero], [zero])?; // 2d - c == 0 - cs.new_gate( - [d, c, dummy, dummy], - [two, negative_one, zero, zero, zero, zero], - [zero] - )?; + cs.new_gate([d, c, dummy, dummy], [two, negative_one, zero, zero, zero, zero], [zero])?; - cs.new_gate( - [d, c, dummy, d], - [one, negative_one, zero, one, zero, zero], - [zero] - )?; + cs.new_gate([d, c, dummy, d], [one, negative_one, zero, one, zero, zero], [zero])?; // make a gate that affects next step // 10a + 10b - c - (something in d on next step) == 0, then // d + 0 + 0 - d = 0 - cs.new_gate( - [a, b, c, dummy], - [ten, ten, negative_one, zero, zero, zero], - [negative_one] - )?; + cs.new_gate([a, b, c, dummy], [ten, ten, negative_one, zero, zero, zero], [negative_one])?; - cs.new_gate( - [d, dummy, dummy, d], - [one, zero, zero, negative_one, zero, zero], - [zero] - )?; + cs.new_gate([d, dummy, dummy, d], [one, zero, zero, negative_one, zero, zero], [zero])?; // check internal constant - cs.new_gate( - [d, dummy, dummy, dummy], - [negative_one, zero, zero, zero, zero, E::Fr::from_str("100").unwrap()], - [zero] - )?; + cs.new_gate([d, dummy, dummy, dummy], [negative_one, zero, zero, zero, zero, E::Fr::from_str("100").unwrap()], [zero])?; Ok(()) } @@ -1124,15 +971,13 @@ mod test { #[test] fn test_prove_trivial_circuit() { use crate::pairing::bn256::{Bn256, Fr}; - use crate::worker::Worker; use crate::plonk::better_cs::generator::*; use crate::plonk::better_cs::keys::*; + use crate::worker::Worker; let mut assembly = GeneratorAssembly4WithNextStep::::new(); - let circuit = TestCircuit4:: { - _marker: PhantomData - }; + let circuit = TestCircuit4:: { _marker: PhantomData }; circuit.clone().synthesize(&mut assembly).expect("must work"); @@ -1147,18 +992,11 @@ mod test { let crs_mons = Crs::::crs_42(setup.permutation_polynomials[0].size(), &worker); let crs_vals = Crs::::crs_42(setup.permutation_polynomials[0].size(), &worker); - let verification_key = VerificationKey::from_setup( - &setup, - &worker, - &crs_mons - ).unwrap(); + let verification_key = VerificationKey::from_setup(&setup, &worker, &crs_mons).unwrap(); // println!("Verification key = {:?}", verification_key); - let precomputations = SetupPolynomialsPrecomputations::from_setup( - &setup, - &worker - ).unwrap(); + let precomputations = SetupPolynomialsPrecomputations::from_setup(&setup, &worker).unwrap(); let mut assembly = ProverAssembly4WithNextStep::::new(); @@ -1171,22 +1009,14 @@ mod test { type Transcr = Blake2sTranscript; let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); - - let proof = assembly.prove::( - &worker, - &setup, - &precomputations, - &crs_vals, - &crs_mons, - &omegas_bitreversed, - &omegas_inv_bitreversed, - None, - ).unwrap(); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); + + let proof = assembly + .prove::(&worker, &setup, &precomputations, &crs_vals, &crs_mons, &omegas_bitreversed, &omegas_inv_bitreversed, None) + .unwrap(); let is_valid = verify::(&proof, &verification_key, None).unwrap(); assert!(is_valid); - } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_cs/prover/prove_steps.rs b/crates/bellman/src/plonk/better_cs/prover/prove_steps.rs index cdf407f..b939bff 100644 --- a/crates/bellman/src/plonk/better_cs/prover/prove_steps.rs +++ b/crates/bellman/src/plonk/better_cs/prover/prove_steps.rs @@ -3,18 +3,14 @@ use super::*; pub(crate) enum PrecomputationsForPolynomial<'a, F: PrimeField> { Borrowed(&'a Polynomial), Owned(Polynomial), - None + None, } impl<'a, F: PrimeField> AsRef> for PrecomputationsForPolynomial<'a, F> { fn as_ref(&self) -> &Polynomial { match self { - PrecomputationsForPolynomial::Borrowed(b) => { - b - }, - PrecomputationsForPolynomial::Owned(o) => { - &o - } + PrecomputationsForPolynomial::Borrowed(b) => b, + PrecomputationsForPolynomial::Owned(o) => &o, PrecomputationsForPolynomial::None => { unreachable!("precomputations must have been made"); } @@ -25,12 +21,8 @@ impl<'a, F: PrimeField> AsRef> for PrecomputationsForPolyn impl<'a, F: PrimeField> PrecomputationsForPolynomial<'a, F> { pub(crate) fn into_poly(self) -> Polynomial { match self { - PrecomputationsForPolynomial::Borrowed(b) => { - b.clone() - }, - PrecomputationsForPolynomial::Owned(o) => { - o - } + PrecomputationsForPolynomial::Borrowed(b) => b.clone(), + PrecomputationsForPolynomial::Owned(o) => o, PrecomputationsForPolynomial::None => { unreachable!("precomputations must have been made"); } @@ -40,11 +32,11 @@ impl<'a, F: PrimeField> PrecomputationsForPolynomial<'a, F> { pub(crate) fn get_precomputed_permutation_poly_lde_for_index<'a, E: Engine, CP: CTPrecomputations>( index: usize, - domain_size: usize, + domain_size: usize, setup: &SetupPolynomials, - setup_precomputations: &Option< &'a SetupPolynomialsPrecomputations >, + setup_precomputations: &Option<&'a SetupPolynomialsPrecomputations>, precomputed_omegas: &mut PrecomputedOmegas, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { let coset_factor = E::Fr::multiplicative_generator(); @@ -62,12 +54,7 @@ pub(crate) fn get_precomputed_permutation_poly_lde_for_index<'a, E: Engine, CP: let p = setup.permutation_polynomials[index] .clone() - .bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - precomputed_omegas.as_ref(), - &coset_factor - )?; + .bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, precomputed_omegas.as_ref(), &coset_factor)?; return Ok(PrecomputationsForPolynomial::Owned(p)); } @@ -75,11 +62,11 @@ pub(crate) fn get_precomputed_permutation_poly_lde_for_index<'a, E: Engine, CP: pub(crate) fn get_precomputed_selector_lde_for_index<'a, E: Engine, CP: CTPrecomputations>( index: usize, - domain_size: usize, + domain_size: usize, setup: &SetupPolynomials, - setup_precomputations: &Option< &'a SetupPolynomialsPrecomputations >, + setup_precomputations: &Option<&'a SetupPolynomialsPrecomputations>, precomputed_omegas: &mut PrecomputedOmegas, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { let coset_factor = E::Fr::multiplicative_generator(); @@ -97,12 +84,7 @@ pub(crate) fn get_precomputed_selector_lde_for_index<'a, E: Engine, CP: CTPrecom let p = setup.selector_polynomials[index] .clone() - .bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - precomputed_omegas.as_ref(), - &coset_factor - )?; + .bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, precomputed_omegas.as_ref(), &coset_factor)?; return Ok(PrecomputationsForPolynomial::Owned(p)); } @@ -110,11 +92,11 @@ pub(crate) fn get_precomputed_selector_lde_for_index<'a, E: Engine, CP: CTPrecom pub(crate) fn get_precomputed_next_step_selector_lde_for_index<'a, E: Engine, CP: CTPrecomputations>( index: usize, - domain_size: usize, + domain_size: usize, setup: &SetupPolynomials, - setup_precomputations: &Option< &'a SetupPolynomialsPrecomputations >, + setup_precomputations: &Option<&'a SetupPolynomialsPrecomputations>, precomputed_omegas: &mut PrecomputedOmegas, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { let coset_factor = E::Fr::multiplicative_generator(); @@ -132,21 +114,16 @@ pub(crate) fn get_precomputed_next_step_selector_lde_for_index<'a, E: Engine, CP let p = setup.next_step_selector_polynomials[index] .clone() - .bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - precomputed_omegas.as_ref(), - &coset_factor - )?; + .bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, precomputed_omegas.as_ref(), &coset_factor)?; return Ok(PrecomputationsForPolynomial::Owned(p)); } } pub(crate) fn get_precomputed_x_lde<'a, E: Engine>( - domain_size: usize, - setup_precomputations: &Option< &'a SetupPolynomialsPrecomputations >, - worker: &Worker + domain_size: usize, + setup_precomputations: &Option<&'a SetupPolynomialsPrecomputations>, + worker: &Worker, ) -> Result, SynthesisError> { let coset_factor = E::Fr::multiplicative_generator(); @@ -155,10 +132,7 @@ pub(crate) fn get_precomputed_x_lde<'a, E: Engine>( return Ok(PrecomputationsForPolynomial::Borrowed(p)); } else { - let mut x_poly = Polynomial::from_values(vec![ - coset_factor; - domain_size * LDE_FACTOR - ])?; + let mut x_poly = Polynomial::from_values(vec![coset_factor; domain_size * LDE_FACTOR])?; x_poly.distribute_powers(&worker, x_poly.omega); x_poly.bitreverse_enumeration(&worker); @@ -167,9 +141,9 @@ pub(crate) fn get_precomputed_x_lde<'a, E: Engine>( } pub(crate) fn get_precomputed_inverse_divisor<'a, E: Engine>( - domain_size: usize, - setup_precomputations: &Option< &'a SetupPolynomialsPrecomputations >, - worker: &Worker + domain_size: usize, + setup_precomputations: &Option<&'a SetupPolynomialsPrecomputations>, + worker: &Worker, ) -> Result, SynthesisError> { let coset_factor = E::Fr::multiplicative_generator(); @@ -178,13 +152,7 @@ pub(crate) fn get_precomputed_inverse_divisor<'a, E: Engine>( return Ok(PrecomputationsForPolynomial::Borrowed(p)); } else { - let mut vanishing_poly_inverse_bitreversed = - evaluate_vanishing_polynomial_of_degree_on_domain_size::( - domain_size as u64, - &coset_factor, - (domain_size * LDE_FACTOR) as u64, - &worker, - )?; + let mut vanishing_poly_inverse_bitreversed = evaluate_vanishing_polynomial_of_degree_on_domain_size::(domain_size as u64, &coset_factor, (domain_size * LDE_FACTOR) as u64, &worker)?; vanishing_poly_inverse_bitreversed.batch_inversion(&worker)?; vanishing_poly_inverse_bitreversed.bitreverse_enumeration(&worker); @@ -195,18 +163,14 @@ pub(crate) fn get_precomputed_inverse_divisor<'a, E: Engine>( pub(crate) enum PrecomputedOmegas<'a, F: PrimeField, CP: CTPrecomputations> { Borrowed(&'a CP, F), Owned(CP, F), - None + None, } impl<'a, F: PrimeField, CP: CTPrecomputations> AsRef for PrecomputedOmegas<'a, F, CP> { fn as_ref(&self) -> &CP { match self { - PrecomputedOmegas::Borrowed(b, _) => { - b - }, - PrecomputedOmegas::Owned(o, _) => { - &o - } + PrecomputedOmegas::Borrowed(b, _) => b, + PrecomputedOmegas::Owned(o, _) => &o, PrecomputedOmegas::None => { unreachable!("precomputations must have been made"); } @@ -221,7 +185,7 @@ pub(crate) struct FirstPartialProverState>, witness_polys_unpadded_values: Vec>, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } pub(crate) struct FirstProverMessage> { @@ -230,14 +194,14 @@ pub(crate) struct FirstProverMessage, pub(crate) wire_commitments: Vec, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } pub(crate) struct FirstVerifierMessage> { pub(crate) beta: E::Fr, pub(crate) gamma: E::Fr, - pub(crate) _marker: std::marker::PhantomData

+ pub(crate) _marker: std::marker::PhantomData

, } pub(crate) struct SecondPartialProverState> { @@ -247,13 +211,13 @@ pub(crate) struct SecondPartialProverState>, z_in_monomial_form: Polynomial, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } pub(crate) struct SecondProverMessage> { pub(crate) z_commitment: E::G1Affine, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } pub(crate) struct SecondVerifierMessage> { @@ -261,7 +225,7 @@ pub(crate) struct SecondVerifierMessage + pub(crate) _marker: std::marker::PhantomData

, } pub(crate) struct ThirdPartialProverState> { @@ -272,13 +236,13 @@ pub(crate) struct ThirdPartialProverState, t_poly_parts: Vec>, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } pub(crate) struct ThirdProverMessage> { pub(crate) quotient_poly_commitments: Vec, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } pub(crate) struct ThirdVerifierMessage> { @@ -287,7 +251,7 @@ pub(crate) struct ThirdVerifierMessage + pub(crate) _marker: std::marker::PhantomData

, } pub(crate) struct FourthPartialProverState> { @@ -305,7 +269,7 @@ pub(crate) struct FourthPartialProverState + _marker: std::marker::PhantomData

, } pub(crate) struct FourthProverMessage> { @@ -316,7 +280,7 @@ pub(crate) struct FourthProverMessage + _marker: std::marker::PhantomData

, } pub(crate) struct FourthVerifierMessage> { @@ -326,26 +290,22 @@ pub(crate) struct FourthVerifierMessage + pub(crate) _marker: std::marker::PhantomData

, } pub(crate) struct FifthProverMessage> { pub(crate) opening_proof_at_z: E::G1Affine, pub(crate) opening_proof_at_z_omega: E::G1Affine, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } impl ProverAssembly4WithNextStep { pub(crate) fn first_step_with_lagrange_form_key( - self, - worker: &Worker, - crs_vals: &Crs, - ) -> Result<( - FirstPartialProverState, - FirstProverMessage - ), SynthesisError> - { + self, + worker: &Worker, + crs_vals: &Crs, + ) -> Result<(FirstPartialProverState, FirstProverMessage), SynthesisError> { use crate::pairing::CurveAffine; use std::sync::Arc; @@ -359,13 +319,11 @@ impl ProverAssembly4WithNextStep { let required_domain_size = n + 1; assert!(required_domain_size.is_power_of_two()); - let non_residues = make_non_residues::( - >::STATE_WIDTH - 1 - ); + let non_residues = make_non_residues::(>::STATE_WIDTH - 1); let full_assignments = self.make_witness_polynomials()?; - // Commit wire polynomials + // Commit wire polynomials let mut first_message = FirstProverMessage:: { n: n, @@ -373,15 +331,11 @@ impl ProverAssembly4WithNextStep { input_values: input_values.clone(), wire_commitments: Vec::with_capacity(4), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; for wire_poly in full_assignments.iter() { - let commitment = commit_using_raw_values( - &wire_poly, - &crs_vals, - &worker - )?; + let commitment = commit_using_raw_values(&wire_poly, &crs_vals, &worker)?; first_message.wire_commitments.push(commitment); } @@ -401,22 +355,18 @@ impl ProverAssembly4WithNextStep { witness_polys_as_coeffs: vec![], witness_polys_unpadded_values: assignment_polynomials, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok((state, first_message)) } pub(crate) fn first_step_with_monomial_form_key>( - self, - worker: &Worker, - crs_mons: &Crs, - precomputed_omegas_inv: &mut PrecomputedOmegas - ) -> Result<( - FirstPartialProverState, - FirstProverMessage - ), SynthesisError> - { + self, + worker: &Worker, + crs_mons: &Crs, + precomputed_omegas_inv: &mut PrecomputedOmegas, + ) -> Result<(FirstPartialProverState, FirstProverMessage), SynthesisError> { use crate::pairing::CurveAffine; use std::sync::Arc; @@ -430,13 +380,11 @@ impl ProverAssembly4WithNextStep { let required_domain_size = n + 1; assert!(required_domain_size.is_power_of_two()); - let non_residues = make_non_residues::( - >::STATE_WIDTH - 1 - ); + let non_residues = make_non_residues::(>::STATE_WIDTH - 1); let full_assignments = self.make_witness_polynomials()?; - // Commit wire polynomials + // Commit wire polynomials let mut first_message = FirstProverMessage:: { n: n, @@ -444,7 +392,7 @@ impl ProverAssembly4WithNextStep { input_values: input_values.clone(), wire_commitments: Vec::with_capacity(4), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; let mut wire_polys_as_coefficients = Vec::with_capacity(full_assignments.len()); @@ -458,14 +406,9 @@ impl ProverAssembly4WithNextStep { for wire_poly in full_assignments.iter() { let as_poly = Polynomial::from_values(wire_poly.clone())?; - let as_coeffs = as_poly - .ifft_using_bitreversed_ntt(&worker, precomputed_omegas_inv.as_ref(), &E::Fr::one())?; + let as_coeffs = as_poly.ifft_using_bitreversed_ntt(&worker, precomputed_omegas_inv.as_ref(), &E::Fr::one())?; - let commitment = commit_using_monomials( - &as_coeffs, - &crs_mons, - &worker - )?; + let commitment = commit_using_monomials(&as_coeffs, &crs_mons, &worker)?; wire_polys_as_coefficients.push(as_coeffs); @@ -480,7 +423,6 @@ impl ProverAssembly4WithNextStep { assignment_polynomials.push(p); } - let state = FirstPartialProverState:: { required_domain_size, non_residues, @@ -488,7 +430,7 @@ impl ProverAssembly4WithNextStep { witness_polys_as_coeffs: wire_polys_as_coefficients, witness_polys_unpadded_values: assignment_polynomials, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok((state, first_message)) @@ -498,16 +440,12 @@ impl ProverAssembly4WithNextStep { first_state: FirstPartialProverState, first_verifier_message: FirstVerifierMessage, setup: &SetupPolynomials, - crs_mons: &Crs, - setup_precomputations: &Option< &SetupPolynomialsPrecomputations >, + crs_mons: &Crs, + setup_precomputations: &Option<&SetupPolynomialsPrecomputations>, precomputed_omegas_inv: &mut PrecomputedOmegas, - worker: &Worker - ) -> Result<( - SecondPartialProverState, - SecondProverMessage - ), SynthesisError> - { - let FirstVerifierMessage { beta, gamma, ..} = first_verifier_message; + worker: &Worker, + ) -> Result<(SecondPartialProverState, SecondProverMessage), SynthesisError> { + let FirstVerifierMessage { beta, gamma, .. } = first_verifier_message; assert_eq!(first_state.witness_polys_unpadded_values.len(), 4, "first state must containt assignment poly values"); @@ -522,10 +460,7 @@ impl ProverAssembly4WithNextStep { let domain = Domain::new_for_size(required_domain_size as u64)?; - let mut domain_elements = materialize_domain_elements_with_natural_enumeration( - &domain, - &worker - ); + let mut domain_elements = materialize_domain_elements_with_natural_enumeration(&domain, &worker); domain_elements.pop().expect("must pop last element for omega^i"); @@ -569,9 +504,7 @@ impl ProverAssembly4WithNextStep { for p in setup.permutation_polynomials.iter() { let as_values = p.clone().fft(&worker); let mut as_values = as_values.into_coeffs(); - as_values - .pop() - .expect("must shorted permutation polynomial values by one"); + as_values.pop().expect("must shorted permutation polynomial values by one"); let p = Polynomial::from_values_unpadded(as_values)?; let p = PrecomputationsForPolynomial::Owned(p); @@ -581,19 +514,15 @@ impl ProverAssembly4WithNextStep { } let z_den = { - assert_eq!( - permutation_polynomials_values_of_size_n_minus_one.len(), - grand_products_protos_with_gamma.len() - ); + assert_eq!(permutation_polynomials_values_of_size_n_minus_one.len(), grand_products_protos_with_gamma.len()); let mut grand_products_proto_it = grand_products_protos_with_gamma.into_iter(); let mut permutation_polys_it = permutation_polynomials_values_of_size_n_minus_one.iter(); let mut z_2 = grand_products_proto_it.next().unwrap(); z_2.add_assign_scaled(&worker, permutation_polys_it.next().unwrap().as_ref(), &beta); - for (mut p, perm) in grand_products_proto_it - .zip(permutation_polys_it) { - // permutation polynomials + for (mut p, perm) in grand_products_proto_it.zip(permutation_polys_it) { + // permutation polynomials p.add_assign_scaled(&worker, perm.as_ref(), &beta); z_2.mul_assign(&worker, &p); } @@ -617,11 +546,7 @@ impl ProverAssembly4WithNextStep { // interpolate on the main domain let z_in_monomial_form = z.ifft_using_bitreversed_ntt(&worker, precomputed_omegas_inv.as_ref(), &E::Fr::one())?; - let z_commitment = commit_using_monomials( - &z_in_monomial_form, - &crs_mons, - &worker - )?; + let z_commitment = commit_using_monomials(&z_in_monomial_form, &crs_mons, &worker)?; let state = SecondPartialProverState:: { required_domain_size, @@ -630,13 +555,12 @@ impl ProverAssembly4WithNextStep { witness_polys_as_coeffs: first_state.witness_polys_as_coeffs, z_in_monomial_form: z_in_monomial_form, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; let message = SecondProverMessage:: { z_commitment: z_commitment, - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok((state, message)) @@ -646,22 +570,18 @@ impl ProverAssembly4WithNextStep { second_state: SecondPartialProverState, second_verifier_message: SecondVerifierMessage, setup: &SetupPolynomials, - crs_mons: &Crs, - setup_precomputations: &Option< &SetupPolynomialsPrecomputations >, + crs_mons: &Crs, + setup_precomputations: &Option<&SetupPolynomialsPrecomputations>, precomputed_omegas: &mut PrecomputedOmegas, precomputed_omegas_inv: &mut PrecomputedOmegas, - worker: &Worker - ) -> Result<( - ThirdPartialProverState, - ThirdProverMessage - ), SynthesisError> - { + worker: &Worker, + ) -> Result<(ThirdPartialProverState, ThirdProverMessage), SynthesisError> { let z_in_monomial_form = second_state.z_in_monomial_form; // those are z(x*Omega) formally let mut z_shifted_in_monomial_form = z_in_monomial_form.clone(); z_shifted_in_monomial_form.distribute_powers(&worker, z_in_monomial_form.omega); - + // now we have to LDE everything and compute quotient polynomial // also to save on openings that we will have to do from the monomial form anyway @@ -686,33 +606,24 @@ impl ProverAssembly4WithNextStep { let mut witness_ldes_on_coset = vec![]; let mut witness_next_ldes_on_coset = vec![]; - + for (idx, monomial) in witness_polys_in_monomial_form.iter().enumerate() { // this is D polynomial and we need to make next if idx == >::STATE_WIDTH - 1 { let mut d_next = monomial.clone(); d_next.distribute_powers(&worker, d_next.omega); - let lde = d_next.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - precomputed_omegas.as_ref(), - &coset_factor - )?; + let lde = d_next.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, precomputed_omegas.as_ref(), &coset_factor)?; witness_next_ldes_on_coset.push(lde); } - let lde = monomial.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - precomputed_omegas.as_ref(), - &coset_factor - )?; + let lde = monomial + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, precomputed_omegas.as_ref(), &coset_factor)?; witness_ldes_on_coset.push(lde); } - let SecondVerifierMessage { alpha, beta, gamma, .. } = second_verifier_message; // calculate first part of the quotient polynomial - the gate itself @@ -735,67 +646,34 @@ impl ProverAssembly4WithNextStep { inputs_poly.add_assign(&worker, setup.selector_polynomials.last().unwrap()); // LDE - let mut t_1 = inputs_poly.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - precomputed_omegas.as_ref(), - &coset_factor - )?; + let mut t_1 = inputs_poly.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, precomputed_omegas.as_ref(), &coset_factor)?; // t_1 is now q_constant // Q_A * A let mut tmp = witness_ldes_on_coset[0].clone(); - let a_selector = get_precomputed_selector_lde_for_index( - 0, - required_domain_size, - &setup, - &setup_precomputations, - precomputed_omegas, - &worker - )?; + let a_selector = get_precomputed_selector_lde_for_index(0, required_domain_size, &setup, &setup_precomputations, precomputed_omegas, &worker)?; tmp.mul_assign(&worker, &a_selector.as_ref()); t_1.add_assign(&worker, &tmp); drop(a_selector); // Q_B * B tmp.reuse_allocation(&witness_ldes_on_coset[1]); - let b_selector = get_precomputed_selector_lde_for_index( - 1, - required_domain_size, - &setup, - &setup_precomputations, - precomputed_omegas, - &worker - )?; + let b_selector = get_precomputed_selector_lde_for_index(1, required_domain_size, &setup, &setup_precomputations, precomputed_omegas, &worker)?; tmp.mul_assign(&worker, &b_selector.as_ref()); t_1.add_assign(&worker, &tmp); drop(b_selector); // Q_C * C tmp.reuse_allocation(&witness_ldes_on_coset[2]); - let c_selector = get_precomputed_selector_lde_for_index( - 2, - required_domain_size, - &setup, - &setup_precomputations, - precomputed_omegas, - &worker - )?; + let c_selector = get_precomputed_selector_lde_for_index(2, required_domain_size, &setup, &setup_precomputations, precomputed_omegas, &worker)?; tmp.mul_assign(&worker, c_selector.as_ref()); t_1.add_assign(&worker, &tmp); drop(c_selector); // Q_D * D tmp.reuse_allocation(&witness_ldes_on_coset[3]); - let d_selector = get_precomputed_selector_lde_for_index( - 3, - required_domain_size, - &setup, - &setup_precomputations, - precomputed_omegas, - &worker - )?; + let d_selector = get_precomputed_selector_lde_for_index(3, required_domain_size, &setup, &setup_precomputations, precomputed_omegas, &worker)?; tmp.mul_assign(&worker, d_selector.as_ref()); t_1.add_assign(&worker, &tmp); drop(d_selector); @@ -803,27 +681,13 @@ impl ProverAssembly4WithNextStep { // Q_M * A * B tmp.reuse_allocation(&witness_ldes_on_coset[0]); tmp.mul_assign(&worker, &witness_ldes_on_coset[1]); - let m_selector = get_precomputed_selector_lde_for_index( - 4, - required_domain_size, - &setup, - &setup_precomputations, - precomputed_omegas, - &worker - )?; + let m_selector = get_precomputed_selector_lde_for_index(4, required_domain_size, &setup, &setup_precomputations, precomputed_omegas, &worker)?; tmp.mul_assign(&worker, &m_selector.as_ref()); t_1.add_assign(&worker, &tmp); drop(m_selector); tmp.reuse_allocation(&witness_next_ldes_on_coset[0]); - let d_next_selector = get_precomputed_next_step_selector_lde_for_index( - 0, - required_domain_size, - &setup, - &setup_precomputations, - precomputed_omegas, - &worker - )?; + let d_next_selector = get_precomputed_next_step_selector_lde_for_index(0, required_domain_size, &setup, &setup_precomputations, precomputed_omegas, &worker)?; tmp.mul_assign(&worker, d_next_selector.as_ref()); t_1.add_assign(&worker, &tmp); drop(d_next_selector); @@ -836,30 +700,20 @@ impl ProverAssembly4WithNextStep { // now compute the permutation argument - let z_coset_lde_bitreversed = z_in_monomial_form.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - precomputed_omegas.as_ref(), - &coset_factor - )?; + let z_coset_lde_bitreversed = z_in_monomial_form + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, precomputed_omegas.as_ref(), &coset_factor)?; - assert!(z_coset_lde_bitreversed.size() == required_domain_size*LDE_FACTOR); + assert!(z_coset_lde_bitreversed.size() == required_domain_size * LDE_FACTOR); - let z_shifted_coset_lde_bitreversed = z_shifted_in_monomial_form.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - precomputed_omegas.as_ref(), - &coset_factor - )?; + let z_shifted_coset_lde_bitreversed = z_shifted_in_monomial_form.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, precomputed_omegas.as_ref(), &coset_factor)?; - assert!(z_shifted_coset_lde_bitreversed.size() == required_domain_size*LDE_FACTOR); + assert!(z_shifted_coset_lde_bitreversed.size() == required_domain_size * LDE_FACTOR); - let non_residues = make_non_residues::( - >::STATE_WIDTH - 1 - ); + let non_residues = make_non_residues::(>::STATE_WIDTH - 1); // For both Z_1 and Z_2 we first check for grand products - // z*(X)(A + beta*X + gamma)(B + beta*k_1*X + gamma)(C + beta*K_2*X + gamma) - + // z*(X)(A + beta*X + gamma)(B + beta*k_1*X + gamma)(C + beta*K_2*X + gamma) - // - (A + beta*perm_a(X) + gamma)(B + beta*perm_b(X) + gamma)(C + beta*perm_c(X) + gamma)*Z(X*Omega)== 0 // we use evaluations of the polynomial X and K_i * X on a large domain's coset @@ -873,11 +727,7 @@ impl ProverAssembly4WithNextStep { tmp.reuse_allocation(&witness_ldes_on_coset[0]); tmp.add_constant(&worker, &gamma); - let x_precomp = get_precomputed_x_lde( - required_domain_size, - setup_precomputations, - &worker - )?; + let x_precomp = get_precomputed_x_lde(required_domain_size, setup_precomputations, &worker)?; tmp.add_assign_scaled(&worker, x_precomp.as_ref(), &beta); contrib_z.mul_assign(&worker, &tmp); @@ -902,19 +752,12 @@ impl ProverAssembly4WithNextStep { // A + beta*perm_a + gamma for (idx, w) in witness_ldes_on_coset.iter().enumerate() { - let perm = get_precomputed_permutation_poly_lde_for_index( - idx, - required_domain_size, - &setup, - &setup_precomputations, - precomputed_omegas, - &worker - )?; - tmp.reuse_allocation(&w); - tmp.add_constant(&worker, &gamma); - tmp.add_assign_scaled(&worker, perm.as_ref(), &beta); - contrib_z.mul_assign(&worker, &tmp); - } + let perm = get_precomputed_permutation_poly_lde_for_index(idx, required_domain_size, &setup, &setup_precomputations, precomputed_omegas, &worker)?; + tmp.reuse_allocation(&w); + tmp.add_constant(&worker, &gamma); + tmp.add_assign_scaled(&worker, perm.as_ref(), &beta); + contrib_z.mul_assign(&worker, &tmp); + } t_1.sub_assign_scaled(&worker, &contrib_z, "ient_linearization_challenge); @@ -931,12 +774,7 @@ impl ProverAssembly4WithNextStep { let mut z_minus_one_by_l_0 = z_coset_lde_bitreversed; z_minus_one_by_l_0.sub_constant(&worker, &E::Fr::one()); - let l_coset_lde_bitreversed = l_0.bitreversed_lde_using_bitreversed_ntt( - &worker, - LDE_FACTOR, - precomputed_omegas.as_ref(), - &coset_factor - )?; + let l_coset_lde_bitreversed = l_0.bitreversed_lde_using_bitreversed_ntt(&worker, LDE_FACTOR, precomputed_omegas.as_ref(), &coset_factor)?; z_minus_one_by_l_0.mul_assign(&worker, &l_coset_lde_bitreversed); @@ -947,11 +785,7 @@ impl ProverAssembly4WithNextStep { drop(tmp); - let divisor_inversed = get_precomputed_inverse_divisor( - required_domain_size, - setup_precomputations, - &worker - )?; + let divisor_inversed = get_precomputed_inverse_divisor(required_domain_size, setup_precomputations, &worker)?; t_1.mul_assign(&worker, divisor_inversed.as_ref()); t_1.bitreverse_enumeration(&worker); @@ -966,23 +800,18 @@ impl ProverAssembly4WithNextStep { input_values: input_values, witness_polys_as_coeffs: witness_polys_in_monomial_form, z_in_monomial_form: z_in_monomial_form, - t_poly_parts : t_poly_parts, + t_poly_parts: t_poly_parts, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; let mut message = ThirdProverMessage:: { quotient_poly_commitments: Vec::with_capacity(4), - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; for t_part in state.t_poly_parts.iter() { - let t_part_commitment = commit_using_monomials( - &t_part, - &crs_mons, - &worker - )?; + let t_part_commitment = commit_using_monomials(&t_part, &crs_mons, &worker)?; message.quotient_poly_commitments.push(t_part_commitment); } @@ -994,12 +823,8 @@ impl ProverAssembly4WithNextStep { third_state: ThirdPartialProverState, third_verifier_message: ThirdVerifierMessage, setup: &SetupPolynomials, - worker: &Worker - ) -> Result<( - FourthPartialProverState, - FourthProverMessage - ), SynthesisError> - { + worker: &Worker, + ) -> Result<(FourthPartialProverState, FourthProverMessage), SynthesisError> { let ThirdVerifierMessage { alpha, beta, gamma, z, .. } = third_verifier_message; let required_domain_size = third_state.required_domain_size; @@ -1011,7 +836,7 @@ impl ProverAssembly4WithNextStep { input_values: third_state.input_values, witness_polys_as_coeffs: third_state.witness_polys_as_coeffs, z_in_monomial_form: third_state.z_in_monomial_form, - t_poly_parts : third_state.t_poly_parts, + t_poly_parts: third_state.t_poly_parts, linearization_polynomial: Polynomial::::new_for_size(0)?, wire_values_at_z: vec![], wire_values_at_z_omega: vec![], @@ -1020,7 +845,7 @@ impl ProverAssembly4WithNextStep { quotient_polynomial_at_z: E::Fr::zero(), linearization_polynomial_at_z: E::Fr::zero(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; let mut z_by_omega = z; @@ -1091,9 +916,7 @@ impl ProverAssembly4WithNextStep { // + (a(z) + beta*z + gamma)*()*()*()*Z(x) let mut factor = quotient_linearization_challenge; - for (wire_at_z, non_residue) in state.wire_values_at_z.iter() - .zip(Some(E::Fr::one()).iter().chain(&state.non_residues)) - { + for (wire_at_z, non_residue) in state.wire_values_at_z.iter().zip(Some(E::Fr::one()).iter().chain(&state.non_residues)) { let mut t = z; t.mul_assign(&non_residue); t.mul_assign(&beta); @@ -1111,9 +934,7 @@ impl ProverAssembly4WithNextStep { factor.mul_assign(&beta); factor.mul_assign(&z_at_z_omega); - for (wire_at_z, perm_at_z) in state.wire_values_at_z.iter() - .zip(state.permutation_polynomials_at_z.iter()) - { + for (wire_at_z, perm_at_z) in state.wire_values_at_z.iter().zip(state.permutation_polynomials_at_z.iter()) { let mut t = *perm_at_z; t.mul_assign(&beta); t.add_assign(&wire_at_z); @@ -1146,7 +967,7 @@ impl ProverAssembly4WithNextStep { // sanity check - verification { let mut lhs = t_at_z; - let vanishing_at_z = evaluate_vanishing_for_size(&z ,required_domain_size as u64); + let vanishing_at_z = evaluate_vanishing_for_size(&z, required_domain_size as u64); lhs.mul_assign(&vanishing_at_z); let mut quotient_linearization_challenge = E::Fr::one(); @@ -1176,9 +997,9 @@ impl ProverAssembly4WithNextStep { tmp.mul_assign(&beta); tmp.add_assign(&gamma); tmp.add_assign(&w); - + z_part.mul_assign(&tmp); - } + } // last poly value and gamma let mut tmp = gamma; @@ -1190,7 +1011,7 @@ impl ProverAssembly4WithNextStep { rhs.sub_assign(&z_part); quotient_linearization_challenge.mul_assign(&alpha); - + // - L_0(z) * \alpha^2 let mut l_0_at_z = evaluate_l0_at_point(required_domain_size as u64, z)?; @@ -1211,21 +1032,19 @@ impl ProverAssembly4WithNextStep { quotient_polynomial_at_z: state.quotient_polynomial_at_z, linearization_polynomial_at_z: state.linearization_polynomial_at_z, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok((state, message)) } - pub(crate) fn fifth_step_from_fourth_step( mut fourth_state: FourthPartialProverState, fourth_verifier_message: FourthVerifierMessage, setup: &SetupPolynomials, - crs_mons: &Crs, - worker: &Worker - ) -> Result, SynthesisError> - { + crs_mons: &Crs, + worker: &Worker, + ) -> Result, SynthesisError> { let FourthVerifierMessage { z, v, .. } = fourth_verifier_message; let required_domain_size = fourth_state.required_domain_size; @@ -1307,23 +1126,15 @@ impl ProverAssembly4WithNextStep { let open_at_z_omega = polys.pop().unwrap().0; let open_at_z = polys.pop().unwrap().0; - let opening_at_z = commit_using_monomials( - &open_at_z, - &crs_mons, - &worker - )?; + let opening_at_z = commit_using_monomials(&open_at_z, &crs_mons, &worker)?; - let opening_at_z_omega = commit_using_monomials( - &open_at_z_omega, - &crs_mons, - &worker - )?; + let opening_at_z_omega = commit_using_monomials(&open_at_z_omega, &crs_mons, &worker)?; let message = FifthProverMessage:: { opening_proof_at_z: opening_at_z, opening_proof_at_z_omega: opening_at_z_omega, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok(message) diff --git a/crates/bellman/src/plonk/better_cs/test_assembly.rs b/crates/bellman/src/plonk/better_cs/test_assembly.rs index cc4cb03..0e56b6e 100644 --- a/crates/bellman/src/plonk/better_cs/test_assembly.rs +++ b/crates/bellman/src/plonk/better_cs/test_assembly.rs @@ -1,7 +1,7 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use super::cs::*; @@ -23,14 +23,14 @@ pub struct TestAssembly> { next_step_leftover_from_previous_gate: Option<(E::Fr, P::NextTraceStepCoefficients)>, - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } impl> ConstraintSystem for TestAssembly { // allocate a variable fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -46,7 +46,7 @@ impl> ConstraintSystem for Te // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -59,22 +59,15 @@ impl> ConstraintSystem for Te self.n += 1; Ok(input_var) - } // allocate an abstract gate - fn new_gate(&mut self, - variables: P::StateVariables, - this_step_coeffs: P::ThisTraceStepCoefficients, - next_step_coeffs: P::NextTraceStepCoefficients - ) -> Result<(), SynthesisError> { + fn new_gate(&mut self, variables: P::StateVariables, this_step_coeffs: P::ThisTraceStepCoefficients, next_step_coeffs: P::NextTraceStepCoefficients) -> Result<(), SynthesisError> { // check that leftover of this gate is satisfied if let Some((value_leftover, coeffs)) = self.next_step_leftover_from_previous_gate.take() { let mut leftover = value_leftover; - for (&var, coeff) in variables.as_ref().iter().rev() - .zip(coeffs.as_ref().iter()) - { + for (&var, coeff) in variables.as_ref().iter().rev().zip(coeffs.as_ref().iter()) { let mut value = self.get_value(var)?; value.mul_assign(&coeff); @@ -93,9 +86,7 @@ impl> ConstraintSystem for Te let mut this_step_coeffs_iter = this_step_coeffs.as_ref().iter(); // first take an LC - for (&var, coeff) in variables.as_ref().iter() - .zip(&mut this_step_coeffs_iter) - { + for (&var, coeff) in variables.as_ref().iter().zip(&mut this_step_coeffs_iter) { let mut value = self.get_value(var)?; value.mul_assign(&coeff); @@ -120,7 +111,7 @@ impl> ConstraintSystem for Te // assert!(self.next_step_vars.is_some()); // let next_step_vars = self.next_step_vars.take().expect("must have some next step variables") // for (&var, coeff) in variables.as_ref().iter().rev() - // .zip(next_step_coeffs.as_ref().iter()) + // .zip(next_step_coeffs.as_ref().iter()) // { // let mut value = self.get_value(var)?; // value.mul_assign(&coeff); @@ -133,10 +124,6 @@ impl> ConstraintSystem for Te } } - - - - self.n += 1; Ok(()) @@ -151,12 +138,8 @@ impl> ConstraintSystem for Te Variable(Index::Input(0)) => { return Err(SynthesisError::AssignmentMissing); } - Variable(Index::Input(input)) => { - self.input_assingments[input - 1] - }, - Variable(Index::Aux(aux)) => { - self.aux_assingments[aux - 1] - } + Variable(Index::Input(input)) => self.input_assingments[input - 1], + Variable(Index::Aux(aux)) => self.aux_assingments[aux - 1], }; Ok(value) @@ -185,7 +168,7 @@ impl> TestAssembly { next_step_leftover_from_previous_gate: None, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; tmp @@ -208,7 +191,7 @@ impl> TestAssembly { next_step_leftover_from_previous_gate: None, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; tmp diff --git a/crates/bellman/src/plonk/better_cs/utils.rs b/crates/bellman/src/plonk/better_cs/utils.rs index e1ea9f4..81945c8 100644 --- a/crates/bellman/src/plonk/better_cs/utils.rs +++ b/crates/bellman/src/plonk/better_cs/utils.rs @@ -1,16 +1,12 @@ use crate::ff::PrimeField; -use crate::pairing::{Engine, CurveAffine}; -use crate::worker::Worker; -use crate::SynthesisError; +use crate::pairing::{CurveAffine, Engine}; +use crate::plonk::commitments::transcript::Transcript; use crate::plonk::domains::Domain; use crate::plonk::polynomials::*; -use crate::plonk::commitments::transcript::Transcript; +use crate::worker::Worker; +use crate::SynthesisError; -pub(crate) fn calculate_inverse_vanishing_polynomial_in_a_coset( - worker: &Worker, - poly_size: usize, - vahisning_size: usize -) -> Result, SynthesisError> { +pub(crate) fn calculate_inverse_vanishing_polynomial_in_a_coset(worker: &Worker, poly_size: usize, vahisning_size: usize) -> Result, SynthesisError> { assert!(poly_size.is_power_of_two()); assert!(vahisning_size.is_power_of_two()); @@ -40,7 +36,7 @@ pub(crate) fn calculate_inverse_vanishing_polynomial_in_a_coset( // now we should evaluate X^(n+1) - 1 in a linear time let shift = multiplicative_generator.pow([vahisning_size as u64]); - + let mut denominator = Polynomial::::from_values(vec![shift; poly_size])?; // elements are h^size - 1, (hg)^size - 1, (hg^2)^size - 1, ... @@ -55,10 +51,7 @@ pub(crate) fn calculate_inverse_vanishing_polynomial_in_a_coset( Ok(numerator) } -pub(crate) fn evaluate_inverse_vanishing_poly_with_last_point_cut( - vahisning_size: usize, - point: F -) -> F { +pub(crate) fn evaluate_inverse_vanishing_poly_with_last_point_cut(vahisning_size: usize, point: F) -> F { assert!(vahisning_size.is_power_of_two()); // update from the paper - it should not hold for the last generator, omega^(n) in original notations @@ -82,11 +75,7 @@ pub(crate) fn evaluate_inverse_vanishing_poly_with_last_point_cut numerator } -pub(crate) fn calculate_lagrange_poly( - worker: &Worker, - poly_size:usize, - poly_number: usize -) -> Result, SynthesisError> { +pub(crate) fn calculate_lagrange_poly(worker: &Worker, poly_size: usize, poly_number: usize) -> Result, SynthesisError> { assert!(poly_size.is_power_of_two()); assert!(poly_number < poly_size); @@ -101,7 +90,7 @@ pub(crate) fn evaluate_vanishing_polynomial_of_degree_on_domain_size Result, SynthesisError> { let domain = Domain::::new_for_size(domain_size)?; let domain_generator = domain.generator; @@ -139,10 +128,7 @@ pub(crate) fn evaluate_vanishing_for_size(point: &F, vanishing_do result } -pub(crate) fn evaluate_l0_at_point( - domain_size: u64, - point: F -) -> Result { +pub(crate) fn evaluate_l0_at_point(domain_size: u64, point: F) -> Result { let size_as_fe = F::from_str(&format!("{}", domain_size)).unwrap(); let mut den = point; @@ -158,11 +144,7 @@ pub(crate) fn evaluate_l0_at_point( Ok(num) } -pub(crate) fn evaluate_lagrange_poly_at_point( - poly_number: usize, - domain: &Domain, - point: F -) -> Result { +pub(crate) fn evaluate_lagrange_poly_at_point(poly_number: usize, domain: &Domain, point: F) -> Result { // lagrange polynomials have a form // (omega^i / N) / (X - omega^i) * (X^N - 1) @@ -185,7 +167,6 @@ pub(crate) fn evaluate_lagrange_poly_at_point( use crate::ff::SqrtField; - pub fn make_non_residues(num: usize) -> Vec { // create largest domain possible assert!(F::S < 63); @@ -198,8 +179,8 @@ pub fn make_non_residues(num: usize) -> Vec { pub fn make_non_residues_for_domain(num: usize, domain: &Domain) -> Vec { use crate::ff::LegendreSymbol; - - // we need to check that + + // we need to check that // - some k is not a residue // - it's NOT a part of coset formed as other_k * {1, omega^1, ...} @@ -213,7 +194,7 @@ pub fn make_non_residues_for_domain(num: usize, domai } else { let mut is_unique = true; { - // first pow into the domain size + // first pow into the domain size let tmp = current.pow(&[domain.size]); // then check: if it's in some other coset, then // X^N == other_k ^ N @@ -239,10 +220,7 @@ pub fn make_non_residues_for_domain(num: usize, domai non_residues } -pub fn commit_point_as_xy>( - transcript: &mut T, - point: &E::G1Affine -) { +pub fn commit_point_as_xy>(transcript: &mut T, point: &E::G1Affine) { use crate::ff::Field; if point.is_zero() { @@ -255,22 +233,21 @@ pub fn commit_point_as_xy>( } } - #[cfg(test)] - mod test { +mod test { #[test] fn test_lagrange_poly_explicit_multicore_validity() { - use crate::pairing::bn256::Fr; - use crate::ff::{Field, PrimeField}; use super::*; + use crate::ff::{Field, PrimeField}; + use crate::pairing::bn256::Fr; if cfg!(debug_assertions) { println!("Will be too slow to run in test mode, abort"); return; } - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; use crate::worker::Worker; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let size: usize = 1 << 21; let worker = Worker::new(); @@ -292,4 +269,4 @@ pub fn commit_point_as_xy>( } } } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/better_cs/verifier.rs b/crates/bellman/src/plonk/better_cs/verifier.rs index 2f150ae..9d0b062 100644 --- a/crates/bellman/src/plonk/better_cs/verifier.rs +++ b/crates/bellman/src/plonk/better_cs/verifier.rs @@ -1,10 +1,10 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::plonk::domains::*; use crate::plonk::polynomials::*; use crate::worker::Worker; -use crate::plonk::domains::*; +use crate::SynthesisError; use std::marker::PhantomData; @@ -13,15 +13,15 @@ use super::keys::{Proof, VerificationKey}; use crate::source::{DensityTracker, DensityTrackerersChain}; -use crate::kate_commitment::*; use super::utils::*; +use crate::kate_commitment::*; use crate::plonk::commitments::transcript::*; pub fn verify, T: Transcript>( proof: &Proof, verification_key: &VerificationKey, - transcript_init_params: Option< >:: InitializationParameters>, + transcript_init_params: Option<>::InitializationParameters>, ) -> Result { let (valid, _) = verify_and_aggregate::(proof, verification_key, transcript_init_params)?; @@ -31,18 +31,14 @@ pub fn verify, T: Transcript pub fn verify_and_aggregate, T: Transcript>( proof: &Proof, verification_key: &VerificationKey, - transcript_init_params: Option< >:: InitializationParameters>, + transcript_init_params: Option<>::InitializationParameters>, ) -> Result<(bool, [E::G1Affine; 2]), SynthesisError> { use crate::pairing::CurveAffine; use crate::pairing::CurveProjective; assert!(P::CAN_ACCESS_NEXT_TRACE_STEP); - let mut transcript = if let Some(p) = transcript_init_params { - T::new_from_params(p) - } else { - T::new() - }; + let mut transcript = if let Some(p) = transcript_init_params { T::new_from_params(p) } else { T::new() }; if proof.n != verification_key.n { return Err(SynthesisError::MalformedVerifyingKey); @@ -112,7 +108,6 @@ pub fn verify_and_aggregate, T: Tra transcript.commit_field_element(&proof.grand_product_at_z_omega); - // do the actual check for relationship at z { @@ -145,9 +140,9 @@ pub fn verify_and_aggregate, T: Tra tmp.mul_assign(&beta); tmp.add_assign(&gamma); tmp.add_assign(&w); - + z_part.mul_assign(&tmp); - } + } // last poly value and gamma let mut tmp = gamma; @@ -159,7 +154,7 @@ pub fn verify_and_aggregate, T: Tra rhs.sub_assign(&z_part); quotient_linearization_challenge.mul_assign(&alpha); - + // - L_0(z) * \alpha^2 let mut l_0_at_z = evaluate_l0_at_point(required_domain_size as u64, z)?; @@ -188,7 +183,7 @@ pub fn verify_and_aggregate, T: Tra // calculate the power to add z(X) commitment that is opened at x*omega // it's r(X) + witness + all permutations + 1 - let v_power_for_standalone_z_x_opening = 1 + 1 + P::STATE_WIDTH + (P::STATE_WIDTH-1); + let v_power_for_standalone_z_x_opening = 1 + 1 + P::STATE_WIDTH + (P::STATE_WIDTH - 1); let virtual_commitment_for_linearization_poly = { let mut r = E::G1::zero(); @@ -214,7 +209,7 @@ pub fn verify_and_aggregate, T: Tra // v * [alpha * (a + beta*z + gamma)(b + beta*k_1*z + gamma)()() * z(X) - // - \alpha * (a*perm_a(z)*beta + gamma)()()*beta*z(z*omega) * perm_d(X) + - // + alpha^2 * L_0(z) * z(X) ] + + // + alpha^2 * L_0(z) * z(X) ] + // + v^{P} * u * z(X) // and join alpha^2 * L_0(z) and v^{P} * u into the first term containing z(X) @@ -223,9 +218,7 @@ pub fn verify_and_aggregate, T: Tra let mut scalar = E::Fr::one(); // permutation part - for (wire, non_res) in proof.wire_values_at_z.iter() - .zip(Some(E::Fr::one()).iter().chain(&non_residues)) - { + for (wire, non_res) in proof.wire_values_at_z.iter().zip(Some(E::Fr::one()).iter().chain(&non_residues)) { let mut tmp = z; tmp.mul_assign(&non_res); tmp.mul_assign(&beta); @@ -265,9 +258,7 @@ pub fn verify_and_aggregate, T: Tra let mut scalar = E::Fr::one(); // permutation part - for (wire, perm_at_z) in proof.wire_values_at_z.iter() - .zip(&proof.permutation_polynomials_at_z) - { + for (wire, perm_at_z) in proof.wire_values_at_z.iter().zip(&proof.permutation_polynomials_at_z) { let mut tmp = beta; tmp.mul_assign(&perm_at_z); tmp.add_assign(&wire); @@ -287,7 +278,7 @@ pub fn verify_and_aggregate, T: Tra { let mut tmp = proof.grand_product_commitment.mul(grand_product_part_at_z.into_repr()); tmp.sub_assign(&verification_key.permutation_commitments.last().unwrap().mul(last_permutation_part_at_z.into_repr())); - + r.add_assign(&tmp); } @@ -352,19 +343,20 @@ pub fn verify_and_aggregate, T: Tra let mut multiopening_challenge_for_values = E::Fr::one(); let mut aggregated_value = proof.quotient_polynomial_at_z; - for value_at_z in Some(proof.linearization_polynomial_at_z).iter() - .chain(&proof.wire_values_at_z) - .chain(&proof.permutation_polynomials_at_z) - { - multiopening_challenge_for_values.mul_assign(&v); - let mut tmp = *value_at_z; - tmp.mul_assign(&multiopening_challenge_for_values); - aggregated_value.add_assign(&tmp); - } + for value_at_z in Some(proof.linearization_polynomial_at_z) + .iter() + .chain(&proof.wire_values_at_z) + .chain(&proof.permutation_polynomials_at_z) + { + multiopening_challenge_for_values.mul_assign(&v); + let mut tmp = *value_at_z; + tmp.mul_assign(&multiopening_challenge_for_values); + aggregated_value.add_assign(&tmp); + } // add parts that are opened at z*omega using `u` { - multiopening_challenge_for_values.mul_assign(&v); + multiopening_challenge_for_values.mul_assign(&v); let mut scalar = multiopening_challenge_for_values; scalar.mul_assign(&u); let mut tmp = proof.grand_product_at_z_omega; @@ -373,7 +365,7 @@ pub fn verify_and_aggregate, T: Tra aggregated_value.add_assign(&tmp); } { - multiopening_challenge_for_values.mul_assign(&v); + multiopening_challenge_for_values.mul_assign(&v); let mut scalar = multiopening_challenge_for_values; scalar.mul_assign(&u); let mut tmp = proof.wire_values_at_z_omega[0]; @@ -388,7 +380,7 @@ pub fn verify_and_aggregate, T: Tra commitments_aggregation.sub_assign(&E::G1Affine::one().mul(aggregated_value.into_repr())); // now check that - // e(proof_for_z + u*proof_for_z_omega, g2^x) = e(z*proof_for_z + z*omega*u*proof_for_z_omega + (aggregated_commitment - aggregated_opening), g2^1) + // e(proof_for_z + u*proof_for_z_omega, g2^x) = e(z*proof_for_z + z*omega*u*proof_for_z_omega + (aggregated_commitment - aggregated_opening), g2^1) // with a corresponding change of sign let mut pair_with_generator = commitments_aggregation; @@ -405,12 +397,12 @@ pub fn verify_and_aggregate, T: Tra let pair_with_generator = pair_with_generator.into_affine(); let pair_with_x = pair_with_x.into_affine(); - let valid = E::final_exponentiation( - &E::miller_loop(&[ - (&pair_with_generator.prepare(), &verification_key.g2_elements[0].prepare()), - (&pair_with_x.prepare(), &verification_key.g2_elements[1].prepare()) - ]) - ).unwrap() == E::Fqk::one(); + let valid = E::final_exponentiation(&E::miller_loop(&[ + (&pair_with_generator.prepare(), &verification_key.g2_elements[0].prepare()), + (&pair_with_x.prepare(), &verification_key.g2_elements[1].prepare()), + ])) + .unwrap() + == E::Fqk::one(); Ok((valid, [pair_with_generator, pair_with_x])) -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/commitments/mod.rs b/crates/bellman/src/plonk/commitments/mod.rs index 7ba4e29..505d312 100644 --- a/crates/bellman/src/plonk/commitments/mod.rs +++ b/crates/bellman/src/plonk/commitments/mod.rs @@ -1,7 +1,7 @@ use crate::pairing::ff::PrimeField; -use crate::plonk::polynomials::*; use crate::plonk::commitments::transcript::*; +use crate::plonk::polynomials::*; pub mod transparent; @@ -22,7 +22,24 @@ pub trait CommitmentScheme { fn commit_single(&self, poly: &Polynomial) -> (Self::Commitment, Option); fn commit_multiple(&self, polynomials: Vec<&Polynomial>, degrees: Vec, aggregation_coefficient: F) -> (Self::Commitment, Option>); fn open_single(&self, poly: &Polynomial, at_point: F, opening_value: F, data: &Option<&Self::IntermediateData>, prng: &mut Self::Prng) -> Self::OpeningProof; - fn open_multiple(&self, polynomials: Vec<&Polynomial>, degrees: Vec, aggregation_coefficient: F, at_points: Vec, opening_values: Vec, data: &Option>, prng: &mut Self::Prng) -> Self::OpeningProof; + fn open_multiple( + &self, + polynomials: Vec<&Polynomial>, + degrees: Vec, + aggregation_coefficient: F, + at_points: Vec, + opening_values: Vec, + data: &Option>, + prng: &mut Self::Prng, + ) -> Self::OpeningProof; fn verify_single(&self, commitment: &Self::Commitment, at_point: F, claimed_value: F, proof: &Self::OpeningProof, prng: &mut Self::Prng) -> bool; - fn verify_multiple_openings(&self, commitments: Vec<&Self::Commitment>, at_points: Vec, claimed_values: &Vec, aggregation_coefficient: F, proof: &Self::OpeningProof, prng: &mut Self::Prng) -> bool; -} \ No newline at end of file + fn verify_multiple_openings( + &self, + commitments: Vec<&Self::Commitment>, + at_points: Vec, + claimed_values: &Vec, + aggregation_coefficient: F, + proof: &Self::OpeningProof, + prng: &mut Self::Prng, + ) -> bool; +} diff --git a/crates/bellman/src/plonk/commitments/transcript/keccak_transcript.rs b/crates/bellman/src/plonk/commitments/transcript/keccak_transcript.rs index 163a5d7..39760c2 100644 --- a/crates/bellman/src/plonk/commitments/transcript/keccak_transcript.rs +++ b/crates/bellman/src/plonk/commitments/transcript/keccak_transcript.rs @@ -1,6 +1,6 @@ -use tiny_keccak::Keccak; +use crate::byteorder::{BigEndian, ByteOrder}; use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; -use crate::byteorder::{ByteOrder, BigEndian}; +use tiny_keccak::Keccak; use super::*; @@ -9,18 +9,18 @@ pub struct RollingKeccakTranscript { state_part_0: [u8; 32], state_part_1: [u8; 32], challenge_counter: u32, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl RollingKeccakTranscript { const SHAVE_BITS: u32 = 256 - F::CAPACITY; // const REPR_SIZE: usize = std::mem::size_of::(); - const REPR_SIZE: usize = (((F::NUM_BITS as usize)/ 64) + 1) * 8; + const REPR_SIZE: usize = (((F::NUM_BITS as usize) / 64) + 1) * 8; const DST_0_TAG: u32 = 0; const DST_1_TAG: u32 = 1; const CHALLENGE_DST_TAG: u32 = 2; - fn update(&mut self, bytes: &[u8]){ + fn update(&mut self, bytes: &[u8]) { let old_state_0 = self.state_part_0; let mut input = vec![0u8; bytes.len() + 32 + 32 + 4]; @@ -72,7 +72,7 @@ impl Prng for RollingKeccakTranscript { state_part_0: [0u8; 32], state_part_1: [0u8; 32], challenge_counter: 0, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } @@ -88,7 +88,7 @@ impl Prng for RollingKeccakTranscript { // self.state = Keccak::new_keccak256(); // self.state.update(&value); - + let mut repr = F::Repr::default(); let shaving_mask: u64 = 0xffffffffffffffff >> (Self::SHAVE_BITS % 64); repr.read_be(&value[..]).expect("will read"); @@ -115,7 +115,7 @@ impl Transcript for RollingKeccakTranscript { let repr = element.into_repr(); let mut bytes: Vec = vec![0u8; Self::REPR_SIZE]; repr.write_be(&mut bytes[..]).expect("should write"); - + // self.state.update(&bytes[..]); self.update(&bytes); } diff --git a/crates/bellman/src/plonk/commitments/transcript/mod.rs b/crates/bellman/src/plonk/commitments/transcript/mod.rs index 5da8d3f..2596725 100644 --- a/crates/bellman/src/plonk/commitments/transcript/mod.rs +++ b/crates/bellman/src/plonk/commitments/transcript/mod.rs @@ -1,8 +1,8 @@ -use blake2s_simd::{Params, State}; use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; +use blake2s_simd::{Params, State}; -pub mod prng; pub mod keccak_transcript; +pub mod prng; // #[cfg(feature = "redshift")] // pub mod rescue_transcript; @@ -10,13 +10,7 @@ pub mod keccak_transcript; // pub mod poseidon_transcript; lazy_static! { - static ref TRANSCRIPT_BLAKE2S_PARAMS: State = { - Params::new() - .hash_length(32) - .key(b"Squeamish Ossifrage") - .personal(b"Shaftoe") - .to_state() - }; + static ref TRANSCRIPT_BLAKE2S_PARAMS: State = { Params::new().hash_length(32).key(b"Squeamish Ossifrage").personal(b"Shaftoe").to_state() }; } pub trait Prng: Sized + Clone { @@ -40,16 +34,15 @@ pub trait Transcript: Prng + Sized + Clone { #[derive(Clone)] pub struct Blake2sTranscript { state: State, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl Blake2sTranscript { const SHAVE_BITS: u32 = 256 - F::CAPACITY; // const REPR_SIZE: usize = std::mem::size_of::(); - const REPR_SIZE: usize = (((F::NUM_BITS as usize)/ 64) + 1) * 8; + const REPR_SIZE: usize = (((F::NUM_BITS as usize) / 64) + 1) * 8; } - // impl Prng for Blake2sTranscript { // type Input = F; @@ -69,7 +62,7 @@ impl Blake2sTranscript { // fn get_challenge(&mut self) -> F { // let value = *(self.state.finalize().as_array()); // self.state.update(&value[..]); - + // let mut repr = F::Repr::default(); // let shaving_mask: u64 = 0xffffffffffffffff >> (Self::SHAVE_BITS % 64); // repr.read_be(&value[..]).expect("will read"); @@ -90,7 +83,7 @@ impl Prng for Blake2sTranscript { let state = (*TRANSCRIPT_BLAKE2S_PARAMS).clone(); Self { state, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } @@ -101,7 +94,7 @@ impl Prng for Blake2sTranscript { fn get_challenge(&mut self) -> F { let value = *(self.state.finalize().as_array()); self.state.update(&value[..]); - + let mut repr = F::Repr::default(); let shaving_mask: u64 = 0xffffffffffffffff >> (Self::SHAVE_BITS % 64); repr.read_be(&value[..]).expect("will read"); @@ -126,7 +119,7 @@ impl Transcript for Blake2sTranscript { let repr = element.into_repr(); let mut bytes: Vec = vec![0u8; Self::REPR_SIZE]; repr.write_be(&mut bytes[..]).expect("should write"); - + self.state.update(&bytes[..]); } @@ -143,7 +136,7 @@ impl Transcript for Blake2sTranscript { let repr = element.into_repr(); let mut bytes: Vec = vec![0u8; Self::REPR_SIZE]; repr.write_be(&mut bytes[..]).expect("should write"); - + self.state.update(&bytes[..]); } } diff --git a/crates/bellman/src/plonk/commitments/transcript/prng.rs b/crates/bellman/src/plonk/commitments/transcript/prng.rs index 721c92c..d79b557 100644 --- a/crates/bellman/src/plonk/commitments/transcript/prng.rs +++ b/crates/bellman/src/plonk/commitments/transcript/prng.rs @@ -1,27 +1,21 @@ -use blake2s_simd::{Params, State}; -use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; use super::Prng; +use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; +use blake2s_simd::{Params, State}; lazy_static! { - static ref STATELESS_PRNG_BLAKE2S_PARAMS: State = { - Params::new() - .hash_length(32) - .key(b"Squeamish Ossifrage") - .personal(b"S_Prng_F") - .to_state() - }; + static ref STATELESS_PRNG_BLAKE2S_PARAMS: State = { Params::new().hash_length(32).key(b"Squeamish Ossifrage").personal(b"S_Prng_F").to_state() }; } #[derive(Clone)] pub struct StatelessBlake2sPrng { state: State, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl StatelessBlake2sPrng { const SHAVE_BITS: u32 = 256 - F::CAPACITY; // const REPR_SIZE: usize = std::mem::size_of::(); - const REPR_SIZE: usize = (((F::NUM_BITS as usize)/ 64) + 1) * 8; + const REPR_SIZE: usize = (((F::NUM_BITS as usize) / 64) + 1) * 8; } impl Prng for StatelessBlake2sPrng { @@ -32,7 +26,7 @@ impl Prng for StatelessBlake2sPrng { assert!(F::NUM_BITS < 256); Self { state: STATELESS_PRNG_BLAKE2S_PARAMS.clone(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } @@ -48,7 +42,7 @@ impl Prng for StatelessBlake2sPrng { fn get_challenge(&mut self) -> F { let value = *(self.state.finalize().as_array()); self.state = STATELESS_PRNG_BLAKE2S_PARAMS.clone(); - + let mut repr = F::Repr::default(); let shaving_mask: u64 = 0xffffffffffffffff >> (Self::SHAVE_BITS % 64); repr.read_be(&value[..]).expect("will read"); diff --git a/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/fri.rs b/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/fri.rs index 75b1182..17ee02c 100644 --- a/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/fri.rs +++ b/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/fri.rs @@ -1,13 +1,13 @@ +use super::*; use crate::pairing::ff::PrimeField; -use crate::plonk::commitments::transparent::iop_compiler::*; +use crate::plonk::commitments::transcript::Prng; use crate::plonk::commitments::transparent::iop_compiler::coset_combining_blake2s_tree::*; +use crate::plonk::commitments::transparent::iop_compiler::*; +use crate::plonk::commitments::transparent::precomputations::*; +use crate::plonk::commitments::transparent::utils::log2_floor; use crate::plonk::polynomials::*; use crate::worker::*; use crate::SynthesisError; -use crate::plonk::commitments::transparent::utils::log2_floor; -use crate::plonk::commitments::transcript::Prng; -use crate::plonk::commitments::transparent::precomputations::*; -use super::*; pub struct CosetCombiningFriIop { cosets_schedule: Vec, @@ -17,7 +17,7 @@ pub struct CosetCombiningFriIop { #[derive(Clone, Debug)] pub struct CosetParams { pub cosets_schedule: Vec, - pub coset_factor: F + pub coset_factor: F, } impl FriIop for CosetCombiningFriIop { @@ -28,43 +28,29 @@ impl FriIop for CosetCombiningFriIop { type Proof = FRIProof; type Params = CosetParams; - fn proof_from_lde>::Commitment>, - C: FriPrecomputations - >( - lde_values: &Polynomial, + fn proof_from_lde>::Commitment>, C: FriPrecomputations>( + lde_values: &Polynomial, lde_factor: usize, output_coeffs_at_degree_plus_one: usize, precomputations: &C, worker: &Worker, prng: &mut P, - params: &Self::Params + params: &Self::Params, ) -> Result { - Self::proof_from_lde_by_values( - lde_values, - lde_factor, - output_coeffs_at_degree_plus_one, - precomputations, - worker, - prng, - params - ) + Self::proof_from_lde_by_values(lde_values, lde_factor, output_coeffs_at_degree_plus_one, precomputations, worker, prng, params) } fn prototype_into_proof( prototype: Self::ProofPrototype, iop_values: &Polynomial, natural_first_element_indexes: Vec, - params: &Self::Params + params: &Self::Params, ) -> Result { unimplemented!() // prototype.produce_proof(iop_values, natural_first_element_indexes) } - fn get_fri_challenges>::Commitment>>( - proof: &Self::Proof, - prng: &mut P, - params: &Self::Params - ) -> Vec { + fn get_fri_challenges>::Commitment>>(proof: &Self::Proof, prng: &mut P, params: &Self::Params) -> Vec { let mut fri_challenges = vec![]; for root in proof.roots.iter() { @@ -79,13 +65,7 @@ impl FriIop for CosetCombiningFriIop { fri_challenges } - fn verify_proof_with_challenges( - proof: &Self::Proof, - natural_element_indexes: Vec, - expected_value: &[F], - fri_challenges: &[F], - params: &Self::Params - ) -> Result { + fn verify_proof_with_challenges(proof: &Self::Proof, natural_element_indexes: Vec, expected_value: &[F], fri_challenges: &[F], params: &Self::Params) -> Result { unimplemented!() // Self::verify_proof_queries(proof, natural_element_indexes, Self::DEGREE, expected_value, fri_challenges) } @@ -97,7 +77,7 @@ use std::time::Instant; pub struct FRIProofPrototype> { // pub l0_commitment: I, pub intermediate_commitments: Vec, - pub intermediate_values: Vec< Polynomial >, + pub intermediate_values: Vec>, pub challenges: Vec>, pub final_root: I::Commitment, pub final_coefficients: Vec, @@ -147,16 +127,14 @@ impl> FriProof for FRIProof { } impl CosetCombiningFriIop { - pub fn proof_from_lde_by_values>::IopType as IopInstance>::Commitment>, - C: FriPrecomputations - >( - lde_values: &Polynomial, + pub fn proof_from_lde_by_values>::IopType as IopInstance>::Commitment>, C: FriPrecomputations>( + lde_values: &Polynomial, lde_factor: usize, output_coeffs_at_degree_plus_one: usize, precomputations: &C, worker: &Worker, prng: &mut P, - params: &>::Params + params: &>::Params, ) -> Result>::IopType>, SynthesisError> { let mut coset_schedule_index = 0; let coset_factor = params.cosets_schedule[coset_schedule_index]; @@ -182,14 +160,19 @@ impl CosetCombiningFriIop { let mut two = F::one(); two.double(); let two_inv = two.inverse().expect("should exist"); - + assert!(output_coeffs_at_degree_plus_one.is_power_of_two()); assert!(lde_factor.is_power_of_two()); let initial_degree_plus_one = initial_domain_size / lde_factor; - assert_eq!(initial_degree_plus_one / total_wrap_factor, output_coeffs_at_degree_plus_one, + assert_eq!( + initial_degree_plus_one / total_wrap_factor, + output_coeffs_at_degree_plus_one, "number of FRI round does not match the ouput degree: initial degree+1 = {}, wrapping factor {}, output at degree+1 = {}", - initial_degree_plus_one, total_wrap_factor, output_coeffs_at_degree_plus_one); + initial_degree_plus_one, + total_wrap_factor, + output_coeffs_at_degree_plus_one + ); let mut intermediate_commitments = vec![]; let mut intermediate_values = vec![]; @@ -223,7 +206,7 @@ impl CosetCombiningFriIop { // etc... let num_steps = params.cosets_schedule.len(); - + for (fri_step, coset_factor) in params.cosets_schedule.iter().enumerate() { let coset_factor = *coset_factor; let wrapping_factor = 1 << coset_factor; @@ -236,12 +219,12 @@ impl CosetCombiningFriIop { // intermediate(omega*) intermediate(-omega*) // / \ / \ // this(omega) this(-omega) this(omega') this(-omega') - // + // // so omega* = omega^2i. omega' = sqrt(-omega^2i) = sqrt(omega^(N/2 + 2i)) = omega^N/4 + i - // + // // we expect values to come bitreversed, so this(omega) and this(-omega) are always adjustent to each other // because in normal emumeration it would be elements b0XYZ and b1XYZ, and now it's bZYX0 and bZYX1 - // + // // this(omega^(N/4 + i)) for b00YZ has a form b01YZ, so bitreversed it's bZY00 and bZY10 // this(-omega^(N/4 + i)) obviously has bZY11, so they are all near in initial values @@ -249,12 +232,12 @@ impl CosetCombiningFriIop { for (i, v) in next_values.chunks_mut(chunk).enumerate() { let next_domain_challenges = next_domain_challenges.clone(); scope.spawn(move |_| { - let initial_k = i*chunk; + let initial_k = i * chunk; let mut this_level_values = Vec::with_capacity(wrapping_factor); let mut next_level_values = vec![F::zero(); wrapping_factor]; for (j, v) in v.iter_mut().enumerate() { let batch_id = initial_k + j; - let values_offset = batch_id*wrapping_factor; + let values_offset = batch_id * wrapping_factor; for (wrapping_step, challenge) in next_domain_challenges.iter().enumerate() { let base_omega_idx = (batch_id * wrapping_factor) >> (1 + wrapping_step); let expected_this_level_values = wrapping_factor >> wrapping_step; @@ -314,9 +297,7 @@ impl CosetCombiningFriIop { coset_schedule_index += 1; this_domain_size = next_domain_size; let coset_factor = params.cosets_schedule[coset_schedule_index]; - let tree_params = FriSpecificBlake2sTreeParams { - values_per_leaf: (1 << coset_factor) - }; + let tree_params = FriSpecificBlake2sTreeParams { values_per_leaf: (1 << coset_factor) }; let intermediate_iop = FriSpecificBlake2sTree::create(next_values.as_ref(), &tree_params); let root = intermediate_iop.get_commitment(); roots.push(root); @@ -333,19 +314,19 @@ impl CosetCombiningFriIop { challenges.push(next_domain_challenges.clone()); intermediate_commitments.push(intermediate_iop); - } + } let next_values_as_poly = Polynomial::from_values(next_values)?; intermediate_values.push(next_values_as_poly); - values_slice = intermediate_values.last().expect("is something").as_ref(); + values_slice = intermediate_values.last().expect("is something").as_ref(); } let final_root = roots.last().expect("will work").clone(); assert_eq!(challenges.len(), num_steps); // assert_eq!(roots.len(), num_steps); - assert_eq!(intermediate_commitments.len(), num_steps-1); + assert_eq!(intermediate_commitments.len(), num_steps - 1); assert_eq!(intermediate_values.len(), num_steps); let mut final_poly_values = Polynomial::from_values(values_slice.to_vec())?; @@ -363,7 +344,7 @@ impl CosetCombiningFriIop { if c.is_zero() { degree -= 1; } else { - break + break; } } @@ -382,7 +363,6 @@ impl CosetCombiningFriIop { output_coeffs_at_degree_plus_one, lde_factor, }) - } } @@ -392,17 +372,17 @@ mod test { fn test_bench_fri_with_coset_combining() { use crate::ff::Field; use crate::ff::PrimeField; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use crate::plonk::commitments::transcript::*; + use crate::plonk::commitments::transparent::fri::coset_combining_fri::fri::*; + use crate::plonk::commitments::transparent::fri::coset_combining_fri::FriPrecomputations; + use crate::plonk::commitments::transparent::utils::*; + use crate::plonk::fft::cooley_tukey_ntt::{BitReversedOmegas, CTPrecomputations, OmegasInvBitreversed}; + use crate::plonk::polynomials::*; use crate::plonk::transparent_engine::proth_engine::Fr; use crate::plonk::transparent_engine::PartialTwoBitReductionField; - use crate::plonk::polynomials::*; - use std::time::Instant; use crate::worker::*; - use crate::plonk::commitments::transparent::utils::*; - use crate::plonk::fft::cooley_tukey_ntt::{CTPrecomputations, BitReversedOmegas, OmegasInvBitreversed}; - use crate::plonk::commitments::transparent::fri::coset_combining_fri::FriPrecomputations; - use crate::plonk::commitments::transparent::fri::coset_combining_fri::fri::*; - use crate::plonk::commitments::transcript::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; const SIZE: usize = 1024; @@ -412,7 +392,7 @@ mod test { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..SIZE).map(|_| Fr::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let precomp = BitReversedOmegas::::new_for_domain_size(poly.size()); let start = Instant::now(); @@ -420,22 +400,14 @@ mod test { let eval_result = poly.bitreversed_lde_using_bitreversed_ntt(&worker, 16, &precomp, &coset_factor).unwrap(); println!("LDE with factor 16 for size {} bitreversed {:?}", SIZE, start.elapsed()); - let fri_precomp = as FriPrecomputations>::new_for_domain_size(eval_result.size()); + let fri_precomp = as FriPrecomputations>::new_for_domain_size(eval_result.size()); let params = CosetParams:: { cosets_schedule: vec![3, 3, 3], - coset_factor: coset_factor + coset_factor: coset_factor, }; - let fri_proto = CosetCombiningFriIop::::proof_from_lde( - &eval_result, - 16, - 2, - &fri_precomp, - &worker, - &mut transcript, - ¶ms - ).expect("FRI must succeed"); + let fri_proto = CosetCombiningFriIop::::proof_from_lde(&eval_result, 16, 2, &fri_precomp, &worker, &mut transcript, ¶ms).expect("FRI must succeed"); } #[test] @@ -443,17 +415,17 @@ mod test { fn test_invalid_eval_fri_with_coset_combining() { use crate::ff::Field; use crate::ff::PrimeField; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use crate::plonk::commitments::transcript::*; + use crate::plonk::commitments::transparent::fri::coset_combining_fri::fri::*; + use crate::plonk::commitments::transparent::fri::coset_combining_fri::FriPrecomputations; + use crate::plonk::commitments::transparent::utils::*; + use crate::plonk::fft::cooley_tukey_ntt::{BitReversedOmegas, CTPrecomputations, OmegasInvBitreversed}; + use crate::plonk::polynomials::*; use crate::plonk::transparent_engine::proth_engine::Fr; use crate::plonk::transparent_engine::PartialTwoBitReductionField; - use crate::plonk::polynomials::*; - use std::time::Instant; use crate::worker::*; - use crate::plonk::commitments::transparent::utils::*; - use crate::plonk::fft::cooley_tukey_ntt::{CTPrecomputations, BitReversedOmegas, OmegasInvBitreversed}; - use crate::plonk::commitments::transparent::fri::coset_combining_fri::FriPrecomputations; - use crate::plonk::commitments::transparent::fri::coset_combining_fri::fri::*; - use crate::plonk::commitments::transcript::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; const SIZE: usize = 1024; @@ -463,7 +435,7 @@ mod test { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..SIZE).map(|_| Fr::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let precomp = BitReversedOmegas::::new_for_domain_size(poly.size()); let start = Instant::now(); @@ -472,21 +444,13 @@ mod test { eval_result.as_mut()[1].sub_assign(&Fr::one()); println!("LDE with factor 16 for size {} bitreversed {:?}", SIZE, start.elapsed()); - let fri_precomp = as FriPrecomputations>::new_for_domain_size(eval_result.size()); + let fri_precomp = as FriPrecomputations>::new_for_domain_size(eval_result.size()); let params = CosetParams:: { cosets_schedule: vec![3, 3, 3], - coset_factor: coset_factor + coset_factor: coset_factor, }; - let fri_proto = CosetCombiningFriIop::::proof_from_lde( - &eval_result, - 16, - 2, - &fri_precomp, - &worker, - &mut transcript, - ¶ms - ).expect("FRI must succeed"); + let fri_proto = CosetCombiningFriIop::::proof_from_lde(&eval_result, 16, 2, &fri_precomp, &worker, &mut transcript, ¶ms).expect("FRI must succeed"); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/mod.rs b/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/mod.rs index 1039a3c..58657ad 100644 --- a/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/mod.rs +++ b/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/mod.rs @@ -3,13 +3,13 @@ pub mod fri; // pub mod verifier; pub mod precomputation; -use crate::SynthesisError; -use crate::worker::Worker; use crate::ff::PrimeField; use crate::plonk::commitments::transparent::iop_compiler::*; +use crate::worker::Worker; +use crate::SynthesisError; -use crate::plonk::polynomials::*; use crate::plonk::commitments::transcript::Prng; +use crate::plonk::polynomials::*; pub trait FriProofPrototype> { fn get_roots(&self) -> Vec; @@ -36,36 +36,24 @@ pub trait FriIop { type Proof: FriProof; type Params: Clone + std::fmt::Debug; - fn proof_from_lde>::Commitment>, - C: FriPrecomputations - >( - lde_values: &Polynomial, + fn proof_from_lde>::Commitment>, C: FriPrecomputations>( + lde_values: &Polynomial, lde_factor: usize, output_coeffs_at_degree_plus_one: usize, precomputations: &C, worker: &Worker, prng: &mut P, - params: &Self::Params + params: &Self::Params, ) -> Result; fn prototype_into_proof( prototype: Self::ProofPrototype, iop_values: &Polynomial, natural_first_element_indexes: Vec, - params: &Self::Params + params: &Self::Params, ) -> Result; - fn get_fri_challenges>::Commitment>>( - proof: &Self::Proof, - prng: &mut P, - params: &Self::Params - ) -> Vec; + fn get_fri_challenges>::Commitment>>(proof: &Self::Proof, prng: &mut P, params: &Self::Params) -> Vec; - fn verify_proof_with_challenges( - proof: &Self::Proof, - natural_element_indexes: Vec, - expected_value: &[F], - fri_challenges: &[F], - params: &Self::Params - ) -> Result; -} \ No newline at end of file + fn verify_proof_with_challenges(proof: &Self::Proof, natural_element_indexes: Vec, expected_value: &[F], fri_challenges: &[F], params: &Self::Params) -> Result; +} diff --git a/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/precomputation.rs b/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/precomputation.rs index 739eab0..50da29a 100644 --- a/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/precomputation.rs +++ b/crates/bellman/src/plonk/commitments/transparent/fri/coset_combining_fri/precomputation.rs @@ -1,11 +1,11 @@ use crate::ff::PrimeField; -use crate::plonk::domains::Domain; -use crate::worker::Worker; -use crate::plonk::fft::distribute_powers; use super::*; +use crate::plonk::domains::Domain; +use crate::plonk::fft::cooley_tukey_ntt::OmegasInvBitreversed; use crate::plonk::fft::cooley_tukey_ntt::{bitreverse, log2_floor}; -use crate::plonk::fft::cooley_tukey_ntt::{OmegasInvBitreversed}; +use crate::plonk::fft::distribute_powers; +use crate::worker::Worker; impl FriPrecomputations for OmegasInvBitreversed { fn new_for_domain_size(size: usize) -> Self { @@ -25,13 +25,13 @@ impl FriPrecomputations for OmegasInvBitreversed { pub struct CosetOmegasInvBitreversed { pub omegas: Vec, - domain_size: usize + domain_size: usize, } impl CosetOmegasInvBitreversed { pub fn new_for_domain(domain: &Domain, worker: &Worker) -> Self { let domain_size = domain.size as usize; - + let omega = domain.generator.inverse().expect("must exist"); let precomputation_size = domain_size / 2; @@ -62,10 +62,7 @@ impl CosetOmegasInvBitreversed { } } - CosetOmegasInvBitreversed{ - omegas, - domain_size - } + CosetOmegasInvBitreversed { omegas, domain_size } } } @@ -83,4 +80,4 @@ impl FriPrecomputations for CosetOmegasInvBitreversed { fn domain_size(&self) -> usize { self.domain_size } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/commitments/transparent/fri/mod.rs b/crates/bellman/src/plonk/commitments/transparent/fri/mod.rs index 2b6fd85..c9bd381 100644 --- a/crates/bellman/src/plonk/commitments/transparent/fri/mod.rs +++ b/crates/bellman/src/plonk/commitments/transparent/fri/mod.rs @@ -1,17 +1,17 @@ use crate::pairing::ff::PrimeField; +use crate::plonk::commitments::transcript::Prng; use crate::plonk::commitments::transparent::iop::*; +use crate::plonk::commitments::transparent::utils::log2_floor; use crate::plonk::polynomials::*; use crate::worker::*; use crate::SynthesisError; -use crate::plonk::commitments::transparent::utils::log2_floor; -use crate::plonk::commitments::transcript::Prng; -pub mod naive_fri; pub mod coset_combining_fri; +pub mod naive_fri; pub trait FriProofPrototype> { - fn get_roots(&self) -> Vec< < >::TreeHasher as IopTreeHasher>::HashOutput>; - fn get_final_root(&self) -> < >::TreeHasher as IopTreeHasher>::HashOutput; + fn get_roots(&self) -> Vec<<>::TreeHasher as IopTreeHasher>::HashOutput>; + fn get_final_root(&self) -> <>::TreeHasher as IopTreeHasher>::HashOutput; fn get_final_coefficients(&self) -> Vec; } @@ -34,23 +34,21 @@ pub trait FriIop { type Proof: FriProof; type Params: Clone + std::fmt::Debug; - fn proof_from_lde>::Tree as IopTree >::TreeHasher as IopTreeHasher>::HashOutput >, - C: FriPrecomputations - >( - lde_values: &Polynomial, + fn proof_from_lde>::Tree as IopTree>::TreeHasher as IopTreeHasher>::HashOutput>, C: FriPrecomputations>( + lde_values: &Polynomial, lde_factor: usize, output_coeffs_at_degree_plus_one: usize, precomputations: &C, worker: &Worker, prng: &mut P, - params: &Self::Params + params: &Self::Params, ) -> Result; fn prototype_into_proof( prototype: Self::ProofPrototype, iop_values: &Polynomial, natural_first_element_indexes: Vec, - params: &Self::Params + params: &Self::Params, ) -> Result; // // will write roots to prng values @@ -61,17 +59,11 @@ pub trait FriIop { // prng: &mut P // ) -> Result; - fn get_fri_challenges>::Tree as IopTree >::TreeHasher as IopTreeHasher>::HashOutput > >( + fn get_fri_challenges>::Tree as IopTree>::TreeHasher as IopTreeHasher>::HashOutput>>( proof: &Self::Proof, prng: &mut P, - params: &Self::Params + params: &Self::Params, ) -> Vec; - fn verify_proof_with_challenges( - proof: &Self::Proof, - natural_element_indexes: Vec, - expected_value: &[F], - fri_challenges: &[F], - params: &Self::Params - ) -> Result; -} \ No newline at end of file + fn verify_proof_with_challenges(proof: &Self::Proof, natural_element_indexes: Vec, expected_value: &[F], fri_challenges: &[F], params: &Self::Params) -> Result; +} diff --git a/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/mod.rs b/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/mod.rs index ba7866a..50404e9 100644 --- a/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/mod.rs +++ b/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/mod.rs @@ -1,3 +1,3 @@ pub mod naive_fri; pub mod query_producer; -pub mod verifier; \ No newline at end of file +pub mod verifier; diff --git a/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/naive_fri.rs b/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/naive_fri.rs index 27208e7..557395c 100644 --- a/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/naive_fri.rs +++ b/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/naive_fri.rs @@ -1,20 +1,20 @@ +use super::super::*; use crate::pairing::ff::PrimeField; +use crate::plonk::commitments::transcript::Prng; +use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transparent::iop::*; +use crate::plonk::commitments::transparent::precomputations::*; +use crate::plonk::commitments::transparent::utils::log2_floor; use crate::plonk::polynomials::*; use crate::worker::*; use crate::SynthesisError; -use crate::plonk::commitments::transparent::iop::*; -use crate::plonk::commitments::transparent::utils::log2_floor; -use crate::plonk::commitments::transcript::Prng; -use crate::plonk::commitments::transparent::precomputations::*; -use super::super::*; pub struct NaiveFriIop> { _marker_f: std::marker::PhantomData, _marker_i: std::marker::PhantomData, } -impl > FriIop for NaiveFriIop { +impl> FriIop for NaiveFriIop { const DEGREE: usize = 2; type IopType = I; @@ -22,41 +22,28 @@ impl > FriIop for NaiveFriIop { type Proof = FRIProof; type Params = (); - fn proof_from_lde >::TreeHasher as IopTreeHasher >::HashOutput>, - C: FriPrecomputations - >( - lde_values: &Polynomial, + fn proof_from_lde>::TreeHasher as IopTreeHasher>::HashOutput>, C: FriPrecomputations>( + lde_values: &Polynomial, lde_factor: usize, output_coeffs_at_degree_plus_one: usize, precomputations: &C, worker: &Worker, prng: &mut P, - params: &Self::Params + params: &Self::Params, ) -> Result { - NaiveFriIop::proof_from_lde_by_values( - lde_values, - lde_factor, - output_coeffs_at_degree_plus_one, - precomputations, - worker, - prng - ) + NaiveFriIop::proof_from_lde_by_values(lde_values, lde_factor, output_coeffs_at_degree_plus_one, precomputations, worker, prng) } fn prototype_into_proof( prototype: Self::ProofPrototype, iop_values: &Polynomial, natural_first_element_indexes: Vec, - _params: &Self::Params + _params: &Self::Params, ) -> Result { prototype.produce_proof(iop_values, natural_first_element_indexes) } - fn get_fri_challenges >::TreeHasher as IopTreeHasher >::HashOutput> >( - proof: &Self::Proof, - prng: &mut P, - _params: &Self::Params - ) -> Vec { + fn get_fri_challenges>::TreeHasher as IopTreeHasher>::HashOutput>>(proof: &Self::Proof, prng: &mut P, _params: &Self::Params) -> Vec { let mut fri_challenges = vec![]; for root in proof.roots.iter() { @@ -71,13 +58,7 @@ impl > FriIop for NaiveFriIop { fri_challenges } - fn verify_proof_with_challenges( - proof: &Self::Proof, - natural_element_indexes: Vec, - expected_value: &[F], - fri_challenges: &[F], - _params: &Self::Params - ) -> Result { + fn verify_proof_with_challenges(proof: &Self::Proof, natural_element_indexes: Vec, expected_value: &[F], fri_challenges: &[F], _params: &Self::Params) -> Result { Self::verify_proof_queries(proof, natural_element_indexes, Self::DEGREE, expected_value, fri_challenges) } } @@ -88,9 +69,9 @@ use std::time::Instant; pub struct FRIProofPrototype> { pub l0_commitment: I, pub intermediate_commitments: Vec, - pub intermediate_values: Vec< Polynomial >, + pub intermediate_values: Vec>, pub challenges: Vec, - pub final_root: < >::TreeHasher as IopTreeHasher>::HashOutput, + pub final_root: <>::TreeHasher as IopTreeHasher>::HashOutput, pub final_coefficients: Vec, pub initial_degree_plus_one: usize, pub output_coeffs_at_degree_plus_one: usize, @@ -98,7 +79,7 @@ pub struct FRIProofPrototype> { } impl> FriProofPrototype for FRIProofPrototype { - fn get_roots(&self) -> Vec< < >::TreeHasher as IopTreeHasher>::HashOutput> { + fn get_roots(&self) -> Vec<<>::TreeHasher as IopTreeHasher>::HashOutput> { let mut roots = vec![]; roots.push(self.l0_commitment.get_root().clone()); for c in self.intermediate_commitments.iter() { @@ -108,7 +89,7 @@ impl> FriProofPrototype for FRIProofPrototype < >::TreeHasher as IopTreeHasher>::HashOutput { + fn get_final_root(&self) -> <>::TreeHasher as IopTreeHasher>::HashOutput { self.final_root.clone() } @@ -119,8 +100,8 @@ impl> FriProofPrototype for FRIProofPrototype> { - pub queries: Vec< Vec< >::Query > >, - pub roots: Vec< < >::TreeHasher as IopTreeHasher>::HashOutput>, + pub queries: Vec>::Query>>, + pub roots: Vec<<>::TreeHasher as IopTreeHasher>::HashOutput>, pub final_coefficients: Vec, pub initial_degree_plus_one: usize, pub output_coeffs_at_degree_plus_one: usize, @@ -134,12 +115,12 @@ impl> FriProof for FRIProof { } impl> NaiveFriIop { - pub fn proof_from_lde_through_coefficients >::TreeHasher as IopTreeHasher >::HashOutput> >( - lde_values: Polynomial, + pub fn proof_from_lde_through_coefficients>::TreeHasher as IopTreeHasher>::HashOutput>>( + lde_values: Polynomial, lde_factor: usize, output_coeffs_at_degree_plus_one: usize, worker: &Worker, - prng: &mut P + prng: &mut P, ) -> Result, SynthesisError> { let l0_commitment: I = I::create(lde_values.as_ref()); let initial_domain_size = lde_values.size(); @@ -153,7 +134,7 @@ impl> NaiveFriIop { let initial_polynomial = lde_values.ifft(&worker); let mut initial_polynomial_coeffs = initial_polynomial.into_coeffs(); initial_polynomial_coeffs.truncate(initial_degree_plus_one); - + let mut intermediate_commitments = vec![]; let mut intermediate_values = vec![]; let mut challenges = vec![]; @@ -166,15 +147,14 @@ impl> NaiveFriIop { let mut coeffs = initial_polynomial_coeffs; let mut roots = vec![]; - + for step in 0..num_steps { let mut next_coefficients = vec![F::zero(); next_domain_size]; let coeffs_slice: &[F] = coeffs.as_ref(); - assert!(next_coefficients.len()*2 == coeffs_slice.len()); + assert!(next_coefficients.len() * 2 == coeffs_slice.len()); worker.scope(next_coefficients.len(), |scope, chunk| { - for (v, old) in next_coefficients.chunks_mut(chunk) - .zip(coeffs_slice.chunks(chunk*2)) { + for (v, old) in next_coefficients.chunks_mut(chunk).zip(coeffs_slice.chunks(chunk * 2)) { scope.spawn(move |_| { for (v, old) in v.iter_mut().zip(old.chunks(2)) { // a_0 + beta * a_1 @@ -236,18 +216,15 @@ impl> NaiveFriIop { output_coeffs_at_degree_plus_one, lde_factor, }) - } - pub fn proof_from_lde_by_values >::TreeHasher as IopTreeHasher >::HashOutput>, - C: FriPrecomputations - >( - lde_values: &Polynomial, + pub fn proof_from_lde_by_values>::TreeHasher as IopTreeHasher>::HashOutput>, C: FriPrecomputations>( + lde_values: &Polynomial, lde_factor: usize, output_coeffs_at_degree_plus_one: usize, precomputations: &C, worker: &Worker, - prng: &mut P + prng: &mut P, ) -> Result, SynthesisError> { println!("Starting FRI"); let start = Instant::now(); @@ -263,7 +240,7 @@ impl> NaiveFriIop { let mut two = F::one(); two.double(); let two_inv = two.inverse().expect("should exist"); - + assert!(output_coeffs_at_degree_plus_one.is_power_of_two()); assert!(lde_factor.is_power_of_two()); @@ -289,9 +266,9 @@ impl> NaiveFriIop { // step 0: fold totally by 2 // step 1: fold totally by 4 // etc... - + for i in 0..num_steps { - // we step over 1, omega, omega^2, + // we step over 1, omega, omega^2, // then over 1, omega^2, // etc. let stride = 1 << i; @@ -302,7 +279,7 @@ impl> NaiveFriIop { worker.scope(next_values.len(), |scope, chunk| { for (i, v) in next_values.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let initial_k = i*chunk; + let initial_k = i * chunk; for (j, v) in v.iter_mut().enumerate() { let idx = initial_k + j; debug_assert!(idx < next_domain_size); @@ -318,7 +295,7 @@ impl> NaiveFriIop { v_odd_coeffs.mul_assign(&omegas_inv_ref[omega_idx]); // those can be treated as (doubled) evaluations of polynomials that - // are themselves made only from even or odd coefficients of original poly + // are themselves made only from even or odd coefficients of original poly // (with reduction of degree by 2) on a domain of the size twice smaller // with an extra factor of "omega" in odd coefficients @@ -347,19 +324,19 @@ impl> NaiveFriIop { next_domain_size >>= 1; intermediate_commitments.push(intermediate_iop); - } + } let next_values_as_poly = Polynomial::from_values(next_values)?; intermediate_values.push(next_values_as_poly); - values_slice = intermediate_values.last().expect("is something").as_ref(); + values_slice = intermediate_values.last().expect("is something").as_ref(); } let final_root = roots.last().expect("will work").clone(); assert_eq!(challenges.len(), num_steps); assert_eq!(roots.len(), num_steps); - assert_eq!(intermediate_commitments.len(), num_steps-1); + assert_eq!(intermediate_commitments.len(), num_steps - 1); assert_eq!(intermediate_values.len(), num_steps); let final_poly_values = Polynomial::from_values(values_slice.to_vec())?; @@ -372,7 +349,7 @@ impl> NaiveFriIop { if c.is_zero() { degree -= 1; } else { - break + break; } } @@ -380,7 +357,7 @@ impl> NaiveFriIop { final_poly_coeffs.truncate(output_coeffs_at_degree_plus_one); - println!("Done FRI for degree {} in {:?}", lde_values.size()/lde_factor, start.elapsed()); + println!("Done FRI for degree {} in {:?}", lde_values.size() / lde_factor, start.elapsed()); Ok(FRIProofPrototype { l0_commitment, @@ -393,6 +370,5 @@ impl> NaiveFriIop { output_coeffs_at_degree_plus_one, lde_factor, }) - } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/query_producer.rs b/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/query_producer.rs index 1565140..70c0519 100644 --- a/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/query_producer.rs +++ b/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/query_producer.rs @@ -1,20 +1,16 @@ +use super::super::*; +use super::naive_fri::*; use crate::pairing::ff::PrimeField; use crate::plonk::commitments::transparent::iop::*; -use crate::plonk::polynomials::*; +use crate::plonk::commitments::transparent::iop::*; +use crate::plonk::commitments::transparent::utils::log2_floor; use crate::plonk::domains::*; +use crate::plonk::polynomials::*; use crate::worker::*; use crate::SynthesisError; -use crate::plonk::commitments::transparent::iop::*; -use crate::plonk::commitments::transparent::utils::log2_floor; -use super::naive_fri::*; -use super::super::*; impl> FRIProofPrototype { - pub fn produce_proof( - self, - iop_values: &Polynomial, - natural_first_element_indexes: Vec, - ) -> Result, SynthesisError> { + pub fn produce_proof(self, iop_values: &Polynomial, natural_first_element_indexes: Vec) -> Result, SynthesisError> { let domain_size = self.initial_degree_plus_one * self.lde_factor; let mut roots = vec![]; @@ -31,9 +27,11 @@ impl> FRIProofPrototype { let mut domain_idx = natural_first_element_index; let mut domain_size = domain_size; - for (iop, leaf_values) in l0_commitment.iter().chain(&self.intermediate_commitments) - .zip(Some(iop_values).into_iter().chain(&self.intermediate_values)) { - + for (iop, leaf_values) in l0_commitment + .iter() + .chain(&self.intermediate_commitments) + .zip(Some(iop_values).into_iter().chain(&self.intermediate_values)) + { let coset_values = >::get_coset_for_natural_index(domain_idx, domain_size); if coset_values.len() != >::COSET_SIZE { return Err(SynthesisError::PolynomialDegreeTooLarge); @@ -64,4 +62,4 @@ impl> FRIProofPrototype { Ok(proof) } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/verifier.rs b/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/verifier.rs index 7508187..e3e54c8 100644 --- a/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/verifier.rs +++ b/crates/bellman/src/plonk/commitments/transparent/fri/naive_fri/verifier.rs @@ -1,26 +1,20 @@ +use super::super::*; +use super::naive_fri::*; use crate::pairing::ff::PrimeField; use crate::plonk::commitments::transparent::iop::*; -use crate::plonk::polynomials::*; +use crate::plonk::commitments::transparent::iop::*; +use crate::plonk::commitments::transparent::utils::log2_floor; use crate::plonk::domains::*; +use crate::plonk::polynomials::*; use crate::worker::*; use crate::SynthesisError; -use crate::plonk::commitments::transparent::iop::*; -use crate::plonk::commitments::transparent::utils::log2_floor; -use super::naive_fri::*; -use super::super::*; impl> NaiveFriIop { - pub fn verify_prototype( - proof: & FRIProofPrototype, - leaf_values: & Polynomial, - natural_element_index: usize - ) -> Result { + pub fn verify_prototype(proof: &FRIProofPrototype, leaf_values: &Polynomial, natural_element_index: usize) -> Result { let mut two = F::one(); two.double(); - let two_inv = two.inverse().ok_or( - SynthesisError::DivisionByZero - )?; + let two_inv = two.inverse().ok_or(SynthesisError::DivisionByZero)?; // start from the bottom: we need to get a "pair" and calculate FRI step @@ -34,9 +28,7 @@ impl> NaiveFriIop { } let mut omega = domain.generator; - let mut omega_inv = omega.inverse().ok_or( - SynthesisError::DivisionByZero - )?; + let mut omega_inv = omega.inverse().ok_or(SynthesisError::DivisionByZero)?; debug_assert_eq!(F::one(), omega_inv.pow([domain.size])); @@ -44,9 +36,7 @@ impl> NaiveFriIop { let mut domain_size = domain.size as usize; let mut domain_idx = natural_element_index; - for (iop_values, iop_challenge) in Some(leaf_values).into_iter().chain(&proof.intermediate_values) - .zip(proof.challenges.iter()) { - + for (iop_values, iop_challenge) in Some(leaf_values).into_iter().chain(&proof.intermediate_values).zip(proof.challenges.iter()) { let coset_values = >::get_coset_for_natural_index(domain_idx, domain_size); assert!(coset_values.len() == 2); @@ -77,7 +67,7 @@ impl> NaiveFriIop { v_odd_coeffs.mul_assign(&divisor); // those can be treated as (doubled) evaluations of polynomials that - // are themselves made only from even or odd coefficients of original poly + // are themselves made only from even or odd coefficients of original poly // (with reduction of degree by 2) on a domain of the size twice smaller // with an extra factor of "omega" in odd coefficients @@ -104,7 +94,6 @@ impl> NaiveFriIop { omega_inv.square(); } - // finally we need to get expected value from coefficients let mut expected_value_from_coefficients = F::zero(); @@ -118,7 +107,7 @@ impl> NaiveFriIop { expected_value_from_coefficients.add_assign(&tmp); power.mul_assign(&evaluation_point); } - + let expected_value = expected_value.expect("is some"); let valid = expected_value_from_coefficients == expected_value; @@ -129,43 +118,29 @@ impl> NaiveFriIop { // pub fn verify_proof_queries >::TreeHasher as IopTreeHasher >::HashOutput> >( // proof: &FRIProof, // natural_element_indexes: Vec, - // degree: usize, + // degree: usize, // expected_value_from_oracle: F, // prng: &mut P // ) -> Result { // } - pub fn verify_proof_queries( - proof: &FRIProof, - natural_element_indexes: Vec, - degree: usize, - expected_values_from_oracle: &[F], - fri_challenges: &[F] - ) -> Result { + pub fn verify_proof_queries(proof: &FRIProof, natural_element_indexes: Vec, degree: usize, expected_values_from_oracle: &[F], fri_challenges: &[F]) -> Result { let mut two = F::one(); two.double(); - let two_inv = two.inverse().ok_or( - SynthesisError::DivisionByZero - )?; + let two_inv = two.inverse().ok_or(SynthesisError::DivisionByZero)?; let domain = Domain::::new_for_size((proof.initial_degree_plus_one * proof.lde_factor) as u64)?; let omega = domain.generator; - let omega_inv = omega.inverse().ok_or( - SynthesisError::DivisionByZero - )?; + let omega_inv = omega.inverse().ok_or(SynthesisError::DivisionByZero)?; assert!(fri_challenges.len() == proof.roots.len()); assert!(natural_element_indexes.len() == proof.queries.len()); - for ((query, natural_element_index), expected_value_from_oracle) in proof.queries.iter() - .zip(natural_element_indexes.into_iter()) - .zip(expected_values_from_oracle.iter()) - { - + for ((query, natural_element_index), expected_value_from_oracle) in proof.queries.iter().zip(natural_element_indexes.into_iter()).zip(expected_values_from_oracle.iter()) { let domain_element = domain.generator.pow([natural_element_index as u64]); let el = domain_element.pow([domain.size]); @@ -188,11 +163,7 @@ impl> NaiveFriIop { return Err(SynthesisError::PolynomialDegreeTooLarge); } - for (round, ((root, queries), iop_challenge)) in proof.roots.iter() - .zip(query.chunks_exact(degree)) - .zip(fri_challenges.iter()) - .enumerate() - { + for (round, ((root, queries), iop_challenge)) in proof.roots.iter().zip(query.chunks_exact(degree)).zip(fri_challenges.iter()).enumerate() { let coset_values = >::get_coset_for_natural_index(domain_idx, domain_size); if coset_values.len() != >::COSET_SIZE { @@ -229,7 +200,7 @@ impl> NaiveFriIop { return Ok(false); } } - + let f_at_omega = (&queries[0]).value(); if let Some(value) = expected_value { if !coset_values.contains(&domain_idx) { @@ -240,7 +211,7 @@ impl> NaiveFriIop { let q: Vec<_> = queries.iter().filter(|el| el.natural_index() == domain_idx).collect(); if q.len() != 1 { println!("Queries containt duplicate opening for required index {}", domain_idx); - return Ok(false) + return Ok(false); } let supplied_value = q[0].value(); @@ -262,7 +233,7 @@ impl> NaiveFriIop { v_odd_coeffs.mul_assign(&divisor); // those can be treated as (doubled) evaluations of polynomials that - // are themselves made only from even or odd coefficients of original poly + // are themselves made only from even or odd coefficients of original poly // (with reduction of degree by 2) on a domain of the size twice smaller // with an extra factor of "omega" in odd coefficients @@ -287,7 +258,6 @@ impl> NaiveFriIop { omega_inv.square(); } - // finally we need to get expected value from coefficients let mut expected_value_from_coefficients = F::zero(); @@ -301,13 +271,16 @@ impl> NaiveFriIop { expected_value_from_coefficients.add_assign(&tmp); power.mul_assign(&evaluation_point); } - + let expected_value = expected_value.expect("is some"); let valid = expected_value_from_coefficients == expected_value; if !valid { - println!("Value from supplied coefficients {} is not equal to the value from queries {} for natural index {}", expected_value_from_coefficients, expected_value, natural_element_index); + println!( + "Value from supplied coefficients {} is not equal to the value from queries {} for natural index {}", + expected_value_from_coefficients, expected_value, natural_element_index + ); println!("Final coefficients = {:?}", proof.final_coefficients); return Ok(false); } diff --git a/crates/bellman/src/plonk/commitments/transparent/iop/blake2s_trivial_iop.rs b/crates/bellman/src/plonk/commitments/transparent/iop/blake2s_trivial_iop.rs index 738d0b6..fabff8d 100644 --- a/crates/bellman/src/plonk/commitments/transparent/iop/blake2s_trivial_iop.rs +++ b/crates/bellman/src/plonk/commitments/transparent/iop/blake2s_trivial_iop.rs @@ -1,36 +1,28 @@ -use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; -use blake2s_simd::{Params, State}; -use crate::worker::Worker; use super::super::utils::log2_floor; -use super::*; use super::trivial_coset_combiner::*; +use super::*; +use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; +use crate::worker::Worker; +use blake2s_simd::{Params, State}; lazy_static! { - static ref BASE_BLAKE2S_PARAMS: State = { - Params::new() - .hash_length(32) - .key(b"Squeamish Ossifrage") - .personal(b"Shaftoe") - .to_state() - }; + static ref BASE_BLAKE2S_PARAMS: State = { Params::new().hash_length(32).key(b"Squeamish Ossifrage").personal(b"Shaftoe").to_state() }; } pub struct Blake2sLeafEncoder { - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } -impl Blake2sLeafEncoder { +impl Blake2sLeafEncoder { const SHAVE_BITS: u32 = 256 - F::CAPACITY; pub fn new() -> Self { assert!(F::NUM_BITS < 256); - Self { - _marker: std::marker::PhantomData - } + Self { _marker: std::marker::PhantomData } } } -impl LeafEncoder for Blake2sLeafEncoder{ +impl LeafEncoder for Blake2sLeafEncoder { type Output = [u8; 32]; fn encode_leaf(value: &F) -> Self::Output { @@ -42,7 +34,7 @@ impl LeafEncoder for Blake2sLeafEncoder{ } } -impl FiatShamirHasher for Blake2sLeafEncoder{ +impl FiatShamirHasher for Blake2sLeafEncoder { type Input = [u8; 32]; fn transform(value: &Self::Input) -> F { @@ -60,14 +52,12 @@ impl FiatShamirHasher for Blake2sLeafEncoder{ } pub struct Blake2sTreeHasher { - encoder: Blake2sLeafEncoder + encoder: Blake2sLeafEncoder, } impl Blake2sTreeHasher { pub fn new() -> Self { - Self { - encoder: Blake2sLeafEncoder::new() - } + Self { encoder: Blake2sLeafEncoder::new() } } } @@ -78,7 +68,7 @@ impl IopTreeHasher for Blake2sTreeHasher { type LeafEncoder = Blake2sLeafEncoder; fn hash_leaf(value: &F) -> Self::HashOutput { - let value = >::encode_leaf(value); + let value = >::encode_leaf(value); Self::hash_encoded_leaf(&value) } @@ -105,15 +95,12 @@ impl IopTreeHasher for Blake2sTreeHasher { pub struct Blake2sIopTree { pub(crate) size: usize, - pub(crate) nodes: Vec< < Blake2sTreeHasher as IopTreeHasher >::HashOutput >, + pub(crate) nodes: Vec< as IopTreeHasher>::HashOutput>, } impl Blake2sIopTree { pub fn new() -> Self { - Self { - size: 0usize, - nodes: vec![], - } + Self { size: 0usize, nodes: vec![] } } } @@ -150,14 +137,13 @@ impl<'a, F: PrimeField> IopTree for Blake2sIopTree { { worker.scope(leafs.len(), |scope, chunk| { - for (i, lh) in leaf_hashes.chunks_mut(chunk) - .enumerate() { + for (i, lh) in leaf_hashes.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let base_idx = i*chunk; + let base_idx = i * chunk; for (j, lh) in lh.iter_mut().enumerate() { let idx = base_idx + j; - let leaf_ref = >::get_for_tree_index(&leafs, idx); - *lh = < Self::TreeHasher as IopTreeHasher >::hash_leaf(leaf_ref); + let leaf_ref = >::get_for_tree_index(&leafs, idx); + *lh = >::hash_leaf(leaf_ref); } }); } @@ -171,37 +157,35 @@ impl<'a, F: PrimeField> IopTree for Blake2sIopTree { // separately hash last level, which hashes leaf hashes into first nodes { - let level = num_levels-1; + let level = num_levels - 1; let inputs = &mut leaf_hashes[..]; - let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { for (o, i) in o.iter_mut().zip(i.chunks(2)) { - *o = < Self::TreeHasher as IopTreeHasher >::hash_node(i, level); + *o = >::hash_node(i, level); } }); } }); } - for level in (0..(num_levels-1)).rev() { + for level in (0..(num_levels - 1)).rev() { // do the trick - split - let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); let (_, outputs) = next_levels.split_at_mut(next_levels.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { for (o, i) in o.iter_mut().zip(i.chunks(2)) { - *o = < Self::TreeHasher as IopTreeHasher >::hash_node(i, level); + *o = >::hash_node(i, level); } }); } @@ -212,10 +196,7 @@ impl<'a, F: PrimeField> IopTree for Blake2sIopTree { println!("Done creating a tree of size {} in {:?}", leafs.len(), start.elapsed()); - Self { - size: size, - nodes: nodes, - } + Self { size: size, nodes: nodes } } fn get_root(&self) -> >::HashOutput { @@ -223,7 +204,7 @@ impl<'a, F: PrimeField> IopTree for Blake2sIopTree { self.nodes[1] } - fn encode_root_into_challenge(root: & >::HashOutput) -> F { + fn encode_root_into_challenge(root: &>::HashOutput) -> F { >::transform(&root) } @@ -248,7 +229,7 @@ impl<'a, F: PrimeField> IopTree for Blake2sIopTree { &hash == root } - fn get_path(&self, tree_index: usize, leafs_values: &[F]) -> Vec< >::HashOutput >{ + fn get_path(&self, tree_index: usize, leafs_values: &[F]) -> Vec<>::HashOutput> { assert!(self.size == self.nodes.len()); let mut nodes = &self.nodes[..]; @@ -259,7 +240,7 @@ impl<'a, F: PrimeField> IopTree for Blake2sIopTree { let pair_natural_index = >::tree_index_into_natural_index(tree_pair_index); let pair = &leafs_values[pair_natural_index as usize]; - let encoded_pair_hash = < Self::TreeHasher as IopTreeHasher >::hash_leaf(pair); + let encoded_pair_hash = >::hash_leaf(pair); path.push(encoded_pair_hash); let mut idx = tree_index; @@ -283,18 +264,15 @@ pub struct TrivialBlake2sIOP { tree: Blake2sIopTree, } - impl IOP for TrivialBlake2sIOP { type Combiner = TrivialCombiner; type Tree = Blake2sIopTree; type Query = TrivialBlake2sIopQuery; - fn create<'l> (leafs: &'l [F]) -> Self { + fn create<'l>(leafs: &'l [F]) -> Self { let tree = Self::Tree::create(leafs); - Self { - tree - } + Self { tree } } fn get_for_natural_index(leafs: &[F], natural_index: usize) -> &F { @@ -305,11 +283,11 @@ impl IOP for TrivialBlake2sIOP { >::get_for_tree_index(leafs, tree_index) } - fn get_root(&self) -> < >::TreeHasher as IopTreeHasher>::HashOutput { + fn get_root(&self) -> <>::TreeHasher as IopTreeHasher>::HashOutput { self.tree.get_root() } - fn verify_query(query: &Self::Query, root: &< >::TreeHasher as IopTreeHasher>::HashOutput) -> bool { + fn verify_query(query: &Self::Query, root: &<>::TreeHasher as IopTreeHasher>::HashOutput) -> bool { Self::Tree::verify(root, &query.value(), &query.path(), query.tree_index()) } @@ -325,7 +303,7 @@ impl IOP for TrivialBlake2sIOP { TrivialBlake2sIopQuery:: { index: natural_index, value: vec![value], - path: path + path: path, } } } @@ -368,7 +346,7 @@ impl IopQuery for TrivialBlake2sIopQuery { &self.value } - fn path(&self) -> &[>::HashOutput] { + fn path(&self) -> &[>::HashOutput] { &self.path } } @@ -406,4 +384,4 @@ impl IopQuery for TrivialBlake2sIopQuery { // let valid = TrivialBlake2sIOP::verify_query(&query, &root); // assert!(valid, "invalid query for leaf {}", i); // } -// } \ No newline at end of file +// } diff --git a/crates/bellman/src/plonk/commitments/transparent/iop/keccak_trivial_iop.rs b/crates/bellman/src/plonk/commitments/transparent/iop/keccak_trivial_iop.rs index 1994689..99b216f 100644 --- a/crates/bellman/src/plonk/commitments/transparent/iop/keccak_trivial_iop.rs +++ b/crates/bellman/src/plonk/commitments/transparent/iop/keccak_trivial_iop.rs @@ -1,26 +1,24 @@ -use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; -use tiny_keccak::*; -use crate::worker::Worker; use super::super::utils::log2_floor; -use super::*; use super::trivial_coset_combiner::*; +use super::*; +use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; +use crate::worker::Worker; +use tiny_keccak::*; pub struct KeccakLeafEncoder { - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } -impl KeccakLeafEncoder { +impl KeccakLeafEncoder { const SHAVE_BITS: u32 = 256 - F::CAPACITY; pub fn new() -> Self { assert!(F::NUM_BITS < 256); - Self { - _marker: std::marker::PhantomData - } + Self { _marker: std::marker::PhantomData } } } -impl LeafEncoder for KeccakLeafEncoder{ +impl LeafEncoder for KeccakLeafEncoder { type Output = [u8; 32]; fn encode_leaf(value: &F) -> Self::Output { @@ -32,7 +30,7 @@ impl LeafEncoder for KeccakLeafEncoder{ } } -impl FiatShamirHasher for KeccakLeafEncoder{ +impl FiatShamirHasher for KeccakLeafEncoder { type Input = [u8; 32]; fn transform(value: &Self::Input) -> F { @@ -50,14 +48,12 @@ impl FiatShamirHasher for KeccakLeafEncoder{ } pub struct KeccakTreeHasher { - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl KeccakTreeHasher { pub fn new() -> Self { - Self { - _marker: std::marker::PhantomData - } + Self { _marker: std::marker::PhantomData } } } @@ -66,7 +62,7 @@ impl IopTreeHasher for KeccakTreeHasher { type LeafEncoder = KeccakLeafEncoder; fn hash_leaf(value: &F) -> Self::HashOutput { - let value = >::encode_leaf(value); + let value = >::encode_leaf(value); Self::hash_encoded_leaf(&value) } @@ -92,15 +88,12 @@ impl IopTreeHasher for KeccakTreeHasher { pub struct KeccakIopTree { size: usize, - nodes: Vec< < KeccakTreeHasher as IopTreeHasher >::HashOutput >, + nodes: Vec< as IopTreeHasher>::HashOutput>, } impl KeccakIopTree { pub fn new() -> Self { - Self { - size: 0usize, - nodes: vec![], - } + Self { size: 0usize, nodes: vec![] } } } @@ -133,14 +126,13 @@ impl<'a, F: PrimeField> IopTree for KeccakIopTree { { worker.scope(leafs.len(), |scope, chunk| { - for (i, lh) in leaf_hashes.chunks_mut(chunk) - .enumerate() { + for (i, lh) in leaf_hashes.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let base_idx = i*chunk; + let base_idx = i * chunk; for (j, lh) in lh.iter_mut().enumerate() { let idx = base_idx + j; - let leaf_ref = >::get_for_tree_index(&leafs, idx); - *lh = < Self::TreeHasher as IopTreeHasher >::hash_leaf(leaf_ref); + let leaf_ref = >::get_for_tree_index(&leafs, idx); + *lh = >::hash_leaf(leaf_ref); } }); } @@ -154,37 +146,35 @@ impl<'a, F: PrimeField> IopTree for KeccakIopTree { // separately hash last level, which hashes leaf hashes into first nodes { - let level = num_levels-1; + let level = num_levels - 1; let inputs = &mut leaf_hashes[..]; - let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { for (o, i) in o.iter_mut().zip(i.chunks(2)) { - *o = < Self::TreeHasher as IopTreeHasher >::hash_node(i, level); + *o = >::hash_node(i, level); } }); } }); } - for level in (0..(num_levels-1)).rev() { + for level in (0..(num_levels - 1)).rev() { // do the trick - split - let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); let (_, outputs) = next_levels.split_at_mut(next_levels.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { for (o, i) in o.iter_mut().zip(i.chunks(2)) { - *o = < Self::TreeHasher as IopTreeHasher >::hash_node(i, level); + *o = >::hash_node(i, level); } }); } @@ -195,10 +185,7 @@ impl<'a, F: PrimeField> IopTree for KeccakIopTree { println!("Done creating a tree of size {} in {:?}", leafs.len(), start.elapsed()); - Self { - size: size, - nodes: nodes, - } + Self { size: size, nodes: nodes } } fn get_root(&self) -> >::HashOutput { @@ -206,7 +193,7 @@ impl<'a, F: PrimeField> IopTree for KeccakIopTree { self.nodes[1] } - fn encode_root_into_challenge(root: & >::HashOutput) -> F { + fn encode_root_into_challenge(root: &>::HashOutput) -> F { >::transform(&root) } @@ -231,7 +218,7 @@ impl<'a, F: PrimeField> IopTree for KeccakIopTree { &hash == root } - fn get_path(&self, tree_index: usize, leafs_values: &[F]) -> Vec< >::HashOutput >{ + fn get_path(&self, tree_index: usize, leafs_values: &[F]) -> Vec<>::HashOutput> { assert!(self.size == self.nodes.len()); let mut nodes = &self.nodes[..]; @@ -242,7 +229,7 @@ impl<'a, F: PrimeField> IopTree for KeccakIopTree { let pair_natural_index = >::tree_index_into_natural_index(tree_pair_index); let pair = &leafs_values[pair_natural_index as usize]; - let encoded_pair_hash = < Self::TreeHasher as IopTreeHasher >::hash_leaf(pair); + let encoded_pair_hash = >::hash_leaf(pair); path.push(encoded_pair_hash); let mut idx = tree_index; @@ -266,18 +253,15 @@ pub struct TrivialKeccakIOP { tree: KeccakIopTree, } - impl IOP for TrivialKeccakIOP { type Combiner = TrivialCombiner; type Tree = KeccakIopTree; type Query = TrivialKeccakIopQuery; - fn create<'l> (leafs: &'l [F]) -> Self { + fn create<'l>(leafs: &'l [F]) -> Self { let tree = Self::Tree::create(leafs); - Self { - tree - } + Self { tree } } fn get_for_natural_index(leafs: &[F], natural_index: usize) -> &F { @@ -288,11 +272,11 @@ impl IOP for TrivialKeccakIOP { >::get_for_tree_index(leafs, tree_index) } - fn get_root(&self) -> < >::TreeHasher as IopTreeHasher>::HashOutput { + fn get_root(&self) -> <>::TreeHasher as IopTreeHasher>::HashOutput { self.tree.get_root() } - fn verify_query(query: &Self::Query, root: &< >::TreeHasher as IopTreeHasher>::HashOutput) -> bool { + fn verify_query(query: &Self::Query, root: &<>::TreeHasher as IopTreeHasher>::HashOutput) -> bool { Self::Tree::verify(root, &query.value(), &query.path(), query.tree_index()) } @@ -308,7 +292,7 @@ impl IOP for TrivialKeccakIOP { TrivialKeccakIopQuery:: { index: natural_index, value: vec![value], - path: path + path: path, } } } @@ -351,7 +335,7 @@ impl IopQuery for TrivialKeccakIopQuery { &self.value } - fn path(&self) -> &[>::HashOutput] { + fn path(&self) -> &[>::HashOutput] { &self.path } } @@ -389,4 +373,4 @@ impl IopQuery for TrivialKeccakIopQuery { // let valid = TrivialBlake2sIOP::verify_query(&query, &root); // assert!(valid, "invalid query for leaf {}", i); // } -// } \ No newline at end of file +// } diff --git a/crates/bellman/src/plonk/commitments/transparent/iop/mod.rs b/crates/bellman/src/plonk/commitments/transparent/iop/mod.rs index c47c573..db4ba7c 100644 --- a/crates/bellman/src/plonk/commitments/transparent/iop/mod.rs +++ b/crates/bellman/src/plonk/commitments/transparent/iop/mod.rs @@ -1,8 +1,8 @@ use crate::pairing::ff::PrimeField; -pub mod trivial_coset_combiner; pub mod blake2s_trivial_iop; pub mod keccak_trivial_iop; +pub mod trivial_coset_combiner; pub trait CosetInformation: Sized + Clone + Copy { const COSET_SIZE: usize; @@ -12,7 +12,7 @@ pub trait CosetCombiner { const EXPECTED_DEGREE: usize; const COSET_SIZE: usize; // type CosetData: CosetInformation; - + fn get_for_natural_index(leafs: &[F], natural_index: usize) -> &F; fn get_for_tree_index(leafs: &[F], tree_index: usize) -> &F; fn tree_index_into_natural_index(tree_index: usize) -> usize; @@ -44,19 +44,18 @@ pub trait IopTreeHasher { fn hash_node(values: &[Self::HashOutput], level: usize) -> Self::HashOutput; } - pub trait IopTree { type Combiner: CosetCombiner; type TreeHasher: IopTreeHasher; - type FiatShamirTransformer: FiatShamirHasher>::HashOutput>; + type FiatShamirTransformer: FiatShamirHasher>::HashOutput>; fn create(leafs: &[F]) -> Self; fn size(&self) -> usize; fn get_root(&self) -> >::HashOutput; - fn encode_root_into_challenge(root: & >::HashOutput) -> F; + fn encode_root_into_challenge(root: &>::HashOutput) -> F; fn get_challenge_scalar_from_root(&self) -> F; fn verify(root: &>::HashOutput, leaf_value: &F, path: &[>::HashOutput], index: usize) -> bool; - fn get_path(&self, index: usize, leafs_values: &[F]) -> Vec< >::HashOutput >; + fn get_path(&self, index: usize, leafs_values: &[F]) -> Vec<>::HashOutput>; } pub trait IopQuery: 'static + PartialEq + Eq + Clone + std::fmt::Debug { @@ -67,18 +66,18 @@ pub trait IopQuery: 'static + PartialEq + Eq + Clone + std::fmt:: fn natural_indexes(&self) -> Vec; fn value(&self) -> F; fn values(&self) -> &[F]; - fn path(&self) -> &[>::HashOutput]; + fn path(&self) -> &[>::HashOutput]; } pub trait IOP { type Combiner: CosetCombiner; type Tree: IopTree; - type Query: IopQuery >::TreeHasher>; + type Query: IopQuery>::TreeHasher>; - fn create(leafs: & [F]) -> Self; + fn create(leafs: &[F]) -> Self; fn get_for_natural_index(leafs: &[F], natural_index: usize) -> &F; fn get_for_tree_index(leafs: &[F], tree_index: usize) -> &F; - fn get_root(&self) -> < >::TreeHasher as IopTreeHasher>::HashOutput; - fn verify_query(query: &Self::Query, root: &< >::TreeHasher as IopTreeHasher>::HashOutput) -> bool; + fn get_root(&self) -> <>::TreeHasher as IopTreeHasher>::HashOutput; + fn verify_query(query: &Self::Query, root: &<>::TreeHasher as IopTreeHasher>::HashOutput) -> bool; fn query(&self, natural_index: usize, leafs: &[F]) -> Self::Query; -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/commitments/transparent/iop/trivial_coset_combiner.rs b/crates/bellman/src/plonk/commitments/transparent/iop/trivial_coset_combiner.rs index 5e2acce..581b43a 100644 --- a/crates/bellman/src/plonk/commitments/transparent/iop/trivial_coset_combiner.rs +++ b/crates/bellman/src/plonk/commitments/transparent/iop/trivial_coset_combiner.rs @@ -1,5 +1,5 @@ -use crate::pairing::ff::PrimeField; use super::*; +use crate::pairing::ff::PrimeField; #[derive(Copy, Clone)] pub struct CosetOfSizeTwo; @@ -9,19 +9,19 @@ impl CosetInformation for CosetOfSizeTwo { } pub struct TrivialCombiner { - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl<'c, F: PrimeField> CosetCombiner for TrivialCombiner { const EXPECTED_DEGREE: usize = 2usize; const COSET_SIZE: usize = 2usize; - #[inline(always)] + #[inline(always)] fn get_for_natural_index(leafs: &[F], natural_index: usize) -> &F { &leafs[natural_index] } - #[inline(always)] + #[inline(always)] fn get_for_tree_index(leafs: &[F], tree_index: usize) -> &F { &leafs[tree_index] } @@ -39,13 +39,13 @@ impl<'c, F: PrimeField> CosetCombiner for TrivialCombiner { Self::get_coset_for_natural_index(natural_index, domain_size) } - #[inline(always)] + #[inline(always)] fn tree_index_into_natural_index(tree_index: usize) -> usize { tree_index } - #[inline(always)] + #[inline(always)] fn natural_index_into_tree_index(natural_index: usize) -> usize { natural_index - } -} \ No newline at end of file + } +} diff --git a/crates/bellman/src/plonk/commitments/transparent/iop_compiler/coset_combining_blake2s_tree.rs b/crates/bellman/src/plonk/commitments/transparent/iop_compiler/coset_combining_blake2s_tree.rs index 069cbf4..691043b 100644 --- a/crates/bellman/src/plonk/commitments/transparent/iop_compiler/coset_combining_blake2s_tree.rs +++ b/crates/bellman/src/plonk/commitments/transparent/iop_compiler/coset_combining_blake2s_tree.rs @@ -1,20 +1,20 @@ -use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; -use blake2s_const::blake2s_const; -use crate::worker::Worker; use super::super::utils::log2_floor; use super::*; +use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; +use crate::worker::Worker; +use blake2s_const::blake2s_const; #[derive(Debug)] pub struct FriSpecificBlake2sTree { size: usize, nodes: Vec<[u8; 32]>, params: FriSpecificBlake2sTreeParams, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } #[derive(Clone, PartialEq, Eq, Debug)] pub struct FriSpecificBlake2sTreeParams { - pub values_per_leaf: usize + pub values_per_leaf: usize, } // impl FriSpecificBlake2sTree { @@ -112,10 +112,9 @@ impl IopInstance for FriSpecificBlake2sTree { { worker.scope(leaf_hashes.len(), |scope, chunk| { - for (i, lh) in leaf_hashes.chunks_mut(chunk) - .enumerate() { + for (i, lh) in leaf_hashes.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let base_idx = i*chunk; + let base_idx = i * chunk; let mut scratch_space = vec![0u8; Self::VALUE_BYTE_SIZE * values_per_leaf]; for (j, lh) in lh.iter_mut().enumerate() { let idx = base_idx + j; @@ -135,15 +134,14 @@ impl IopInstance for FriSpecificBlake2sTree { // separately hash last level, which hashes leaf hashes into first nodes { - let _level = num_levels-1; + let _level = num_levels - 1; let inputs = &mut leaf_hashes[..]; - let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (_, outputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { let mut hash_input = [0u8; 64]; for (o, i) in o.iter_mut().zip(i.chunks(2)) { @@ -156,16 +154,15 @@ impl IopInstance for FriSpecificBlake2sTree { }); } - for _ in (0..(num_levels-1)).rev() { + for _ in (0..(num_levels - 1)).rev() { // do the trick - split - let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len()/2); + let (next_levels, inputs) = nodes_for_hashing.split_at_mut(nodes_for_hashing.len() / 2); let (_, outputs) = next_levels.split_at_mut(next_levels.len() / 2); assert!(outputs.len() * 2 == inputs.len()); assert!(outputs.len().is_power_of_two()); worker.scope(outputs.len(), |scope, chunk| { - for (o, i) in outputs.chunks_mut(chunk) - .zip(inputs.chunks(chunk*2)) { + for (o, i) in outputs.chunks_mut(chunk).zip(inputs.chunks(chunk * 2)) { scope.spawn(move |_| { let mut hash_input = [0u8; 64]; for (o, i) in o.iter_mut().zip(i.chunks(2)) { @@ -184,7 +181,7 @@ impl IopInstance for FriSpecificBlake2sTree { size: size, nodes: nodes, params: params.clone(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } @@ -196,18 +193,21 @@ impl IopInstance for FriSpecificBlake2sTree { // we never expect that query is mis-alligned, so check it debug_assert!(indexes[0] % self.params.values_per_leaf == 0); debug_assert!(indexes.len() == self.params.values_per_leaf); - debug_assert!(indexes == (indexes[0]..(indexes[0]+self.params.values_per_leaf)).collect::>()); + debug_assert!(indexes == (indexes[0]..(indexes[0] + self.params.values_per_leaf)).collect::>()); debug_assert!(*indexes.last().expect("is some") < self.size()); debug_assert!(*indexes.last().expect("is some") < values.len()); - let query_values = Vec::from(&values[indexes[0]..(indexes[0]+self.params.values_per_leaf)]); + let query_values = Vec::from(&values[indexes[0]..(indexes[0] + self.params.values_per_leaf)]); let leaf_index = indexes[0] / self.params.values_per_leaf; let pair_index = leaf_index ^ 1; let mut scratch_space = vec![0u8; Self::VALUE_BYTE_SIZE * self.params.values_per_leaf]; - let leaf_pair_hash = Self::hash_into_leaf(&values[(pair_index*self.params.values_per_leaf)..((pair_index+1)*self.params.values_per_leaf)], &mut scratch_space); + let leaf_pair_hash = Self::hash_into_leaf( + &values[(pair_index * self.params.values_per_leaf)..((pair_index + 1) * self.params.values_per_leaf)], + &mut scratch_space, + ); let path = self.make_full_path(leaf_index, leaf_pair_hash); @@ -280,9 +280,7 @@ fn make_small_iop() { const SIZE: usize = 16; const VALUES_PER_LEAF: usize = 4; - let params = FriSpecificBlake2sTreeParams { - values_per_leaf: VALUES_PER_LEAF - }; + let params = FriSpecificBlake2sTreeParams { values_per_leaf: VALUES_PER_LEAF }; let mut inputs = vec![]; let mut f = Fr::one(); @@ -297,14 +295,13 @@ fn make_small_iop() { assert!(tree_size == SIZE); assert!(iop.nodes.len() == (SIZE / VALUES_PER_LEAF)); for i in 0..(SIZE / VALUES_PER_LEAF) { - let indexes: Vec<_> = ((i*VALUES_PER_LEAF)..(VALUES_PER_LEAF + i*VALUES_PER_LEAF)).collect(); + let indexes: Vec<_> = ((i * VALUES_PER_LEAF)..(VALUES_PER_LEAF + i * VALUES_PER_LEAF)).collect(); let query = iop.produce_query(indexes, &inputs); let valid = FriSpecificBlake2sTree::verify_query(&commitment, &query, ¶ms); assert!(valid, "invalid query for leaf index {}", i); } } - #[test] fn test_bench_large_fri_specific_iop() { use crate::ff::Field; @@ -313,9 +310,7 @@ fn test_bench_large_fri_specific_iop() { const SIZE: usize = 1 << (20 + 4); const VALUES_PER_LEAF: usize = 8; - let params = FriSpecificBlake2sTreeParams { - values_per_leaf: VALUES_PER_LEAF - }; + let params = FriSpecificBlake2sTreeParams { values_per_leaf: VALUES_PER_LEAF }; let mut inputs = vec![]; let mut f = Fr::one(); @@ -330,9 +325,9 @@ fn test_bench_large_fri_specific_iop() { assert!(tree_size == SIZE); assert!(iop.nodes.len() == (SIZE / VALUES_PER_LEAF)); for i in 0..128 { - let indexes: Vec<_> = ((i*VALUES_PER_LEAF)..(VALUES_PER_LEAF + i*VALUES_PER_LEAF)).collect(); + let indexes: Vec<_> = ((i * VALUES_PER_LEAF)..(VALUES_PER_LEAF + i * VALUES_PER_LEAF)).collect(); let query = iop.produce_query(indexes, &inputs); let valid = FriSpecificBlake2sTree::verify_query(&commitment, &query, ¶ms); assert!(valid, "invalid query for leaf index {}", i); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/commitments/transparent/iop_compiler/mod.rs b/crates/bellman/src/plonk/commitments/transparent/iop_compiler/mod.rs index 40d409a..8fa58f6 100644 --- a/crates/bellman/src/plonk/commitments/transparent/iop_compiler/mod.rs +++ b/crates/bellman/src/plonk/commitments/transparent/iop_compiler/mod.rs @@ -23,4 +23,4 @@ pub trait IopQuery: 'static + PartialEq + Eq + Clone + std::fmt:: // const fn byte_size() -> usize { // (((F::NUM_BITS as usize) / 64) + 1) * 8 -// } \ No newline at end of file +// } diff --git a/crates/bellman/src/plonk/commitments/transparent/mod.rs b/crates/bellman/src/plonk/commitments/transparent/mod.rs index bb18419..3b2379d 100644 --- a/crates/bellman/src/plonk/commitments/transparent/mod.rs +++ b/crates/bellman/src/plonk/commitments/transparent/mod.rs @@ -1,30 +1,30 @@ use crate::pairing::ff::PrimeField; +use super::CommitmentScheme; use crate::plonk::polynomials::*; use crate::worker::Worker; -use super::CommitmentScheme; -pub mod precomputations; -pub mod iop; pub mod fri; +pub mod iop; pub mod iop_compiler; +pub mod precomputations; pub mod utils; use self::precomputations::PrecomputedInvOmegas; -use crate::plonk::domains::*; use crate::plonk::commitments::transcript::Prng; +use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::transparent::fri::*; use crate::plonk::commitments::transparent::iop::*; -use crate::plonk::commitments::transcript::*; -use crate::plonk::fft::cooley_tukey_ntt::{CTPrecomputations, BitReversedOmegas}; +use crate::plonk::domains::*; +use crate::plonk::fft::cooley_tukey_ntt::{BitReversedOmegas, CTPrecomputations}; // Such committer uses external transcript for all the operations pub struct StatelessTransparentCommitter< - F: PrimeField, + F: PrimeField, FRI: FriIop, - T: Transcript >::IopType as IOP >::Tree as IopTree >::TreeHasher as IopTreeHasher>::HashOutput > ->{ + T: Transcript>::IopType as IOP>::Tree as IopTree>::TreeHasher as IopTreeHasher>::HashOutput>, +> { max_degree_plus_one: usize, lde_factor: usize, output_coeffs_at_degree_plus_one: usize, @@ -34,21 +34,19 @@ pub struct StatelessTransparentCommitter< precomputed_bitreversed_omegas: BitReversedOmegas, fri_params: >::Params, _marker_fri: std::marker::PhantomData, - _marker_t: std::marker::PhantomData + _marker_t: std::marker::PhantomData, } -impl< - F: PrimeField, - FRI: FriIop, - T: Transcript >::IopType as IOP >::Tree as IopTree >::TreeHasher as IopTreeHasher>::HashOutput > -> std::fmt::Debug for StatelessTransparentCommitter { +impl, T: Transcript>::IopType as IOP>::Tree as IopTree>::TreeHasher as IopTreeHasher>::HashOutput>> std::fmt::Debug + for StatelessTransparentCommitter +{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { writeln!(f, "Stateless transparent committer") } } #[derive(Debug)] -pub struct TransparentCommitterParameters>{ +pub struct TransparentCommitterParameters> { pub lde_factor: usize, pub num_queries: usize, pub output_coeffs_at_degree_plus_one: usize, @@ -57,7 +55,7 @@ pub struct TransparentCommitterParameters>{ impl> Clone for TransparentCommitterParameters { fn clone(&self) -> Self { - TransparentCommitterParameters::{ + TransparentCommitterParameters:: { lde_factor: self.lde_factor, num_queries: self.num_queries, output_coeffs_at_degree_plus_one: self.output_coeffs_at_degree_plus_one, @@ -68,14 +66,12 @@ impl> Clone for TransparentCommitterParameters, - T: Transcript >::IopType as IOP >::Tree as IopTree >::TreeHasher as IopTreeHasher>::HashOutput > -> CommitmentScheme for StatelessTransparentCommitter { - type Commitment = < < < >::IopType as IOP >::Tree as IopTree >::TreeHasher as IopTreeHasher>::HashOutput; - type OpeningProof = (FRI::Proof, Vec >::IopType as IOP >::Query) > >); - type IntermediateData = (Polynomial, < FRI as FriIop >::IopType); +impl, T: Transcript>::IopType as IOP>::Tree as IopTree>::TreeHasher as IopTreeHasher>::HashOutput>> CommitmentScheme + for StatelessTransparentCommitter +{ + type Commitment = <<<>::IopType as IOP>::Tree as IopTree>::TreeHasher as IopTreeHasher>::HashOutput; + type OpeningProof = (FRI::Proof, Vec>::IopType as IOP>::Query)>>); + type IntermediateData = (Polynomial, >::IopType); type Meta = TransparentCommitterParameters; type Prng = T; @@ -86,7 +82,7 @@ impl< let base_size = max_degree_plus_one.next_power_of_two(); assert!(meta.lde_factor.is_power_of_two()); assert!(meta.output_coeffs_at_degree_plus_one.is_power_of_two()); - let lde_domain_size = base_size*meta.lde_factor; + let lde_domain_size = base_size * meta.lde_factor; let base_domain = Domain::::new_for_size(base_size as u64).expect("domain of large enough size should exist"); let lde_domain = Domain::::new_for_size(lde_domain_size as u64).expect("domain of large enough size should exist"); let worker = Worker::new(); @@ -103,15 +99,18 @@ impl< precomputed_bitreversed_omegas: omegas_bitrev_precomp, fri_params: meta.fri_params, _marker_fri: std::marker::PhantomData, - _marker_t: std::marker::PhantomData + _marker_t: std::marker::PhantomData, } } fn precompute(&self, poly: &Polynomial) -> Option { assert!(poly.size() == self.max_degree_plus_one); - let original_poly_lde = poly.clone().lde_using_bitreversed_ntt(&self.worker, self.lde_factor, &self.precomputed_bitreversed_omegas).expect("must make an LDE"); + let original_poly_lde = poly + .clone() + .lde_using_bitreversed_ntt(&self.worker, self.lde_factor, &self.precomputed_bitreversed_omegas) + .expect("must make an LDE"); // let original_poly_lde = poly.clone().lde(&self.worker, self.lde_factor).expect("must make an LDE"); - let original_tree = < < FRI as FriIop >::IopType as IOP >::create(&original_poly_lde.as_ref()); + let original_tree = <>::IopType as IOP>::create(&original_poly_lde.as_ref()); Some((original_poly_lde, original_tree)) } @@ -120,36 +119,26 @@ impl< println!("Start commit single"); let start = Instant::now(); // let mut original_poly_lde = poly.clone().lde_using_bitreversed_ntt(&self.worker, self.lde_factor, &self.precomputed_bitreversed_omegas).expect("must make an LDE"); - let mut original_poly_lde = poly.clone().bitreversed_lde_using_bitreversed_ntt( - &self.worker, - self.lde_factor, - &self.precomputed_bitreversed_omegas, - &F::one(), - ).expect("must make an LDE"); + let mut original_poly_lde = poly + .clone() + .bitreversed_lde_using_bitreversed_ntt(&self.worker, self.lde_factor, &self.precomputed_bitreversed_omegas, &F::one()) + .expect("must make an LDE"); original_poly_lde.bitreverse_enumeration(&self.worker); // let original_poly_lde = poly.clone().lde(&self.worker, self.lde_factor).expect("must make an LDE"); - let original_tree = < < FRI as FriIop >::IopType as IOP >::create(&original_poly_lde.as_ref()); + let original_tree = <>::IopType as IOP>::create(&original_poly_lde.as_ref()); let commitment = original_tree.get_root(); println!("Done in {:?} for max degree {}", start.elapsed(), poly.size()); println!("Done commit single"); (commitment, Some((original_poly_lde, original_tree))) - } fn commit_multiple(&self, polynomials: Vec<&Polynomial>, degrees: Vec, aggregation_coefficient: F) -> (Self::Commitment, Option>) { unimplemented!() } - fn open_single( - &self, - poly: &Polynomial, - at_point: F, - _opening_value: F, - data: &Option<&Self::IntermediateData>, - prng: &mut Self::Prng - ) -> Self::OpeningProof { + fn open_single(&self, poly: &Polynomial, at_point: F, _opening_value: F, data: &Option<&Self::IntermediateData>, prng: &mut Self::Prng) -> Self::OpeningProof { println!("Start open single"); let start = Instant::now(); @@ -161,20 +150,23 @@ impl< }; let q_poly = Polynomial::::from_coeffs(division_result).expect("must be small enough"); - let q_poly_lde = q_poly.lde_using_bitreversed_ntt(&self.worker, self.lde_factor, &self.precomputed_bitreversed_omegas).expect("must make an LDE"); + let q_poly_lde = q_poly + .lde_using_bitreversed_ntt(&self.worker, self.lde_factor, &self.precomputed_bitreversed_omegas) + .expect("must make an LDE"); // let q_poly_lde = q_poly.lde(&self.worker, self.lde_factor).expect("must make an LDE"); let lde_size = q_poly_lde.size(); let fri_proto = FRI::proof_from_lde( - &q_poly_lde, - self.lde_factor, - self.output_coeffs_at_degree_plus_one, - &self.precomputed_inverse_omegas, - &self.worker, + &q_poly_lde, + self.lde_factor, + self.output_coeffs_at_degree_plus_one, + &self.precomputed_inverse_omegas, + &self.worker, prng, - &self.fri_params - ).expect("FRI must succeed"); + &self.fri_params, + ) + .expect("FRI must succeed"); for c in fri_proto.get_final_coefficients().iter() { prng.commit_field_element(&c); @@ -188,12 +180,12 @@ impl< while domain_indexes.len() < self.num_queries { let domain_idx = bytes_to_challenge_index(prng.get_challenge_bytes(), lde_size); - let coset_index_values = < < >::IopType as IOP >::Combiner as CosetCombiner>::get_coset_for_natural_index(domain_idx, lde_size); + let coset_index_values = <<>::IopType as IOP>::Combiner as CosetCombiner>::get_coset_for_natural_index(domain_idx, lde_size); let mut can_use = true; for v in coset_index_values.iter() { if used_queries.contains(&v) { can_use = false; - break + break; } } if can_use { @@ -206,11 +198,7 @@ impl< let mut original_poly_queries = vec![]; - let precomputations = if data.is_some() { - None - } else { - self.precompute(&poly) - }; + let precomputations = if data.is_some() { None } else { self.precompute(&poly) }; let (original_poly_lde, original_poly_lde_oracle) = if let Some((lde, oracle)) = data.as_ref() { (lde, oracle) @@ -221,7 +209,7 @@ impl< }; for idx in domain_indexes.into_iter() { - let original_value = < < >::IopType as IOP >::Combiner as CosetCombiner>::get_for_natural_index(original_poly_lde.as_ref(), idx); + let original_value = <<>::IopType as IOP>::Combiner as CosetCombiner>::get_for_natural_index(original_poly_lde.as_ref(), idx); let original_poly_query = original_poly_lde_oracle.query(idx, original_poly_lde.as_ref()); original_poly_queries.push((*original_value, original_poly_query)); } @@ -230,18 +218,17 @@ impl< println!("Done open single"); (q_poly_fri_proof, vec![original_poly_queries]) - } fn open_multiple( - &self, - polynomials: Vec<&Polynomial>, - degrees: Vec, - aggregation_coefficient: F, - at_points: Vec, + &self, + polynomials: Vec<&Polynomial>, + degrees: Vec, + aggregation_coefficient: F, + at_points: Vec, opening_values: Vec, - data: &Option>, - prng: &mut Self::Prng + data: &Option>, + prng: &mut Self::Prng, ) -> Self::OpeningProof { println!("Start open multiple"); let start = Instant::now(); @@ -251,15 +238,15 @@ impl< let max_degree = *degrees.iter().max().expect("MAX element exists"); let min_degree = *degrees.iter().min().expect("MIN element exists"); - assert!(f64::from(max_degree as u32) / f64::from(min_degree as u32) < 2.0, "polynomials should not have too large degree difference"); + assert!( + f64::from(max_degree as u32) / f64::from(min_degree as u32) < 2.0, + "polynomials should not have too large degree difference" + ); let mut division_results = vec![vec![]; polynomials.len()]; self.worker.scope(polynomials.len(), |scope, chunk| { - for ((p, q), at) in polynomials.chunks(chunk) - .zip(division_results.chunks_mut(chunk)) - .zip(at_points.chunks(chunk)) - { + for ((p, q), at) in polynomials.chunks(chunk).zip(division_results.chunks_mut(chunk)).zip(at_points.chunks(chunk)) { scope.spawn(move |_| { for ((p, q), at) in p.iter().zip(q.iter_mut()).zip(at.iter()) { let division_result = kate_divison_with_same_return_size(p.as_ref(), *at); @@ -272,7 +259,7 @@ impl< // aggregate starting usign the first coefficient of 1 - let mut q_poly: Option> = None; + let mut q_poly: Option> = None; let mut alpha = F::one(); @@ -290,25 +277,23 @@ impl< let q_poly = q_poly.expect("now it's aggregated"); // let q_poly_lde = q_poly.lde(&self.worker, self.lde_factor).expect("must make an LDE"); - let mut q_poly_lde = q_poly.bitreversed_lde_using_bitreversed_ntt( - &self.worker, - self.lde_factor, - &self.precomputed_bitreversed_omegas, - &F::one(), - ).expect("must make an LDE"); + let mut q_poly_lde = q_poly + .bitreversed_lde_using_bitreversed_ntt(&self.worker, self.lde_factor, &self.precomputed_bitreversed_omegas, &F::one()) + .expect("must make an LDE"); q_poly_lde.bitreverse_enumeration(&self.worker); let lde_size = q_poly_lde.size(); let fri_proto = FRI::proof_from_lde( - &q_poly_lde, - self.lde_factor, - self.output_coeffs_at_degree_plus_one, - &self.precomputed_inverse_omegas, - &self.worker, + &q_poly_lde, + self.lde_factor, + self.output_coeffs_at_degree_plus_one, + &self.precomputed_inverse_omegas, + &self.worker, prng, - &self.fri_params - ).expect("FRI must succeed"); + &self.fri_params, + ) + .expect("FRI must succeed"); for c in fri_proto.get_final_coefficients().iter() { prng.commit_field_element(&c); @@ -322,12 +307,12 @@ impl< while domain_indexes.len() < self.num_queries { let domain_idx = bytes_to_challenge_index(prng.get_challenge_bytes(), lde_size); - let coset_index_values = < < >::IopType as IOP >::Combiner as CosetCombiner>::get_coset_for_natural_index(domain_idx, lde_size); + let coset_index_values = <<>::IopType as IOP>::Combiner as CosetCombiner>::get_coset_for_natural_index(domain_idx, lde_size); let mut can_use = true; for v in coset_index_values.iter() { if used_queries.contains(&v) { can_use = false; - break + break; } } if can_use { @@ -336,12 +321,7 @@ impl< } } - let q_poly_fri_proof = FRI::prototype_into_proof( - fri_proto, - &q_poly_lde, - domain_indexes.clone(), - &self.fri_params - ).expect("must generate a proper proof"); + let q_poly_fri_proof = FRI::prototype_into_proof(fri_proto, &q_poly_lde, domain_indexes.clone(), &self.fri_params).expect("must generate a proper proof"); let precomputations = if data.is_some() { None @@ -356,20 +336,21 @@ impl< }; let mut prec_may_be = None; - + let data = if data.is_some() { data.as_ref() } else { prec_may_be = Some(precomputations.as_ref().expect("is some").iter().map(|el| el).collect::>()); prec_may_be.as_ref() - }.expect("there is aux data in full"); + } + .expect("there is aux data in full"); let mut queries = vec![]; for (original_poly_lde, original_poly_lde_oracle) in data.iter() { let mut original_poly_queries = vec![]; for idx in domain_indexes.clone().into_iter() { - let original_value = < < >::IopType as IOP >::Combiner as CosetCombiner>::get_for_natural_index(original_poly_lde.as_ref(), idx); + let original_value = <<>::IopType as IOP>::Combiner as CosetCombiner>::get_for_natural_index(original_poly_lde.as_ref(), idx); let original_poly_query = original_poly_lde_oracle.query(idx, original_poly_lde.as_ref()); original_poly_queries.push((*original_value, original_poly_query)); } @@ -385,7 +366,6 @@ impl< // println!("Will open poly at indexes {:?} for values {:?}", domain_indexes, opened_values); - println!("Done in {:?} for max degree {}", start.elapsed(), max_degree); println!("Done open multiple"); @@ -420,12 +400,12 @@ impl< while domain_indexes.len() < self.num_queries { let domain_idx = bytes_to_challenge_index(prng.get_challenge_bytes(), lde_size); - let coset_index_values = < < >::IopType as IOP >::Combiner as CosetCombiner>::get_coset_for_natural_index(domain_idx, lde_size); + let coset_index_values = <<>::IopType as IOP>::Combiner as CosetCombiner>::get_coset_for_natural_index(domain_idx, lde_size); let mut can_use = true; for v in coset_index_values.iter() { if used_queries.contains(&v) { can_use = false; - break + break; } } if can_use { @@ -438,12 +418,11 @@ impl< let mut simulated_q_poly_values = vec![]; - for (domain_idx, original_poly_query) in domain_indexes.clone().into_iter() - .zip(original_poly_queries.iter()) { + for (domain_idx, original_poly_query) in domain_indexes.clone().into_iter().zip(original_poly_queries.iter()) { let x = lde_domain.generator.pow(&[domain_idx as u64]); assert!(original_poly_query.1.value() == original_poly_query.0); - + let mut num = original_poly_query.0; num.sub_assign(&claimed_value); @@ -455,7 +434,7 @@ impl< let mut value_at_x = num; value_at_x.mul_assign(&den_inversed); - let is_in_commitment = < >::IopType as IOP >::verify_query(&original_poly_query.1, commitment); + let is_in_commitment = <>::IopType as IOP>::verify_query(&original_poly_query.1, commitment); if !is_in_commitment { return false; } @@ -463,26 +442,20 @@ impl< simulated_q_poly_values.push(value_at_x); } - let valid = FRI::verify_proof_with_challenges( - q_poly_fri_proof, - domain_indexes, - &simulated_q_poly_values, - &fri_challenges, - &self.fri_params - ).expect("fri verification should work"); + let valid = FRI::verify_proof_with_challenges(q_poly_fri_proof, domain_indexes, &simulated_q_poly_values, &fri_challenges, &self.fri_params).expect("fri verification should work"); valid } #[track_caller] fn verify_multiple_openings( - &self, - commitments: Vec<&Self::Commitment>, - at_points: Vec, - claimed_values: &Vec, - aggregation_coefficient: F, - proof: &Self::OpeningProof, - prng: &mut Self::Prng + &self, + commitments: Vec<&Self::Commitment>, + at_points: Vec, + claimed_values: &Vec, + aggregation_coefficient: F, + proof: &Self::OpeningProof, + prng: &mut Self::Prng, ) -> bool { let (q_poly_fri_proof, original_poly_queries_vec) = proof; @@ -507,12 +480,12 @@ impl< while domain_indexes.len() < self.num_queries { let domain_idx = bytes_to_challenge_index(prng.get_challenge_bytes(), lde_size); - let coset_index_values = < < >::IopType as IOP >::Combiner as CosetCombiner>::get_coset_for_natural_index(domain_idx, lde_size); + let coset_index_values = <<>::IopType as IOP>::Combiner as CosetCombiner>::get_coset_for_natural_index(domain_idx, lde_size); let mut can_use = true; for v in coset_index_values.iter() { if used_queries.contains(&v) { can_use = false; - break + break; } } if can_use { @@ -546,13 +519,11 @@ impl< let mut simulated_q_poly_subvalues = vec![]; - for (domain_idx, original_poly_query) in domain_indexes.clone().into_iter() - .zip(queries_to_the_same_poly.iter()) { - + for (domain_idx, original_poly_query) in domain_indexes.clone().into_iter().zip(queries_to_the_same_poly.iter()) { let x = lde_domain.generator.pow(&[domain_idx as u64]); assert!(original_poly_query.1.value() == original_poly_query.0); - + let mut num = original_poly_query.0; num.sub_assign(&claimed_value); @@ -564,7 +535,7 @@ impl< let mut value_at_x = num; value_at_x.mul_assign(&den_inversed); - let is_in_commitment = < >::IopType as IOP >::verify_query(&original_poly_query.1, subpoly_commitment); + let is_in_commitment = <>::IopType as IOP>::verify_query(&original_poly_query.1, subpoly_commitment); if !is_in_commitment { println!("Not in the root for subpoly {} out of {}", subpoly_index, original_poly_queries_vec.len()); return false; @@ -573,7 +544,7 @@ impl< simulated_q_poly_subvalues.push(value_at_x); } - // in simulated_q_poly_values now there are values of this polynomial for all the queries, + // in simulated_q_poly_values now there are values of this polynomial for all the queries, // now we need to sum them up with a proper coefficients starting with 0 assert_eq!(simulated_q_poly_values.len(), simulated_q_poly_subvalues.len()); @@ -590,13 +561,7 @@ impl< // println!("Will open poly at indexes {:?} for simulated values {:?}", domain_indexes, simulated_q_poly_values); let now = std::time::Instant::now(); - let valid = FRI::verify_proof_with_challenges( - q_poly_fri_proof, - domain_indexes, - &simulated_q_poly_values, - &fri_challenges, - &self.fri_params - ).expect("fri verification should work"); + let valid = FRI::verify_proof_with_challenges(q_poly_fri_proof, domain_indexes, &simulated_q_poly_values, &fri_challenges, &self.fri_params).expect("fri verification should work"); println!("FRI part taken {:?}", now.elapsed()); @@ -604,10 +569,8 @@ impl< } } - // use single threaded Kate division for now -fn kate_divison_with_same_return_size(a: &[F], mut b: F) -> Vec -{ +fn kate_divison_with_same_return_size(a: &[F], mut b: F) -> Vec { b.negate(); let mut q = vec![F::zero(); a.len()]; @@ -617,7 +580,7 @@ fn kate_divison_with_same_return_size(a: &[F], mut b: F) -> Vec>(bytes: S, lde_size: usize) -> usize natural_x_index } - #[cfg(test)] mod test { use super::*; use crate::pairing::ff::{Field, PrimeField}; - use crate::{SynthesisError}; + use crate::SynthesisError; use std::marker::PhantomData; - use crate::plonk::utils::*; - use crate::plonk::commitments::transparent::fri::*; - use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*; + use crate::plonk::commitments::transparent::fri::*; use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*; + use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::*; - + use crate::plonk::utils::*; #[test] fn test_small_transparent_commitment() { use crate::pairing::bn256::{Bn256, Fr}; - const SIZE:usize = 16; + const SIZE: usize = 16; let worker = Worker::new(); @@ -689,7 +650,7 @@ mod test { lde_factor: 16, num_queries: 2, output_coeffs_at_degree_plus_one: 1, - fri_params: () + fri_params: (), }; let committer = >::new_for_size(SIZE, meta); @@ -711,12 +672,12 @@ mod test { #[test] fn test_large_transparent_commitment() { - use std::time::Instant; use crate::pairing::bn256::{Bn256, Fr}; + use std::time::Instant; let worker = Worker::new(); - const SIZE:usize = 1 << 20; + const SIZE: usize = 1 << 20; // const SIZE:usize = 1 << 10; let coeffs: Vec<_> = (0..SIZE).collect(); @@ -733,7 +694,7 @@ mod test { lde_factor: 16, num_queries: 6, // ~100 bits of security output_coeffs_at_degree_plus_one: 16, - fri_params: () + fri_params: (), }; let committer = >::new_for_size(SIZE, meta); @@ -764,4 +725,4 @@ mod test { assert!(valid); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/commitments/transparent/precomputations/mod.rs b/crates/bellman/src/plonk/commitments/transparent/precomputations/mod.rs index 5fb0448..77cdb1b 100644 --- a/crates/bellman/src/plonk/commitments/transparent/precomputations/mod.rs +++ b/crates/bellman/src/plonk/commitments/transparent/precomputations/mod.rs @@ -1,25 +1,25 @@ use crate::pairing::ff::PrimeField; +use crate::plonk::commitments::transparent::fri::FriPrecomputations; use crate::plonk::domains::Domain; use crate::plonk::fft::cooley_tukey_ntt::bitreverse; -use crate::plonk::polynomials::Polynomial; -use crate::worker::Worker; use crate::plonk::fft::distribute_powers; -use crate::plonk::commitments::transparent::fri::FriPrecomputations; use crate::plonk::fft::with_precomputation::FftPrecomputations; +use crate::plonk::polynomials::Polynomial; +use crate::worker::Worker; pub struct PrecomputedOmegas { pub omegas: Vec, pub coset: Vec, pub omegas_inv: Vec, pub omegas_inv_bitreversed: Vec, - domain_size: usize + domain_size: usize, } impl PrecomputedOmegas { pub fn new_for_domain(domain: &Domain, worker: &Worker) -> Self { let domain_size = domain.size as usize; - let precomputation_size = domain_size/2; + let precomputation_size = domain_size / 2; let omega = domain.generator; let omega_inv = domain.generator.inverse().expect("must exist"); @@ -68,17 +68,17 @@ impl PrecomputedOmegas { } }); - PrecomputedOmegas{ + PrecomputedOmegas { omegas, coset, omegas_inv, omegas_inv_bitreversed, - domain_size + domain_size, } } } -impl FriPrecomputations for PrecomputedOmegas{ +impl FriPrecomputations for PrecomputedOmegas { fn new_for_domain_size(size: usize) -> Self { let domain = Domain::::new_for_size(size as u64).expect("domain must exist"); let worker = Worker::new(); @@ -98,7 +98,7 @@ impl FriPrecomputations for PrecomputedOmegas{ } } -impl FftPrecomputations for PrecomputedOmegas{ +impl FftPrecomputations for PrecomputedOmegas { fn new_for_domain_size(size: usize) -> Self { let domain = Domain::::new_for_size(size as u64).expect("domain must exist"); let worker = Worker::new(); @@ -117,13 +117,13 @@ impl FftPrecomputations for PrecomputedOmegas{ pub struct PrecomputedInvOmegas { pub omegas_inv: Vec, pub omegas_inv_bitreversed: Vec, - domain_size: usize + domain_size: usize, } impl PrecomputedInvOmegas { pub fn new_for_domain(domain: &Domain, worker: &Worker) -> Self { let domain_size = domain.size as usize; - let precomputation_size = domain_size/2; + let precomputation_size = domain_size / 2; let omega = domain.generator; let omega_inv = omega.inverse().expect("must exist"); @@ -146,15 +146,15 @@ impl PrecomputedInvOmegas { omegas_inv_bitreversed.bitreverse_enumeration(worker); let omegas_inv_bitreversed = omegas_inv_bitreversed.into_coeffs(); - PrecomputedInvOmegas{ + PrecomputedInvOmegas { omegas_inv, omegas_inv_bitreversed, - domain_size + domain_size, } } } -impl FriPrecomputations for PrecomputedInvOmegas{ +impl FriPrecomputations for PrecomputedInvOmegas { fn new_for_domain_size(size: usize) -> Self { let domain = Domain::::new_for_size(size as u64).expect("domain must exist"); let worker = Worker::new(); @@ -172,4 +172,4 @@ impl FriPrecomputations for PrecomputedInvOmegas{ fn domain_size(&self) -> usize { self.domain_size } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/commitments/transparent/utils.rs b/crates/bellman/src/plonk/commitments/transparent/utils.rs index 4468583..b70f76c 100644 --- a/crates/bellman/src/plonk/commitments/transparent/utils.rs +++ b/crates/bellman/src/plonk/commitments/transparent/utils.rs @@ -3,9 +3,9 @@ pub fn log2_floor(num: usize) -> u32 { let mut pow = 0; - while (1 << (pow+1)) <= num { + while (1 << (pow + 1)) <= num { pow += 1; } pow -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/cs/gates.rs b/crates/bellman/src/plonk/cs/gates.rs index e4d9c0a..f9b01cf 100644 --- a/crates/bellman/src/plonk/cs/gates.rs +++ b/crates/bellman/src/plonk/cs/gates.rs @@ -1,8 +1,8 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; -use std::ops::{Add, Sub, Neg}; +use crate::pairing::Engine; +use std::ops::{Add, Neg, Sub}; -pub use super::variable::{Variable, Index}; +pub use super::variable::{Index, Variable}; pub enum Coeff { Zero, @@ -16,16 +16,16 @@ impl std::fmt::Debug for Coeff { match self { Coeff::Zero => { write!(f, "Coeff 0x0") - }, + } Coeff::One => { write!(f, "Coeff 0x1") - }, + } Coeff::NegativeOne => { write!(f, "Coeff -0x1") - }, + } Coeff::Full(c) => { write!(f, "Coeff {:?}", c) - }, + } } } } @@ -35,18 +35,18 @@ impl Coeff { match self { Coeff::Zero => { *with = F::zero(); - }, - Coeff::One => {}, + } + Coeff::One => {} Coeff::NegativeOne => { with.negate(); - }, + } Coeff::Full(val) => { with.mul_assign(val); } } } - pub fn new(coeff: F) -> Self { + pub fn new(coeff: F) -> Self { let mut negative_one = F::one(); negative_one.negate(); @@ -95,13 +95,15 @@ pub struct Gate { pub(crate) q_o: Coeff, pub(crate) q_m: Coeff, pub(crate) q_c: Coeff, -} +} impl std::fmt::Debug for Gate { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Gate A = {:?}, B = {:?}, C = {:?}, q_l = {:?}, q_r = {:?}, q_o = {:?}, q_m = {:?}, q_c = {:?}", - self.a_wire, self.b_wire, self.c_wire, self.q_l, self.q_r, self.q_o, self.q_m, self.q_c) - + write!( + f, + "Gate A = {:?}, B = {:?}, C = {:?}, q_l = {:?}, q_r = {:?}, q_o = {:?}, q_m = {:?}, q_c = {:?}", + self.a_wire, self.b_wire, self.c_wire, self.q_l, self.q_r, self.q_o, self.q_m, self.q_c + ) } } @@ -132,7 +134,6 @@ impl Gate { } pub(crate) fn new_multiplication_gate(variables: (Variable, Variable, Variable)) -> Self { - Self { a_wire: variables.0, b_wire: variables.1, @@ -160,7 +161,7 @@ impl Gate { pub(crate) fn new_lc_gate(variables: (Variable, Variable, Variable), coeffs: (F, F, F), constant: F) -> Self { let (a_coeff, b_coeff, c_coeff) = coeffs; - + Self { a_wire: variables.0, b_wire: variables.1, @@ -175,7 +176,7 @@ impl Gate { pub(crate) fn new_enforce_zero_gate(variables: (Variable, Variable, Variable), coeffs: (F, F, F)) -> Self { let (a_coeff, b_coeff, c_coeff) = coeffs; - + Self { a_wire: variables.0, b_wire: variables.1, @@ -189,7 +190,6 @@ impl Gate { } pub(crate) fn new_enforce_boolean_gate(variable: Variable, dummy_variable: Variable) -> Self { - Self { a_wire: variable, b_wire: variable, @@ -203,7 +203,6 @@ impl Gate { } pub(crate) fn new_empty_gate(dummy_variable: Variable) -> Self { - Self { a_wire: dummy_variable, b_wire: dummy_variable, @@ -250,8 +249,7 @@ impl Gate { } } - pub(crate) fn new_gate(variables: (Variable, Variable, Variable), - coeffs: (F, F, F, F, F)) -> Self { + pub(crate) fn new_gate(variables: (Variable, Variable, Variable), coeffs: (F, F, F, F, F)) -> Self { let (q_l, q_r, q_o, q_m, q_c) = coeffs; Self { diff --git a/crates/bellman/src/plonk/cs/mod.rs b/crates/bellman/src/plonk/cs/mod.rs index 5d3c18c..d8421bd 100644 --- a/crates/bellman/src/plonk/cs/mod.rs +++ b/crates/bellman/src/plonk/cs/mod.rs @@ -1,14 +1,14 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine}; +use crate::pairing::ff::Field; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; pub mod gates; pub mod variable; -use self::variable::*; use self::gates::*; +use self::variable::*; pub trait Circuit { fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError>; @@ -42,8 +42,7 @@ pub trait ConstraintSystem { fn enforce_boolean(&mut self, variable: Variable) -> Result<(), SynthesisError>; // allocate an abstract gate - fn new_gate(&mut self, variables: (Variable, Variable, Variable), - coeffs:(E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError>; + fn new_gate(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError>; // allocate a constant fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError>; @@ -55,11 +54,10 @@ pub trait ConstraintSystem { fn enforce_mul_3(&mut self, variables: (Variable, Variable, Variable)) -> Result<(), SynthesisError>; // allocate a linear combination gate - fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs:(E::Fr, E::Fr)) -> Result<(), SynthesisError>; + fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs: (E::Fr, E::Fr)) -> Result<(), SynthesisError>; // allocate a linear combination gate - fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs:(E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError>; - + fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError>; // // allocate a linear combination gate // fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs:(E::Fr, E::Fr), values: F) -> Result<(), SynthesisError>; @@ -77,7 +75,7 @@ pub trait ConstraintSystem { // where // F: FnOnce() -> Result<(E::Fr, E::Fr, E::Fr), SynthesisError>; - fn get_value(&self, _variable: Variable) -> Result { + fn get_value(&self, _variable: Variable) -> Result { Err(SynthesisError::AssignmentMissing) } @@ -88,8 +86,6 @@ pub trait ConstraintSystem { // } } - - // /// This is a backend for the `SynthesisDriver` to relay information about // /// the concrete circuit. One backend might just collect basic information // /// about the circuit for verification, while another actually constructs @@ -124,4 +120,4 @@ pub trait ConstraintSystem { // /// This is an abstraction which synthesizes circuits. // pub trait SynthesisDriver { // fn synthesize, B: Backend>(backend: B, circuit: &C) -> Result<(), SynthesisError>; -// } \ No newline at end of file +// } diff --git a/crates/bellman/src/plonk/cs/variable.rs b/crates/bellman/src/plonk/cs/variable.rs index 5c63b19..53ab09f 100644 --- a/crates/bellman/src/plonk/cs/variable.rs +++ b/crates/bellman/src/plonk/cs/variable.rs @@ -21,5 +21,5 @@ impl Variable { #[derive(Copy, Clone, PartialEq, Debug, Hash, Eq, serde::Serialize, serde::Deserialize)] pub enum Index { Input(usize), - Aux(usize) -} \ No newline at end of file + Aux(usize), +} diff --git a/crates/bellman/src/plonk/domains/mod.rs b/crates/bellman/src/plonk/domains/mod.rs index d59243a..d0eb6f5 100644 --- a/crates/bellman/src/plonk/domains/mod.rs +++ b/crates/bellman/src/plonk/domains/mod.rs @@ -1,6 +1,6 @@ use crate::pairing::ff::PrimeField; -use crate::SynthesisError; use crate::worker::Worker; +use crate::SynthesisError; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Domain { @@ -31,7 +31,7 @@ impl Domain { Ok(Self { size: size, power_of_two: power_of_two, - generator: generator + generator: generator, }) } @@ -53,28 +53,20 @@ impl Domain { assert!(domain_size.is_power_of_two()); let next_size = domain_size / 2; - let next_index = if natural_index < next_size { - natural_index - } else { - natural_index - next_size - }; + let next_index = if natural_index < next_size { natural_index } else { natural_index - next_size }; (next_index, next_size) } } -pub(crate) fn materialize_domain_elements_with_natural_enumeration( - domain: &Domain, - worker: &Worker -) -> Vec { +pub(crate) fn materialize_domain_elements_with_natural_enumeration(domain: &Domain, worker: &Worker) -> Vec { let mut values = vec![F::zero(); domain.size as usize]; let generator = domain.generator; worker.scope(values.len(), |scope, chunk| { - for (i, values) in values.chunks_mut(chunk).enumerate() - { + for (i, values) in values.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut current_power = generator.pow(&[(i*chunk) as u64]); + let mut current_power = generator.pow(&[(i * chunk) as u64]); for p in values { *p = current_power; @@ -85,4 +77,4 @@ pub(crate) fn materialize_domain_elements_with_natural_enumeration u32 { r } - pub struct BitReversedOmegas { pub omegas: Vec, - pub(crate) domain_size: usize + pub(crate) domain_size: usize, } impl BitReversedOmegas { pub fn new_for_domain(domain: &Domain, worker: &Worker) -> Self { let domain_size = domain.size as usize; - + let omega = domain.generator; let precomputation_size = domain_size / 2; // let precomputation_size = domain_size; @@ -72,14 +71,11 @@ impl BitReversedOmegas { } } - BitReversedOmegas{ - omegas, - domain_size - } + BitReversedOmegas { omegas, domain_size } } } -impl CTPrecomputations for BitReversedOmegas{ +impl CTPrecomputations for BitReversedOmegas { fn new_for_domain_size(size: usize) -> Self { let domain = Domain::::new_for_size(size as u64).expect("domain must exist"); let worker = Worker::new(); @@ -95,16 +91,15 @@ impl CTPrecomputations for BitReversedOmegas{ } } - pub struct OmegasInvBitreversed { pub omegas: Vec, - pub(crate) domain_size: usize + pub(crate) domain_size: usize, } impl OmegasInvBitreversed { pub fn new_for_domain(domain: &Domain, worker: &Worker) -> Self { let domain_size = domain.size as usize; - + let omega = domain.generator.inverse().expect("must exist"); let precomputation_size = domain_size / 2; @@ -133,10 +128,7 @@ impl OmegasInvBitreversed { } } - OmegasInvBitreversed{ - omegas, - domain_size - } + OmegasInvBitreversed { omegas, domain_size } } } @@ -161,28 +153,17 @@ pub(crate) fn log2_floor(num: usize) -> u32 { let mut pow = 0; - while (1 << (pow+1)) <= num { + while (1 << (pow + 1)) <= num { pow += 1; } pow } -pub(crate) fn best_ct_ntt>( - a: &mut [F], - worker: &Worker, - log_n: u32, - use_cpus_hint: Option, - precomputed_omegas: &P -) -{ +pub(crate) fn best_ct_ntt>(a: &mut [F], worker: &Worker, log_n: u32, use_cpus_hint: Option, precomputed_omegas: &P) { let log_cpus = if let Some(hint) = use_cpus_hint { assert!(hint <= worker.cpus); - let hint = if hint > 0 { - log2_floor(hint) - } else { - 0 - }; + let hint = if hint > 0 { log2_floor(hint) } else { 0 }; hint } else { @@ -196,14 +177,9 @@ pub(crate) fn best_ct_ntt>( } } -pub(crate) fn serial_ct_ntt>( - a: &mut [F], - log_n: u32, - precomputed_omegas: &P -) -{ +pub(crate) fn serial_ct_ntt>(a: &mut [F], log_n: u32, precomputed_omegas: &P) { assert_eq!(a.len(), precomputed_omegas.domain_size()); - assert_eq!(a.len(), (1<>( for j in idx_1..idx_2 { let u = a[j]; - let v = a[j+distance]; + let v = a[j + distance]; let mut tmp = u; tmp.sub_assign(&v); - a[j+distance] = tmp; + a[j + distance] = tmp; a[j].add_assign(&v); } @@ -246,13 +222,13 @@ pub(crate) fn serial_ct_ntt>( for j in idx_1..idx_2 { let u = a[j]; - let mut v = a[j+distance]; + let mut v = a[j + distance]; v.mul_assign(&s); let mut tmp = u; tmp.sub_assign(&v); - a[j+distance] = tmp; + a[j + distance] = tmp; a[j].add_assign(&v); } } @@ -272,7 +248,6 @@ pub(crate) fn serial_ct_ntt>( // } } - // pub(crate) fn serial_ct_ntt>( // a: &mut [F], // // worker: &Worker, @@ -328,15 +303,7 @@ pub(crate) fn serial_ct_ntt>( // } // } - -pub(crate) fn parallel_ct_ntt>( - a: &mut [F], - worker: &Worker, - log_n: u32, - log_cpus: u32, - precomputed_omegas: &P -) -{ +pub(crate) fn parallel_ct_ntt>(a: &mut [F], worker: &Worker, log_n: u32, log_cpus: u32, precomputed_omegas: &P) { assert!(log_n >= log_cpus); assert_eq!(a.len(), precomputed_omegas.domain_size()); @@ -369,7 +336,7 @@ pub(crate) fn parallel_ct_ntt>( worker.scope(0, |scope, _| { for thread_id in 0..to_spawn { - let a = unsafe {&mut *a}; + let a = unsafe { &mut *a }; let mut pairs_per_group = pairs_per_group; let mut num_groups = num_groups; let mut distance = distance; @@ -386,20 +353,16 @@ pub(crate) fn parallel_ct_ntt>( let chunk = Worker::chunk_size_for_num_spawned_threads(group_size, to_spawn); let start = group_start_idx + thread_id * chunk; - let end = if start + chunk <= group_end_idx { - start + chunk - } else { - group_end_idx - }; + let end = if start + chunk <= group_end_idx { start + chunk } else { group_end_idx }; for j in start..end { let u = a[j]; - let v = a[j+distance]; + let v = a[j + distance]; let mut tmp = u; tmp.sub_assign(&v); - a[j+distance] = tmp; + a[j + distance] = tmp; a[j].add_assign(&v); } @@ -425,11 +388,7 @@ pub(crate) fn parallel_ct_ntt>( let chunk = Worker::chunk_size_for_num_spawned_threads(num_groups, to_spawn); let start = thread_id * chunk; - let end = if start + chunk <= num_groups { - start + chunk - } else { - num_groups - }; + let end = if start + chunk <= num_groups { start + chunk } else { num_groups }; for k in start..end { let group_start_idx = k * pairs_per_group * 2; @@ -438,13 +397,13 @@ pub(crate) fn parallel_ct_ntt>( for j in group_start_idx..group_end_idx { let u = a[j]; - let mut v = a[j+distance]; + let mut v = a[j + distance]; v.mul_assign(&s); let mut tmp = u; tmp.sub_assign(&v); - a[j+distance] = tmp; + a[j + distance] = tmp; a[j].add_assign(&v); } } @@ -466,21 +425,17 @@ pub(crate) fn parallel_ct_ntt>( let chunk = Worker::chunk_size_for_num_spawned_threads(group_size, to_spawn); let start = group_start_idx + thread_id * chunk; - let end = if start + chunk <= group_end_idx { - start + chunk - } else { - group_end_idx - }; + let end = if start + chunk <= group_end_idx { start + chunk } else { group_end_idx }; for j in start..end { let u = a[j]; - let mut v = a[j+distance]; + let mut v = a[j + distance]; v.mul_assign(&s); let mut tmp = u; tmp.sub_assign(&v); - a[j+distance] = tmp; + a[j + distance] = tmp; a[j].add_assign(&v); } } @@ -511,19 +466,18 @@ pub(crate) fn parallel_ct_ntt>( // } } - #[cfg(test)] mod test { #[test] fn test_bit_reversed_omegas_computation() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use crate::plonk::transparent_engine::proth::Fr; + use super::BitReversedOmegas; + use super::CTPrecomputations; + use crate::plonk::commitments::transparent::utils::*; use crate::plonk::polynomials::*; - use std::time::Instant; + use crate::plonk::transparent_engine::proth::Fr; use crate::worker::*; - use crate::plonk::commitments::transparent::utils::*; - use super::CTPrecomputations; - use super::BitReversedOmegas; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; // let poly_sizes = vec![1_000_000, 2_000_000, 4_000_000]; @@ -539,17 +493,17 @@ mod test { #[test] fn test_bench_ct_serial_fft() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use crate::plonk::transparent_engine::proth::Fr; - use crate::plonk::polynomials::*; - use std::time::Instant; + use super::BitReversedOmegas; + use super::CTPrecomputations; use super::*; - use crate::worker::*; use crate::plonk::commitments::transparent::utils::*; - use crate::plonk::fft::fft::serial_fft; - use super::CTPrecomputations; - use super::BitReversedOmegas; use crate::plonk::domains::Domain; + use crate::plonk::fft::fft::serial_fft; + use crate::plonk::polynomials::*; + use crate::plonk::transparent_engine::proth::Fr; + use crate::worker::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; let poly_sizes = vec![1_000_000, 2_000_000, 4_000_000]; @@ -635,17 +589,17 @@ mod test { #[test] fn test_bench_ct_parallel_fft() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use crate::plonk::transparent_engine::proth::Fr; - use crate::plonk::polynomials::*; - use std::time::Instant; + use super::BitReversedOmegas; + use super::CTPrecomputations; use super::*; - use crate::worker::*; use crate::plonk::commitments::transparent::utils::*; - use crate::plonk::fft::fft::parallel_fft; - use super::CTPrecomputations; - use super::BitReversedOmegas; use crate::plonk::domains::Domain; + use crate::plonk::fft::fft::parallel_fft; + use crate::plonk::polynomials::*; + use crate::plonk::transparent_engine::proth::Fr; + use crate::worker::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; let poly_sizes = vec![1_000_000, 2_000_000, 4_000_000]; @@ -694,9 +648,3 @@ mod test { } } } - - - - - - diff --git a/crates/bellman/src/plonk/fft/cooley_tukey_ntt/partial_reduction.rs b/crates/bellman/src/plonk/fft/cooley_tukey_ntt/partial_reduction.rs index 64aa3f5..b0d8fb8 100644 --- a/crates/bellman/src/plonk/fft/cooley_tukey_ntt/partial_reduction.rs +++ b/crates/bellman/src/plonk/fft/cooley_tukey_ntt/partial_reduction.rs @@ -1,26 +1,15 @@ use crate::pairing::ff::PrimeField; -use crate::worker::*; use crate::plonk::domains::*; use crate::plonk::transparent_engine::PartialTwoBitReductionField; +use crate::worker::*; -use super::CTPrecomputations; use super::log2_floor; +use super::CTPrecomputations; -pub(crate) fn best_ct_ntt_partial_reduction>( - a: &mut [F], - worker: &Worker, - log_n: u32, - use_cpus_hint: Option, - precomputed_omegas: &P -) -{ +pub(crate) fn best_ct_ntt_partial_reduction>(a: &mut [F], worker: &Worker, log_n: u32, use_cpus_hint: Option, precomputed_omegas: &P) { let log_cpus = if let Some(hint) = use_cpus_hint { assert!(hint <= worker.cpus); - let hint = if hint > 0 { - log2_floor(hint) - } else { - 0 - }; + let hint = if hint > 0 { log2_floor(hint) } else { 0 }; hint } else { @@ -34,14 +23,9 @@ pub(crate) fn best_ct_ntt_partial_reduction>( - a: &mut [F], - log_n: u32, - precomputed_omegas: &P -) -{ +pub(crate) fn serial_ct_ntt_partial_reduction>(a: &mut [F], log_n: u32, precomputed_omegas: &P) { assert_eq!(a.len(), precomputed_omegas.domain_size(), "precomputation size is invalid for ntt"); - assert_eq!(a.len(), (1<= 2); let n = a.len(); @@ -64,16 +48,16 @@ pub(crate) fn serial_ct_ntt_partial_reduction>( - a: &mut [F], - worker: &Worker, - log_n: u32, - log_cpus: u32, - precomputed_omegas: &P -) -{ +pub(crate) fn parallel_ct_ntt_partial_reduction>(a: &mut [F], worker: &Worker, log_n: u32, log_cpus: u32, precomputed_omegas: &P) { assert!(log_n >= log_cpus); assert_eq!(a.len(), precomputed_omegas.domain_size(), "precomputation size is invalid for ntt"); assert!(64 - (F::NUM_BITS % 64) >= 2); @@ -203,7 +180,7 @@ pub(crate) fn parallel_ct_ntt_partial_reduction(one: &[F], two: &[F]) -> (bool, Vec) { @@ -615,7 +566,7 @@ mod test { let ntt_time = (elapsed2 + elapsed5).div_f32(2.); let diff_pr = ntt_time.checked_sub(elapsed3); if let Some(diff) = diff_pr { - println!("Partial reduction: speed up is {}%.", diff.as_nanos()*100/ntt_time.as_nanos()); + println!("Partial reduction: speed up is {}%.", diff.as_nanos() * 100 / ntt_time.as_nanos()); } else { println!("Partial reduction: no speed up."); } @@ -628,17 +579,17 @@ mod test { #[test] fn test_bench_ct_parallel_fft() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use crate::plonk::transparent_engine::proth::Fr; - use crate::plonk::polynomials::*; - use std::time::Instant; + use super::super::BitReversedOmegas; + use super::CTPrecomputations; use super::*; - use crate::worker::*; use crate::plonk::commitments::transparent::utils::*; - use crate::plonk::fft::fft::parallel_fft; - use super::CTPrecomputations; - use super::super::BitReversedOmegas; use crate::plonk::domains::Domain; + use crate::plonk::fft::fft::parallel_fft; + use crate::plonk::polynomials::*; + use crate::plonk::transparent_engine::proth::Fr; + use crate::worker::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; let poly_sizes = if cfg!(debug_assertions) { vec![10_000] @@ -710,7 +661,7 @@ mod test { let ntt_time = elapsed2; let diff_pr = ntt_time.checked_sub(elapsed3); if let Some(diff) = diff_pr { - println!("Partial reduction: speed up is {}%.", diff.as_nanos()*100/ntt_time.as_nanos()); + println!("Partial reduction: speed up is {}%.", diff.as_nanos() * 100 / ntt_time.as_nanos()); } else { println!("Partial reduction: no speed up."); } diff --git a/crates/bellman/src/plonk/fft/fft.rs b/crates/bellman/src/plonk/fft/fft.rs index 71cd9db..fa830fb 100644 --- a/crates/bellman/src/plonk/fft/fft.rs +++ b/crates/bellman/src/plonk/fft/fft.rs @@ -6,22 +6,17 @@ fn log2_floor(num: usize) -> u32 { let mut pow = 0; - while (1 << (pow+1)) <= num { + while (1 << (pow + 1)) <= num { pow += 1; } pow } -pub(crate) fn best_fft(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, use_cpus_hint: Option) -{ +pub(crate) fn best_fft(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, use_cpus_hint: Option) { let log_cpus = if let Some(hint) = use_cpus_hint { assert!(hint <= worker.cpus); - let hint = if hint > 0 { - log2_floor(hint) - } else { - 0 - }; + let hint = if hint > 0 { log2_floor(hint) } else { 0 }; hint } else { @@ -35,8 +30,7 @@ pub(crate) fn best_fft(a: &mut [F], worker: &Worker, omega: &F, l } } -pub(crate) fn serial_fft(a: &mut [F], omega: &F, log_n: u32) -{ +pub(crate) fn serial_fft(a: &mut [F], omega: &F, log_n: u32) { #[inline(always)] fn bitreverse(mut n: u32, l: u32) -> u32 { let mut r = 0; @@ -59,36 +53,29 @@ pub(crate) fn serial_fft(a: &mut [F], omega: &F, log_n: u32) let mut m = 1; for _ in 0..log_n { - let w_m = omega.pow(&[(n / (2*m)) as u64]); + let w_m = omega.pow(&[(n / (2 * m)) as u64]); let mut k = 0; while k < n { let mut w = F::one(); for j in 0..m { - let mut t = a[(k+j+m) as usize]; + let mut t = a[(k + j + m) as usize]; t.mul_assign(&w); - let mut tmp = a[(k+j) as usize]; + let mut tmp = a[(k + j) as usize]; tmp.sub_assign(&t); - a[(k+j+m) as usize] = tmp; - a[(k+j) as usize].add_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); w.mul_assign(&w_m); } - k += 2*m; + k += 2 * m; } - + m *= 2; } } -pub(crate) fn parallel_fft( - a: &mut [F], - worker: &Worker, - omega: &F, - log_n: u32, - log_cpus: u32 -) -{ +pub(crate) fn parallel_fft(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, log_cpus: u32) { assert!(log_n >= log_cpus); let num_cpus = 1 << log_cpus; @@ -138,4 +125,4 @@ pub(crate) fn parallel_fft( }); } }); -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/fft/lde.rs b/crates/bellman/src/plonk/fft/lde.rs index d75401d..6bd9e4a 100644 --- a/crates/bellman/src/plonk/fft/lde.rs +++ b/crates/bellman/src/plonk/fft/lde.rs @@ -1,8 +1,7 @@ use crate::pairing::ff::PrimeField; use crate::worker::*; -pub(crate) fn best_lde(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, lde_factor: usize) -{ +pub(crate) fn best_lde(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, lde_factor: usize) { let log_cpus = worker.log_num_cpus(); if log_n <= log_cpus { @@ -12,8 +11,7 @@ pub(crate) fn best_lde(a: &mut [F], worker: &Worker, omega: &F, l } } -pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_factor: usize) -{ +pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_factor: usize) { #[inline(always)] fn bitreverse(mut n: u32, l: u32) -> u32 { let mut r = 0; @@ -36,7 +34,7 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ if f <= 1 { return true; } - + false } @@ -56,30 +54,30 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ let mut step = 0; for _ in 0..log_n { - let w_m = omega.pow(&[(n / (2*m)) as u64]); + let w_m = omega.pow(&[(n / (2 * m)) as u64]); - let step_by = 2*m as usize; - if is_dense_round(lde_factor, step) { + let step_by = 2 * m as usize; + if is_dense_round(lde_factor, step) { // standard fft for k in (0..n).step_by(step_by) { let mut w = F::one(); for j in 0..m { - let mut t = a[(k+j+m) as usize]; + let mut t = a[(k + j + m) as usize]; t.mul_assign(&w); - let mut tmp = a[(k+j) as usize]; + let mut tmp = a[(k + j) as usize]; tmp.sub_assign(&t); - a[(k+j+m) as usize] = tmp; - a[(k+j) as usize].add_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); w.mul_assign(&w_m); - } + } } } else { // have some pain trying to save on memory reads and multiplications for k in (0..n).step_by(step_by) { let mut w = F::one(); for j in 0..m { - let odd_idx = (k+j+m) as usize; - let even_idx = (k+j) as usize; + let odd_idx = (k + j + m) as usize; + let even_idx = (k + j) as usize; let odd_is_non_zero = is_non_zero(odd_idx, lde_factor, step); let even_is_non_zero = is_non_zero(even_idx, lde_factor, step); @@ -97,22 +95,21 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ a[odd_idx] = tmp; a[even_idx].add_assign(&t); - }, + } (false, true) => { a[odd_idx] = a[even_idx]; - }, + } (true, false) => { let mut t = a[odd_idx]; t.mul_assign(&w); let mut tmp = t; tmp.negate(); - + a[odd_idx] = tmp; a[even_idx] = t; - }, - (false, false) => { } + (false, false) => {} } w.mul_assign(&w_m); @@ -125,15 +122,7 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ } } -pub(crate) fn parallel_lde( - a: &mut [F], - worker: &Worker, - omega: &F, - log_n: u32, - log_cpus: u32, - lde_factor: usize -) -{ +pub(crate) fn parallel_lde(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, log_cpus: u32, lde_factor: usize) { assert!(log_n >= log_cpus); let num_cpus = 1 << log_cpus; @@ -354,4 +343,3 @@ pub(crate) fn parallel_lde( // assert!(naive_lde.into_coeffs() == lde); // } - diff --git a/crates/bellman/src/plonk/fft/mod.rs b/crates/bellman/src/plonk/fft/mod.rs index b18492b..3f8c03b 100644 --- a/crates/bellman/src/plonk/fft/mod.rs +++ b/crates/bellman/src/plonk/fft/mod.rs @@ -1,17 +1,17 @@ +pub mod cooley_tukey_ntt; pub(crate) mod fft; pub(crate) mod lde; pub(crate) mod radix_4; pub(crate) mod with_precomputation; -pub mod cooley_tukey_ntt; use cfg_if; #[cfg(feature = "nightly")] -mod prefetch_lde; +mod prefetch; #[cfg(feature = "nightly")] mod prefetch_fft; #[cfg(feature = "nightly")] -mod prefetch; +mod prefetch_lde; use crate::pairing::ff::PrimeField; use crate::worker::Worker; @@ -45,11 +45,10 @@ cfg_if! { pub(crate) fn serial_fft(a: &mut [F], omega: &F, log_n: u32) { self::fft::serial_fft(a, omega, log_n) } - } + } } -pub fn distribute_powers(coeffs: &mut [F], worker: &Worker, g: F) -{ +pub fn distribute_powers(coeffs: &mut [F], worker: &Worker, g: F) { worker.scope(coeffs.len(), |scope, chunk| { for (i, v) in coeffs.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { @@ -63,8 +62,7 @@ pub fn distribute_powers(coeffs: &mut [F], worker: &Worker, g: F) }); } -pub fn distribute_powers_with_num_cpus(coeffs: &mut [F], worker: &Worker, g: F, cpus: usize) -{ +pub fn distribute_powers_with_num_cpus(coeffs: &mut [F], worker: &Worker, g: F, cpus: usize) { assert!(cpus > 0); let chunk = Worker::chunk_size_for_num_spawned_threads(coeffs.len(), cpus); worker.scope(0, |scope, _| { @@ -80,11 +78,10 @@ pub fn distribute_powers_with_num_cpus(coeffs: &mut [F], worker: }); } -pub fn distribute_powers_serial(coeffs: &mut [F], g: F) -{ +pub fn distribute_powers_serial(coeffs: &mut [F], g: F) { let mut u = F::one(); for v in coeffs.iter_mut() { v.mul_assign(&u); u.mul_assign(&g); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/fft/prefetch.rs b/crates/bellman/src/plonk/fft/prefetch.rs index c6a8e81..af3965f 100644 --- a/crates/bellman/src/plonk/fft/prefetch.rs +++ b/crates/bellman/src/plonk/fft/prefetch.rs @@ -14,4 +14,4 @@ pub(crate) fn prefetch_index_read(slice: &[T], idx: usize) { let p: *const T = &slice[idx]; // unsafe { std::intrinsics::prefetch_read_data(p, 2) }; prefetch::(p); -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/fft/prefetch_fft.rs b/crates/bellman/src/plonk/fft/prefetch_fft.rs index cf8a069..6751e79 100644 --- a/crates/bellman/src/plonk/fft/prefetch_fft.rs +++ b/crates/bellman/src/plonk/fft/prefetch_fft.rs @@ -1,21 +1,20 @@ +use super::prefetch::*; use crate::ff::PrimeField; use crate::worker::*; -use super::prefetch::*; fn log2_floor(num: usize) -> u32 { assert!(num > 0); let mut pow = 0; - while (1 << (pow+1)) <= num { + while (1 << (pow + 1)) <= num { pow += 1; } pow } -pub(crate) fn best_fft(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, use_cpus_hint: Option) -{ +pub(crate) fn best_fft(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, use_cpus_hint: Option) { let log_cpus = if let Some(hint) = use_cpus_hint { assert!(hint <= worker.cpus); log2_floor(hint) @@ -30,8 +29,7 @@ pub(crate) fn best_fft(a: &mut [F], worker: &Worker, omega: &F, l } } -pub(crate) fn serial_fft(a: &mut [F], omega: &F, log_n: u32) -{ +pub(crate) fn serial_fft(a: &mut [F], omega: &F, log_n: u32) { #[inline(always)] fn bitreverse(mut n: u32, l: u32) -> u32 { let mut r = 0; @@ -54,51 +52,44 @@ pub(crate) fn serial_fft(a: &mut [F], omega: &F, log_n: u32) let mut m = 1; for _ in 0..log_n { - let w_m = omega.pow(&[(n / (2*m)) as u64]); + let w_m = omega.pow(&[(n / (2 * m)) as u64]); - let step_by = 2*m as usize; + let step_by = 2 * m as usize; for k in (0..n).step_by(step_by) { { prefetch_index::(a, (k + m) as usize); prefetch_index::(a, k as usize); } let mut w = F::one(); - for j in 0..(m-1) { + for j in 0..(m - 1) { { - prefetch_index::(a, (k+j+1+m) as usize); - prefetch_index::(a, (k+j+1) as usize); + prefetch_index::(a, (k + j + 1 + m) as usize); + prefetch_index::(a, (k + j + 1) as usize); } - let mut t = a[(k+j+m) as usize]; + let mut t = a[(k + j + m) as usize]; t.mul_assign(&w); - let mut tmp = a[(k+j) as usize]; + let mut tmp = a[(k + j) as usize]; tmp.sub_assign(&t); - a[(k+j+m) as usize] = tmp; - a[(k+j) as usize].add_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); w.mul_assign(&w_m); - } + } let j = m - 1; - let mut t = a[(k+j+m) as usize]; + let mut t = a[(k + j + m) as usize]; t.mul_assign(&w); - let mut tmp = a[(k+j) as usize]; + let mut tmp = a[(k + j) as usize]; tmp.sub_assign(&t); - a[(k+j+m) as usize] = tmp; - a[(k+j) as usize].add_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); w.mul_assign(&w_m); } - + m *= 2; } } -pub(crate) fn parallel_fft( - a: &mut [F], - worker: &Worker, - omega: &F, - log_n: u32, - log_cpus: u32 -) -{ +pub(crate) fn parallel_fft(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, log_cpus: u32) { assert!(log_n >= log_cpus); let num_cpus = 1 << log_cpus; @@ -147,4 +138,4 @@ pub(crate) fn parallel_fft( }); } }); -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/fft/prefetch_lde.rs b/crates/bellman/src/plonk/fft/prefetch_lde.rs index 659af1a..a79b420 100644 --- a/crates/bellman/src/plonk/fft/prefetch_lde.rs +++ b/crates/bellman/src/plonk/fft/prefetch_lde.rs @@ -1,21 +1,20 @@ +use super::prefetch::*; use crate::ff::PrimeField; use crate::worker::*; -use super::prefetch::*; fn log2_floor(num: usize) -> u32 { assert!(num > 0); let mut pow = 0; - while (1 << (pow+1)) <= num { + while (1 << (pow + 1)) <= num { pow += 1; } pow } -pub(crate) fn best_lde(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, lde_factor: usize) -{ +pub(crate) fn best_lde(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, lde_factor: usize) { let log_cpus = worker.log_num_cpus(); if log_n <= log_cpus { @@ -25,8 +24,7 @@ pub(crate) fn best_lde(a: &mut [F], worker: &Worker, omega: &F, l } } -pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_factor: usize) -{ +pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_factor: usize) { #[inline(always)] fn bitreverse(mut n: u32, l: u32) -> u32 { let mut r = 0; @@ -49,7 +47,7 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ if f <= 1 { return true; } - + false } @@ -73,10 +71,10 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ let mut step = 0; for _ in 0..log_n { - let w_m = omega.pow(&[(n / (2*m)) as u64]); + let w_m = omega.pow(&[(n / (2 * m)) as u64]); - let step_by = 2*m as usize; - if is_dense_round(lde_factor, step) { + let step_by = 2 * m as usize; + if is_dense_round(lde_factor, step) { // standard fft for k in (0..n).step_by(step_by) { { @@ -84,27 +82,27 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ prefetch_index::(a, k as usize); } let mut w = F::one(); - for j in 0..(m-1) { + for j in 0..(m - 1) { { - prefetch_index::(a, (k+j+1+m) as usize); - prefetch_index::(a, (k+j+1) as usize); + prefetch_index::(a, (k + j + 1 + m) as usize); + prefetch_index::(a, (k + j + 1) as usize); } - let mut t = a[(k+j+m) as usize]; + let mut t = a[(k + j + m) as usize]; t.mul_assign(&w); - let mut tmp = a[(k+j) as usize]; + let mut tmp = a[(k + j) as usize]; tmp.sub_assign(&t); - a[(k+j+m) as usize] = tmp; - a[(k+j) as usize].add_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); w.mul_assign(&w_m); - } + } let j = m - 1; - let mut t = a[(k+j+m) as usize]; + let mut t = a[(k + j + m) as usize]; t.mul_assign(&w); - let mut tmp = a[(k+j) as usize]; + let mut tmp = a[(k + j) as usize]; tmp.sub_assign(&t); - a[(k+j+m) as usize] = tmp; - a[(k+j) as usize].add_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); w.mul_assign(&w_m); } } else { @@ -119,11 +117,11 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ } } let mut w = F::one(); - for j in 0..(m-1) { - let odd_idx = (k+j+m) as usize; - let even_idx = (k+j) as usize; + for j in 0..(m - 1) { + let odd_idx = (k + j + m) as usize; + let even_idx = (k + j) as usize; { - if is_non_zero(even_idx+1, lde_factor, step) || is_non_zero(odd_idx+1, lde_factor, step) { + if is_non_zero(even_idx + 1, lde_factor, step) || is_non_zero(odd_idx + 1, lde_factor, step) { prefetch_index::(a, odd_idx + 1); prefetch_index::(a, even_idx + 1); } @@ -145,31 +143,30 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ a[odd_idx] = tmp; a[even_idx].add_assign(&t); - }, + } (false, true) => { a[odd_idx] = a[even_idx]; - }, + } (true, false) => { let mut t = a[odd_idx]; t.mul_assign(&w); let mut tmp = t; tmp.negate(); - + a[odd_idx] = tmp; a[even_idx] = t; - }, - (false, false) => { } + (false, false) => {} } w.mul_assign(&w_m); } - let j = m-1; + let j = m - 1; - let odd_idx = (k+j+m) as usize; - let even_idx = (k+j) as usize; + let odd_idx = (k + j + m) as usize; + let even_idx = (k + j) as usize; let odd_is_non_zero = is_non_zero(odd_idx, lde_factor, step); let even_is_non_zero = is_non_zero(even_idx, lde_factor, step); @@ -187,22 +184,21 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ a[odd_idx] = tmp; a[even_idx].add_assign(&t); - }, + } (false, true) => { a[odd_idx] = a[even_idx]; - }, + } (true, false) => { let mut t = a[odd_idx]; t.mul_assign(&w); let mut tmp = t; tmp.negate(); - + a[odd_idx] = tmp; a[even_idx] = t; - }, - (false, false) => { } + (false, false) => {} } w.mul_assign(&w_m); @@ -214,15 +210,7 @@ pub(crate) fn serial_lde(a: &mut [F], omega: &F, log_n: u32, lde_ } } -pub(crate) fn parallel_lde( - a: &mut [F], - worker: &Worker, - omega: &F, - log_n: u32, - log_cpus: u32, - lde_factor: usize -) -{ +pub(crate) fn parallel_lde(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, log_cpus: u32, lde_factor: usize) { assert!(log_n >= log_cpus); let num_cpus = 1 << log_cpus; @@ -441,7 +429,5 @@ pub(crate) fn parallel_lde( // best_lde(&mut lde, &worker, &omega, log_n, LDE_FACTOR); // println!("LDE taken {}ms", now.elapsed().as_millis()); - // assert!(naive_lde.into_coeffs() == lde); // } - diff --git a/crates/bellman/src/plonk/fft/radix_4/mod.rs b/crates/bellman/src/plonk/fft/radix_4/mod.rs index b043a14..d12ec50 100644 --- a/crates/bellman/src/plonk/fft/radix_4/mod.rs +++ b/crates/bellman/src/plonk/fft/radix_4/mod.rs @@ -1,12 +1,10 @@ use crate::ff::PrimeField; use crate::worker::*; -pub(crate) fn best_fft(a: &mut [F], worker: &Worker, omega: &F, log_n: u32) -{ +pub(crate) fn best_fft(a: &mut [F], worker: &Worker, omega: &F, log_n: u32) { assert!(log_n % 2 == 0); // TODO: For now let mut log_cpus = worker.log_num_cpus(); - if log_cpus % 2 != 0 - { + if log_cpus % 2 != 0 { log_cpus -= 1; } @@ -30,19 +28,16 @@ fn base_4_digit_reverse(mut n: u64, l: u64) -> u64 { } #[inline(always)] -fn bitreverse(mut n: u64, l: u64) -> u64 -{ +fn bitreverse(mut n: u64, l: u64) -> u64 { let mut r = 0; - for _ in 0..l - { + for _ in 0..l { r = (r << 1) | (n & 1); n >>= 1; } r } -pub(crate) fn serial_fft_radix_4(a: &mut [F], omega: &F, log_n: u32) -{ +pub(crate) fn serial_fft_radix_4(a: &mut [F], omega: &F, log_n: u32) { let n = a.len() as u64; assert_eq!(n, 1 << log_n); @@ -61,13 +56,12 @@ pub(crate) fn serial_fft_radix_4(a: &mut [F], omega: &F, log_n: u let mut m = 1; for _ in 0..(log_n / 2) { - let w_m = omega.pow(&[(n / (4*m)) as u64]); + let w_m = omega.pow(&[(n / (4 * m)) as u64]); let mut k = 0; while k < n { let mut w = F::one(); for j in 0..m { - // y_0 = x_0 + x_1 + x_2 + x_3 // y_1 = x_0 + W_4 * x_1 - x_2 - W_4 * x_3 // y_2 = x_0 - x_1 + x_2 - x3 @@ -75,16 +69,16 @@ pub(crate) fn serial_fft_radix_4(a: &mut [F], omega: &F, log_n: u let mut u = w; - let x0 = a[(k+j) as usize]; + let x0 = a[(k + j) as usize]; - let mut x1 = a[(k+j+m) as usize]; + let mut x1 = a[(k + j + m) as usize]; x1.mul_assign(&w); - let mut x2 = a[(k+j+2*m) as usize]; + let mut x2 = a[(k + j + 2 * m) as usize]; u.mul_assign(&w); x2.mul_assign(&u); - let mut x3 = a[(k+j+3*m) as usize]; + let mut x3 = a[(k + j + 3 * m) as usize]; u.mul_assign(&w); x3.mul_assign(&u); @@ -94,10 +88,10 @@ pub(crate) fn serial_fft_radix_4(a: &mut [F], omega: &F, log_n: u let mut x1_plus_x3 = x1; x1_plus_x3.add_assign(&x3); - a[(k+j) as usize] = x0_plus_x2; - a[(k+j) as usize].add_assign(&x1_plus_x3); - a[(k+j+2*m) as usize] = x0_plus_x2; - a[(k+j+2*m) as usize].sub_assign(&x1_plus_x3); + a[(k + j) as usize] = x0_plus_x2; + a[(k + j) as usize].add_assign(&x1_plus_x3); + a[(k + j + 2 * m) as usize] = x0_plus_x2; + a[(k + j + 2 * m) as usize].sub_assign(&x1_plus_x3); let mut x0_minus_x2 = x0; x0_minus_x2.sub_assign(&x2); @@ -106,35 +100,28 @@ pub(crate) fn serial_fft_radix_4(a: &mut [F], omega: &F, log_n: u x1_minus_x3_by_w4.sub_assign(&x3); x1_minus_x3_by_w4.mul_assign(&v); - a[(k+j+m) as usize] = x0_minus_x2; - a[(k+j+m) as usize].add_assign(&x1_minus_x3_by_w4); - a[(k+j+3*m) as usize] = x0_minus_x2; - a[(k+j+3*m) as usize].sub_assign(&x1_minus_x3_by_w4); + a[(k + j + m) as usize] = x0_minus_x2; + a[(k + j + m) as usize].add_assign(&x1_minus_x3_by_w4); + a[(k + j + 3 * m) as usize] = x0_minus_x2; + a[(k + j + 3 * m) as usize].sub_assign(&x1_minus_x3_by_w4); w.mul_assign(&w_m); } - k += 4*m; + k += 4 * m; } m *= 4; } } -pub(crate) fn parallel_fft_radix_4( - a: &mut [F], - worker: &Worker, - omega: &F, - log_n: u32, - log_cpus: u32 -) -{ +pub(crate) fn parallel_fft_radix_4(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, log_cpus: u32) { assert!(log_n >= log_cpus); - + //we need log_n and log_cpu to be even assert!(log_n % 2 == 0); assert!(log_cpus % 2 == 0); - + let num_cpus = 1 << log_cpus; let log_new_n = log_n - log_cpus; let mut tmp = vec![vec![F::zero(); 1 << log_new_n]; num_cpus]; @@ -181,4 +168,4 @@ pub(crate) fn parallel_fft_radix_4( }); } }); -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/fft/with_precomputation/fft.rs b/crates/bellman/src/plonk/fft/with_precomputation/fft.rs index e6fd1ef..ce4bfcb 100644 --- a/crates/bellman/src/plonk/fft/with_precomputation/fft.rs +++ b/crates/bellman/src/plonk/fft/with_precomputation/fft.rs @@ -1,28 +1,20 @@ +use super::FftPrecomputations; use crate::pairing::ff::PrimeField; use crate::worker::*; -use super::FftPrecomputations; fn log2_floor(num: usize) -> u32 { assert!(num > 0); let mut pow = 0; - while (1 << (pow+1)) <= num { + while (1 << (pow + 1)) <= num { pow += 1; } pow } -pub(crate) fn best_fft>( - a: &mut [F], - worker: &Worker, - omega: &F, - log_n: u32, - use_cpus_hint: Option, - precomputed_omegas: &P -) -{ +pub(crate) fn best_fft>(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, use_cpus_hint: Option, precomputed_omegas: &P) { let log_cpus = if let Some(hint) = use_cpus_hint { assert!(hint <= worker.cpus); log2_floor(hint) @@ -37,8 +29,7 @@ pub(crate) fn best_fft>( } } -pub(crate) fn serial_fft>(a: &mut [F], omega: &F, log_n: u32, stride: usize, precomputed_omegas: &P) -{ +pub(crate) fn serial_fft>(a: &mut [F], omega: &F, log_n: u32, stride: usize, precomputed_omegas: &P) { #[inline(always)] fn bitreverse(mut n: u32, l: u32) -> u32 { let mut r = 0; @@ -66,7 +57,7 @@ pub(crate) fn serial_fft>(a: &mut [F], o let mut m = 1; for _ in 0..log_n { - let stride_idx = ((n / (2*m)) as usize) * stride; + let stride_idx = ((n / (2 * m)) as usize) * stride; // let w_m = omega.pow(&[(n / (2*m)) as u64]); let mut k = 0; @@ -74,35 +65,26 @@ pub(crate) fn serial_fft>(a: &mut [F], o let mut idx = 0; // let mut w = F::one(); for j in 0..m { - - let mut t = a[(k+j+m) as usize]; + let mut t = a[(k + j + m) as usize]; t.mul_assign(precomputed_omegas.element_for_index(idx)); // t.mul_assign(&w); - let mut tmp = a[(k+j) as usize]; + let mut tmp = a[(k + j) as usize]; tmp.sub_assign(&t); - a[(k+j+m) as usize] = tmp; - a[(k+j) as usize].add_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); // precomputations save one multiplication here per loop idx += stride_idx; // w.mul_assign(&w_m); } - k += 2*m; + k += 2 * m; } - + m *= 2; } } -pub(crate) fn parallel_fft>( - a: &mut [F], - worker: &Worker, - omega: &F, - log_n: u32, - log_cpus: u32, - precomputed_omegas: &P -) -{ +pub(crate) fn parallel_fft>(a: &mut [F], worker: &Worker, omega: &F, log_n: u32, log_cpus: u32, precomputed_omegas: &P) { assert!(log_n >= log_cpus); assert_eq!(a.len(), precomputed_omegas.domain_size()); @@ -153,4 +135,4 @@ pub(crate) fn parallel_fft>( }); } }); -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/fft/with_precomputation/mod.rs b/crates/bellman/src/plonk/fft/with_precomputation/mod.rs index 4b744a5..8e0380e 100644 --- a/crates/bellman/src/plonk/fft/with_precomputation/mod.rs +++ b/crates/bellman/src/plonk/fft/with_precomputation/mod.rs @@ -6,4 +6,4 @@ pub trait FftPrecomputations: Send + Sync { fn domain_size(&self) -> usize; } -pub(crate) mod fft; \ No newline at end of file +pub(crate) mod fft; diff --git a/crates/bellman/src/plonk/generator/mod.rs b/crates/bellman/src/plonk/generator/mod.rs index 8705081..0efdee0 100644 --- a/crates/bellman/src/plonk/generator/mod.rs +++ b/crates/bellman/src/plonk/generator/mod.rs @@ -1,17 +1,17 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use crate::plonk::cs::gates::*; use crate::plonk::cs::*; -use crate::worker::*; -use super::polynomials::*; use super::domains::*; +use super::polynomials::*; use crate::plonk::commitments::*; use crate::plonk::utils::*; +use crate::worker::*; #[derive(Debug)] struct GeneratorAssembly { @@ -32,7 +32,7 @@ impl ConstraintSystem for GeneratorAssembly { // allocate a variable fn alloc(&mut self, _value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { self.num_aux += 1; let index = self.num_aux; @@ -43,7 +43,7 @@ impl ConstraintSystem for GeneratorAssembly { // allocate an input variable fn alloc_input(&mut self, _value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { self.num_inputs += 1; let index = self.num_inputs; @@ -54,7 +54,6 @@ impl ConstraintSystem for GeneratorAssembly { self.input_gates.push(gate); Ok(input_var) - } // enforce variable as boolean @@ -67,9 +66,7 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate an abstract gate - fn new_gate(&mut self, variables: (Variable, Variable, Variable), - coeffs:(E::Fr,E::Fr,E::Fr,E::Fr,E::Fr)) -> Result<(), SynthesisError> - { + fn new_gate(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; @@ -78,8 +75,7 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate a constant - fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> - { + fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_constant_gate(variable, Some(constant), self.dummy_variable()); self.aux_gates.push(gate); self.n += 1; @@ -111,8 +107,7 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate a linear combination gate - fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs:(E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs: (E::Fr, E::Fr)) -> Result<(), SynthesisError> { let (v_0, v_1) = variables; let (c_0, c_1) = coeffs; let zero = E::Fr::zero(); @@ -125,14 +120,12 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate a linear combination gate - fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs:(E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_zero_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; Ok(()) - } fn get_dummy_variable(&self) -> Variable { @@ -151,7 +144,7 @@ impl GeneratorAssembly { } fn set_gate(&mut self, gate: Gate, index: usize) { - self.aux_gates[index-1] = gate; + self.aux_gates[index - 1] = gate; } pub(crate) fn new() -> Self { @@ -167,15 +160,14 @@ impl GeneratorAssembly { inputs_map: vec![], is_finalized: false, - }; let zero = tmp.alloc(|| Ok(E::Fr::zero())).expect("should have no issues"); tmp.enforce_constant(zero, E::Fr::zero()).expect("should have no issues"); match (tmp.dummy_variable(), zero) { - (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {}, - _ => panic!("zero variable is incorrect") + (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {} + _ => panic!("zero variable is incorrect"), } tmp @@ -186,10 +178,19 @@ impl GeneratorAssembly { Variable(Index::Aux(1)) } - pub(crate) fn make_circuit_description_polynomials(&self, worker: &Worker) -> Result<( - Polynomial::, Polynomial::, Polynomial::, - Polynomial::, Polynomial:: - ), SynthesisError> { + pub(crate) fn make_circuit_description_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, + Polynomial, + Polynomial, + Polynomial, + Polynomial, + ), + SynthesisError, + > { assert!(self.is_finalized); let total_num_gates = self.input_gates.len() + self.aux_gates.len(); let mut q_l = vec![E::Fr::zero(); total_num_gates]; @@ -198,33 +199,29 @@ impl GeneratorAssembly { let mut q_m = vec![E::Fr::zero(); total_num_gates]; let mut q_c = vec![E::Fr::zero(); total_num_gates]; - fn coeff_into_field_element(coeff: & Coeff) -> F { + fn coeff_into_field_element(coeff: &Coeff) -> F { match coeff { - Coeff::Zero => { - F::zero() - }, - Coeff::One => { - F::one() - }, + Coeff::Zero => F::zero(), + Coeff::One => F::one(), Coeff::NegativeOne => { let mut tmp = F::one(); tmp.negate(); tmp - }, - Coeff::Full(c) => { - *c - }, + } + Coeff::Full(c) => *c, } } // expect a small number of inputs - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.input_gates.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .input_gates + .iter() + .zip(q_l.iter_mut()) + .zip(q_r.iter_mut()) + .zip(q_o.iter_mut()) + .zip(q_m.iter_mut()) + .zip(q_c.iter_mut()) { *q_l = coeff_into_field_element(&gate.q_l); *q_r = coeff_into_field_element(&gate.q_r); @@ -233,7 +230,6 @@ impl GeneratorAssembly { *q_c = coeff_into_field_element(&gate.q_c); } - let num_input_gates = self.input_gates.len(); let q_l_aux = &mut q_l[num_input_gates..]; let q_r_aux = &mut q_r[num_input_gates..]; @@ -244,27 +240,23 @@ impl GeneratorAssembly { debug_assert!(self.aux_gates.len() == q_l_aux.len()); worker.scope(self.aux_gates.len(), |scope, chunk| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.aux_gates.chunks(chunk) - .zip(q_l_aux.chunks_mut(chunk)) - .zip(q_r_aux.chunks_mut(chunk)) - .zip(q_o_aux.chunks_mut(chunk)) - .zip(q_m_aux.chunks_mut(chunk)) - .zip(q_c_aux.chunks_mut(chunk)) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .aux_gates + .chunks(chunk) + .zip(q_l_aux.chunks_mut(chunk)) + .zip(q_r_aux.chunks_mut(chunk)) + .zip(q_o_aux.chunks_mut(chunk)) + .zip(q_m_aux.chunks_mut(chunk)) + .zip(q_c_aux.chunks_mut(chunk)) { scope.spawn(move |_| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) - { - *q_l = coeff_into_field_element(&gate.q_l); - *q_r = coeff_into_field_element(&gate.q_r); - *q_o = coeff_into_field_element(&gate.q_o); - *q_m = coeff_into_field_element(&gate.q_m); - *q_c = coeff_into_field_element(&gate.q_c); - } + for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter().zip(q_l.iter_mut()).zip(q_r.iter_mut()).zip(q_o.iter_mut()).zip(q_m.iter_mut()).zip(q_c.iter_mut()) { + *q_l = coeff_into_field_element(&gate.q_l); + *q_r = coeff_into_field_element(&gate.q_r); + *q_o = coeff_into_field_element(&gate.q_o); + *q_m = coeff_into_field_element(&gate.q_m); + *q_c = coeff_into_field_element(&gate.q_c); + } }); } }); @@ -287,51 +279,50 @@ impl GeneratorAssembly { // in the partition number i there is a set of indexes in V = (a, b, c) such that V_j = i let mut partitions = vec![vec![]; num_partitions + 1]; - for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { match gate.a_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j+1); - }, + partitions[i].push(j + 1); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j+1); + partitions[i].push(j + 1); } - }, + } } match gate.b_wire() { Variable(Index::Input(index)) => { let i = *index; partitions[i].push(j + 1 + num_gates); - }, + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; partitions[i].push(j + 1 + num_gates); } - }, + } } match gate.c_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j + 1 + 2*num_gates); - }, + partitions[i].push(j + 1 + 2 * num_gates); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j + 1 + 2*num_gates); + partitions[i].push(j + 1 + 2 * num_gates); } - }, + } } } let mut sigma_1: Vec<_> = (1..=num_gates).collect(); - let mut sigma_2: Vec<_> = ((num_gates+1)..=(2*num_gates)).collect(); - let mut sigma_3: Vec<_> = ((2*num_gates + 1)..=(3*num_gates)).collect(); + let mut sigma_2: Vec<_> = ((num_gates + 1)..=(2 * num_gates)).collect(); + let mut sigma_3: Vec<_> = ((2 * num_gates + 1)..=(3 * num_gates)).collect(); let mut permutations = vec![vec![]; num_partitions + 1]; @@ -350,18 +341,16 @@ impl GeneratorAssembly { let permutation = rotate(partition.clone()); permutations[i] = permutation.clone(); - for (original, new) in partition.into_iter() - .zip(permutation.into_iter()) - { + for (original, new) in partition.into_iter().zip(permutation.into_iter()) { if original <= num_gates { debug_assert!(sigma_1[original - 1] == original); sigma_1[original - 1] = new; - } else if original <= 2*num_gates { + } else if original <= 2 * num_gates { debug_assert!(sigma_2[original - num_gates - 1] == original); sigma_2[original - num_gates - 1] = new; } else { - debug_assert!(sigma_3[original - 2*num_gates - 1] == original); - sigma_3[original - 2*num_gates - 1] = new; + debug_assert!(sigma_3[original - 2 * num_gates - 1] == original); + sigma_3[original - 2 * num_gates - 1] = new; } } } @@ -378,19 +367,23 @@ impl GeneratorAssembly { result } - pub(crate) fn output_setup_polynomials(&self, worker: &Worker) -> Result< - ( - Polynomial::, // q_l - Polynomial::, // q_r - Polynomial::, // q_o - Polynomial::, // q_m - Polynomial::, // q_c - Polynomial::, // s_id - Polynomial::, // sigma_1 - Polynomial::, // sigma_2 - Polynomial::, // sigma_3 - ), SynthesisError> - { + pub(crate) fn output_setup_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, // q_l + Polynomial, // q_r + Polynomial, // q_o + Polynomial, // q_m + Polynomial, // q_c + Polynomial, // s_id + Polynomial, // sigma_1 + Polynomial, // sigma_2 + Polynomial, // sigma_3 + ), + SynthesisError, + > { assert!(self.is_finalized); let s_id = self.make_s_id(); @@ -431,13 +424,13 @@ impl GeneratorAssembly { return; } let n = self.input_gates.len() + self.aux_gates.len(); - if (n+1).is_power_of_two() { + if (n + 1).is_power_of_two() { return; } let empty_gate = Gate::::new_empty_gate(self.dummy_variable()); - let new_aux_len = (n+1).next_power_of_two() - 1 - self.input_gates.len(); + let new_aux_len = (n + 1).next_power_of_two() - 1 - self.input_gates.len(); self.aux_gates.resize(new_aux_len, empty_gate); @@ -446,7 +439,7 @@ impl GeneratorAssembly { } #[derive(Debug)] -pub struct PlonkSetup >{ +pub struct PlonkSetup> { pub n: usize, pub q_l: S::Commitment, pub q_r: S::Commitment, @@ -460,7 +453,7 @@ pub struct PlonkSetup >{ } #[derive(Debug)] -pub struct PlonkSetupAuxData >{ +pub struct PlonkSetupAuxData> { pub q_l_aux: Option, pub q_r_aux: Option, pub q_o_aux: Option, @@ -476,7 +469,7 @@ pub fn setup, C: Circuit>(circuit: &C, let mut assembly = GeneratorAssembly::::new(); circuit.synthesize(&mut assembly)?; assembly.finalize(); - + let n = assembly.num_gates(); let worker = Worker::new(); @@ -517,8 +510,8 @@ pub fn setup, C: Circuit>(circuit: &C, s_id_aux, sigma_1_aux, sigma_2_aux, - sigma_3_aux + sigma_3_aux, }; Ok((setup, aux)) -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/mod.rs b/crates/bellman/src/plonk/mod.rs index 352ad5f..1b2e2ea 100644 --- a/crates/bellman/src/plonk/mod.rs +++ b/crates/bellman/src/plonk/mod.rs @@ -1,14 +1,14 @@ pub mod adaptor; pub mod cs; +pub mod domains; +pub mod fft; pub mod generator; +pub mod polynomials; pub mod prover; -pub mod verifier; pub mod tester; -pub mod polynomials; -pub mod domains; -pub mod fft; -pub mod utils; pub mod transparent_engine; +pub mod utils; +pub mod verifier; pub mod redshift; @@ -20,16 +20,16 @@ pub mod better_cs; pub mod better_better_cs; -pub use self::better_cs::adaptor::{TranspilationVariant, Transpiler, Adaptor, AdaptorCircuit}; -pub use self::better_cs::keys::{SetupPolynomials, SetupPolynomialsPrecomputations, VerificationKey, Proof}; +pub use self::better_cs::adaptor::{Adaptor, AdaptorCircuit, TranspilationVariant, Transpiler}; +pub use self::better_cs::keys::{Proof, SetupPolynomials, SetupPolynomialsPrecomputations, VerificationKey}; -use crate::pairing::Engine; -use crate::{SynthesisError, Circuit}; -use crate::worker::Worker; +use self::better_cs::cs::{PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams}; use crate::kate_commitment::*; -use self::better_cs::cs::{PlonkCsWidth4WithNextStepParams, PlonkConstraintSystemParams}; +use crate::pairing::Engine; use crate::plonk::commitments::transcript::*; use crate::plonk::fft::cooley_tukey_ntt::*; +use crate::worker::Worker; +use crate::{Circuit, SynthesisError}; pub fn transpile>(circuit: C) -> Result, SynthesisError> { let mut transpiler = Transpiler::::new(); @@ -51,10 +51,7 @@ pub fn transpile_with_gates_count>(circuit: C) - Ok((n, hints)) } -pub fn is_satisfied>( - circuit: C, - hints: &Vec<(usize, TranspilationVariant)> -) -> Result<(), SynthesisError> { +pub fn is_satisfied>(circuit: C, hints: &Vec<(usize, TranspilationVariant)>) -> Result<(), SynthesisError> { use crate::plonk::better_cs::cs::Circuit; let adapted_curcuit = AdaptorCircuit::::new(circuit, &hints); @@ -64,10 +61,7 @@ pub fn is_satisfied>( adapted_curcuit.synthesize(&mut assembly) } -pub fn is_satisfied_using_one_shot_check>( - circuit: C, - hints: &Vec<(usize, TranspilationVariant)> -) -> Result<(), SynthesisError> { +pub fn is_satisfied_using_one_shot_check>(circuit: C, hints: &Vec<(usize, TranspilationVariant)>) -> Result<(), SynthesisError> { use crate::plonk::better_cs::cs::Circuit; let adapted_curcuit = AdaptorCircuit::::new(circuit, &hints); @@ -85,10 +79,7 @@ pub fn is_satisfied_using_one_shot_check>( } } -pub fn setup>( - circuit: C, - hints: &Vec<(usize, TranspilationVariant)> -) -> Result, SynthesisError> { +pub fn setup>(circuit: C, hints: &Vec<(usize, TranspilationVariant)>) -> Result, SynthesisError> { use crate::plonk::better_cs::cs::Circuit; let adapted_curcuit = AdaptorCircuit::::new(circuit, &hints); @@ -103,30 +94,18 @@ pub fn setup>( assembly.setup(&worker) } -pub fn make_verification_key>( - setup: &SetupPolynomials, - crs: &Crs -) -> Result, SynthesisError> { +pub fn make_verification_key>(setup: &SetupPolynomials, crs: &Crs) -> Result, SynthesisError> { let worker = Worker::new(); - let verification_key = VerificationKey::from_setup( - &setup, - &worker, - &crs - )?; + let verification_key = VerificationKey::from_setup(&setup, &worker, &crs)?; Ok(verification_key) } -pub fn make_precomputations>( - setup: &SetupPolynomials -) -> Result, SynthesisError> { +pub fn make_precomputations>(setup: &SetupPolynomials) -> Result, SynthesisError> { let worker = Worker::new(); - let precomputations = SetupPolynomialsPrecomputations::from_setup( - &setup, - &worker, - )?; + let precomputations = SetupPolynomialsPrecomputations::from_setup(&setup, &worker)?; Ok(precomputations) } @@ -136,10 +115,10 @@ pub fn prove_native_by_steps, setup_precomputations: Option<&SetupPolynomialsPrecomputations>, csr_mon_basis: &Crs, - transcript_init_params: Option< >:: InitializationParameters>, + transcript_init_params: Option<>::InitializationParameters>, ) -> Result, SynthesisError> { - use crate::plonk::better_cs::utils::{commit_point_as_xy}; - use crate::plonk::better_cs::prover::prove_steps::{FirstVerifierMessage, SecondVerifierMessage, ThirdVerifierMessage, FourthVerifierMessage}; + use crate::plonk::better_cs::prover::prove_steps::{FirstVerifierMessage, FourthVerifierMessage, SecondVerifierMessage, ThirdVerifierMessage}; + use crate::plonk::better_cs::utils::commit_point_as_xy; use std::time::Instant; @@ -156,24 +135,16 @@ pub fn prove_native_by_steps >::None; - let mut precomputed_omegas_inv = crate::plonk::better_cs::prover::prove_steps::PrecomputedOmegas::< E::Fr, OmegasInvBitreversed >::None; + let mut precomputed_omegas = crate::plonk::better_cs::prover::prove_steps::PrecomputedOmegas::>::None; + let mut precomputed_omegas_inv = crate::plonk::better_cs::prover::prove_steps::PrecomputedOmegas::>::None; let mut proof = Proof::::empty(); let subtime = Instant::now(); - let (first_state, first_message) = assembly.first_step_with_monomial_form_key( - &worker, - csr_mon_basis, - &mut precomputed_omegas_inv - )?; + let (first_state, first_message) = assembly.first_step_with_monomial_form_key(&worker, csr_mon_basis, &mut precomputed_omegas_inv)?; println!("First step (witness commitment) taken {:?}", subtime.elapsed()); @@ -196,21 +167,13 @@ pub fn prove_native_by_steps { beta, gamma, - - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; let subtime = Instant::now(); - let (second_state, second_message) = self::better_cs::prover::ProverAssembly::second_step_from_first_step( - first_state, - first_verifier_message, - &setup, - csr_mon_basis, - &setup_precomputations, - &mut precomputed_omegas_inv, - &worker - )?; + let (second_state, second_message) = + self::better_cs::prover::ProverAssembly::second_step_from_first_step(first_state, first_verifier_message, &setup, csr_mon_basis, &setup_precomputations, &mut precomputed_omegas_inv, &worker)?; println!("Second step (grand product commitment) taken {:?}", subtime.elapsed()); @@ -223,8 +186,7 @@ pub fn prove_native_by_steps, T: Transcript>( setup: &SetupPolynomials, setup_precomputations: Option<&SetupPolynomialsPrecomputations>, csr_mon_basis: &Crs, - transcript_init_params: Option< >:: InitializationParameters>, + transcript_init_params: Option<>::InitializationParameters>, ) -> Result, SynthesisError> { use crate::plonk::better_cs::cs::Circuit; - use crate::plonk::better_cs::utils::{commit_point_as_xy}; - use crate::plonk::better_cs::prover::prove_steps::{FirstVerifierMessage, SecondVerifierMessage, ThirdVerifierMessage, FourthVerifierMessage}; + use crate::plonk::better_cs::prover::prove_steps::{FirstVerifierMessage, FourthVerifierMessage, SecondVerifierMessage, ThirdVerifierMessage}; + use crate::plonk::better_cs::utils::commit_point_as_xy; let adapted_curcuit = AdaptorCircuit::::new(circuit, &hints); - prove_native_by_steps::<_, _, T>( - &adapted_curcuit, - setup, - setup_precomputations, - csr_mon_basis, - transcript_init_params - ) + prove_native_by_steps::<_, _, T>(&adapted_curcuit, setup, setup_precomputations, csr_mon_basis, transcript_init_params) } pub fn prove, T: Transcript>( @@ -353,7 +296,7 @@ pub fn prove, T: Transcript>( hints: &Vec<(usize, TranspilationVariant)>, setup: &SetupPolynomials, csr_mon_basis: &Crs, - crs_lagrange_basis: &Crs + crs_lagrange_basis: &Crs, ) -> Result, SynthesisError> { use crate::plonk::better_cs::cs::Circuit; @@ -372,7 +315,7 @@ pub fn prove, T: Transcript>( let worker = Worker::new(); let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); use std::time::Instant; let now = Instant::now(); @@ -392,14 +335,7 @@ pub fn prove, T: Transcript>( Ok(proof) } - -pub fn prove_from_recomputations< - E: Engine, - C: crate::Circuit, - T: Transcript, - CP: CTPrecomputations, - CPI: CTPrecomputations, ->( +pub fn prove_from_recomputations, T: Transcript, CP: CTPrecomputations, CPI: CTPrecomputations>( circuit: C, hints: &Vec<(usize, TranspilationVariant)>, setup: &SetupPolynomials, @@ -407,7 +343,7 @@ pub fn prove_from_recomputations< omegas_bitreversed: &CP, omegas_inv_bitreversed: &CPI, csr_mon_basis: &Crs, - crs_lagrange_basis: &Crs + crs_lagrange_basis: &Crs, ) -> Result, SynthesisError> { use crate::plonk::better_cs::cs::Circuit; @@ -445,7 +381,7 @@ pub fn prove_from_recomputations< pub fn verify>( proof: &Proof, - verification_key: &VerificationKey + verification_key: &VerificationKey, ) -> Result { self::better_cs::verifier::verify::(&proof, &verification_key, None) -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/plonk/generator.rs b/crates/bellman/src/plonk/plonk/generator.rs index 82014f8..fbf5e55 100644 --- a/crates/bellman/src/plonk/plonk/generator.rs +++ b/crates/bellman/src/plonk/plonk/generator.rs @@ -1,17 +1,17 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use crate::plonk::cs::gates::*; use crate::plonk::cs::*; -use crate::worker::*; -use crate::plonk::polynomials::*; -use crate::plonk::domains::*; use crate::plonk::commitments::*; +use crate::plonk::domains::*; +use crate::plonk::polynomials::*; use crate::plonk::utils::*; +use crate::worker::*; use super::prover::ProvingAssembly; @@ -37,7 +37,7 @@ impl ConstraintSystem for GeneratorAssembly { // allocate a variable fn alloc(&mut self, _value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { self.num_aux += 1; let index = self.num_aux; @@ -48,7 +48,7 @@ impl ConstraintSystem for GeneratorAssembly { // allocate an input variable fn alloc_input(&mut self, _value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { self.num_inputs += 1; let index = self.num_inputs; @@ -59,7 +59,6 @@ impl ConstraintSystem for GeneratorAssembly { self.input_gates.push(gate); Ok(input_var) - } // enforce variable as boolean @@ -72,9 +71,7 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate an abstract gate - fn new_gate(&mut self, variables: (Variable, Variable, Variable), - coeffs:(E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn new_gate(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; @@ -83,8 +80,7 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate a constant - fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> - { + fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_constant_gate(variable, Some(constant), self.dummy_variable()); self.aux_gates.push(gate); self.n += 1; @@ -116,8 +112,7 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate a linear combination gate - fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs:(E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs: (E::Fr, E::Fr)) -> Result<(), SynthesisError> { let (v_0, v_1) = variables; let (c_0, c_1) = coeffs; let zero = E::Fr::zero(); @@ -130,14 +125,12 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate a linear combination gate - fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs:(E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_zero_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; Ok(()) - } fn get_dummy_variable(&self) -> Variable { @@ -156,7 +149,7 @@ impl GeneratorAssembly { } fn set_gate(&mut self, gate: Gate, index: usize) { - self.aux_gates[index-1] = gate; + self.aux_gates[index - 1] = gate; } pub fn new() -> Self { @@ -172,7 +165,6 @@ impl GeneratorAssembly { inputs_map: vec![], is_finalized: false, - }; let zero = tmp.alloc(|| Ok(E::Fr::zero())).expect("should have no issues"); @@ -192,14 +184,13 @@ impl GeneratorAssembly { // } match (tmp.dummy_variable(), zero) { - (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {}, - _ => panic!("zero variable is incorrect") + (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {} + _ => panic!("zero variable is incorrect"), } assert_eq!(tmp.num_inputs, 0); assert_eq!(tmp.num_aux, 1); - tmp } @@ -209,10 +200,19 @@ impl GeneratorAssembly { Variable(Index::Aux(1)) } - pub(crate) fn make_circuit_description_polynomials(&self, worker: &Worker) -> Result<( - Polynomial::, Polynomial::, Polynomial::, - Polynomial::, Polynomial:: - ), SynthesisError> { + pub(crate) fn make_circuit_description_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, + Polynomial, + Polynomial, + Polynomial, + Polynomial, + ), + SynthesisError, + > { assert!(self.is_finalized); let total_num_gates = self.input_gates.len() + self.aux_gates.len(); let mut q_l = vec![E::Fr::zero(); total_num_gates]; @@ -223,31 +223,27 @@ impl GeneratorAssembly { fn coeff_into_field_element(coeff: &Coeff) -> F { match coeff { - Coeff::Zero => { - F::zero() - }, - Coeff::One => { - F::one() - }, + Coeff::Zero => F::zero(), + Coeff::One => F::one(), Coeff::NegativeOne => { let mut tmp = F::one(); tmp.negate(); tmp - }, - Coeff::Full(c) => { - *c - }, + } + Coeff::Full(c) => *c, } } // expect a small number of inputs - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.input_gates.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .input_gates + .iter() + .zip(q_l.iter_mut()) + .zip(q_r.iter_mut()) + .zip(q_o.iter_mut()) + .zip(q_m.iter_mut()) + .zip(q_c.iter_mut()) { *q_l = coeff_into_field_element::(&gate.q_l); *q_r = coeff_into_field_element::(&gate.q_r); @@ -256,7 +252,6 @@ impl GeneratorAssembly { *q_c = coeff_into_field_element::(&gate.q_c); } - let num_input_gates = self.input_gates.len(); let q_l_aux = &mut q_l[num_input_gates..]; let q_r_aux = &mut q_r[num_input_gates..]; @@ -267,27 +262,23 @@ impl GeneratorAssembly { debug_assert!(self.aux_gates.len() == q_l_aux.len()); worker.scope(self.aux_gates.len(), |scope, chunk| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.aux_gates.chunks(chunk) - .zip(q_l_aux.chunks_mut(chunk)) - .zip(q_r_aux.chunks_mut(chunk)) - .zip(q_o_aux.chunks_mut(chunk)) - .zip(q_m_aux.chunks_mut(chunk)) - .zip(q_c_aux.chunks_mut(chunk)) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .aux_gates + .chunks(chunk) + .zip(q_l_aux.chunks_mut(chunk)) + .zip(q_r_aux.chunks_mut(chunk)) + .zip(q_o_aux.chunks_mut(chunk)) + .zip(q_m_aux.chunks_mut(chunk)) + .zip(q_c_aux.chunks_mut(chunk)) { scope.spawn(move |_| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) - { - *q_l = coeff_into_field_element(&gate.q_l); - *q_r = coeff_into_field_element(&gate.q_r); - *q_o = coeff_into_field_element(&gate.q_o); - *q_m = coeff_into_field_element(&gate.q_m); - *q_c = coeff_into_field_element(&gate.q_c); - } + for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter().zip(q_l.iter_mut()).zip(q_r.iter_mut()).zip(q_o.iter_mut()).zip(q_m.iter_mut()).zip(q_c.iter_mut()) { + *q_l = coeff_into_field_element(&gate.q_l); + *q_r = coeff_into_field_element(&gate.q_r); + *q_o = coeff_into_field_element(&gate.q_o); + *q_m = coeff_into_field_element(&gate.q_m); + *q_c = coeff_into_field_element(&gate.q_c); + } }); } }); @@ -310,51 +301,50 @@ impl GeneratorAssembly { // in the partition number i there is a set of indexes in V = (a, b, c) such that V_j = i let mut partitions = vec![vec![]; num_partitions + 1]; - for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { match gate.a_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j+1); - }, + partitions[i].push(j + 1); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j+1); + partitions[i].push(j + 1); } - }, + } } match gate.b_wire() { Variable(Index::Input(index)) => { let i = *index; partitions[i].push(j + 1 + num_gates); - }, + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; partitions[i].push(j + 1 + num_gates); } - }, + } } match gate.c_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j + 1 + 2*num_gates); - }, + partitions[i].push(j + 1 + 2 * num_gates); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j + 1 + 2*num_gates); + partitions[i].push(j + 1 + 2 * num_gates); } - }, + } } } let mut sigma_1: Vec<_> = (1..=num_gates).collect(); - let mut sigma_2: Vec<_> = ((num_gates+1)..=(2*num_gates)).collect(); - let mut sigma_3: Vec<_> = ((2*num_gates + 1)..=(3*num_gates)).collect(); + let mut sigma_2: Vec<_> = ((num_gates + 1)..=(2 * num_gates)).collect(); + let mut sigma_3: Vec<_> = ((2 * num_gates + 1)..=(3 * num_gates)).collect(); let mut permutations = vec![vec![]; num_partitions + 1]; @@ -373,18 +363,16 @@ impl GeneratorAssembly { let permutation = rotate(partition.clone()); permutations[i] = permutation.clone(); - for (original, new) in partition.into_iter() - .zip(permutation.into_iter()) - { + for (original, new) in partition.into_iter().zip(permutation.into_iter()) { if original <= num_gates { debug_assert!(sigma_1[original - 1] == original); sigma_1[original - 1] = new; - } else if original <= 2*num_gates { + } else if original <= 2 * num_gates { debug_assert!(sigma_2[original - num_gates - 1] == original); sigma_2[original - num_gates - 1] = new; } else { - debug_assert!(sigma_3[original - 2*num_gates - 1] == original); - sigma_3[original - 2*num_gates - 1] = new; + debug_assert!(sigma_3[original - 2 * num_gates - 1] == original); + sigma_3[original - 2 * num_gates - 1] = new; } } } @@ -401,19 +389,23 @@ impl GeneratorAssembly { result } - pub(crate) fn output_setup_polynomials(&self, worker: &Worker) -> Result< - ( - Polynomial::, // q_l - Polynomial::, // q_r - Polynomial::, // q_o - Polynomial::, // q_m - Polynomial::, // q_c - Polynomial::, // s_id - Polynomial::, // sigma_1 - Polynomial::, // sigma_2 - Polynomial::, // sigma_3 - ), SynthesisError> - { + pub(crate) fn output_setup_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, // q_l + Polynomial, // q_r + Polynomial, // q_o + Polynomial, // q_m + Polynomial, // q_c + Polynomial, // s_id + Polynomial, // sigma_1 + Polynomial, // sigma_2 + Polynomial, // sigma_3 + ), + SynthesisError, + > { assert!(self.is_finalized); let s_id = self.make_s_id(); @@ -455,19 +447,19 @@ impl GeneratorAssembly { } let n = self.input_gates.len() + self.aux_gates.len(); - if (n+1).is_power_of_two() { + if (n + 1).is_power_of_two() { self.is_finalized = true; return; } let empty_gate = Gate::::new_empty_gate(self.dummy_variable()); - let new_aux_len = (n+1).next_power_of_two() - 1 - self.input_gates.len(); + let new_aux_len = (n + 1).next_power_of_two() - 1 - self.input_gates.len(); self.aux_gates.resize(new_aux_len, empty_gate); let n = self.input_gates.len() + self.aux_gates.len(); - assert!((n+1).is_power_of_two()); + assert!((n + 1).is_power_of_two()); self.is_finalized = true; } @@ -481,13 +473,12 @@ use crate::pairing::CurveAffine; pub fn setup_with_precomputations, CP: CTPrecomputations>( circuit: &C, omegas_bitreversed: &CP, - bases: &[E::G1Affine] - ) -> Result<(PlonkSetup, PlonkSetupPrecomputation), SynthesisError> -{ + bases: &[E::G1Affine], +) -> Result<(PlonkSetup, PlonkSetupPrecomputation), SynthesisError> { let mut assembly = GeneratorAssembly::::new(); circuit.synthesize(&mut assembly)?; assembly.finalize(); - + let n = assembly.num_gates(); let worker = Worker::new(); @@ -540,8 +531,8 @@ pub fn setup_with_precomputations, CP: CTPrecomputation s_id_aux: s_id_lde, sigma_1_aux: sigma_1_lde, sigma_2_aux: sigma_2_lde, - sigma_3_aux: sigma_3_lde + sigma_3_aux: sigma_3_lde, }; Ok((setup, precomputation)) -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/plonk/mod.rs b/crates/bellman/src/plonk/plonk/mod.rs index bc10e00..fb538fb 100644 --- a/crates/bellman/src/plonk/plonk/mod.rs +++ b/crates/bellman/src/plonk/plonk/mod.rs @@ -1,2 +1,2 @@ +pub mod generator; pub mod prover; -pub mod generator; \ No newline at end of file diff --git a/crates/bellman/src/plonk/plonk/prover.rs b/crates/bellman/src/plonk/plonk/prover.rs index 0ab5e85..1cf4255 100644 --- a/crates/bellman/src/plonk/plonk/prover.rs +++ b/crates/bellman/src/plonk/plonk/prover.rs @@ -1,19 +1,19 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; use crate::plonk::transparent_engine::TransparentEngine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use crate::plonk::cs::gates::*; use crate::plonk::cs::*; -use crate::worker::*; -use crate::plonk::domains::*; -use crate::plonk::commitments::*; use crate::plonk::commitments::transcript::*; -use crate::plonk::utils::*; +use crate::plonk::commitments::*; +use crate::plonk::domains::*; use crate::plonk::polynomials::*; +use crate::plonk::utils::*; +use crate::worker::*; #[derive(Debug, Clone)] pub struct ProvingAssembly { @@ -30,7 +30,7 @@ pub struct ProvingAssembly { inputs_map: Vec, - is_finalized: bool + is_finalized: bool, } impl ConstraintSystem for ProvingAssembly { @@ -40,7 +40,7 @@ impl ConstraintSystem for ProvingAssembly { // allocate a variable fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -56,7 +56,7 @@ impl ConstraintSystem for ProvingAssembly { // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -73,7 +73,6 @@ impl ConstraintSystem for ProvingAssembly { // println!("Allocated input Input({}) with value {}", index, value); Ok(input_var) - } // enforce variable as boolean @@ -86,9 +85,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate an abstract gate - fn new_gate(&mut self, variables: (Variable, Variable, Variable), - coeffs:(E::Fr,E::Fr,E::Fr,E::Fr,E::Fr)) -> Result<(), SynthesisError> - { + fn new_gate(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_gate(variables, coeffs); // println!("Enforced new gate number {}: {:?}", self.n, gate); self.aux_gates.push(gate); @@ -103,8 +100,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate a constant - fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> - { + fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_constant_gate(variable, Some(constant), self.dummy_variable()); // println!("Enforced new constant gate number {}: {:?}", self.n, gate); self.aux_gates.push(gate); @@ -137,8 +133,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate a linear combination gate - fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs:(E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs: (E::Fr, E::Fr)) -> Result<(), SynthesisError> { let (v_0, v_1) = variables; let (c_0, c_1) = coeffs; let zero = E::Fr::zero(); @@ -151,8 +146,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate a linear combination gate - fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs:(E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_zero_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; @@ -162,12 +156,8 @@ impl ConstraintSystem for ProvingAssembly { fn get_value(&self, var: Variable) -> Result { let value = match var { - Variable(Index::Input(input)) => { - self.input_assingments[input - 1] - }, - Variable(Index::Aux(aux)) => { - self.aux_assingments[aux - 1] - } + Variable(Index::Input(input)) => self.input_assingments[input - 1], + Variable(Index::Aux(aux)) => self.aux_assingments[aux - 1], }; Ok(value) @@ -214,8 +204,8 @@ impl ProvingAssembly { // } match (tmp.dummy_variable(), zero) { - (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {}, - _ => panic!("zero variable is incorrect") + (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {} + _ => panic!("zero variable is incorrect"), } tmp @@ -231,7 +221,7 @@ impl ProvingAssembly { } fn set_gate(&mut self, gate: Gate, index: usize) { - self.aux_gates[index-1] = gate; + self.aux_gates[index - 1] = gate; } // return variable that is not in a constraint formally, but has some value @@ -250,43 +240,51 @@ impl ProvingAssembly { let mut f_r = vec![E::Fr::zero(); total_num_gates]; let mut f_o = vec![E::Fr::zero(); total_num_gates]; - for (i, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (i, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { match gate.a_wire() { Variable(Index::Input(index)) => { f_l[i] = self.input_assingments[index - 1]; - }, + } Variable(Index::Aux(index)) => { f_l[i] = self.aux_assingments[index - 1]; - }, + } } match gate.b_wire() { Variable(Index::Input(index)) => { f_r[i] = self.input_assingments[index - 1]; - }, + } Variable(Index::Aux(index)) => { f_r[i] = self.aux_assingments[index - 1]; - }, + } } match gate.c_wire() { Variable(Index::Input(index)) => { f_o[i] = self.input_assingments[index - 1]; - }, + } Variable(Index::Aux(index)) => { f_o[i] = self.aux_assingments[index - 1]; - }, + } } } (f_l, f_r, f_o) } - pub(crate) fn make_circuit_description_polynomials(&self, worker: &Worker) -> Result<( - Polynomial::, Polynomial::, Polynomial::, - Polynomial::, Polynomial:: - ), SynthesisError> { + pub(crate) fn make_circuit_description_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, + Polynomial, + Polynomial, + Polynomial, + Polynomial, + ), + SynthesisError, + > { assert!(self.is_finalized); let total_num_gates = self.input_gates.len() + self.aux_gates.len(); @@ -296,33 +294,29 @@ impl ProvingAssembly { let mut q_m = vec![E::Fr::zero(); total_num_gates]; let mut q_c = vec![E::Fr::zero(); total_num_gates]; - fn coeff_into_field_element(coeff: & Coeff) -> F { + fn coeff_into_field_element(coeff: &Coeff) -> F { match coeff { - Coeff::Zero => { - F::zero() - }, - Coeff::One => { - F::one() - }, + Coeff::Zero => F::zero(), + Coeff::One => F::one(), Coeff::NegativeOne => { let mut tmp = F::one(); tmp.negate(); tmp - }, - Coeff::Full(c) => { - *c - }, + } + Coeff::Full(c) => *c, } } // expect a small number of inputs - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.input_gates.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .input_gates + .iter() + .zip(q_l.iter_mut()) + .zip(q_r.iter_mut()) + .zip(q_o.iter_mut()) + .zip(q_m.iter_mut()) + .zip(q_c.iter_mut()) { *q_l = coeff_into_field_element(&gate.q_l); *q_r = coeff_into_field_element(&gate.q_r); @@ -331,7 +325,6 @@ impl ProvingAssembly { *q_c = coeff_into_field_element(&gate.q_c); } - let num_input_gates = self.input_gates.len(); let q_l_aux = &mut q_l[num_input_gates..]; let q_r_aux = &mut q_r[num_input_gates..]; @@ -342,27 +335,23 @@ impl ProvingAssembly { debug_assert!(self.aux_gates.len() == q_l_aux.len()); worker.scope(self.aux_gates.len(), |scope, chunk| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.aux_gates.chunks(chunk) - .zip(q_l_aux.chunks_mut(chunk)) - .zip(q_r_aux.chunks_mut(chunk)) - .zip(q_o_aux.chunks_mut(chunk)) - .zip(q_m_aux.chunks_mut(chunk)) - .zip(q_c_aux.chunks_mut(chunk)) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .aux_gates + .chunks(chunk) + .zip(q_l_aux.chunks_mut(chunk)) + .zip(q_r_aux.chunks_mut(chunk)) + .zip(q_o_aux.chunks_mut(chunk)) + .zip(q_m_aux.chunks_mut(chunk)) + .zip(q_c_aux.chunks_mut(chunk)) { scope.spawn(move |_| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) - { - *q_l = coeff_into_field_element(&gate.q_l); - *q_r = coeff_into_field_element(&gate.q_r); - *q_o = coeff_into_field_element(&gate.q_o); - *q_m = coeff_into_field_element(&gate.q_m); - *q_c = coeff_into_field_element(&gate.q_c); - } + for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter().zip(q_l.iter_mut()).zip(q_r.iter_mut()).zip(q_o.iter_mut()).zip(q_m.iter_mut()).zip(q_c.iter_mut()) { + *q_l = coeff_into_field_element(&gate.q_l); + *q_r = coeff_into_field_element(&gate.q_r); + *q_o = coeff_into_field_element(&gate.q_o); + *q_m = coeff_into_field_element(&gate.q_m); + *q_c = coeff_into_field_element(&gate.q_c); + } }); } }); @@ -385,51 +374,50 @@ impl ProvingAssembly { // in the partition number i there is a set of indexes in V = (a, b, c) such that V_j = i let mut partitions = vec![vec![]; num_partitions + 1]; - for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { match gate.a_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j+1); - }, + partitions[i].push(j + 1); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j+1); + partitions[i].push(j + 1); } - }, + } } match gate.b_wire() { Variable(Index::Input(index)) => { let i = *index; partitions[i].push(j + 1 + num_gates); - }, + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; partitions[i].push(j + 1 + num_gates); } - }, + } } match gate.c_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j + 1 + 2*num_gates); - }, + partitions[i].push(j + 1 + 2 * num_gates); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j + 1 + 2*num_gates); + partitions[i].push(j + 1 + 2 * num_gates); } - }, + } } } let mut sigma_1: Vec<_> = (1..=num_gates).collect(); - let mut sigma_2: Vec<_> = ((num_gates+1)..=(2*num_gates)).collect(); - let mut sigma_3: Vec<_> = ((2*num_gates + 1)..=(3*num_gates)).collect(); + let mut sigma_2: Vec<_> = ((num_gates + 1)..=(2 * num_gates)).collect(); + let mut sigma_3: Vec<_> = ((2 * num_gates + 1)..=(3 * num_gates)).collect(); let mut permutations = vec![vec![]; num_partitions + 1]; @@ -448,18 +436,16 @@ impl ProvingAssembly { let permutation = rotate(partition.clone()); permutations[i] = permutation.clone(); - for (original, new) in partition.into_iter() - .zip(permutation.into_iter()) - { + for (original, new) in partition.into_iter().zip(permutation.into_iter()) { if original <= num_gates { debug_assert!(sigma_1[original - 1] == original); sigma_1[original - 1] = new; - } else if original <= 2*num_gates { + } else if original <= 2 * num_gates { debug_assert!(sigma_2[original - num_gates - 1] == original); sigma_2[original - num_gates - 1] = new; } else { - debug_assert!(sigma_3[original - 2*num_gates - 1] == original); - sigma_3[original - 2*num_gates - 1] = new; + debug_assert!(sigma_3[original - 2 * num_gates - 1] == original); + sigma_3[original - 2 * num_gates - 1] = new; } } } @@ -474,19 +460,23 @@ impl ProvingAssembly { result } - pub(crate) fn output_setup_polynomials(&self, worker: &Worker) -> Result< - ( - Polynomial::, // q_l - Polynomial::, // q_r - Polynomial::, // q_o - Polynomial::, // q_m - Polynomial::, // q_c - Polynomial::, // s_id - Polynomial::, // sigma_1 - Polynomial::, // sigma_2 - Polynomial::, // sigma_3 - ), SynthesisError> - { + pub(crate) fn output_setup_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, // q_l + Polynomial, // q_r + Polynomial, // q_o + Polynomial, // q_m + Polynomial, // q_c + Polynomial, // s_id + Polynomial, // sigma_1 + Polynomial, // sigma_2 + Polynomial, // sigma_3 + ), + SynthesisError, + > { assert!(self.is_finalized); let s_id = self.make_s_id(); @@ -529,14 +519,14 @@ impl ProvingAssembly { return; } let n = self.input_gates.len() + self.aux_gates.len(); - if (n+1).is_power_of_two() { + if (n + 1).is_power_of_two() { self.is_finalized = true; return; } let empty_gate = Gate::::new_empty_gate(self.dummy_variable()); - let new_aux_len = (n+1).next_power_of_two() - 1 - self.input_gates.len(); + let new_aux_len = (n + 1).next_power_of_two() - 1 - self.input_gates.len(); self.aux_gates.resize(new_aux_len, empty_gate); @@ -547,29 +537,22 @@ impl ProvingAssembly { // self.finalize(); // assert!(self.is_finalized); - fn coeff_into_field_element(coeff: & Coeff) -> F { + fn coeff_into_field_element(coeff: &Coeff) -> F { match coeff { - Coeff::Zero => { - F::zero() - }, - Coeff::One => { - F::one() - }, + Coeff::Zero => F::zero(), + Coeff::One => F::one(), Coeff::NegativeOne => { let mut tmp = F::one(); tmp.negate(); tmp - }, - Coeff::Full(c) => { - *c - }, + } + Coeff::Full(c) => *c, } } // expect a small number of inputs - for (i, gate) in self.input_gates.iter().enumerate() - { + for (i, gate) in self.input_gates.iter().enumerate() { let q_l = coeff_into_field_element(&gate.q_l); let q_r = coeff_into_field_element(&gate.q_r); let q_o = coeff_into_field_element(&gate.q_o); @@ -604,14 +587,13 @@ impl ProvingAssembly { res.add_assign(&tmp); if !res.is_zero() { - println!("Unsatisfied at input gate {}: {:?}", i+1, gate); + println!("Unsatisfied at input gate {}: {:?}", i + 1, gate); println!("A value = {}, B value = {}, C value = {}", a_value, b_value, c_value); return false; } } - for (i, gate) in self.aux_gates.iter().enumerate() - { + for (i, gate) in self.aux_gates.iter().enumerate() { let q_l = coeff_into_field_element(&gate.q_l); let q_r = coeff_into_field_element(&gate.q_r); let q_o = coeff_into_field_element(&gate.q_o); @@ -642,7 +624,7 @@ impl ProvingAssembly { res.add_assign(&tmp); if !res.is_zero() { - println!("Unsatisfied at aux gate {}", i+1); + println!("Unsatisfied at aux gate {}", i + 1); println!("Gate {:?}", *gate); println!("A = {}, B = {}, C = {}", a_value, b_value, c_value); return false; @@ -652,7 +634,7 @@ impl ProvingAssembly { true } - fn calculate_inverse_vanishing_polynomial_in_a_coset(&self, worker: &Worker, poly_size:usize, vahisning_size: usize) -> Result, SynthesisError> { + fn calculate_inverse_vanishing_polynomial_in_a_coset(&self, worker: &Worker, poly_size: usize, vahisning_size: usize) -> Result, SynthesisError> { assert!(poly_size.is_power_of_two()); assert!(vahisning_size.is_power_of_two()); @@ -682,7 +664,7 @@ impl ProvingAssembly { // now we should evaluate X^(n+1) - 1 in a linear time let shift = multiplicative_generator.pow([vahisning_size as u64]); - + let mut denominator = Polynomial::::from_values(vec![shift; poly_size])?; // elements are h^size - 1, (hg)^size - 1, (hg^2)^size - 1, ... @@ -721,7 +703,7 @@ impl ProvingAssembly { numerator } - fn calculate_lagrange_poly(&self, worker: &Worker, poly_size:usize, poly_number: usize) -> Result, SynthesisError> { + fn calculate_lagrange_poly(&self, worker: &Worker, poly_size: usize, poly_number: usize) -> Result, SynthesisError> { assert!(poly_size.is_power_of_two()); assert!(poly_number < poly_size); @@ -766,11 +748,11 @@ impl ProvingAssembly { use crate::plonk::fft::cooley_tukey_ntt::CTPrecomputations; -use crate::pairing::{CurveAffine, CurveProjective}; use crate::pairing::EncodedPoint; +use crate::pairing::{CurveAffine, CurveProjective}; #[derive(Debug)] -pub struct PlonkSetup{ +pub struct PlonkSetup { pub n: usize, pub q_l: E::G1Affine, pub q_r: E::G1Affine, @@ -784,7 +766,7 @@ pub struct PlonkSetup{ } // #[derive(Debug)] -pub struct PlonkSetupPrecomputation{ +pub struct PlonkSetupPrecomputation { pub q_l_aux: Polynomial, pub q_r_aux: Polynomial, pub q_o_aux: Polynomial, @@ -799,23 +781,17 @@ pub struct PlonkSetupPrecomputation{ struct OpeningRequest<'a, E: Engine> { polynomials: Vec<&'a Polynomial>, opening_point: E::Fr, - opening_values: Vec + opening_values: Vec, } use crate::multiexp::dense_multiexp; -pub(crate) fn field_elements_into_representations( - worker: &Worker, - scalars: Vec -) -> Result::Repr>, SynthesisError> -{ +pub(crate) fn field_elements_into_representations(worker: &Worker, scalars: Vec) -> Result::Repr>, SynthesisError> { let mut representations = vec![::Repr::default(); scalars.len()]; worker.scope(scalars.len(), |scope, chunk| { - for (scalar, repr) in scalars.chunks(chunk) - .zip(representations.chunks_mut(chunk)) { + for (scalar, repr) in scalars.chunks(chunk).zip(representations.chunks_mut(chunk)) { scope.spawn(move |_| { - for (scalar, repr) in scalar.iter() - .zip(repr.iter_mut()) { + for (scalar, repr) in scalar.iter().zip(repr.iter_mut()) { *repr = scalar.into_repr(); } }); @@ -826,21 +802,14 @@ pub(crate) fn field_elements_into_representations( } impl ProvingAssembly { - pub(crate) fn commit_single_poly( - poly: &Polynomial, - bases: &[E::G1Affine], - worker: &Worker - ) -> Result { + pub(crate) fn commit_single_poly(poly: &Polynomial, bases: &[E::G1Affine], worker: &Worker) -> Result { let reprs = field_elements_into_representations::(&worker, poly.as_ref().to_owned())?; let result = dense_multiexp(&worker, bases, &reprs)?; Ok(result.into_affine()) } - fn divide_single( - poly: &[E::Fr], - opening_point: E::Fr, - ) -> Vec { + fn divide_single(poly: &[E::Fr], opening_point: E::Fr) -> Vec { // we are only interested in quotient without a reminder, so we actually don't need opening value let mut b = opening_point; b.negate(); @@ -852,7 +821,7 @@ impl ProvingAssembly { for (q, r) in q.iter_mut().rev().skip(1).zip(poly.iter().rev()) { if !found_one { if r.is_zero() { - continue + continue; } else { found_one = true; } @@ -868,43 +837,37 @@ impl ProvingAssembly { q } - fn multiopening> - ( - opening_request: OpeningRequest, - bases: &[E::G1Affine], - worker: &Worker, - transcript: &mut T - ) -> Result { - let required_size = opening_request.polynomials[0].size(); + fn multiopening>(opening_request: OpeningRequest, bases: &[E::G1Affine], worker: &Worker, transcript: &mut T) -> Result { + let required_size = opening_request.polynomials[0].size(); - let mut final_aggregate = Polynomial::from_coeffs(vec![E::Fr::zero(); required_size])?; + let mut final_aggregate = Polynomial::from_coeffs(vec![E::Fr::zero(); required_size])?; - let aggregation_challenge = transcript.get_challenge(); + let aggregation_challenge = transcript.get_challenge(); - let mut alpha = E::Fr::one(); + let mut alpha = E::Fr::one(); - for poly in opening_request.polynomials.iter() { - final_aggregate.add_assign_scaled(&worker, poly, &alpha); + for poly in opening_request.polynomials.iter() { + final_aggregate.add_assign_scaled(&worker, poly, &alpha); - alpha.mul_assign(&aggregation_challenge); - } + alpha.mul_assign(&aggregation_challenge); + } - let q = Self::divide_single(final_aggregate.as_ref(), opening_request.opening_point); + let q = Self::divide_single(final_aggregate.as_ref(), opening_request.opening_point); - let q = Polynomial::from_coeffs(q)?; + let q = Polynomial::from_coeffs(q)?; - let opening = Self::commit_single_poly(&q, bases, &worker)?; + let opening = Self::commit_single_poly(&q, bases, &worker)?; - Ok(opening) + Ok(opening) } - fn prove_with_setup_precomputed, CPI: CTPrecomputations, T: Transcript >( + fn prove_with_setup_precomputed, CPI: CTPrecomputations, T: Transcript>( self, setup_precomp: &PlonkSetupPrecomputation, worker: &Worker, omegas_bitreversed: &CP, omegas_inv_bitreversed: &CPI, - bases: &[E::G1Affine] + bases: &[E::G1Affine], ) -> Result<(), SynthesisError> { assert!(self.is_finalized); @@ -962,7 +925,7 @@ impl ProvingAssembly { w_l_contribution.add_assign_scaled(&worker, &s_id_1, &beta); drop(s_id_1); - let s_id_2: Vec<_> = ((n+1)..=(2*n)).collect(); + let s_id_2: Vec<_> = ((n + 1)..=(2 * n)).collect(); let s_id_2 = convert_to_field_elements(&s_id_2, &worker); let s_id_2 = Polynomial::::from_values_unpadded(s_id_2)?; let mut w_r_contribution = w_r_plus_gamma.clone(); @@ -971,7 +934,7 @@ impl ProvingAssembly { w_l_contribution.mul_assign(&worker, &w_r_contribution); drop(w_r_contribution); - let s_id_3: Vec<_> = ((2*n+1)..=(3*n)).collect(); + let s_id_3: Vec<_> = ((2 * n + 1)..=(3 * n)).collect(); let s_id_3 = convert_to_field_elements(&s_id_3, &worker); let s_id_3 = Polynomial::::from_values_unpadded(s_id_3)?; let mut w_o_contribution = w_o_plus_gamma.clone(); @@ -1049,32 +1012,22 @@ impl ProvingAssembly { let mut z_1_shifted = z_1.clone(); z_1_shifted.distribute_powers(&worker, z_1.omega); - + let mut z_2_shifted = z_2.clone(); z_2_shifted.distribute_powers(&worker, z_2.omega); + let a_coset_lde_bitreversed = a_poly + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; + + let b_coset_lde_bitreversed = b_poly + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; + + let c_coset_lde_bitreversed = c_poly + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; - let a_coset_lde_bitreversed = a_poly.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; - - let b_coset_lde_bitreversed = b_poly.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; - - let c_coset_lde_bitreversed = c_poly.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; - let q_l_coset_lde_bitreversed = setup_precomp.q_l_aux.clone(); let q_r_coset_lde_bitreversed = setup_precomp.q_r_aux.clone(); let q_o_coset_lde_bitreversed = setup_precomp.q_o_aux.clone(); @@ -1139,47 +1092,31 @@ impl ProvingAssembly { break; } } - + println!("Degree = {}", degree); - + degree } - let z_1_coset_lde_bitreversed = z_1.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let z_1_coset_lde_bitreversed = z_1.clone().bitreversed_lde_using_bitreversed_ntt(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; - assert!(z_1_coset_lde_bitreversed.size() == required_domain_size*4); + assert!(z_1_coset_lde_bitreversed.size() == required_domain_size * 4); - let z_1_shifted_coset_lde_bitreversed = z_1_shifted.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let z_1_shifted_coset_lde_bitreversed = z_1_shifted + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; - assert!(z_1_shifted_coset_lde_bitreversed.size() == required_domain_size*4); + assert!(z_1_shifted_coset_lde_bitreversed.size() == required_domain_size * 4); - let z_2_coset_lde_bitreversed = z_2.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let z_2_coset_lde_bitreversed = z_2.clone().bitreversed_lde_using_bitreversed_ntt(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; - assert!(z_2_coset_lde_bitreversed.size() == required_domain_size*4); + assert!(z_2_coset_lde_bitreversed.size() == required_domain_size * 4); - let z_2_shifted_coset_lde_bitreversed = z_2_shifted.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let z_2_shifted_coset_lde_bitreversed = z_2_shifted + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; - assert!(z_2_shifted_coset_lde_bitreversed.size() == required_domain_size*4); + assert!(z_2_shifted_coset_lde_bitreversed.size() == required_domain_size * 4); // (A + beta*i + gamma)(B + beta(n+i) + gamma)(C + beta(2n+i) + gamma)*Z(k) = Z(k+1) { @@ -1235,7 +1172,6 @@ impl ProvingAssembly { contrib_z_2.mul_assign(&worker, &a_perm); drop(a_perm); - let mut b_perm = sigma_2_coset_lde_bitreversed; b_perm.scale(&worker, beta); b_perm.add_constant(&worker, &gamma); @@ -1264,18 +1200,15 @@ impl ProvingAssembly { drop(c_coset_lde_bitreversed); let l_0 = self.calculate_lagrange_poly(&worker, required_domain_size.next_power_of_two(), 0)?; - let l_n_minus_one = self.calculate_lagrange_poly(&worker, required_domain_size.next_power_of_two(), n-1)?; + let l_n_minus_one = self.calculate_lagrange_poly(&worker, required_domain_size.next_power_of_two(), n - 1)?; { let mut z_1_minus_z_2_shifted = z_1_shifted_coset_lde_bitreversed.clone(); z_1_minus_z_2_shifted.sub_assign(&worker, &z_2_shifted_coset_lde_bitreversed); - let l_coset_lde_bitreversed = l_n_minus_one.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let l_coset_lde_bitreversed = l_n_minus_one + .clone() + .bitreversed_lde_using_bitreversed_ntt(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; z_1_minus_z_2_shifted.mul_assign(&worker, &l_coset_lde_bitreversed); drop(l_coset_lde_bitreversed); @@ -1291,12 +1224,7 @@ impl ProvingAssembly { let mut z_1_minus_z_2 = z_1_coset_lde_bitreversed.clone(); z_1_minus_z_2.sub_assign(&worker, &z_2_coset_lde_bitreversed); - let l_coset_lde_bitreversed = l_0.clone().bitreversed_lde_using_bitreversed_ntt( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let l_coset_lde_bitreversed = l_0.clone().bitreversed_lde_using_bitreversed_ntt(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; z_1_minus_z_2.mul_assign(&worker, &l_coset_lde_bitreversed); drop(l_coset_lde_bitreversed); @@ -1317,7 +1245,7 @@ impl ProvingAssembly { let t_poly = t_1.icoset_fft_for_generator(&worker, &E::Fr::multiplicative_generator()); - debug_assert!(get_degree::(&t_poly) <= 3*n); + debug_assert!(get_degree::(&t_poly) <= 3 * n); let mut t_poly_parts = t_poly.break_into_multiples(required_domain_size)?; @@ -1624,20 +1552,7 @@ impl ProvingAssembly { z_by_omega.mul_assign(&z_1.omega); let request_at_z = OpeningRequest { - polynomials: vec![ - &a_poly, - &b_poly, - &c_poly, - &z_1, - &z_2, - &s_id, - &sigma_1, - &sigma_2, - &sigma_3, - &t_poly_low, - &t_poly_mid, - &t_poly_high - ], + polynomials: vec![&a_poly, &b_poly, &c_poly, &z_1, &z_2, &s_id, &sigma_1, &sigma_2, &sigma_3, &t_poly_low, &t_poly_mid, &t_poly_high], opening_point: z, opening_values: vec![ a_at_z, @@ -1652,28 +1567,20 @@ impl ProvingAssembly { t_low_at_z, t_mid_at_z, t_high_at_z, - ] + ], }; let request_at_z_omega = OpeningRequest { - polynomials: vec![ - &z_1, - &z_2 - ], + polynomials: vec![&z_1, &z_2], opening_point: z_by_omega, - opening_values: vec![ - z_1_shifted_at_z, - z_2_shifted_at_z, - ] + opening_values: vec![z_1_shifted_at_z, z_2_shifted_at_z], }; let _ = Self::multiopening(request_at_z, &bases, &worker, &mut transcript); let _ = Self::multiopening(request_at_z_omega, &bases, &worker, &mut transcript); - Ok(()) - // let proof = PlonkChunkedNonhomomorphicProof:: { // a_opening_value: a_at_z, // b_opening_value: b_at_z, @@ -1712,18 +1619,18 @@ impl ProvingAssembly { #[cfg(test)] mod test { - use crate::plonk::cs::*; + use super::super::generator::*; + use super::*; use crate::pairing::Engine; + use crate::plonk::cs::*; use crate::SynthesisError; - use super::*; - use super::super::generator::*; use crate::ff::{Field, PrimeField}; #[derive(Clone)] - struct BenchmarkCircuit{ + struct BenchmarkCircuit { num_steps: usize, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl Circuit for BenchmarkCircuit { @@ -1736,21 +1643,15 @@ mod test { let mut two = one; two.double(); - - let mut a = cs.alloc(|| { - Ok(E::Fr::one()) - })?; - let mut b = cs.alloc(|| { - Ok(E::Fr::one()) - })?; + let mut a = cs.alloc(|| Ok(E::Fr::one()))?; + + let mut b = cs.alloc(|| Ok(E::Fr::one()))?; cs.enforce_zero_2((a, b), (one, negative_one))?; // cs.enforce_zero_2((b, CS::ONE), (one, negative_one))?; - let mut c = cs.alloc(|| { - Ok(two) - })?; + let mut c = cs.alloc(|| Ok(two))?; cs.enforce_zero_3((a, b, c), (one, one, negative_one))?; @@ -1766,9 +1667,7 @@ mod test { b_value = c_value; c_value.add_assign(&a_value); - c = cs.alloc(|| { - Ok(c_value) - })?; + c = cs.alloc(|| Ok(c_value))?; cs.enforce_zero_3((a, b, c), (one, one, negative_one))?; } @@ -1779,9 +1678,9 @@ mod test { #[test] fn test_bench_plonk_bls12() { - use crate::pairing::Engine; - use crate::pairing::{CurveProjective, CurveAffine}; use crate::pairing::bls12_381::{Bls12, Fr}; + use crate::pairing::Engine; + use crate::pairing::{CurveAffine, CurveProjective}; use crate::plonk::utils::*; use crate::worker::Worker; // use crate::plonk::tester::*; @@ -1791,8 +1690,8 @@ mod test { use std::time::Instant; - use crate::plonk::fft::cooley_tukey_ntt::*; use crate::plonk::commitments::transparent::fri::coset_combining_fri::precomputation::*; + use crate::plonk::fft::cooley_tukey_ntt::*; let sizes: Vec = vec![(1 << 18) - 10, (1 << 19) - 10, (1 << 20) - 10, (1 << 21) - 10, (1 << 22) - 10, (1 << 23) - 10]; @@ -1820,13 +1719,11 @@ mod test { // Compute the H query with multiple threads worker.scope(bases.len(), |scope, chunk| { - for (h, p) in bases.chunks_mut(chunk).zip(powers_of_tau.chunks(chunk)) - { + for (h, p) in bases.chunks_mut(chunk).zip(powers_of_tau.chunks(chunk)) { let mut g1_wnaf = g1_wnaf.shared(); scope.spawn(move |_| { // Set values of the H query to g1^{(tau^i * t(tau)) / delta} - for (h, p) in h.iter_mut().zip(p.iter()) - { + for (h, p) in h.iter_mut().zip(p.iter()) { // Exponentiate *h = g1_wnaf.scalar(p.into_repr()); } @@ -1842,22 +1739,17 @@ mod test { println!("Done making bases"); for size in sizes.into_iter() { - let circuit = BenchmarkCircuit:: { // num_steps: 1_000_000, num_steps: size, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); println!("Start setup and precomputations"); - let (_, setup_precomp) = setup_with_precomputations::( - &circuit, - &omegas_bitreversed, - &bases[0..size.next_power_of_two()] - ).unwrap(); + let (_, setup_precomp) = setup_with_precomputations::(&circuit, &omegas_bitreversed, &bases[0..size.next_power_of_two()]).unwrap(); let mut prover = ProvingAssembly::::new(); circuit.synthesize(&mut prover).unwrap(); @@ -1869,18 +1761,13 @@ mod test { let start = Instant::now(); - let _ = prover.prove_with_setup_precomputed::<_, _, Transcr>( - &setup_precomp, - &worker, - &omegas_bitreversed, - &omegas_inv_bitreversed, - &bases[0..size.next_power_of_two()] - ).unwrap(); + let _ = prover + .prove_with_setup_precomputed::<_, _, Transcr>(&setup_precomp, &worker, &omegas_bitreversed, &omegas_inv_bitreversed, &bases[0..size.next_power_of_two()]) + .unwrap(); println!("Proving taken {:?} for size {}", start.elapsed(), size); } - // { // let mut tester = TestingAssembly::::new(); @@ -1915,9 +1802,9 @@ mod test { #[test] fn test_bench_plonk_bn254() { - use crate::pairing::Engine; - use crate::pairing::{CurveProjective, CurveAffine}; use crate::pairing::bn256::{Bn256, Fr}; + use crate::pairing::Engine; + use crate::pairing::{CurveAffine, CurveProjective}; use crate::plonk::utils::*; use crate::worker::Worker; // use crate::plonk::tester::*; @@ -1927,8 +1814,8 @@ mod test { use std::time::Instant; - use crate::plonk::fft::cooley_tukey_ntt::*; use crate::plonk::commitments::transparent::fri::coset_combining_fri::precomputation::*; + use crate::plonk::fft::cooley_tukey_ntt::*; let sizes: Vec = vec![(1 << 18) - 10, (1 << 19) - 10, (1 << 20) - 10, (1 << 21) - 10, (1 << 22) - 10, (1 << 23) - 10]; @@ -1956,13 +1843,11 @@ mod test { // Compute the H query with multiple threads worker.scope(bases.len(), |scope, chunk| { - for (h, p) in bases.chunks_mut(chunk).zip(powers_of_tau.chunks(chunk)) - { + for (h, p) in bases.chunks_mut(chunk).zip(powers_of_tau.chunks(chunk)) { let mut g1_wnaf = g1_wnaf.shared(); scope.spawn(move |_| { // Set values of the H query to g1^{(tau^i * t(tau)) / delta} - for (h, p) in h.iter_mut().zip(p.iter()) - { + for (h, p) in h.iter_mut().zip(p.iter()) { // Exponentiate *h = g1_wnaf.scalar(p.into_repr()); } @@ -1983,18 +1868,14 @@ mod test { let circuit = BenchmarkCircuit:: { // num_steps: 1_000_000, num_steps: size, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); println!("Start setup and precomputations"); - let (_, setup_precomp) = setup_with_precomputations::( - &circuit, - &omegas_bitreversed, - &bases[0..size.next_power_of_two()] - ).unwrap(); + let (_, setup_precomp) = setup_with_precomputations::(&circuit, &omegas_bitreversed, &bases[0..size.next_power_of_two()]).unwrap(); let mut prover = ProvingAssembly::::new(); circuit.synthesize(&mut prover).unwrap(); @@ -2006,18 +1887,13 @@ mod test { let start = Instant::now(); - let _ = prover.prove_with_setup_precomputed::<_, _, Transcr>( - &setup_precomp, - &worker, - &omegas_bitreversed, - &omegas_inv_bitreversed, - &bases[0..size.next_power_of_two()] - ).unwrap(); + let _ = prover + .prove_with_setup_precomputed::<_, _, Transcr>(&setup_precomp, &worker, &omegas_bitreversed, &omegas_inv_bitreversed, &bases[0..size.next_power_of_two()]) + .unwrap(); println!("Proving taken {:?} for size {}", start.elapsed(), size); } - // { // let mut tester = TestingAssembly::::new(); @@ -2049,4 +1925,4 @@ mod test { // assert!(valid); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/polynomials/mod.rs b/crates/bellman/src/plonk/polynomials/mod.rs index bdaf8ed..7fbbbb3 100644 --- a/crates/bellman/src/plonk/polynomials/mod.rs +++ b/crates/bellman/src/plonk/polynomials/mod.rs @@ -1,27 +1,27 @@ use crate::pairing::ff::PrimeField; use crate::plonk::domains::*; -use crate::SynthesisError; -use crate::worker::*; -use crate::plonk::fft::*; use crate::plonk::fft::with_precomputation; use crate::plonk::fft::with_precomputation::FftPrecomputations; +use crate::plonk::fft::*; +use crate::worker::*; +use crate::SynthesisError; use crate::plonk::fft::cooley_tukey_ntt; -use crate::plonk::fft::cooley_tukey_ntt::CTPrecomputations; use crate::plonk::fft::cooley_tukey_ntt::partial_reduction; +use crate::plonk::fft::cooley_tukey_ntt::CTPrecomputations; use crate::plonk::transparent_engine::PartialTwoBitReductionField; pub trait PolynomialForm: Sized + Copy + Clone {} #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum Coefficients { } +pub enum Coefficients {} #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub enum Values { } +pub enum Values {} impl PolynomialForm for Coefficients {} -impl PolynomialForm for Values{} +impl PolynomialForm for Values {} // TODO: Enforce bitreversed values as a separate form @@ -38,10 +38,9 @@ pub struct Polynomial { #[serde(skip_serializing, default)] #[serde(bound(serialize = ""))] #[serde(bound(deserialize = ""))] - _marker: std::marker::PhantomData

+ _marker: std::marker::PhantomData

, } - impl Polynomial { pub fn size(&self) -> usize { self.coeffs.len() @@ -59,12 +58,11 @@ impl Polynomial { self.coeffs } - pub fn distribute_powers(&mut self, worker: &Worker, g: F) - { + pub fn distribute_powers(&mut self, worker: &Worker, g: F) { distribute_powers(&mut self.coeffs, &worker, g); } - pub fn reuse_allocation (&mut self, other: &Polynomial) { + pub fn reuse_allocation(&mut self, other: &Polynomial) { assert_eq!(self.coeffs.len(), other.coeffs.len()); self.coeffs.copy_from_slice(&other.coeffs); } @@ -77,7 +75,7 @@ impl Polynomial { let rj = cooley_tukey_ntt::bitreverse(j, log_n); if j < rj { self.coeffs.swap(j, rj); - } + } } return; @@ -93,27 +91,22 @@ impl Polynomial { worker.scope(0, |scope, _| { for thread_id in 0..to_spawn { - let r = unsafe {&mut *r}; + let r = unsafe { &mut *r }; scope.spawn(move |_| { let start = thread_id * chunk; - let end = if start + chunk <= total_len { - start + chunk - } else { - total_len - }; + let end = if start + chunk <= total_len { start + chunk } else { total_len }; for j in start..end { let rj = cooley_tukey_ntt::bitreverse(j, log_n); if j < rj { r.swap(j, rj); - } + } } }); } }); } - pub fn scale(&mut self, worker: &Worker, g: F) - { + pub fn scale(&mut self, worker: &Worker, g: F) { if g == F::one() { return; } @@ -129,8 +122,7 @@ impl Polynomial { }); } - pub fn negate(&mut self, worker: &Worker) - { + pub fn negate(&mut self, worker: &Worker) { worker.scope(self.coeffs.len(), |scope, chunk| { for v in self.coeffs.chunks_mut(chunk) { scope.spawn(move |_| { @@ -142,8 +134,7 @@ impl Polynomial { }); } - pub fn map () + Send + Copy>(&mut self, worker: &Worker, func: M) - { + pub fn map () + Send + Copy>(&mut self, worker: &Worker, func: M) { worker.scope(self.coeffs.len(), |scope, chunk| { for v in self.coeffs.chunks_mut(chunk) { scope.spawn(move |_| { @@ -155,8 +146,7 @@ impl Polynomial { }); } - pub fn map_indexed () + Send + Copy>(&mut self, worker: &Worker, func: M) - { + pub fn map_indexed () + Send + Copy>(&mut self, worker: &Worker, func: M) { worker.scope(self.coeffs.len(), |scope, chunk| { for (chunk_idx, v) in self.coeffs.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { @@ -171,7 +161,7 @@ impl Polynomial { pub fn pad_by_factor(&mut self, factor: usize) -> Result<(), SynthesisError> { debug_assert!(self.coeffs.len().is_power_of_two()); - + if factor == 1 { return Ok(()); } @@ -247,8 +237,7 @@ impl Polynomial { Self::from_coeffs(coeffs) } - pub fn from_coeffs(mut coeffs: Vec) -> Result, SynthesisError> - { + pub fn from_coeffs(mut coeffs: Vec) -> Result, SynthesisError> { let coeffs_len = coeffs.len(); let domain = Domain::new_for_size(coeffs_len as u64)?; @@ -265,13 +254,11 @@ impl Polynomial { omegainv: omega.inverse().unwrap(), geninv: F::multiplicative_generator().inverse().unwrap(), minv: F::from_str(&format!("{}", m)).unwrap().inverse().unwrap(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }) } - pub fn from_roots(roots: Vec, worker: &Worker) -> Result, SynthesisError> - { - + pub fn from_roots(roots: Vec, worker: &Worker) -> Result, SynthesisError> { let coeffs_len = roots.len() + 1; let domain = Domain::::new_for_size(coeffs_len as u64)?; @@ -281,8 +268,7 @@ impl Polynomial { let mut subterms = vec![vec![]; num_threads]; worker.scope(roots.len(), |scope, chunk| { - for (r, s) in roots.chunks(chunk) - .zip(subterms.chunks_mut(1)) { + for (r, s) in roots.chunks(chunk).zip(subterms.chunks_mut(1)) { scope.spawn(move |_| { for r in r.iter() { if s[0].len() == 0 { @@ -330,11 +316,7 @@ impl Polynomial { Ok(result) } - pub fn evaluate_at_domain_for_degree_one( - &self, - worker: &Worker, - domain_size: u64 - ) -> Result, SynthesisError> { + pub fn evaluate_at_domain_for_degree_one(&self, worker: &Worker, domain_size: u64) -> Result, SynthesisError> { assert_eq!(self.coeffs.len(), 2); let alpha = self.coeffs[1]; let c = self.coeffs[0]; @@ -361,11 +343,7 @@ impl Polynomial { Polynomial::from_values(result) } - pub fn coset_evaluate_at_domain_for_degree_one( - &self, - worker: &Worker, - domain_size: u64 - ) -> Result, SynthesisError> { + pub fn coset_evaluate_at_domain_for_degree_one(&self, worker: &Worker, domain_size: u64) -> Result, SynthesisError> { assert_eq!(self.coeffs.len(), 2); let alpha = self.coeffs[1]; let c = self.coeffs[0]; @@ -401,7 +379,7 @@ impl Polynomial { // if factor != next_power_of_two { // return Err(SynthesisError::Error); // } - + // let new_size = self.coeffs.len() * factor; // let new_coeffs = vec![F::zero(); new_size]; // let old_coeffs = std::mem::replace(&mut self.coeffs, new_coeffs); @@ -436,7 +414,7 @@ impl Polynomial { // if factor != next_power_of_two { // return Err(SynthesisError::Error); // } - + // let new_size = self.coeffs.len() * factor; // self.coeffs.resize(new_size, F::zero()); @@ -495,7 +473,7 @@ impl Polynomial { pub fn filtering_lde(self, worker: &Worker, factor: usize) -> Result, SynthesisError> { debug_assert!(self.coeffs.len().is_power_of_two()); - + if factor == 1 { return Ok(self.fft(&worker)); } @@ -512,7 +490,7 @@ impl Polynomial { pub fn lde_using_multiple_cosets_naive(self, worker: &Worker, factor: usize) -> Result, SynthesisError> { debug_assert!(self.coeffs.len().is_power_of_two()); - + if factor == 1 { return Ok(self.fft(&worker)); } @@ -545,10 +523,10 @@ impl Polynomial { worker.scope(final_values.len(), |scope, chunk| { for (i, v) in final_values.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut idx = i*chunk; + let mut idx = i * chunk; for v in v.iter_mut() { let coset_idx = idx % factor; - let element_idx = idx / factor; + let element_idx = idx / factor; *v = results_ref[coset_idx][element_idx]; idx += 1; @@ -562,7 +540,7 @@ impl Polynomial { pub fn lde_using_multiple_cosets(self, worker: &Worker, factor: usize) -> Result, SynthesisError> { debug_assert!(self.coeffs.len().is_power_of_two()); - + if factor == 1 { return Ok(self.fft(&worker)); } @@ -617,10 +595,10 @@ impl Polynomial { worker.scope(final_values.len(), |scope, chunk| { for (i, v) in final_values.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut idx = i*chunk; + let mut idx = i * chunk; for v in v.iter_mut() { let coset_idx = idx % factor; - let element_idx = idx / factor; + let element_idx = idx / factor; *v = results_ref[coset_idx][element_idx]; idx += 1; @@ -632,15 +610,10 @@ impl Polynomial { Polynomial::from_values(final_values) } - pub fn lde_using_multiple_cosets_with_precomputation>( - self, - worker: &Worker, - factor: usize, - precomputed_omegas: &P - ) -> Result, SynthesisError> { + pub fn lde_using_multiple_cosets_with_precomputation>(self, worker: &Worker, factor: usize, precomputed_omegas: &P) -> Result, SynthesisError> { debug_assert!(self.coeffs.len().is_power_of_two()); debug_assert_eq!(self.size(), precomputed_omegas.domain_size()); - + if factor == 1 { return Ok(self.fft(&worker)); } @@ -690,10 +663,10 @@ impl Polynomial { worker.scope(final_values.len(), |scope, chunk| { for (i, v) in final_values.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut idx = i*chunk; + let mut idx = i * chunk; for v in v.iter_mut() { let coset_idx = idx % factor; - let element_idx = idx / factor; + let element_idx = idx / factor; *v = results_ref[coset_idx][element_idx]; idx += 1; @@ -705,16 +678,11 @@ impl Polynomial { Polynomial::from_values(final_values) } - pub fn lde_using_bitreversed_ntt>( - self, - worker: &Worker, - factor: usize, - precomputed_omegas: &P - ) -> Result, SynthesisError> { + pub fn lde_using_bitreversed_ntt>(self, worker: &Worker, factor: usize, precomputed_omegas: &P) -> Result, SynthesisError> { use std::time::Instant; debug_assert!(self.coeffs.len().is_power_of_two()); debug_assert_eq!(self.size(), precomputed_omegas.domain_size()); - + if factor == 1 { return Ok(self.fft(&worker)); } @@ -773,7 +741,7 @@ impl Polynomial { // let mut final_values = vec![F::zero(); new_size]; let mut final_values = Vec::with_capacity(new_size); - unsafe {final_values.set_len(new_size)}; + unsafe { final_values.set_len(new_size) }; // copy here is more complicated: to have the value in a natural order // one has to use coset_idx to address the result element @@ -784,11 +752,11 @@ impl Polynomial { worker.scope(final_values.len(), |scope, chunk| { for (i, v) in final_values.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut idx = i*chunk; + let mut idx = i * chunk; for v in v.iter_mut() { let coset_idx = idx % factor; let element_idx = idx / factor; - let element_idx = cooley_tukey_ntt::bitreverse(element_idx, log_n); + let element_idx = cooley_tukey_ntt::bitreverse(element_idx, log_n); *v = results_ref[coset_idx][element_idx]; idx += 1; @@ -805,12 +773,12 @@ impl Polynomial { // for (chunk_idx, r) in results.chunks(chunk).enumerate() { // let res = unsafe {&mut *res_ptr}; // scope.spawn(move |_| { - // // elements from the coset i should be on the places + // // elements from the coset i should be on the places // // of sequence i, i + lde_factor, i + 2*lde_factor, ... // let mut coset_idx = chunk_idx * chunk; // for r in r.iter() { // for (element_idx, el) in r.iter().enumerate() { - // let write_to = (cooley_tukey_ntt::bitreverse(element_idx, log_n) << factor_log_n) | coset_idx; + // let write_to = (cooley_tukey_ntt::bitreverse(element_idx, log_n) << factor_log_n) | coset_idx; // res[write_to] = *el; // } @@ -823,16 +791,15 @@ impl Polynomial { Polynomial::from_values(final_values) } - // pub fn lde_using_bitreversed_ntt_no_allocations_lowest_bits_reversed>( - // self, - // worker: &Worker, + // self, + // worker: &Worker, // factor: usize, // precomputed_omegas: &P // ) -> Result, SynthesisError> { // debug_assert!(self.coeffs.len().is_power_of_two()); // debug_assert_eq!(self.size(), precomputed_omegas.domain_size()); - + // if factor == 1 { // return Ok(self.fft(&worker)); // } @@ -881,7 +848,7 @@ impl Polynomial { // let start = current_size * coset_idx; // let end = start + current_size; // let copy_start_pointer: *mut F = r[start..end].as_mut_ptr(); - + // unsafe { std::ptr::copy_nonoverlapping(self_coeffs_ref.as_ptr(), copy_start_pointer, current_size) }; // } // }); @@ -901,8 +868,6 @@ impl Polynomial { // // } // // println!("Copying taken {:?}", start.elapsed()); - - // // for coset_idx in 0..factor { // // result.extend_from_slice(&self.coeffs); // // if coset_idx != 0 { @@ -977,7 +942,6 @@ impl Polynomial { // // let higher_bits_mask = !lower_bits_mask; - // // worker.scope(0, |scope, _| { // // for thread_id in 0..to_spawn { // // let r = unsafe {&mut *r}; @@ -994,7 +958,7 @@ impl Polynomial { // // let rj = cooley_tukey_ntt::bitreverse(element_idx, log_n) | coset_mask; // // if j < rj { // // r.swap(j, rj); - // // } + // // } // // } // // }); // // } @@ -1007,7 +971,7 @@ impl Polynomial { pub fn coset_filtering_lde(mut self, worker: &Worker, factor: usize) -> Result, SynthesisError> { debug_assert!(self.coeffs.len().is_power_of_two()); - + if factor == 1 { return Ok(self.coset_fft(&worker)); } @@ -1045,7 +1009,7 @@ impl Polynomial { results.push(lde.into_coeffs()); coset_generator.mul_assign(&domain.generator); } - + let mut final_values = vec![F::zero(); new_size]; let results_ref = &results; @@ -1053,10 +1017,10 @@ impl Polynomial { worker.scope(final_values.len(), |scope, chunk| { for (i, v) in final_values.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut idx = i*chunk; + let mut idx = i * chunk; for v in v.iter_mut() { let coset_idx = idx % factor; - let element_idx = idx / factor; + let element_idx = idx / factor; *v = results_ref[coset_idx][element_idx]; idx += 1; @@ -1065,13 +1029,12 @@ impl Polynomial { } }); - Polynomial::from_values(final_values) } pub fn coset_lde_using_multiple_cosets(self, worker: &Worker, factor: usize) -> Result, SynthesisError> { debug_assert!(self.coeffs.len().is_power_of_two()); - + if factor == 1 { return Ok(self.coset_fft(&worker)); } @@ -1123,10 +1086,10 @@ impl Polynomial { worker.scope(final_values.len(), |scope, chunk| { for (i, v) in final_values.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut idx = i*chunk; + let mut idx = i * chunk; for v in v.iter_mut() { let coset_idx = idx % factor; - let element_idx = idx / factor; + let element_idx = idx / factor; *v = results_ref[coset_idx][element_idx]; idx += 1; @@ -1138,8 +1101,7 @@ impl Polynomial { Polynomial::from_values(final_values) } - pub fn fft(mut self, worker: &Worker) -> Polynomial - { + pub fn fft(mut self, worker: &Worker) -> Polynomial { debug_assert!(self.coeffs.len().is_power_of_two()); best_fft(&mut self.coeffs, worker, &self.omega, self.exp, None); @@ -1150,19 +1112,17 @@ impl Polynomial { omegainv: self.omegainv, geninv: self.geninv, minv: self.minv, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } - pub fn coset_fft(mut self, worker: &Worker) -> Polynomial - { + pub fn coset_fft(mut self, worker: &Worker) -> Polynomial { debug_assert!(self.coeffs.len().is_power_of_two()); self.distribute_powers(worker, F::multiplicative_generator()); self.fft(worker) } - pub fn coset_fft_for_generator(mut self, worker: &Worker, gen: F) -> Polynomial - { + pub fn coset_fft_for_generator(mut self, worker: &Worker, gen: F) -> Polynomial { debug_assert!(self.coeffs.len().is_power_of_two()); self.distribute_powers(worker, gen); self.fft(worker) @@ -1234,11 +1194,9 @@ impl Polynomial { let mut subvalues = vec![F::zero(); num_threads]; worker.scope(self.coeffs.len(), |scope, chunk| { - for (i, (a, s)) in self.coeffs.chunks(chunk) - .zip(subvalues.chunks_mut(1)) - .enumerate() { + for (i, (a, s)) in self.coeffs.chunks(chunk).zip(subvalues.chunks_mut(1)).enumerate() { scope.spawn(move |_| { - let mut x = g.pow([(i*chunk) as u64]); + let mut x = g.pow([(i * chunk) as u64]); for a in a.iter() { let mut value = x; value.mul_assign(&a); @@ -1258,7 +1216,6 @@ impl Polynomial { } } - impl Polynomial { pub fn new_for_size(size: usize) -> Result, SynthesisError> { let coeffs = vec![F::zero(); size]; @@ -1266,8 +1223,7 @@ impl Polynomial { Self::from_values(coeffs) } - pub fn from_values(mut values: Vec) -> Result, SynthesisError> - { + pub fn from_values(mut values: Vec) -> Result, SynthesisError> { let coeffs_len = values.len(); let domain = Domain::new_for_size(coeffs_len as u64)?; @@ -1284,12 +1240,11 @@ impl Polynomial { omegainv: omega.inverse().unwrap(), geninv: F::multiplicative_generator().inverse().unwrap(), minv: F::from_str(&format!("{}", m)).unwrap().inverse().unwrap(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }) } - pub fn from_values_unpadded(values: Vec) -> Result, SynthesisError> - { + pub fn from_values_unpadded(values: Vec) -> Result, SynthesisError> { let coeffs_len = values.len(); let domain = Domain::new_for_size(coeffs_len as u64)?; @@ -1304,27 +1259,24 @@ impl Polynomial { omegainv: omega.inverse().unwrap(), geninv: F::multiplicative_generator().inverse().unwrap(), minv: F::from_str(&format!("{}", m)).unwrap().inverse().unwrap(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }) } // this function should only be used on the values that are bitreverse enumerated #[track_caller] - pub fn clone_subset_assuming_bitreversed( - &self, - subset_factor: usize, - ) -> Result, SynthesisError> { + pub fn clone_subset_assuming_bitreversed(&self, subset_factor: usize) -> Result, SynthesisError> { if subset_factor == 1 { return Ok(self.clone()); } assert!(subset_factor.is_power_of_two()); - + let current_size = self.coeffs.len(); let new_size = current_size / subset_factor; let mut result = Vec::with_capacity(new_size); - unsafe { result.set_len(new_size)}; + unsafe { result.set_len(new_size) }; // copy elements. If factor is 2 then non-reversed we would output only elements that are == 0 mod 2 // If factor is 2 and we are bit-reversed - we need to only output first half of the coefficients @@ -1335,19 +1287,18 @@ impl Polynomial { let end = new_size; result.copy_from_slice(&self.coeffs[start..end]); - + // unsafe { result.set_len(new_size)}; // let copy_to_start_pointer: *mut F = result[..].as_mut_ptr(); // let copy_from_start_pointer: *const F = self.coeffs[start..end].as_ptr(); - + // unsafe { std::ptr::copy_nonoverlapping(copy_from_start_pointer, copy_to_start_pointer, new_size) }; Polynomial::from_values(result) } #[track_caller] - pub fn pow(&mut self, worker: &Worker, exp: u64) - { + pub fn pow(&mut self, worker: &Worker, exp: u64) { if exp == 2 { return self.square(&worker); } @@ -1363,8 +1314,7 @@ impl Polynomial { } #[track_caller] - pub fn square(&mut self, worker: &Worker) - { + pub fn square(&mut self, worker: &Worker) { worker.scope(self.coeffs.len(), |scope, chunk| { for v in self.coeffs.chunks_mut(chunk) { scope.spawn(move |_| { @@ -1376,8 +1326,7 @@ impl Polynomial { }); } - pub fn ifft(mut self, worker: &Worker) -> Polynomial - { + pub fn ifft(mut self, worker: &Worker) -> Polynomial { debug_assert!(self.coeffs.len().is_power_of_two()); best_fft(&mut self.coeffs, worker, &self.omegainv, self.exp, None); @@ -1400,13 +1349,12 @@ impl Polynomial { omegainv: self.omegainv, geninv: self.geninv, minv: self.minv, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } #[track_caller] - pub fn icoset_fft(self, worker: &Worker) -> Polynomial - { + pub fn icoset_fft(self, worker: &Worker) -> Polynomial { debug_assert!(self.coeffs.len().is_power_of_two()); let geninv = self.geninv; let mut res = self.ifft(worker); @@ -1416,8 +1364,7 @@ impl Polynomial { } #[track_caller] - pub fn icoset_fft_for_generator(self, worker: &Worker, coset_generator: &F) -> Polynomial - { + pub fn icoset_fft_for_generator(self, worker: &Worker, coset_generator: &F) -> Polynomial { debug_assert!(self.coeffs.len().is_power_of_two()); let geninv = coset_generator.inverse().expect("must exist"); let mut res = self.ifft(worker); @@ -1468,7 +1415,7 @@ impl Polynomial { } #[track_caller] - pub fn rotate(mut self, by: usize) -> Result, SynthesisError>{ + pub fn rotate(mut self, by: usize) -> Result, SynthesisError> { let mut values: Vec<_> = self.coeffs.drain(by..).collect(); for c in self.coeffs.into_iter() { @@ -1483,7 +1430,7 @@ impl Polynomial { // use a barycentric formula // L_i(X) = (omega^i / N) / (X - omega^i) * (X^N - 1) - // we'll have to pay more for batch inversion at some point, but + // we'll have to pay more for batch inversion at some point, but // it's still useful let domain_size = self.size() as u64; assert!(domain_size.is_power_of_two()); @@ -1499,15 +1446,14 @@ impl Polynomial { // constant factor = 1 / ( (1 / N) * (X^N - 1) ) = N / (X^N - 1) worker.scope(tmp.len(), |scope, chunk| { - for (i, vals) in tmp.chunks_mut(chunk) - .enumerate() { + for (i, vals) in tmp.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { // let mut one_over_omega_pow = generator_inv.pow([(i*chunk) as u64]); // one_over_omega_pow.mul_assign(&constant_factor); - let mut omega_power = generator.pow([(i*chunk) as u64]); + let mut omega_power = generator.pow([(i * chunk) as u64]); for val in vals.iter_mut() { val.sub_assign(&omega_power); // (X - omega^i) - // val.mul_assign(&one_over_omega_pow); // (X - omega^i) * N / (X^N - 1) * omega^(-i), so when we inverse it's valid evaluation + // val.mul_assign(&one_over_omega_pow); // (X - omega^i) * N / (X^N - 1) * omega^(-i), so when we inverse it's valid evaluation omega_power.mul_assign(&generator); // one_over_omega_pow.mul_assign(&generator_inv); } @@ -1524,11 +1470,9 @@ impl Polynomial { constant_factor.mul_assign(&self.minv); worker.scope(values.size(), |scope, chunk| { - for (i, (vals, coeffs)) in values.as_mut().chunks_mut(chunk) - .zip(self.coeffs.chunks(chunk)) - .enumerate() { + for (i, (vals, coeffs)) in values.as_mut().chunks_mut(chunk).zip(self.coeffs.chunks(chunk)).enumerate() { scope.spawn(move |_| { - let mut omega_power = generator.pow([(i*chunk) as u64]); + let mut omega_power = generator.pow([(i * chunk) as u64]); omega_power.mul_assign(&constant_factor); for (val, coeff) in vals.iter_mut().zip(coeffs.iter()) { val.mul_assign(&omega_power); @@ -1546,14 +1490,14 @@ impl Polynomial { pub fn barycentric_over_coset_evaluate_at(&self, worker: &Worker, x: F, coset_factor: &F) -> Result { // use a barycentric formula // L_i(x) = \prod_{i != j} (X - x_j) / \prod_{i != j} (x_i - x_j) - // that for a case when x_j = g*omega^j is simplified + // that for a case when x_j = g*omega^j is simplified - // \prod_{i != j} (X - x_j) = (X^N - g^N) / (X - g * omega^i) + // \prod_{i != j} (X - x_j) = (X^N - g^N) / (X - g * omega^i) // \prod_{i != j} (x_i - x_j) = g * (omega)^i / N // L_i(X) = (g*(omega)^i / N) / (X - g*(omega)^i) * (X^N - g^N) - // we'll have to pay more for batch inversion at some point, but + // we'll have to pay more for batch inversion at some point, but // it's still useful let domain_size = self.size() as u64; assert!(domain_size.is_power_of_two()); @@ -1575,10 +1519,9 @@ impl Polynomial { // constant factor = 1 / ( (1 / N) * (X^N - g^N) ) = N / (X^N - g^N) worker.scope(tmp.len(), |scope, chunk| { - for (i, vals) in tmp.chunks_mut(chunk) - .enumerate() { + for (i, vals) in tmp.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut omega_power = generator.pow([(i*chunk) as u64]); + let mut omega_power = generator.pow([(i * chunk) as u64]); omega_power.mul_assign(&coset_factor); for val in vals.iter_mut() { val.sub_assign(&omega_power); // (X - omega^i) @@ -1599,11 +1542,9 @@ impl Polynomial { constant_factor.mul_assign(&normalization_factor); worker.scope(values.size(), |scope, chunk| { - for (i, (vals, coeffs)) in values.as_mut().chunks_mut(chunk) - .zip(self.coeffs.chunks(chunk)) - .enumerate() { + for (i, (vals, coeffs)) in values.as_mut().chunks_mut(chunk).zip(self.coeffs.chunks(chunk)).enumerate() { scope.spawn(move |_| { - let mut omega_power = generator.pow([(i*chunk) as u64]); + let mut omega_power = generator.pow([(i * chunk) as u64]); omega_power.mul_assign(&constant_factor); for (val, coeff) in vals.iter_mut().zip(coeffs.iter()) { val.mul_assign(&omega_power); @@ -1618,7 +1559,7 @@ impl Polynomial { } // pub fn split_into_even_and_odd_assuming_natural_ordering( - // self, + // self, // worker: &Worker, // ) -> Result<(Polynomial::, Polynomial::), SynthesisError> { // // Classical trick: f(x) = f_even(X^2) + x * f_odd(X^2) @@ -1670,11 +1611,7 @@ impl Polynomial { // } #[track_caller] - pub fn split_into_even_and_odd_assuming_natural_ordering( - self, - worker: &Worker, - coset_offset: &F - ) -> Result<(Polynomial::, Polynomial::), SynthesisError> { + pub fn split_into_even_and_odd_assuming_natural_ordering(self, worker: &Worker, coset_offset: &F) -> Result<(Polynomial, Polynomial), SynthesisError> { // Classical trick: f(x) = f_even(X^2) + x * f_odd(X^2) // f(g) = c_0 + c_1 * g + c_2 * g + c_3 * g @@ -1692,9 +1629,8 @@ impl Polynomial { // (f(g*Omega) + f(-g*Omega))/2 = c_0 + c_2 * g*Omega^2 + ... - those are values of the even coefficient polynomial at X^2/g // (f(g*Omega) - f(-g*Omega))/2 / (g * Omega) = c_1 + c_3 * Omega^2 + ... - those are values of the even coefficient polynomial at X^2/g^2 - // to make it homogenius (cause we don't care about particular coefficients) - // we make it as + // we make it as // (f(g*Omega) + f(-g*Omega))/2 / g = c_0/g + c_2 * Omega^2 - values for some polynomial over (X^2 / g^2) // (f(g*Omega) - f(-g*Omega))/2 / (g * Omega) = c_1 + c_3 * Omega^2 - values for some polynomial over (X^2 / g^2) assert!(self.coeffs.len().is_power_of_two()); @@ -1704,7 +1640,7 @@ impl Polynomial { let mut coeffs = self.coeffs; - let mut second: Vec<_> = coeffs.drain(result_len..(2*result_len)).collect(); + let mut second: Vec<_> = coeffs.drain(result_len..(2 * result_len)).collect(); let mut first = coeffs; let generator_inv = self.omegainv; @@ -1726,11 +1662,9 @@ impl Polynomial { // f_odd(X^2) = (f(x) - f(-x))/ 2x worker.scope(first.len(), |scope, chunk| { - for (i, (first, second)) in first.chunks_mut(chunk) - .zip(second.chunks_mut(chunk)) - .enumerate() { + for (i, (first, second)) in first.chunks_mut(chunk).zip(second.chunks_mut(chunk)).enumerate() { scope.spawn(move |_| { - let mut divisor_odd = generator_inv.pow([(i*chunk) as u64]); + let mut divisor_odd = generator_inv.pow([(i * chunk) as u64]); divisor_odd.mul_assign(&constant_factor); for (f, s) in first.iter_mut().zip(second.iter_mut()) { let f_at_x = *f; @@ -1776,12 +1710,9 @@ impl Polynomial { let mut subproducts = vec![F::one(); num_threads as usize]; worker.scope(self.coeffs.len(), |scope, chunk| { - for ((g, c), s) in work_chunk.chunks_mut(chunk) - .zip(self.coeffs.chunks(chunk)) - .zip(subproducts.chunks_mut(1)) { + for ((g, c), s) in work_chunk.chunks_mut(chunk).zip(self.coeffs.chunks(chunk)).zip(subproducts.chunks_mut(1)) { scope.spawn(move |_| { - for (g, c) in g.iter_mut() - .zip(c.iter()) { + for (g, c) in g.iter_mut().zip(c.iter()) { s[0].mul_assign(&c); *g = s[0]; } @@ -1803,8 +1734,7 @@ impl Polynomial { let chunk_len = worker.get_chunk_size(self.coeffs.len()); worker.scope(0, |scope, _| { - for (g, s) in work_chunk[chunk_len..].chunks_mut(chunk_len) - .zip(subproducts.chunks(1)) { + for (g, s) in work_chunk[chunk_len..].chunks_mut(chunk_len).zip(subproducts.chunks(1)) { scope.spawn(move |_| { for g in g.iter_mut() { g.mul_assign(&s[0]); @@ -1824,12 +1754,9 @@ impl Polynomial { let mut subproducts = vec![F::one(); num_threads as usize]; worker.scope(self.coeffs.len(), |scope, chunk| { - for ((g, c), s) in result.chunks_mut(chunk) - .zip(self.coeffs.chunks(chunk)) - .zip(subproducts.chunks_mut(1)) { + for ((g, c), s) in result.chunks_mut(chunk).zip(self.coeffs.chunks(chunk)).zip(subproducts.chunks_mut(1)) { scope.spawn(move |_| { - for (g, c) in g.iter_mut() - .zip(c.iter()) { + for (g, c) in g.iter_mut().zip(c.iter()) { s[0].mul_assign(&c); *g = s[0]; } @@ -1851,8 +1778,7 @@ impl Polynomial { let chunk_len = worker.get_chunk_size(self.coeffs.len()); worker.scope(0, |scope, _| { - for (g, s) in result[chunk_len..].chunks_mut(chunk_len) - .zip(subproducts.chunks(1)) { + for (g, s) in result[chunk_len..].chunks_mut(chunk_len).zip(subproducts.chunks(1)) { scope.spawn(move |_| { let c = s[0]; for g in g.iter_mut() { @@ -1884,8 +1810,7 @@ impl Polynomial { let mut subresults = vec![F::zero(); num_threads as usize]; worker.scope(self.coeffs.len(), |scope, chunk| { - for (c, s) in self.coeffs.chunks(chunk) - .zip(subresults.chunks_mut(1)) { + for (c, s) in self.coeffs.chunks(chunk).zip(subresults.chunks_mut(1)) { scope.spawn(move |_| { for c in c.iter() { s[0].add_assign(&c); @@ -1912,12 +1837,9 @@ impl Polynomial { let mut subsums = vec![F::zero(); num_threads as usize]; worker.scope(self.coeffs.len(), |scope, chunk| { - for ((g, c), s) in result[1..].chunks_mut(chunk) - .zip(self.coeffs.chunks(chunk)) - .zip(subsums.chunks_mut(1)) { + for ((g, c), s) in result[1..].chunks_mut(chunk).zip(self.coeffs.chunks(chunk)).zip(subsums.chunks_mut(1)) { scope.spawn(move |_| { - for (g, c) in g.iter_mut() - .zip(c.iter()) { + for (g, c) in g.iter_mut().zip(c.iter()) { s[0].add_assign(&c); *g = s[0]; } @@ -1939,8 +1861,7 @@ impl Polynomial { let chunk_len = worker.get_chunk_size(self.coeffs.len()); worker.scope(0, |scope, _| { - for (g, s) in result[(chunk_len+1)..].chunks_mut(chunk_len) - .zip(subsums.chunks(1)) { + for (g, s) in result[(chunk_len + 1)..].chunks_mut(chunk_len).zip(subsums.chunks(1)) { scope.spawn(move |_| { let c = s[0]; for g in g.iter_mut() { @@ -2032,9 +1953,7 @@ impl Polynomial { let mut subproducts = vec![F::one(); num_threads as usize]; worker.scope(self.coeffs.len(), |scope, chunk| { - for ((a, g), s) in self.coeffs.chunks(chunk) - .zip(grand_products.chunks_mut(chunk)) - .zip(subproducts.chunks_mut(1)) { + for ((a, g), s) in self.coeffs.chunks(chunk).zip(grand_products.chunks_mut(chunk)).zip(subproducts.chunks_mut(1)) { scope.spawn(move |_| { for (a, g) in a.iter().zip(g.iter_mut()) { s[0].mul_assign(&a); @@ -2071,12 +1990,9 @@ impl Polynomial { } worker.scope(self.coeffs.len(), |scope, chunk| { - for ((a, g), s) in self.coeffs.chunks_mut(chunk) - .zip(grand_products.chunks(chunk)) - .zip(subinverses.chunks_mut(1)) { + for ((a, g), s) in self.coeffs.chunks_mut(chunk).zip(grand_products.chunks(chunk)).zip(subinverses.chunks_mut(1)) { scope.spawn(move |_| { - for (a, g) in a.iter_mut().rev() - .zip(g.iter().rev().skip(1).chain(Some(F::one()).iter())) { + for (a, g) in a.iter_mut().rev().zip(g.iter().rev().skip(1).chain(Some(F::one()).iter())) { // s[0] = abc^-1 // a = c // g = ab @@ -2105,7 +2021,7 @@ impl Polynomial { assert!(by < len); let mut new_coeffs = vec![F::zero(); self.coeffs.len()]; new_coeffs[..(len - by)].copy_from_slice(&self.coeffs[by..]); - new_coeffs[(len-by)..].copy_from_slice(&self.coeffs[..by]); + new_coeffs[(len - by)..].copy_from_slice(&self.coeffs[..by]); Self::from_values(new_coeffs) } @@ -2132,15 +2048,15 @@ impl Polynomial { impl Polynomial { pub fn bitreversed_lde_using_bitreversed_ntt_with_partial_reduction>( - self, - worker: &Worker, + self, + worker: &Worker, factor: usize, precomputed_omegas: &P, - coset_factor: &F + coset_factor: &F, ) -> Result, SynthesisError> { debug_assert!(self.coeffs.len().is_power_of_two()); debug_assert_eq!(self.size(), precomputed_omegas.domain_size()); - + if factor == 1 { return Ok(self.fft(&worker)); } @@ -2172,7 +2088,7 @@ impl Polynomial { // let mut results = vec![self.coeffs.clone(); factor]; let mut result = Vec::with_capacity(new_size); - unsafe { result.set_len(new_size)}; + unsafe { result.set_len(new_size) }; let r = &mut result[..] as *mut [F]; @@ -2188,13 +2104,13 @@ impl Polynomial { worker.scope(range.len(), |scope, chunk| { for coset_idx in range.chunks(chunk) { - let r = unsafe {&mut *r}; + let r = unsafe { &mut *r }; scope.spawn(move |_| { for coset_idx in coset_idx.iter() { let start = current_size * coset_idx; let end = start + current_size; let copy_start_pointer: *mut F = r[start..end].as_mut_ptr(); - + unsafe { std::ptr::copy_nonoverlapping(self_coeffs_ref.as_ptr(), copy_start_pointer, current_size) }; } }); @@ -2213,18 +2129,18 @@ impl Polynomial { // Each coset will produce values at specific indexes only, e.g // coset factor of omega^0 = 1 will produce elements that are only at places == 0 mod 16 // coset factor of omega^1 will produce elements that are only at places == 1 mod 16 - // etc. We expect the output to be bitreversed, so + // etc. We expect the output to be bitreversed, so // elements for coset factor of omega^0 = 1 will need to be placed first (00 top bits, bitreversed 00) // elements for coset factor of omega^1 will need to be placed after the first half (10 top bits, bitreversed 01) worker.scope(0, |scope, _| { for coset_idx in 0..to_spawn { - let r = unsafe {&mut *r}; + let r = unsafe { &mut *r }; scope.spawn(move |_| { let from = coset_size * coset_idx; let to = from + coset_size; let one = F::one(); - let bitreversed_power = cooley_tukey_ntt::bitreverse(coset_idx, factor_log); + let bitreversed_power = cooley_tukey_ntt::bitreverse(coset_idx, factor_log); let mut coset_generator = coset_omega.pow(&[bitreversed_power as u64]); coset_generator.mul_assign(&coset_factor); if coset_generator != one { @@ -2241,10 +2157,10 @@ impl Polynomial { impl Polynomial { pub fn ifft_using_bitreversed_ntt_with_partial_reduction>( - self, - worker: &Worker, + self, + worker: &Worker, precomputed_omegas: &P, - coset_generator: &F + coset_generator: &F, ) -> Result, SynthesisError> { if self.coeffs.len() <= worker.cpus * 4 { return Ok(self.ifft(&worker)); @@ -2255,7 +2171,7 @@ impl Polynomial { cooley_tukey_ntt::partial_reduction::best_ct_ntt_partial_reduction(&mut coeffs, worker, exp, Some(worker.cpus), precomputed_omegas); let mut this = Polynomial::from_coeffs(coeffs)?; - + this.bitreverse_enumeration(&worker); let geninv = coset_generator.inverse().expect("must exist"); @@ -2283,12 +2199,7 @@ impl Polynomial { impl Polynomial { /// taken in natural enumeration /// outputs in natural enumeration - pub fn ifft_using_bitreversed_ntt>( - self, - worker: &Worker, - precomputed_omegas: &P, - coset_generator: &F - ) -> Result, SynthesisError> { + pub fn ifft_using_bitreversed_ntt>(self, worker: &Worker, precomputed_omegas: &P, coset_generator: &F) -> Result, SynthesisError> { if self.coeffs.len() <= worker.cpus * 4 { return Ok(self.ifft(&worker)); } @@ -2297,7 +2208,7 @@ impl Polynomial { let exp = self.exp; cooley_tukey_ntt::best_ct_ntt(&mut coeffs, worker, exp, Some(worker.cpus), precomputed_omegas); let mut this = Polynomial::from_coeffs(coeffs)?; - + this.bitreverse_enumeration(&worker); let geninv = coset_generator.inverse().expect("must exist"); @@ -2324,15 +2235,15 @@ impl Polynomial { impl Polynomial { pub fn bitreversed_lde_using_bitreversed_ntt>( - self, - worker: &Worker, + self, + worker: &Worker, factor: usize, precomputed_omegas: &P, - coset_factor: &F + coset_factor: &F, ) -> Result, SynthesisError> { debug_assert!(self.coeffs.len().is_power_of_two()); debug_assert_eq!(self.size(), precomputed_omegas.domain_size()); - + if factor == 1 { return Ok(self.fft(&worker)); } @@ -2364,7 +2275,7 @@ impl Polynomial { // let mut results = vec![self.coeffs.clone(); factor]; let mut result = Vec::with_capacity(new_size); - unsafe { result.set_len(new_size)}; + unsafe { result.set_len(new_size) }; let r = &mut result[..] as *mut [F]; @@ -2380,13 +2291,13 @@ impl Polynomial { worker.scope(range.len(), |scope, chunk| { for coset_idx in range.chunks(chunk) { - let r = unsafe {&mut *r}; + let r = unsafe { &mut *r }; scope.spawn(move |_| { for coset_idx in coset_idx.iter() { let start = current_size * coset_idx; let end = start + current_size; let copy_start_pointer: *mut F = r[start..end].as_mut_ptr(); - + unsafe { std::ptr::copy_nonoverlapping(self_coeffs_ref.as_ptr(), copy_start_pointer, current_size) }; } }); @@ -2405,18 +2316,18 @@ impl Polynomial { // Each coset will produce values at specific indexes only, e.g // coset factor of omega^0 = 1 will produce elements that are only at places == 0 mod 16 // coset factor of omega^1 will produce elements that are only at places == 1 mod 16 - // etc. We expect the output to be bitreversed, so + // etc. We expect the output to be bitreversed, so // elements for coset factor of omega^0 = 1 will need to be placed first (00 top bits, bitreversed 00) // elements for coset factor of omega^1 will need to be placed after the first half (10 top bits, bitreversed 01) worker.scope(0, |scope, _| { for coset_idx in 0..to_spawn { - let r = unsafe {&mut *r}; + let r = unsafe { &mut *r }; scope.spawn(move |_| { let from = coset_size * coset_idx; let to = from + coset_size; let one = F::one(); - let bitreversed_power = cooley_tukey_ntt::bitreverse(coset_idx, factor_log); + let bitreversed_power = cooley_tukey_ntt::bitreverse(coset_idx, factor_log); let mut coset_generator = coset_omega.pow(&[bitreversed_power as u64]); coset_generator.mul_assign(&coset_factor); if coset_generator != one { @@ -2432,12 +2343,7 @@ impl Polynomial { /// taken in natural enumeration /// outputs in natural enumeration - pub fn fft_using_bitreversed_ntt>( - self, - worker: &Worker, - precomputed_omegas: &P, - coset_generator: &F - ) -> Result, SynthesisError> { + pub fn fft_using_bitreversed_ntt>(self, worker: &Worker, precomputed_omegas: &P, coset_generator: &F) -> Result, SynthesisError> { if self.coeffs.len() <= worker.cpus * 4 { return Ok(self.coset_fft_for_generator(&worker, *coset_generator)); } @@ -2451,7 +2357,7 @@ impl Polynomial { let exp = this.exp; cooley_tukey_ntt::best_ct_ntt(&mut coeffs, worker, exp, Some(worker.cpus), precomputed_omegas); let mut this = Polynomial::from_values(coeffs)?; - + this.bitreverse_enumeration(&worker); Ok(this) @@ -2459,12 +2365,7 @@ impl Polynomial { /// taken in natural enumeration /// outputs in natural enumeration - pub fn fft_using_bitreversed_ntt_output_bitreversed>( - self, - worker: &Worker, - precomputed_omegas: &P, - coset_generator: &F - ) -> Result, SynthesisError> { + pub fn fft_using_bitreversed_ntt_output_bitreversed>(self, worker: &Worker, precomputed_omegas: &P, coset_generator: &F) -> Result, SynthesisError> { if self.coeffs.len() <= worker.cpus * 4 { return Ok(self.coset_fft_for_generator(&worker, *coset_generator)); } @@ -2478,7 +2379,7 @@ impl Polynomial { let exp = this.exp; cooley_tukey_ntt::best_ct_ntt(&mut coeffs, worker, exp, Some(worker.cpus), precomputed_omegas); let this = Polynomial::from_values(coeffs)?; - + Ok(this) } } @@ -2487,19 +2388,18 @@ impl Polynomial { mod test { use core::num; - #[test] fn test_shifted_grand_product() { - use crate::pairing::bn256::Fr; - use crate::ff::{Field, PrimeField}; use super::*; + use crate::ff::{Field, PrimeField}; + use crate::pairing::bn256::Fr; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; use crate::worker::Worker; - + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + let samples: usize = 1 << 20; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - + let v = (0..samples).map(|_| Fr::rand(rng)).collect::>(); let mut manual = vec![]; @@ -2523,16 +2423,16 @@ mod test { #[test] fn test_grand_product() { - use crate::pairing::bn256::Fr; - use crate::ff::{Field, PrimeField}; use super::*; + use crate::ff::{Field, PrimeField}; + use crate::pairing::bn256::Fr; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; use crate::worker::Worker; - + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + let samples: usize = 1 << 20; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - + let v = (0..samples).map(|_| Fr::rand(rng)).collect::>(); let mut manual = vec![]; @@ -2556,18 +2456,18 @@ mod test { #[test] #[ignore] fn test_insane_size_lde() { - use crate::pairing::bn256::Fr; - use crate::ff::{Field, PrimeField}; use super::*; + use crate::ff::{Field, PrimeField}; + use crate::pairing::bn256::Fr; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; use crate::worker::Worker; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let max_size = 1 << 26; let worker = Worker::new(); assert!(worker.cpus >= 16, "should be tested only on large machines"); - + let scalars = crate::kate_commitment::test::make_random_field_elements::(&worker, max_size); for size in vec![1 << 23, 1 << 24, 1 << 25, 1 << 26] { @@ -2576,7 +2476,7 @@ mod test { let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); for cpus in vec![4, 8, 16, 32] { - // for cpus in vec![16, 24, 32] { + // for cpus in vec![16, 24, 32] { use std::time::Instant; @@ -2586,12 +2486,7 @@ mod test { let now = Instant::now(); - let _ = poly.bitreversed_lde_using_bitreversed_ntt( - &subworker, - 4, - &omegas_bitreversed, - &Fr::multiplicative_generator() - ).unwrap(); + let _ = poly.bitreversed_lde_using_bitreversed_ntt(&subworker, 4, &omegas_bitreversed, &Fr::multiplicative_generator()).unwrap(); println!("Total LDE time for {} points on {} cpus = {:?}", size, cpus, now.elapsed()); } @@ -2601,18 +2496,18 @@ mod test { #[test] #[ignore] fn test_fft_scaling() { - use crate::pairing::bn256::Fr; - use crate::ff::{Field, PrimeField}; use super::*; + use crate::ff::{Field, PrimeField}; + use crate::pairing::bn256::Fr; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; use crate::worker::Worker; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let max_size = 1 << 26; let worker = Worker::new(); assert!(worker.cpus >= 16, "should be tested only on large machines"); - + let scalars = crate::kate_commitment::test::make_random_field_elements::(&worker, max_size); for size in vec![1 << 23, 1 << 24, 1 << 25, 1 << 26] { @@ -2621,7 +2516,7 @@ mod test { let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); for cpus in vec![4, 8, 16, 32] { - // for cpus in vec![16, 24, 32] { + // for cpus in vec![16, 24, 32] { use std::time::Instant; @@ -2631,12 +2526,13 @@ mod test { let now = Instant::now(); - let _ = poly.fft_using_bitreversed_ntt_output_bitreversed( - &subworker, - &omegas_bitreversed, - &Fr::one() - // &Fr::multiplicative_generator() - ).unwrap(); + let _ = poly + .fft_using_bitreversed_ntt_output_bitreversed( + &subworker, + &omegas_bitreversed, + &Fr::one(), // &Fr::multiplicative_generator() + ) + .unwrap(); println!("Total FFT time time for {} points on {} cpus = {:?}", size, cpus, now.elapsed()); } @@ -2645,21 +2541,21 @@ mod test { #[test] fn test_lde_explicit_multicore_validity() { - use crate::pairing::bn256::Fr; - use crate::ff::{Field, PrimeField}; use super::*; + use crate::ff::{Field, PrimeField}; + use crate::pairing::bn256::Fr; if cfg!(debug_assertions) { println!("Will be too slow to run in test mode, abort"); return; } - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; use crate::worker::Worker; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let size = 1 << 21; let worker = Worker::new(); - + let scalars = crate::kate_commitment::test::make_random_field_elements::(&worker, size); let poly = Polynomial::from_coeffs(scalars).unwrap(); let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); @@ -2679,12 +2575,7 @@ mod test { // &Fr::multiplicative_generator() // ).unwrap(); - let candidate = poly.bitreversed_lde_using_bitreversed_ntt( - &subworker, - 4, - &omegas_bitreversed, - &Fr::multiplicative_generator() - ).unwrap(); + let candidate = poly.bitreversed_lde_using_bitreversed_ntt(&subworker, 4, &omegas_bitreversed, &Fr::multiplicative_generator()).unwrap(); if let Some(to_compare) = reference.take() { assert_eq!(candidate.as_ref(), to_compare.as_ref(), "mismatch for {} cpus", num_cpus); @@ -2696,4 +2587,4 @@ mod test { } } } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/prover/mod.rs b/crates/bellman/src/plonk/prover/mod.rs index 4e67a39..244f783 100644 --- a/crates/bellman/src/plonk/prover/mod.rs +++ b/crates/bellman/src/plonk/prover/mod.rs @@ -1,20 +1,19 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use crate::plonk::cs::gates::*; use crate::plonk::cs::*; -use crate::worker::*; -use super::polynomials::*; use super::domains::*; -use crate::plonk::commitments::*; +use super::polynomials::*; use crate::plonk::commitments::transcript::*; -use crate::plonk::utils::*; +use crate::plonk::commitments::*; use crate::plonk::generator::*; - +use crate::plonk::utils::*; +use crate::worker::*; #[derive(Debug)] struct ProvingAssembly { @@ -31,14 +30,14 @@ struct ProvingAssembly { inputs_map: Vec, - is_finalized: bool + is_finalized: bool, } impl ConstraintSystem for ProvingAssembly { // allocate a variable fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -52,7 +51,7 @@ impl ConstraintSystem for ProvingAssembly { // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -67,7 +66,6 @@ impl ConstraintSystem for ProvingAssembly { self.input_gates.push(gate); Ok(input_var) - } // enforce variable as boolean @@ -80,9 +78,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate an abstract gate - fn new_gate(&mut self, variables: (Variable, Variable, Variable), - coeffs:(E::Fr,E::Fr,E::Fr,E::Fr,E::Fr)) -> Result<(), SynthesisError> - { + fn new_gate(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; @@ -91,8 +87,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate a constant - fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> - { + fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_constant_gate(variable, Some(constant), self.dummy_variable()); self.aux_gates.push(gate); self.n += 1; @@ -124,8 +119,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate a linear combination gate - fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs:(E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs: (E::Fr, E::Fr)) -> Result<(), SynthesisError> { let (v_0, v_1) = variables; let (c_0, c_1) = coeffs; let zero = E::Fr::zero(); @@ -138,14 +132,12 @@ impl ConstraintSystem for ProvingAssembly { } // allocate a linear combination gate - fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs:(E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_zero_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; Ok(()) - } fn get_dummy_variable(&self) -> Variable { @@ -164,7 +156,7 @@ impl ProvingAssembly { } fn set_gate(&mut self, gate: Gate, index: usize) { - self.aux_gates[index-1] = gate; + self.aux_gates[index - 1] = gate; } pub(crate) fn new() -> Self { @@ -189,8 +181,8 @@ impl ProvingAssembly { tmp.enforce_constant(zero, E::Fr::zero()).expect("should have no issues"); match (tmp.dummy_variable(), zero) { - (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {}, - _ => panic!("zero variable is incorrect") + (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {} + _ => panic!("zero variable is incorrect"), } tmp @@ -211,43 +203,51 @@ impl ProvingAssembly { let mut f_r = vec![E::Fr::zero(); total_num_gates]; let mut f_o = vec![E::Fr::zero(); total_num_gates]; - for (i, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (i, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { match gate.a_wire() { Variable(Index::Input(index)) => { f_l[i] = self.input_assingments[index - 1]; - }, + } Variable(Index::Aux(index)) => { f_l[i] = self.aux_assingments[index - 1]; - }, + } } match gate.b_wire() { Variable(Index::Input(index)) => { f_r[i] = self.input_assingments[index - 1]; - }, + } Variable(Index::Aux(index)) => { f_r[i] = self.aux_assingments[index - 1]; - }, + } } match gate.c_wire() { Variable(Index::Input(index)) => { f_o[i] = self.input_assingments[index - 1]; - }, + } Variable(Index::Aux(index)) => { f_o[i] = self.aux_assingments[index - 1]; - }, + } } } (f_l, f_r, f_o) } - pub(crate) fn make_circuit_description_polynomials(&self, worker: &Worker) -> Result<( - Polynomial::, Polynomial::, Polynomial::, - Polynomial::, Polynomial:: - ), SynthesisError> { + pub(crate) fn make_circuit_description_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, + Polynomial, + Polynomial, + Polynomial, + Polynomial, + ), + SynthesisError, + > { assert!(self.is_finalized); let total_num_gates = self.input_gates.len() + self.aux_gates.len(); @@ -257,33 +257,29 @@ impl ProvingAssembly { let mut q_m = vec![E::Fr::zero(); total_num_gates]; let mut q_c = vec![E::Fr::zero(); total_num_gates]; - fn coeff_into_field_element(coeff: & Coeff) -> F { + fn coeff_into_field_element(coeff: &Coeff) -> F { match coeff { - Coeff::Zero => { - F::zero() - }, - Coeff::One => { - F::one() - }, + Coeff::Zero => F::zero(), + Coeff::One => F::one(), Coeff::NegativeOne => { let mut tmp = F::one(); tmp.negate(); tmp - }, - Coeff::Full(c) => { - *c - }, + } + Coeff::Full(c) => *c, } } // expect a small number of inputs - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.input_gates.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .input_gates + .iter() + .zip(q_l.iter_mut()) + .zip(q_r.iter_mut()) + .zip(q_o.iter_mut()) + .zip(q_m.iter_mut()) + .zip(q_c.iter_mut()) { *q_l = coeff_into_field_element(&gate.q_l); *q_r = coeff_into_field_element(&gate.q_r); @@ -292,7 +288,6 @@ impl ProvingAssembly { *q_c = coeff_into_field_element(&gate.q_c); } - let num_input_gates = self.input_gates.len(); let q_l_aux = &mut q_l[num_input_gates..]; let q_r_aux = &mut q_r[num_input_gates..]; @@ -303,27 +298,23 @@ impl ProvingAssembly { debug_assert!(self.aux_gates.len() == q_l_aux.len()); worker.scope(self.aux_gates.len(), |scope, chunk| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.aux_gates.chunks(chunk) - .zip(q_l_aux.chunks_mut(chunk)) - .zip(q_r_aux.chunks_mut(chunk)) - .zip(q_o_aux.chunks_mut(chunk)) - .zip(q_m_aux.chunks_mut(chunk)) - .zip(q_c_aux.chunks_mut(chunk)) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .aux_gates + .chunks(chunk) + .zip(q_l_aux.chunks_mut(chunk)) + .zip(q_r_aux.chunks_mut(chunk)) + .zip(q_o_aux.chunks_mut(chunk)) + .zip(q_m_aux.chunks_mut(chunk)) + .zip(q_c_aux.chunks_mut(chunk)) { scope.spawn(move |_| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) - { - *q_l = coeff_into_field_element(&gate.q_l); - *q_r = coeff_into_field_element(&gate.q_r); - *q_o = coeff_into_field_element(&gate.q_o); - *q_m = coeff_into_field_element(&gate.q_m); - *q_c = coeff_into_field_element(&gate.q_c); - } + for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter().zip(q_l.iter_mut()).zip(q_r.iter_mut()).zip(q_o.iter_mut()).zip(q_m.iter_mut()).zip(q_c.iter_mut()) { + *q_l = coeff_into_field_element(&gate.q_l); + *q_r = coeff_into_field_element(&gate.q_r); + *q_o = coeff_into_field_element(&gate.q_o); + *q_m = coeff_into_field_element(&gate.q_m); + *q_c = coeff_into_field_element(&gate.q_c); + } }); } }); @@ -346,51 +337,50 @@ impl ProvingAssembly { // in the partition number i there is a set of indexes in V = (a, b, c) such that V_j = i let mut partitions = vec![vec![]; num_partitions + 1]; - for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { match gate.a_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j+1); - }, + partitions[i].push(j + 1); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j+1); + partitions[i].push(j + 1); } - }, + } } match gate.b_wire() { Variable(Index::Input(index)) => { let i = *index; partitions[i].push(j + 1 + num_gates); - }, + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; partitions[i].push(j + 1 + num_gates); } - }, + } } match gate.c_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j + 1 + 2*num_gates); - }, + partitions[i].push(j + 1 + 2 * num_gates); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j + 1 + 2*num_gates); + partitions[i].push(j + 1 + 2 * num_gates); } - }, + } } } let mut sigma_1: Vec<_> = (1..=num_gates).collect(); - let mut sigma_2: Vec<_> = ((num_gates+1)..=(2*num_gates)).collect(); - let mut sigma_3: Vec<_> = ((2*num_gates + 1)..=(3*num_gates)).collect(); + let mut sigma_2: Vec<_> = ((num_gates + 1)..=(2 * num_gates)).collect(); + let mut sigma_3: Vec<_> = ((2 * num_gates + 1)..=(3 * num_gates)).collect(); let mut permutations = vec![vec![]; num_partitions + 1]; @@ -409,18 +399,16 @@ impl ProvingAssembly { let permutation = rotate(partition.clone()); permutations[i] = permutation.clone(); - for (original, new) in partition.into_iter() - .zip(permutation.into_iter()) - { + for (original, new) in partition.into_iter().zip(permutation.into_iter()) { if original <= num_gates { debug_assert!(sigma_1[original - 1] == original); sigma_1[original - 1] = new; - } else if original <= 2*num_gates { + } else if original <= 2 * num_gates { debug_assert!(sigma_2[original - num_gates - 1] == original); sigma_2[original - num_gates - 1] = new; } else { - debug_assert!(sigma_3[original - 2*num_gates - 1] == original); - sigma_3[original - 2*num_gates - 1] = new; + debug_assert!(sigma_3[original - 2 * num_gates - 1] == original); + sigma_3[original - 2 * num_gates - 1] = new; } } } @@ -435,19 +423,23 @@ impl ProvingAssembly { result } - pub(crate) fn output_setup_polynomials(&self, worker: &Worker) -> Result< - ( - Polynomial::, // q_l - Polynomial::, // q_r - Polynomial::, // q_o - Polynomial::, // q_m - Polynomial::, // q_c - Polynomial::, // s_id - Polynomial::, // sigma_1 - Polynomial::, // sigma_2 - Polynomial::, // sigma_3 - ), SynthesisError> - { + pub(crate) fn output_setup_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, // q_l + Polynomial, // q_r + Polynomial, // q_o + Polynomial, // q_m + Polynomial, // q_c + Polynomial, // s_id + Polynomial, // sigma_1 + Polynomial, // sigma_2 + Polynomial, // sigma_3 + ), + SynthesisError, + > { assert!(self.is_finalized); let s_id = self.make_s_id(); @@ -490,20 +482,20 @@ impl ProvingAssembly { return; } let n = self.input_gates.len() + self.aux_gates.len(); - if (n+1).is_power_of_two() { + if (n + 1).is_power_of_two() { return; } let empty_gate = Gate::::new_empty_gate(self.dummy_variable()); - let new_aux_len = (n+1).next_power_of_two() - 1 - self.input_gates.len(); + let new_aux_len = (n + 1).next_power_of_two() - 1 - self.input_gates.len(); self.aux_gates.resize(new_aux_len, empty_gate); self.is_finalized = true; } - fn calculate_inverse_vanishing_polynomial_in_a_coset(&self, worker: &Worker, poly_size:usize, vahisning_size: usize) -> Result, SynthesisError> { + fn calculate_inverse_vanishing_polynomial_in_a_coset(&self, worker: &Worker, poly_size: usize, vahisning_size: usize) -> Result, SynthesisError> { assert!(poly_size.is_power_of_two()); assert!(vahisning_size.is_power_of_two()); @@ -533,7 +525,7 @@ impl ProvingAssembly { // now we should evaluate X^(n+1) - 1 in a linear time let shift = multiplicative_generator.pow([vahisning_size as u64]); - + let mut denominator = Polynomial::::from_values(vec![shift; poly_size])?; // elements are h^size - 1, (hg)^size - 1, (hg^2)^size - 1, ... @@ -572,7 +564,7 @@ impl ProvingAssembly { numerator } - fn calculate_lagrange_poly(&self, worker: &Worker, poly_size:usize, poly_number: usize) -> Result, SynthesisError> { + fn calculate_lagrange_poly(&self, worker: &Worker, poly_size: usize, poly_number: usize) -> Result, SynthesisError> { assert!(poly_size.is_power_of_two()); assert!(poly_number < poly_size); @@ -584,10 +576,9 @@ impl ProvingAssembly { } } - // for a non-homomorphic case we do not need r(x) polynomial at all, just open all the parts of t(x) at z -pub struct PlonkNonhomomorphicProof >{ +pub struct PlonkNonhomomorphicProof> { pub a_opening_value: E::Fr, pub b_opening_value: E::Fr, pub c_opening_value: E::Fr, @@ -616,7 +607,7 @@ pub struct PlonkNonhomomorphicProof >{ pub t_opening_proof: S::OpeningProof, } -pub struct PlonkChunkedNonhomomorphicProof >{ +pub struct PlonkChunkedNonhomomorphicProof> { pub a_opening_value: E::Fr, pub b_opening_value: E::Fr, pub c_opening_value: E::Fr, @@ -647,9 +638,9 @@ pub struct PlonkChunkedNonhomomorphicProof pub openings_proof: S::OpeningProof, } -use crate::plonk::commitments::transparent::StatelessTransparentCommitter; -use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::TrivialBlake2sIOP; use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::NaiveFriIop; +use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::TrivialBlake2sIOP; +use crate::plonk::commitments::transparent::StatelessTransparentCommitter; type Iop = TrivialBlake2sIOP; type Fri = NaiveFriIop>; @@ -683,7 +674,7 @@ impl PlonkChunkedNonhomomorphicProof PlonkChunkedNonhomomorphicProof, T: Transcript, C: Circuit>( - circuit: &C, + circuit: &C, setup: &PlonkSetup, aux: &PlonkSetupAuxData, meta: S::Meta, - large_meta: S::Meta + large_meta: S::Meta, ) -> Result, SynthesisError> { assert!(S::IS_HOMOMORPHIC == false); @@ -776,7 +766,7 @@ pub fn prove_nonhomomorphic, T: w_l_contribution.add_assign_scaled(&worker, &s_id_1, &beta); drop(s_id_1); - let s_id_2: Vec<_> = ((n+1)..=(2*n)).collect(); + let s_id_2: Vec<_> = ((n + 1)..=(2 * n)).collect(); let s_id_2 = convert_to_field_elements(&s_id_2, &worker); let s_id_2 = Polynomial::::from_values_unpadded(s_id_2)?; let mut w_r_contribution = w_r_plus_gamma.clone(); @@ -785,7 +775,7 @@ pub fn prove_nonhomomorphic, T: w_l_contribution.mul_assign(&worker, &w_r_contribution); drop(w_r_contribution); - let s_id_3: Vec<_> = ((2*n+1)..=(3*n)).collect(); + let s_id_3: Vec<_> = ((2 * n + 1)..=(3 * n)).collect(); let s_id_3 = convert_to_field_elements(&s_id_3, &worker); let s_id_3 = Polynomial::::from_values_unpadded(s_id_3)?; let mut w_o_contribution = w_o_plus_gamma.clone(); @@ -858,10 +848,10 @@ pub fn prove_nonhomomorphic, T: let mut z_1_shifted = z_1.clone(); z_1_shifted.distribute_powers(&worker, z_1.omega); - + let mut z_2_shifted = z_2.clone(); z_2_shifted.distribute_powers(&worker, z_2.omega); - + let a_lde = a_poly.clone().coset_lde(&worker, 4)?; let b_lde = b_poly.clone().coset_lde(&worker, 4)?; let c_lde = c_poly.clone().coset_lde(&worker, 4)?; @@ -969,7 +959,7 @@ pub fn prove_nonhomomorphic, T: t_1.add_assign(&worker, &contrib_z_1); } - { + { // TODO: May be optimize number of additions let mut contrib_z_2 = z_2_lde.clone(); @@ -980,7 +970,6 @@ pub fn prove_nonhomomorphic, T: contrib_z_2.mul_assign(&worker, &a_perm); drop(a_perm); - let mut b_perm = sigma_2_lde; b_perm.scale(&worker, beta); b_perm.add_constant(&worker, &gamma); @@ -1009,7 +998,7 @@ pub fn prove_nonhomomorphic, T: drop(c_lde); let l_0 = assembly.calculate_lagrange_poly(&worker, required_domain_size.next_power_of_two(), 0)?; - let l_n_minus_one = assembly.calculate_lagrange_poly(&worker, required_domain_size.next_power_of_two(), n-1)?; + let l_n_minus_one = assembly.calculate_lagrange_poly(&worker, required_domain_size.next_power_of_two(), n - 1)?; { let mut z_1_minus_z_2_shifted = z_1_shifted_lde.clone(); @@ -1028,7 +1017,7 @@ pub fn prove_nonhomomorphic, T: } { - let mut z_1_minus_z_2= z_1_lde.clone(); + let mut z_1_minus_z_2 = z_1_lde.clone(); z_1_minus_z_2.sub_assign(&worker, &z_2_lde); let l = l_0.clone().coset_lde(&worker, 4)?; @@ -1050,8 +1039,8 @@ pub fn prove_nonhomomorphic, T: // let degree = get_degree::(&t_poly); // assert!(degree <= 3*n); - - fn get_degree(poly: &Polynomial) -> usize { + + fn get_degree(poly: &Polynomial) -> usize { let mut degree = poly.as_ref().len() - 1; for c in poly.as_ref().iter().rev() { if c.is_zero() { @@ -1254,24 +1243,7 @@ pub fn prove_nonhomomorphic, T: let mut z_by_omega = z; z_by_omega.mul_assign(&z_1.omega); - let opening_polynomials = vec![ - &a_poly, - &b_poly, - &c_poly, - &q_l, - &q_r, - &q_o, - &q_m, - &q_c, - &s_id, - &sigma_1, - &sigma_2, - &sigma_3, - &z_1, - &z_2, - &z_1, - &z_2, - ]; + let opening_polynomials = vec![&a_poly, &b_poly, &c_poly, &q_l, &q_r, &q_o, &q_m, &q_c, &s_id, &sigma_1, &sigma_2, &sigma_3, &z_1, &z_2, &z_1, &z_2]; let degrees: Vec = opening_polynomials.iter().map(|el| el.size()).collect(); @@ -1310,51 +1282,14 @@ pub fn prove_nonhomomorphic, T: z_1_at_z, z_2_at_z, z_1_shifted_at_z, - z_2_shifted_at_z - ]; - - let opening_points = vec![ - z, - z, - z, - - z, - z, - z, - z, - z, - - z, - z, - z, - z, - - z, - z, - - z_by_omega, - z_by_omega + z_2_shifted_at_z, ]; - let multiopen_proof = committer.open_multiple( - opening_polynomials, - degrees, - aggregation_challenge, - opening_points, - opening_values, - &precomputations, - &mut transcript - ); - - let t_opening_proof = large_committer.open_single( - &t_poly, - z, - t_at_z, - &t_aux.as_ref(), - &mut transcript - ); + let opening_points = vec![z, z, z, z, z, z, z, z, z, z, z, z, z, z, z_by_omega, z_by_omega]; + let multiopen_proof = committer.open_multiple(opening_polynomials, degrees, aggregation_challenge, opening_points, opening_values, &precomputations, &mut transcript); + let t_opening_proof = large_committer.open_single(&t_poly, z, t_at_z, &t_aux.as_ref(), &mut transcript); // let opening_polynomials = vec![ // &z_1, @@ -1373,15 +1308,13 @@ pub fn prove_nonhomomorphic, T: // z_2_shifted_at_z // ]; - - // let shifted_proof = committer.open_multiple( - // opening_polynomials, - // degrees, + // opening_polynomials, + // degrees, // shifted_opening_aggregation_challenge, - // opening_point, + // opening_point, // opening_values, - // &precomputations, + // &precomputations, // &mut transcript // ); @@ -1418,7 +1351,7 @@ pub fn prove_nonhomomorphic, T: } pub fn prove_nonhomomorphic_chunked, T: Transcript, C: Circuit>( - circuit: &C, + circuit: &C, aux: &PlonkSetupAuxData, meta: S::Meta, ) -> Result, SynthesisError> { @@ -1485,7 +1418,7 @@ pub fn prove_nonhomomorphic_chunked = ((n+1)..=(2*n)).collect(); + let s_id_2: Vec<_> = ((n + 1)..=(2 * n)).collect(); let s_id_2 = convert_to_field_elements(&s_id_2, &worker); let s_id_2 = Polynomial::::from_values_unpadded(s_id_2)?; let mut w_r_contribution = w_r_plus_gamma.clone(); @@ -1494,7 +1427,7 @@ pub fn prove_nonhomomorphic_chunked = ((2*n+1)..=(3*n)).collect(); + let s_id_3: Vec<_> = ((2 * n + 1)..=(3 * n)).collect(); let s_id_3 = convert_to_field_elements(&s_id_3, &worker); let s_id_3 = Polynomial::::from_values_unpadded(s_id_3)?; let mut w_o_contribution = w_o_plus_gamma.clone(); @@ -1567,10 +1500,10 @@ pub fn prove_nonhomomorphic_chunked = opening_polynomials.iter().map(|el| el.size()).collect(); @@ -2024,65 +1956,27 @@ pub fn prove_nonhomomorphic_chunked { a_opening_value: a_at_z, @@ -2123,35 +2017,29 @@ mod test { use super::*; use crate::pairing::ff::{Field, PrimeField}; - use crate::pairing::{Engine}; + use crate::pairing::Engine; - use crate::{SynthesisError}; + use crate::SynthesisError; use std::marker::PhantomData; use crate::plonk::cs::gates::*; use crate::plonk::cs::*; - struct TestCircuit{ - _marker: PhantomData + struct TestCircuit { + _marker: PhantomData, } impl Circuit for TestCircuit { fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let a = cs.alloc(|| { - Ok(E::Fr::from_str("10").unwrap()) - })?; + let a = cs.alloc(|| Ok(E::Fr::from_str("10").unwrap()))?; println!("A = {:?}", a); - let b = cs.alloc(|| { - Ok(E::Fr::from_str("20").unwrap()) - })?; + let b = cs.alloc(|| Ok(E::Fr::from_str("20").unwrap()))?; println!("B = {:?}", b); - let c = cs.alloc(|| { - Ok(E::Fr::from_str("200").unwrap()) - })?; + let c = cs.alloc(|| Ok(E::Fr::from_str("200").unwrap()))?; println!("C = {:?}", c); @@ -2180,9 +2068,7 @@ mod test { let mut assembly = ProvingAssembly::::new(); - let circuit = TestCircuit:: { - _marker: PhantomData - }; + let circuit = TestCircuit:: { _marker: PhantomData }; circuit.synthesize(&mut assembly).expect("must work"); @@ -2197,8 +2083,8 @@ mod test { let num_gates = assembly.num_gates(); let id_1: Vec<_> = (1..=num_gates).collect(); - let id_2: Vec<_> = ((num_gates+1)..=(2*num_gates)).collect(); - let id_3: Vec<_> = ((2*num_gates + 1)..=(3*num_gates)).collect(); + let id_2: Vec<_> = ((num_gates + 1)..=(2 * num_gates)).collect(); + let id_3: Vec<_> = ((2 * num_gates + 1)..=(3 * num_gates)).collect(); let beta = Fr::from_str("15").unwrap(); let gamma = Fr::from_str("4").unwrap(); @@ -2239,7 +2125,6 @@ mod test { g_2_poly.push(tmp); } - let mut f_3_poly = vec![]; let mut g_3_poly = vec![]; for (i, el) in f_o.iter().enumerate() { @@ -2296,4 +2181,4 @@ mod test { let _ = assembly.output_setup_polynomials(&worker).unwrap(); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/redshift/generator.rs b/crates/bellman/src/plonk/redshift/generator.rs index 03dd764..f581540 100644 --- a/crates/bellman/src/plonk/redshift/generator.rs +++ b/crates/bellman/src/plonk/redshift/generator.rs @@ -1,17 +1,17 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use crate::plonk::cs::gates::*; use crate::plonk::cs::*; -use crate::worker::*; -use crate::plonk::polynomials::*; -use crate::plonk::domains::*; use crate::plonk::commitments::*; +use crate::plonk::domains::*; +use crate::plonk::polynomials::*; use crate::plonk::utils::*; +use crate::worker::*; use super::prover::ProvingAssembly; @@ -37,7 +37,7 @@ impl ConstraintSystem for GeneratorAssembly { // allocate a variable fn alloc(&mut self, _value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { self.num_aux += 1; let index = self.num_aux; @@ -48,7 +48,7 @@ impl ConstraintSystem for GeneratorAssembly { // allocate an input variable fn alloc_input(&mut self, _value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { self.num_inputs += 1; let index = self.num_inputs; @@ -59,7 +59,6 @@ impl ConstraintSystem for GeneratorAssembly { self.input_gates.push(gate); Ok(input_var) - } // enforce variable as boolean @@ -72,9 +71,7 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate an abstract gate - fn new_gate(&mut self, variables: (Variable, Variable, Variable), - coeffs:(E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn new_gate(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; @@ -83,8 +80,7 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate a constant - fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> - { + fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_constant_gate(variable, Some(constant), self.dummy_variable()); self.aux_gates.push(gate); self.n += 1; @@ -116,8 +112,7 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate a linear combination gate - fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs:(E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs: (E::Fr, E::Fr)) -> Result<(), SynthesisError> { let (v_0, v_1) = variables; let (c_0, c_1) = coeffs; let zero = E::Fr::zero(); @@ -130,14 +125,12 @@ impl ConstraintSystem for GeneratorAssembly { } // allocate a linear combination gate - fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs:(E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_zero_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; Ok(()) - } fn get_dummy_variable(&self) -> Variable { @@ -156,7 +149,7 @@ impl GeneratorAssembly { } fn set_gate(&mut self, gate: Gate, index: usize) { - self.aux_gates[index-1] = gate; + self.aux_gates[index - 1] = gate; } pub(crate) fn new() -> Self { @@ -172,7 +165,6 @@ impl GeneratorAssembly { inputs_map: vec![], is_finalized: false, - }; let zero = tmp.alloc(|| Ok(E::Fr::zero())).expect("should have no issues"); @@ -192,8 +184,8 @@ impl GeneratorAssembly { // } match (tmp.dummy_variable(), zero) { - (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {}, - _ => panic!("zero variable is incorrect") + (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {} + _ => panic!("zero variable is incorrect"), } tmp @@ -205,10 +197,19 @@ impl GeneratorAssembly { Variable(Index::Aux(1)) } - pub(crate) fn make_circuit_description_polynomials(&self, worker: &Worker) -> Result<( - Polynomial::, Polynomial::, Polynomial::, - Polynomial::, Polynomial:: - ), SynthesisError> { + pub(crate) fn make_circuit_description_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, + Polynomial, + Polynomial, + Polynomial, + Polynomial, + ), + SynthesisError, + > { assert!(self.is_finalized); let total_num_gates = self.input_gates.len() + self.aux_gates.len(); let mut q_l = vec![E::Fr::zero(); total_num_gates]; @@ -219,31 +220,27 @@ impl GeneratorAssembly { fn coeff_into_field_element(coeff: &Coeff) -> F { match coeff { - Coeff::Zero => { - F::zero() - }, - Coeff::One => { - F::one() - }, + Coeff::Zero => F::zero(), + Coeff::One => F::one(), Coeff::NegativeOne => { let mut tmp = F::one(); tmp.negate(); tmp - }, - Coeff::Full(c) => { - *c - }, + } + Coeff::Full(c) => *c, } } // expect a small number of inputs - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.input_gates.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .input_gates + .iter() + .zip(q_l.iter_mut()) + .zip(q_r.iter_mut()) + .zip(q_o.iter_mut()) + .zip(q_m.iter_mut()) + .zip(q_c.iter_mut()) { *q_l = coeff_into_field_element::(&gate.q_l); *q_r = coeff_into_field_element::(&gate.q_r); @@ -252,7 +249,6 @@ impl GeneratorAssembly { *q_c = coeff_into_field_element::(&gate.q_c); } - let num_input_gates = self.input_gates.len(); let q_l_aux = &mut q_l[num_input_gates..]; let q_r_aux = &mut q_r[num_input_gates..]; @@ -263,27 +259,23 @@ impl GeneratorAssembly { debug_assert!(self.aux_gates.len() == q_l_aux.len()); worker.scope(self.aux_gates.len(), |scope, chunk| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.aux_gates.chunks(chunk) - .zip(q_l_aux.chunks_mut(chunk)) - .zip(q_r_aux.chunks_mut(chunk)) - .zip(q_o_aux.chunks_mut(chunk)) - .zip(q_m_aux.chunks_mut(chunk)) - .zip(q_c_aux.chunks_mut(chunk)) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .aux_gates + .chunks(chunk) + .zip(q_l_aux.chunks_mut(chunk)) + .zip(q_r_aux.chunks_mut(chunk)) + .zip(q_o_aux.chunks_mut(chunk)) + .zip(q_m_aux.chunks_mut(chunk)) + .zip(q_c_aux.chunks_mut(chunk)) { scope.spawn(move |_| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) - { - *q_l = coeff_into_field_element(&gate.q_l); - *q_r = coeff_into_field_element(&gate.q_r); - *q_o = coeff_into_field_element(&gate.q_o); - *q_m = coeff_into_field_element(&gate.q_m); - *q_c = coeff_into_field_element(&gate.q_c); - } + for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter().zip(q_l.iter_mut()).zip(q_r.iter_mut()).zip(q_o.iter_mut()).zip(q_m.iter_mut()).zip(q_c.iter_mut()) { + *q_l = coeff_into_field_element(&gate.q_l); + *q_r = coeff_into_field_element(&gate.q_r); + *q_o = coeff_into_field_element(&gate.q_o); + *q_m = coeff_into_field_element(&gate.q_m); + *q_c = coeff_into_field_element(&gate.q_c); + } }); } }); @@ -306,51 +298,50 @@ impl GeneratorAssembly { // in the partition number i there is a set of indexes in V = (a, b, c) such that V_j = i let mut partitions = vec![vec![]; num_partitions + 1]; - for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { match gate.a_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j+1); - }, + partitions[i].push(j + 1); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j+1); + partitions[i].push(j + 1); } - }, + } } match gate.b_wire() { Variable(Index::Input(index)) => { let i = *index; partitions[i].push(j + 1 + num_gates); - }, + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; partitions[i].push(j + 1 + num_gates); } - }, + } } match gate.c_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j + 1 + 2*num_gates); - }, + partitions[i].push(j + 1 + 2 * num_gates); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j + 1 + 2*num_gates); + partitions[i].push(j + 1 + 2 * num_gates); } - }, + } } } let mut sigma_1: Vec<_> = (1..=num_gates).collect(); - let mut sigma_2: Vec<_> = ((num_gates+1)..=(2*num_gates)).collect(); - let mut sigma_3: Vec<_> = ((2*num_gates + 1)..=(3*num_gates)).collect(); + let mut sigma_2: Vec<_> = ((num_gates + 1)..=(2 * num_gates)).collect(); + let mut sigma_3: Vec<_> = ((2 * num_gates + 1)..=(3 * num_gates)).collect(); let mut permutations = vec![vec![]; num_partitions + 1]; @@ -369,18 +360,16 @@ impl GeneratorAssembly { let permutation = rotate(partition.clone()); permutations[i] = permutation.clone(); - for (original, new) in partition.into_iter() - .zip(permutation.into_iter()) - { + for (original, new) in partition.into_iter().zip(permutation.into_iter()) { if original <= num_gates { debug_assert!(sigma_1[original - 1] == original); sigma_1[original - 1] = new; - } else if original <= 2*num_gates { + } else if original <= 2 * num_gates { debug_assert!(sigma_2[original - num_gates - 1] == original); sigma_2[original - num_gates - 1] = new; } else { - debug_assert!(sigma_3[original - 2*num_gates - 1] == original); - sigma_3[original - 2*num_gates - 1] = new; + debug_assert!(sigma_3[original - 2 * num_gates - 1] == original); + sigma_3[original - 2 * num_gates - 1] = new; } } } @@ -397,19 +386,23 @@ impl GeneratorAssembly { result } - pub(crate) fn output_setup_polynomials(&self, worker: &Worker) -> Result< - ( - Polynomial::, // q_l - Polynomial::, // q_r - Polynomial::, // q_o - Polynomial::, // q_m - Polynomial::, // q_c - Polynomial::, // s_id - Polynomial::, // sigma_1 - Polynomial::, // sigma_2 - Polynomial::, // sigma_3 - ), SynthesisError> - { + pub(crate) fn output_setup_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, // q_l + Polynomial, // q_r + Polynomial, // q_o + Polynomial, // q_m + Polynomial, // q_c + Polynomial, // s_id + Polynomial, // sigma_1 + Polynomial, // sigma_2 + Polynomial, // sigma_3 + ), + SynthesisError, + > { assert!(self.is_finalized); let s_id = self.make_s_id(); @@ -451,45 +444,46 @@ impl GeneratorAssembly { } let n = self.input_gates.len() + self.aux_gates.len(); - if (n+1).is_power_of_two() { + if (n + 1).is_power_of_two() { self.is_finalized = true; return; } let empty_gate = Gate::::new_empty_gate(self.dummy_variable()); - let new_aux_len = (n+1).next_power_of_two() - 1 - self.input_gates.len(); + let new_aux_len = (n + 1).next_power_of_two() - 1 - self.input_gates.len(); self.aux_gates.resize(new_aux_len, empty_gate); let n = self.input_gates.len() + self.aux_gates.len(); - assert!((n+1).is_power_of_two()); + assert!((n + 1).is_power_of_two()); self.is_finalized = true; } } use super::prover::*; -use crate::plonk::fft::cooley_tukey_ntt::CTPrecomputations; -use crate::plonk::commitments::transparent::fri::coset_combining_fri::*; use crate::plonk::commitments::transparent::fri::coset_combining_fri::fri::*; -use crate::plonk::commitments::transparent::iop_compiler::*; +use crate::plonk::commitments::transparent::fri::coset_combining_fri::*; use crate::plonk::commitments::transparent::iop_compiler::coset_combining_blake2s_tree::*; +use crate::plonk::commitments::transparent::iop_compiler::*; +use crate::plonk::fft::cooley_tukey_ntt::CTPrecomputations; use crate::plonk::transparent_engine::PartialTwoBitReductionField; use crate::plonk::commitments::transcript::*; -pub fn setup_with_precomputations, CP: CTPrecomputations, T: Transcript as IopInstance> :: Commitment> >( +pub fn setup_with_precomputations, CP: CTPrecomputations, T: Transcript as IopInstance>::Commitment>>( circuit: &C, params: &RedshiftParameters, omegas_bitreversed: &CP, - ) -> Result<(RedshiftSetup>, RedshiftSetupPrecomputation>), SynthesisError> - where E::Fr : PartialTwoBitReductionField +) -> Result<(RedshiftSetup>, RedshiftSetupPrecomputation>), SynthesisError> +where + E::Fr: PartialTwoBitReductionField, { let mut assembly = GeneratorAssembly::::new(); circuit.synthesize(&mut assembly)?; assembly.finalize(); - + let n = assembly.num_gates(); let worker = Worker::new(); @@ -602,4 +596,4 @@ pub fn setup_with_precomputations, CP: CTPrecomputation }; Ok((setup, precomputation)) -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/redshift/mod.rs b/crates/bellman/src/plonk/redshift/mod.rs index 1364dd4..b807f8a 100644 --- a/crates/bellman/src/plonk/redshift/mod.rs +++ b/crates/bellman/src/plonk/redshift/mod.rs @@ -1,5 +1,5 @@ -mod prover; mod generator; +mod prover; // use crate::Engine; // use crate::plonk::plonk::prover::PlonkSetup; diff --git a/crates/bellman/src/plonk/redshift/prover.rs b/crates/bellman/src/plonk/redshift/prover.rs index 7608206..a43fa21 100644 --- a/crates/bellman/src/plonk/redshift/prover.rs +++ b/crates/bellman/src/plonk/redshift/prover.rs @@ -1,19 +1,19 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; use crate::plonk::transparent_engine::TransparentEngine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use crate::plonk::cs::gates::*; use crate::plonk::cs::*; -use crate::worker::*; -use crate::plonk::domains::*; -use crate::plonk::commitments::*; use crate::plonk::commitments::transcript::*; -use crate::plonk::utils::*; +use crate::plonk::commitments::*; +use crate::plonk::domains::*; use crate::plonk::polynomials::*; +use crate::plonk::utils::*; +use crate::worker::*; #[derive(Debug)] pub(crate) struct ProvingAssembly { @@ -30,7 +30,7 @@ pub(crate) struct ProvingAssembly { inputs_map: Vec, - is_finalized: bool + is_finalized: bool, } impl ConstraintSystem for ProvingAssembly { @@ -40,7 +40,7 @@ impl ConstraintSystem for ProvingAssembly { // allocate a variable fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -54,7 +54,7 @@ impl ConstraintSystem for ProvingAssembly { // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -69,7 +69,6 @@ impl ConstraintSystem for ProvingAssembly { self.input_gates.push(gate); Ok(input_var) - } // enforce variable as boolean @@ -82,9 +81,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate an abstract gate - fn new_gate(&mut self, variables: (Variable, Variable, Variable), - coeffs:(E::Fr,E::Fr,E::Fr,E::Fr,E::Fr)) -> Result<(), SynthesisError> - { + fn new_gate(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; @@ -93,8 +90,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate a constant - fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> - { + fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_constant_gate(variable, Some(constant), self.dummy_variable()); self.aux_gates.push(gate); self.n += 1; @@ -126,8 +122,7 @@ impl ConstraintSystem for ProvingAssembly { } // allocate a linear combination gate - fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs:(E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs: (E::Fr, E::Fr)) -> Result<(), SynthesisError> { let (v_0, v_1) = variables; let (c_0, c_1) = coeffs; let zero = E::Fr::zero(); @@ -140,14 +135,12 @@ impl ConstraintSystem for ProvingAssembly { } // allocate a linear combination gate - fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs:(E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_zero_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; Ok(()) - } fn get_dummy_variable(&self) -> Variable { @@ -191,8 +184,8 @@ impl ProvingAssembly { // } match (tmp.dummy_variable(), zero) { - (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {}, - _ => panic!("zero variable is incorrect") + (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {} + _ => panic!("zero variable is incorrect"), } tmp @@ -208,7 +201,7 @@ impl ProvingAssembly { } fn set_gate(&mut self, gate: Gate, index: usize) { - self.aux_gates[index-1] = gate; + self.aux_gates[index - 1] = gate; } // return variable that is not in a constraint formally, but has some value @@ -227,43 +220,51 @@ impl ProvingAssembly { let mut f_r = vec![E::Fr::zero(); total_num_gates]; let mut f_o = vec![E::Fr::zero(); total_num_gates]; - for (i, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (i, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { match gate.a_wire() { Variable(Index::Input(index)) => { f_l[i] = self.input_assingments[index - 1]; - }, + } Variable(Index::Aux(index)) => { f_l[i] = self.aux_assingments[index - 1]; - }, + } } match gate.b_wire() { Variable(Index::Input(index)) => { f_r[i] = self.input_assingments[index - 1]; - }, + } Variable(Index::Aux(index)) => { f_r[i] = self.aux_assingments[index - 1]; - }, + } } match gate.c_wire() { Variable(Index::Input(index)) => { f_o[i] = self.input_assingments[index - 1]; - }, + } Variable(Index::Aux(index)) => { f_o[i] = self.aux_assingments[index - 1]; - }, + } } } (f_l, f_r, f_o) } - pub(crate) fn make_circuit_description_polynomials(&self, worker: &Worker) -> Result<( - Polynomial::, Polynomial::, Polynomial::, - Polynomial::, Polynomial:: - ), SynthesisError> { + pub(crate) fn make_circuit_description_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, + Polynomial, + Polynomial, + Polynomial, + Polynomial, + ), + SynthesisError, + > { assert!(self.is_finalized); let total_num_gates = self.input_gates.len() + self.aux_gates.len(); @@ -273,33 +274,29 @@ impl ProvingAssembly { let mut q_m = vec![E::Fr::zero(); total_num_gates]; let mut q_c = vec![E::Fr::zero(); total_num_gates]; - fn coeff_into_field_element(coeff: & Coeff) -> F { + fn coeff_into_field_element(coeff: &Coeff) -> F { match coeff { - Coeff::Zero => { - F::zero() - }, - Coeff::One => { - F::one() - }, + Coeff::Zero => F::zero(), + Coeff::One => F::one(), Coeff::NegativeOne => { let mut tmp = F::one(); tmp.negate(); tmp - }, - Coeff::Full(c) => { - *c - }, + } + Coeff::Full(c) => *c, } } // expect a small number of inputs - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.input_gates.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .input_gates + .iter() + .zip(q_l.iter_mut()) + .zip(q_r.iter_mut()) + .zip(q_o.iter_mut()) + .zip(q_m.iter_mut()) + .zip(q_c.iter_mut()) { *q_l = coeff_into_field_element(&gate.q_l); *q_r = coeff_into_field_element(&gate.q_r); @@ -308,7 +305,6 @@ impl ProvingAssembly { *q_c = coeff_into_field_element(&gate.q_c); } - let num_input_gates = self.input_gates.len(); let q_l_aux = &mut q_l[num_input_gates..]; let q_r_aux = &mut q_r[num_input_gates..]; @@ -319,27 +315,23 @@ impl ProvingAssembly { debug_assert!(self.aux_gates.len() == q_l_aux.len()); worker.scope(self.aux_gates.len(), |scope, chunk| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in self.aux_gates.chunks(chunk) - .zip(q_l_aux.chunks_mut(chunk)) - .zip(q_r_aux.chunks_mut(chunk)) - .zip(q_o_aux.chunks_mut(chunk)) - .zip(q_m_aux.chunks_mut(chunk)) - .zip(q_c_aux.chunks_mut(chunk)) + for (((((gate, q_l), q_r), q_o), q_m), q_c) in self + .aux_gates + .chunks(chunk) + .zip(q_l_aux.chunks_mut(chunk)) + .zip(q_r_aux.chunks_mut(chunk)) + .zip(q_o_aux.chunks_mut(chunk)) + .zip(q_m_aux.chunks_mut(chunk)) + .zip(q_c_aux.chunks_mut(chunk)) { scope.spawn(move |_| { - for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter() - .zip(q_l.iter_mut()) - .zip(q_r.iter_mut()) - .zip(q_o.iter_mut()) - .zip(q_m.iter_mut()) - .zip(q_c.iter_mut()) - { - *q_l = coeff_into_field_element(&gate.q_l); - *q_r = coeff_into_field_element(&gate.q_r); - *q_o = coeff_into_field_element(&gate.q_o); - *q_m = coeff_into_field_element(&gate.q_m); - *q_c = coeff_into_field_element(&gate.q_c); - } + for (((((gate, q_l), q_r), q_o), q_m), q_c) in gate.iter().zip(q_l.iter_mut()).zip(q_r.iter_mut()).zip(q_o.iter_mut()).zip(q_m.iter_mut()).zip(q_c.iter_mut()) { + *q_l = coeff_into_field_element(&gate.q_l); + *q_r = coeff_into_field_element(&gate.q_r); + *q_o = coeff_into_field_element(&gate.q_o); + *q_m = coeff_into_field_element(&gate.q_m); + *q_c = coeff_into_field_element(&gate.q_c); + } }); } }); @@ -362,51 +354,50 @@ impl ProvingAssembly { // in the partition number i there is a set of indexes in V = (a, b, c) such that V_j = i let mut partitions = vec![vec![]; num_partitions + 1]; - for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() - { + for (j, gate) in self.input_gates.iter().chain(&self.aux_gates).enumerate() { match gate.a_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j+1); - }, + partitions[i].push(j + 1); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j+1); + partitions[i].push(j + 1); } - }, + } } match gate.b_wire() { Variable(Index::Input(index)) => { let i = *index; partitions[i].push(j + 1 + num_gates); - }, + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; partitions[i].push(j + 1 + num_gates); } - }, + } } match gate.c_wire() { Variable(Index::Input(index)) => { let i = *index; - partitions[i].push(j + 1 + 2*num_gates); - }, + partitions[i].push(j + 1 + 2 * num_gates); + } Variable(Index::Aux(index)) => { if *index != 0 { let i = index + num_inputs; - partitions[i].push(j + 1 + 2*num_gates); + partitions[i].push(j + 1 + 2 * num_gates); } - }, + } } } let mut sigma_1: Vec<_> = (1..=num_gates).collect(); - let mut sigma_2: Vec<_> = ((num_gates+1)..=(2*num_gates)).collect(); - let mut sigma_3: Vec<_> = ((2*num_gates + 1)..=(3*num_gates)).collect(); + let mut sigma_2: Vec<_> = ((num_gates + 1)..=(2 * num_gates)).collect(); + let mut sigma_3: Vec<_> = ((2 * num_gates + 1)..=(3 * num_gates)).collect(); let mut permutations = vec![vec![]; num_partitions + 1]; @@ -425,18 +416,16 @@ impl ProvingAssembly { let permutation = rotate(partition.clone()); permutations[i] = permutation.clone(); - for (original, new) in partition.into_iter() - .zip(permutation.into_iter()) - { + for (original, new) in partition.into_iter().zip(permutation.into_iter()) { if original <= num_gates { debug_assert!(sigma_1[original - 1] == original); sigma_1[original - 1] = new; - } else if original <= 2*num_gates { + } else if original <= 2 * num_gates { debug_assert!(sigma_2[original - num_gates - 1] == original); sigma_2[original - num_gates - 1] = new; } else { - debug_assert!(sigma_3[original - 2*num_gates - 1] == original); - sigma_3[original - 2*num_gates - 1] = new; + debug_assert!(sigma_3[original - 2 * num_gates - 1] == original); + sigma_3[original - 2 * num_gates - 1] = new; } } } @@ -451,19 +440,23 @@ impl ProvingAssembly { result } - pub(crate) fn output_setup_polynomials(&self, worker: &Worker) -> Result< - ( - Polynomial::, // q_l - Polynomial::, // q_r - Polynomial::, // q_o - Polynomial::, // q_m - Polynomial::, // q_c - Polynomial::, // s_id - Polynomial::, // sigma_1 - Polynomial::, // sigma_2 - Polynomial::, // sigma_3 - ), SynthesisError> - { + pub(crate) fn output_setup_polynomials( + &self, + worker: &Worker, + ) -> Result< + ( + Polynomial, // q_l + Polynomial, // q_r + Polynomial, // q_o + Polynomial, // q_m + Polynomial, // q_c + Polynomial, // s_id + Polynomial, // sigma_1 + Polynomial, // sigma_2 + Polynomial, // sigma_3 + ), + SynthesisError, + > { assert!(self.is_finalized); let s_id = self.make_s_id(); @@ -506,21 +499,21 @@ impl ProvingAssembly { return; } let n = self.input_gates.len() + self.aux_gates.len(); - if (n+1).is_power_of_two() { + if (n + 1).is_power_of_two() { self.is_finalized = true; return; } let empty_gate = Gate::::new_empty_gate(self.dummy_variable()); - let new_aux_len = (n+1).next_power_of_two() - 1 - self.input_gates.len(); + let new_aux_len = (n + 1).next_power_of_two() - 1 - self.input_gates.len(); self.aux_gates.resize(new_aux_len, empty_gate); self.is_finalized = true; } - fn calculate_inverse_vanishing_polynomial_in_a_coset(&self, worker: &Worker, poly_size:usize, vahisning_size: usize) -> Result, SynthesisError> { + fn calculate_inverse_vanishing_polynomial_in_a_coset(&self, worker: &Worker, poly_size: usize, vahisning_size: usize) -> Result, SynthesisError> { assert!(poly_size.is_power_of_two()); assert!(vahisning_size.is_power_of_two()); @@ -550,7 +543,7 @@ impl ProvingAssembly { // now we should evaluate X^(n+1) - 1 in a linear time let shift = multiplicative_generator.pow([vahisning_size as u64]); - + let mut denominator = Polynomial::::from_values(vec![shift; poly_size])?; // elements are h^size - 1, (hg)^size - 1, (hg^2)^size - 1, ... @@ -589,7 +582,7 @@ impl ProvingAssembly { numerator } - fn calculate_lagrange_poly(&self, worker: &Worker, poly_size:usize, poly_number: usize) -> Result, SynthesisError> { + fn calculate_lagrange_poly(&self, worker: &Worker, poly_size: usize, poly_number: usize) -> Result, SynthesisError> { assert!(poly_size.is_power_of_two()); assert!(poly_number < poly_size); @@ -632,15 +625,15 @@ impl ProvingAssembly { // pub openings_proof: FRI::Proof, // } -use crate::plonk::fft::cooley_tukey_ntt::CTPrecomputations; -use crate::plonk::commitments::transparent::fri::coset_combining_fri::*; use crate::plonk::commitments::transparent::fri::coset_combining_fri::fri::*; -use crate::plonk::commitments::transparent::iop_compiler::*; +use crate::plonk::commitments::transparent::fri::coset_combining_fri::*; use crate::plonk::commitments::transparent::iop_compiler::coset_combining_blake2s_tree::*; +use crate::plonk::commitments::transparent::iop_compiler::*; +use crate::plonk::fft::cooley_tukey_ntt::CTPrecomputations; use crate::plonk::transparent_engine::PartialTwoBitReductionField; #[derive(Debug)] -pub struct RedshiftSetup>{ +pub struct RedshiftSetup> { pub n: usize, pub q_l: I::Commitment, pub q_r: I::Commitment, @@ -653,20 +646,20 @@ pub struct RedshiftSetup>{ pub sigma_3: I::Commitment, } -pub struct SinglePolySetupData>{ +pub struct SinglePolySetupData> { pub poly: Polynomial, pub oracle: I, pub setup_point: F, pub setup_value: F, } -pub struct SinglePolyCommitmentData>{ +pub struct SinglePolyCommitmentData> { pub poly: Polynomial, pub oracle: I, } // #[derive(Debug)] -pub struct RedshiftSetupPrecomputation>{ +pub struct RedshiftSetupPrecomputation> { pub q_l_aux: SinglePolySetupData, pub q_r_aux: SinglePolySetupData, pub q_o_aux: SinglePolySetupData, @@ -679,7 +672,7 @@ pub struct RedshiftSetupPrecomputation>{ } #[derive(Debug, Clone)] -pub struct RedshiftParameters{ +pub struct RedshiftParameters { pub lde_factor: usize, pub num_queries: usize, pub output_coeffs_at_degree_plus_one: usize, @@ -689,7 +682,7 @@ pub struct RedshiftParameters{ struct WitnessOpeningRequest<'a, F: PrimeField> { polynomials: Vec<&'a Polynomial>, opening_point: F, - opening_values: Vec + opening_values: Vec, } struct SetupOpeningRequest<'a, F: PrimeField> { @@ -697,33 +690,30 @@ struct SetupOpeningRequest<'a, F: PrimeField> { setup_point: F, setup_values: Vec, opening_point: F, - opening_values: Vec + opening_values: Vec, } -impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { +impl ProvingAssembly +where + E::Fr: PartialTwoBitReductionField, +{ pub(crate) fn commit_single_poly>( - poly: &Polynomial, + poly: &Polynomial, omegas_bitreversed: &CP, params: &RedshiftParameters, - worker: &Worker + worker: &Worker, ) -> Result>, SynthesisError> { - let lde = poly.clone().bitreversed_lde_using_bitreversed_ntt_with_partial_reduction( - worker, - params.lde_factor, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let lde = poly + .clone() + .bitreversed_lde_using_bitreversed_ntt_with_partial_reduction(worker, params.lde_factor, omegas_bitreversed, &E::Fr::multiplicative_generator())?; let oracle_params = FriSpecificBlake2sTreeParams { - values_per_leaf: (1 << params.coset_params.cosets_schedule[0]) + values_per_leaf: (1 << params.coset_params.cosets_schedule[0]), }; let oracle = FriSpecificBlake2sTree::create(&lde.as_ref(), &oracle_params); - Ok(SinglePolyCommitmentData:: { - poly: lde, - oracle: oracle - }) + Ok(SinglePolyCommitmentData:: { poly: lde, oracle: oracle }) } // fn divide_single( @@ -757,157 +747,160 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { // q // } - fn multiopening, T: Transcript as IopInstance> :: Commitment> > - ( - witness_opening_requests: Vec>, - setup_opening_requests: Vec>, - omegas_inv_bitreversed: &P, - params: &RedshiftParameters, - worker: &Worker, - transcript: &mut T - ) -> Result<(), SynthesisError> { - let required_divisor_size = witness_opening_requests[0].polynomials[0].size(); - - let mut final_aggregate = Polynomial::from_values(vec![E::Fr::zero(); required_divisor_size])?; - - let mut precomputed_bitreversed_coset_divisor = Polynomial::from_values(vec![E::Fr::one(); required_divisor_size])?; - precomputed_bitreversed_coset_divisor.distribute_powers(&worker, precomputed_bitreversed_coset_divisor.omega); - precomputed_bitreversed_coset_divisor.scale(&worker, E::Fr::multiplicative_generator()); - precomputed_bitreversed_coset_divisor.bitreverse_enumeration(&worker); - - let mut scratch_space_numerator = final_aggregate.clone(); - let mut scratch_space_denominator = final_aggregate.clone(); - - let aggregation_challenge = transcript.get_challenge(); - - let mut alpha = E::Fr::one(); - - for witness_request in witness_opening_requests.iter() { - let z = witness_request.opening_point; - let mut minus_z = z; - minus_z.negate(); - scratch_space_denominator.reuse_allocation(&precomputed_bitreversed_coset_divisor); - scratch_space_denominator.add_constant(&worker, &minus_z); - scratch_space_denominator.batch_inversion(&worker)?; - for (poly, value) in witness_request.polynomials.iter().zip(witness_request.opening_values.iter()) { - scratch_space_numerator.reuse_allocation(&poly); - let mut v = *value; - v.negate(); - scratch_space_numerator.add_constant(&worker, &v); - scratch_space_numerator.mul_assign(&worker, &scratch_space_denominator); - if aggregation_challenge != E::Fr::one() { - scratch_space_numerator.scale(&worker, alpha); - } + fn multiopening, T: Transcript as IopInstance>::Commitment>>( + witness_opening_requests: Vec>, + setup_opening_requests: Vec>, + omegas_inv_bitreversed: &P, + params: &RedshiftParameters, + worker: &Worker, + transcript: &mut T, + ) -> Result<(), SynthesisError> { + let required_divisor_size = witness_opening_requests[0].polynomials[0].size(); + + let mut final_aggregate = Polynomial::from_values(vec![E::Fr::zero(); required_divisor_size])?; + + let mut precomputed_bitreversed_coset_divisor = Polynomial::from_values(vec![E::Fr::one(); required_divisor_size])?; + precomputed_bitreversed_coset_divisor.distribute_powers(&worker, precomputed_bitreversed_coset_divisor.omega); + precomputed_bitreversed_coset_divisor.scale(&worker, E::Fr::multiplicative_generator()); + precomputed_bitreversed_coset_divisor.bitreverse_enumeration(&worker); + + let mut scratch_space_numerator = final_aggregate.clone(); + let mut scratch_space_denominator = final_aggregate.clone(); + + let aggregation_challenge = transcript.get_challenge(); + + let mut alpha = E::Fr::one(); + + for witness_request in witness_opening_requests.iter() { + let z = witness_request.opening_point; + let mut minus_z = z; + minus_z.negate(); + scratch_space_denominator.reuse_allocation(&precomputed_bitreversed_coset_divisor); + scratch_space_denominator.add_constant(&worker, &minus_z); + scratch_space_denominator.batch_inversion(&worker)?; + for (poly, value) in witness_request.polynomials.iter().zip(witness_request.opening_values.iter()) { + scratch_space_numerator.reuse_allocation(&poly); + let mut v = *value; + v.negate(); + scratch_space_numerator.add_constant(&worker, &v); + scratch_space_numerator.mul_assign(&worker, &scratch_space_denominator); + if aggregation_challenge != E::Fr::one() { + scratch_space_numerator.scale(&worker, alpha); + } - final_aggregate.add_assign(&worker, &scratch_space_numerator); + final_aggregate.add_assign(&worker, &scratch_space_numerator); - alpha.mul_assign(&aggregation_challenge); - } + alpha.mul_assign(&aggregation_challenge); } + } - for setup_request in setup_opening_requests.iter() { - // for now assume a single setup point per poly and setup point is the same for all polys - // (omega - y)(omega - z) = omega^2 - (z+y)*omega + zy - - let setup_point = setup_request.setup_point; - let opening_point = setup_request.opening_point; + for setup_request in setup_opening_requests.iter() { + // for now assume a single setup point per poly and setup point is the same for all polys + // (omega - y)(omega - z) = omega^2 - (z+y)*omega + zy - let mut t0 = setup_point; - t0.add_assign(&opening_point); - t0.negate(); + let setup_point = setup_request.setup_point; + let opening_point = setup_request.opening_point; - let mut t1 = setup_point; - t1.mul_assign(&opening_point); + let mut t0 = setup_point; + t0.add_assign(&opening_point); + t0.negate(); - scratch_space_denominator.reuse_allocation(&precomputed_bitreversed_coset_divisor); - worker.scope(scratch_space_denominator.as_ref().len(), |scope, chunk| { - for den in scratch_space_denominator.as_mut().chunks_mut(chunk) { - scope.spawn(move |_| { - for d in den.iter_mut() { - let mut result = *d; - result.square(); - result.add_assign(&t1); + let mut t1 = setup_point; + t1.mul_assign(&opening_point); - let mut tmp = t0; - tmp.mul_assign(&d); + scratch_space_denominator.reuse_allocation(&precomputed_bitreversed_coset_divisor); + worker.scope(scratch_space_denominator.as_ref().len(), |scope, chunk| { + for den in scratch_space_denominator.as_mut().chunks_mut(chunk) { + scope.spawn(move |_| { + for d in den.iter_mut() { + let mut result = *d; + result.square(); + result.add_assign(&t1); - result.add_assign(&tmp); + let mut tmp = t0; + tmp.mul_assign(&d); - *d = result; - } - }); - } - }); + result.add_assign(&tmp); - scratch_space_denominator.batch_inversion(&worker)?; + *d = result; + } + }); + } + }); - // each numerator must have a value removed of the polynomial that interpolates the following points: - // (setup_x, setup_y) - // (opening_x, opening_y) - // such polynomial is linear and has a form e.g setup_y + (X - setup_x) * (witness_y - setup_y) / (witness_x - setup_x) + scratch_space_denominator.batch_inversion(&worker)?; - for ((poly, value), setup_value) in setup_request.polynomials.iter().zip(setup_request.opening_values.iter()).zip(setup_request.setup_values.iter()) { - scratch_space_numerator.reuse_allocation(&poly); + // each numerator must have a value removed of the polynomial that interpolates the following points: + // (setup_x, setup_y) + // (opening_x, opening_y) + // such polynomial is linear and has a form e.g setup_y + (X - setup_x) * (witness_y - setup_y) / (witness_x - setup_x) - let intercept = setup_value; - let mut t0 = opening_point; - t0.sub_assign(&setup_point); + for ((poly, value), setup_value) in setup_request.polynomials.iter().zip(setup_request.opening_values.iter()).zip(setup_request.setup_values.iter()) { + scratch_space_numerator.reuse_allocation(&poly); - let mut slope = t0.inverse().expect("must exist"); - - let mut t1 = *value; - t1.sub_assign(&setup_value); + let intercept = setup_value; + let mut t0 = opening_point; + t0.sub_assign(&setup_point); - slope.mul_assign(&t1); + let mut slope = t0.inverse().expect("must exist"); - worker.scope(scratch_space_numerator.as_ref().len(), |scope, chunk| { - for (num, omega) in scratch_space_numerator.as_mut().chunks_mut(chunk). - zip(precomputed_bitreversed_coset_divisor.as_ref().chunks(chunk)) { - scope.spawn(move |_| { - for (n, omega) in num.iter_mut().zip(omega.iter()) { - let mut result = *omega; - result.sub_assign(&setup_point); - result.mul_assign(&slope); - result.add_assign(&intercept); + let mut t1 = *value; + t1.sub_assign(&setup_value); - n.sub_assign(&result); - } - }); - } - }); + slope.mul_assign(&t1); - scratch_space_numerator.mul_assign(&worker, &scratch_space_denominator); - if aggregation_challenge != E::Fr::one() { - scratch_space_numerator.scale(&worker, alpha); - } + worker.scope(scratch_space_numerator.as_ref().len(), |scope, chunk| { + for (num, omega) in scratch_space_numerator.as_mut().chunks_mut(chunk).zip(precomputed_bitreversed_coset_divisor.as_ref().chunks(chunk)) { + scope.spawn(move |_| { + for (n, omega) in num.iter_mut().zip(omega.iter()) { + let mut result = *omega; + result.sub_assign(&setup_point); + result.mul_assign(&slope); + result.add_assign(&intercept); - final_aggregate.add_assign(&worker, &scratch_space_numerator); + n.sub_assign(&result); + } + }); + } + }); - alpha.mul_assign(&aggregation_challenge); + scratch_space_numerator.mul_assign(&worker, &scratch_space_denominator); + if aggregation_challenge != E::Fr::one() { + scratch_space_numerator.scale(&worker, alpha); } + + final_aggregate.add_assign(&worker, &scratch_space_numerator); + + alpha.mul_assign(&aggregation_challenge); } + } - let fri_proto = CosetCombiningFriIop::proof_from_lde( - &final_aggregate, - params.lde_factor, - params.output_coeffs_at_degree_plus_one, - omegas_inv_bitreversed, - &worker, - transcript, - ¶ms.coset_params - )?; + let fri_proto = CosetCombiningFriIop::proof_from_lde( + &final_aggregate, + params.lde_factor, + params.output_coeffs_at_degree_plus_one, + omegas_inv_bitreversed, + &worker, + transcript, + ¶ms.coset_params, + )?; - Ok(()) + Ok(()) } - fn prove_with_setup_precomputed, CPI: CTPrecomputations, FP: FriPrecomputations, T: Transcript as IopInstance> :: Commitment> >( + fn prove_with_setup_precomputed< + CP: CTPrecomputations, + CPI: CTPrecomputations, + FP: FriPrecomputations, + T: Transcript as IopInstance>::Commitment>, + >( self, setup_precomp: &RedshiftSetupPrecomputation>, params: &RedshiftParameters, worker: &Worker, omegas_bitreversed: &CP, omegas_inv_bitreversed: &CPI, - bitreversed_omegas_for_fri: &FP + bitreversed_omegas_for_fri: &FP, ) -> Result<(), SynthesisError> { assert!(self.is_finalized); @@ -926,9 +919,15 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { let w_r = Polynomial::::from_values_unpadded(w_r)?; let w_o = Polynomial::::from_values_unpadded(w_o)?; - let a_poly = w_l.clone_padded_to_domain()?.ifft_using_bitreversed_ntt_with_partial_reduction(&worker, omegas_inv_bitreversed, &E::Fr::one())?; - let b_poly = w_r.clone_padded_to_domain()?.ifft_using_bitreversed_ntt_with_partial_reduction(&worker, omegas_inv_bitreversed, &E::Fr::one())?; - let c_poly = w_o.clone_padded_to_domain()?.ifft_using_bitreversed_ntt_with_partial_reduction(&worker, omegas_inv_bitreversed, &E::Fr::one())?; + let a_poly = w_l + .clone_padded_to_domain()? + .ifft_using_bitreversed_ntt_with_partial_reduction(&worker, omegas_inv_bitreversed, &E::Fr::one())?; + let b_poly = w_r + .clone_padded_to_domain()? + .ifft_using_bitreversed_ntt_with_partial_reduction(&worker, omegas_inv_bitreversed, &E::Fr::one())?; + let c_poly = w_o + .clone_padded_to_domain()? + .ifft_using_bitreversed_ntt_with_partial_reduction(&worker, omegas_inv_bitreversed, &E::Fr::one())?; // polynomials inside of these is are values in cosets @@ -965,7 +964,7 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { w_l_contribution.add_assign_scaled(&worker, &s_id_1, &beta); drop(s_id_1); - let s_id_2: Vec<_> = ((n+1)..=(2*n)).collect(); + let s_id_2: Vec<_> = ((n + 1)..=(2 * n)).collect(); let s_id_2 = convert_to_field_elements(&s_id_2, &worker); let s_id_2 = Polynomial::::from_values_unpadded(s_id_2)?; let mut w_r_contribution = w_r_plus_gamma.clone(); @@ -974,7 +973,7 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { w_l_contribution.mul_assign(&worker, &w_r_contribution); drop(w_r_contribution); - let s_id_3: Vec<_> = ((2*n+1)..=(3*n)).collect(); + let s_id_3: Vec<_> = ((2 * n + 1)..=(3 * n)).collect(); let s_id_3 = convert_to_field_elements(&s_id_3, &worker); let s_id_3 = Polynomial::::from_values_unpadded(s_id_3)?; let mut w_o_contribution = w_o_plus_gamma.clone(); @@ -1052,7 +1051,7 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { let mut z_1_shifted = z_1.clone(); z_1_shifted.distribute_powers(&worker, z_1.omega); - + let mut z_2_shifted = z_2.clone(); z_2_shifted.distribute_powers(&worker, z_2.omega); @@ -1064,7 +1063,7 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { let a_coset_lde_bitreversed = a_commitment_data.poly.clone_subset_assuming_bitreversed(partition_factor)?; let b_coset_lde_bitreversed = b_commitment_data.poly.clone_subset_assuming_bitreversed(partition_factor)?; let c_coset_lde_bitreversed = c_commitment_data.poly.clone_subset_assuming_bitreversed(partition_factor)?; - + let q_l_coset_lde_bitreversed = setup_precomp.q_l_aux.poly.clone_subset_assuming_bitreversed(partition_factor)?; let q_r_coset_lde_bitreversed = setup_precomp.q_r_aux.poly.clone_subset_assuming_bitreversed(partition_factor)?; let q_o_coset_lde_bitreversed = setup_precomp.q_o_aux.poly.clone_subset_assuming_bitreversed(partition_factor)?; @@ -1129,37 +1128,31 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { break; } } - + println!("Degree = {}", degree); - + degree } let z_1_coset_lde_bitreversed = z_1_commitment_data.poly.clone_subset_assuming_bitreversed(partition_factor)?; - assert!(z_1_coset_lde_bitreversed.size() == required_domain_size*4); + assert!(z_1_coset_lde_bitreversed.size() == required_domain_size * 4); - let z_1_shifted_coset_lde_bitreversed = z_1_shifted.clone().bitreversed_lde_using_bitreversed_ntt_with_partial_reduction( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let z_1_shifted_coset_lde_bitreversed = z_1_shifted + .clone() + .bitreversed_lde_using_bitreversed_ntt_with_partial_reduction(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; - assert!(z_1_shifted_coset_lde_bitreversed.size() == required_domain_size*4); + assert!(z_1_shifted_coset_lde_bitreversed.size() == required_domain_size * 4); let z_2_coset_lde_bitreversed = z_2_commitment_data.poly.clone_subset_assuming_bitreversed(partition_factor)?; - assert!(z_2_coset_lde_bitreversed.size() == required_domain_size*4); + assert!(z_2_coset_lde_bitreversed.size() == required_domain_size * 4); - let z_2_shifted_coset_lde_bitreversed = z_2_shifted.clone().bitreversed_lde_using_bitreversed_ntt_with_partial_reduction( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let z_2_shifted_coset_lde_bitreversed = z_2_shifted + .clone() + .bitreversed_lde_using_bitreversed_ntt_with_partial_reduction(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; - assert!(z_2_shifted_coset_lde_bitreversed.size() == required_domain_size*4); + assert!(z_2_shifted_coset_lde_bitreversed.size() == required_domain_size * 4); // (A + beta*i + gamma)(B + beta(n+i) + gamma)(C + beta(2n+i) + gamma)*Z(k) = Z(k+1) { @@ -1215,7 +1208,6 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { contrib_z_2.mul_assign(&worker, &a_perm); drop(a_perm); - let mut b_perm = sigma_2_coset_lde_bitreversed; b_perm.scale(&worker, beta); b_perm.add_constant(&worker, &gamma); @@ -1244,18 +1236,15 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { drop(c_coset_lde_bitreversed); let l_0 = self.calculate_lagrange_poly(&worker, required_domain_size.next_power_of_two(), 0)?; - let l_n_minus_one = self.calculate_lagrange_poly(&worker, required_domain_size.next_power_of_two(), n-1)?; + let l_n_minus_one = self.calculate_lagrange_poly(&worker, required_domain_size.next_power_of_two(), n - 1)?; { let mut z_1_minus_z_2_shifted = z_1_shifted_coset_lde_bitreversed.clone(); z_1_minus_z_2_shifted.sub_assign(&worker, &z_2_shifted_coset_lde_bitreversed); - let l_coset_lde_bitreversed = l_n_minus_one.clone().bitreversed_lde_using_bitreversed_ntt_with_partial_reduction( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let l_coset_lde_bitreversed = l_n_minus_one + .clone() + .bitreversed_lde_using_bitreversed_ntt_with_partial_reduction(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; z_1_minus_z_2_shifted.mul_assign(&worker, &l_coset_lde_bitreversed); drop(l_coset_lde_bitreversed); @@ -1271,12 +1260,9 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { let mut z_1_minus_z_2 = z_1_coset_lde_bitreversed.clone(); z_1_minus_z_2.sub_assign(&worker, &z_2_coset_lde_bitreversed); - let l_coset_lde_bitreversed = l_0.clone().bitreversed_lde_using_bitreversed_ntt_with_partial_reduction( - &worker, - 4, - omegas_bitreversed, - &E::Fr::multiplicative_generator() - )?; + let l_coset_lde_bitreversed = l_0 + .clone() + .bitreversed_lde_using_bitreversed_ntt_with_partial_reduction(&worker, 4, omegas_bitreversed, &E::Fr::multiplicative_generator())?; z_1_minus_z_2.mul_assign(&worker, &l_coset_lde_bitreversed); drop(l_coset_lde_bitreversed); @@ -1297,7 +1283,7 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { let t_poly = t_1.icoset_fft_for_generator(&worker, &E::Fr::multiplicative_generator()); - debug_assert!(get_degree::(&t_poly) <= 3*n); + debug_assert!(get_degree::(&t_poly) <= 3 * n); let mut t_poly_parts = t_poly.break_into_multiples(required_domain_size)?; @@ -1521,31 +1507,16 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { &z_2_commitment_data.poly, &t_poly_low_commitment_data.poly, &t_poly_mid_commitment_data.poly, - &t_poly_high_commitment_data.poly + &t_poly_high_commitment_data.poly, ], opening_point: z, - opening_values: vec![ - a_at_z, - b_at_z, - c_at_z, - z_1_at_z, - z_2_at_z, - t_low_at_z, - t_mid_at_z, - t_high_at_z, - ] + opening_values: vec![a_at_z, b_at_z, c_at_z, z_1_at_z, z_2_at_z, t_low_at_z, t_mid_at_z, t_high_at_z], }; let witness_opening_request_at_z_omega = WitnessOpeningRequest { - polynomials: vec![ - &z_1_commitment_data.poly, - &z_2_commitment_data.poly, - ], + polynomials: vec![&z_1_commitment_data.poly, &z_2_commitment_data.poly], opening_point: z_by_omega, - opening_values: vec![ - z_1_shifted_at_z, - z_2_shifted_at_z, - ] + opening_values: vec![z_1_shifted_at_z, z_2_shifted_at_z], }; let setup_opening_request = SetupOpeningRequest { @@ -1573,25 +1544,16 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { setup_precomp.sigma_3_aux.setup_value, ], opening_point: z, - opening_values: vec![ - q_l_at_z, - q_r_at_z, - q_o_at_z, - q_m_at_z, - q_c_at_z, - s_id_at_z, - sigma_1_at_z, - sigma_2_at_z, - sigma_3_at_z, - ] + opening_values: vec![q_l_at_z, q_r_at_z, q_o_at_z, q_m_at_z, q_c_at_z, s_id_at_z, sigma_1_at_z, sigma_2_at_z, sigma_3_at_z], }; - let _ = Self::multiopening(vec![witness_opening_request_at_z, witness_opening_request_at_z_omega], - vec![setup_opening_request], - bitreversed_omegas_for_fri, - ¶ms, - &worker, - &mut transcript + let _ = Self::multiopening( + vec![witness_opening_request_at_z, witness_opening_request_at_z_omega], + vec![setup_opening_request], + bitreversed_omegas_for_fri, + ¶ms, + &worker, + &mut transcript, )?; Ok(()) @@ -1601,18 +1563,18 @@ impl ProvingAssembly where E::Fr : PartialTwoBitReductionField { #[cfg(test)] mod test { - use crate::plonk::cs::*; + use super::super::generator::*; + use super::*; use crate::pairing::Engine; + use crate::plonk::cs::*; use crate::SynthesisError; - use super::*; - use super::super::generator::*; use crate::ff::{Field, PrimeField}; #[derive(Clone)] - struct BenchmarkCircuit{ + struct BenchmarkCircuit { num_steps: usize, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl Circuit for BenchmarkCircuit { @@ -1625,21 +1587,15 @@ mod test { let mut two = one; two.double(); - - let mut a = cs.alloc(|| { - Ok(E::Fr::one()) - })?; - let mut b = cs.alloc(|| { - Ok(E::Fr::one()) - })?; + let mut a = cs.alloc(|| Ok(E::Fr::one()))?; + + let mut b = cs.alloc(|| Ok(E::Fr::one()))?; cs.enforce_zero_2((a, b), (one, negative_one))?; // cs.enforce_zero_2((b, CS::ONE), (one, negative_one))?; - let mut c = cs.alloc(|| { - Ok(two) - })?; + let mut c = cs.alloc(|| Ok(two))?; cs.enforce_zero_3((a, b, c), (one, one, negative_one))?; @@ -1655,9 +1611,7 @@ mod test { b_value = c_value; c_value.add_assign(&a_value); - c = cs.alloc(|| { - Ok(c_value) - })?; + c = cs.alloc(|| Ok(c_value))?; cs.enforce_zero_3((a, b, c), (one, one, negative_one))?; } @@ -1668,27 +1622,27 @@ mod test { #[test] fn test_bench_redshift() { - use crate::pairing::Engine; use crate::ff::ScalarEngine; - use crate::plonk::transparent_engine::{TransparentEngine, PartialTwoBitReductionField}; - use crate::plonk::transparent_engine::proth_engine::Transparent252; - use crate::plonk::utils::*; + use crate::pairing::Engine; + use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::transparent::fri::coset_combining_fri::*; use crate::plonk::commitments::transparent::iop_compiler::*; - use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::*; + use crate::plonk::transparent_engine::proth_engine::Transparent252; + use crate::plonk::transparent_engine::{PartialTwoBitReductionField, TransparentEngine}; + use crate::plonk::utils::*; use crate::worker::Worker; // use crate::plonk::tester::*; type Fr = ::Fr; type Transcr = Blake2sTranscript; - use crate::plonk::fft::cooley_tukey_ntt::*; - use crate::plonk::commitments::transparent::fri::coset_combining_fri::*; use crate::plonk::commitments::transparent::fri::coset_combining_fri::fri::*; use crate::plonk::commitments::transparent::fri::coset_combining_fri::precomputation::*; - use crate::plonk::commitments::transparent::iop_compiler::*; + use crate::plonk::commitments::transparent::fri::coset_combining_fri::*; use crate::plonk::commitments::transparent::iop_compiler::coset_combining_blake2s_tree::*; + use crate::plonk::commitments::transparent::iop_compiler::*; + use crate::plonk::fft::cooley_tukey_ntt::*; use std::time::Instant; @@ -1697,12 +1651,12 @@ mod test { println!("Using rate {}", rate); let sizes = vec![(1 << 18) - 10, (1 << 19) - 10, (1 << 20) - 10, (1 << 21) - 10, (1 << 22) - 10, (1 << 23) - 10]; let coset_schedules = vec![ - vec![3, 3, 3, 3, 3, 3], // 18 - vec![3, 3, 3, 3, 3, 2, 2], // 19 - vec![3, 3, 3, 3, 3, 3, 2], // 20 - vec![3, 3, 3, 3, 3, 3, 3], // 21 - vec![3, 3, 3, 3, 3, 3, 2, 2], // 22 - vec![3, 3, 3, 3, 3, 3, 3, 2], // 23 + vec![3, 3, 3, 3, 3, 3], // 18 + vec![3, 3, 3, 3, 3, 2, 2], // 19 + vec![3, 3, 3, 3, 3, 3, 2], // 20 + vec![3, 3, 3, 3, 3, 3, 3], // 21 + vec![3, 3, 3, 3, 3, 3, 2, 2], // 22 + vec![3, 3, 3, 3, 3, 3, 3, 2], // 23 ]; let worker = Worker::new(); @@ -1711,30 +1665,26 @@ mod test { println!("Working for size {}", size); let coset_params = CosetParams { cosets_schedule: coset_schedule, - coset_factor: Fr::multiplicative_generator() + coset_factor: Fr::multiplicative_generator(), }; let params = RedshiftParameters { lde_factor: rate, num_queries: 4, output_coeffs_at_degree_plus_one: 1, - coset_params: coset_params + coset_params: coset_params, }; let circuit = BenchmarkCircuit:: { num_steps: size, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed_for_fri = as FriPrecomputations::>::new_for_domain_size(size.next_power_of_two() * rate); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); + let omegas_inv_bitreversed_for_fri = as FriPrecomputations>::new_for_domain_size(size.next_power_of_two() * rate); - let (_, setup_precomp) = setup_with_precomputations::( - &circuit, - ¶ms, - &omegas_bitreversed - ).unwrap(); + let (_, setup_precomp) = setup_with_precomputations::(&circuit, ¶ms, &omegas_bitreversed).unwrap(); let mut prover = ProvingAssembly::::new(); circuit.synthesize(&mut prover).unwrap(); @@ -1744,18 +1694,12 @@ mod test { let start = Instant::now(); - let _ = prover.prove_with_setup_precomputed::<_, _, _, Transcr>( - &setup_precomp, - ¶ms, - &worker, - &omegas_bitreversed, - &omegas_inv_bitreversed, - &omegas_inv_bitreversed_for_fri - ).unwrap(); + let _ = prover + .prove_with_setup_precomputed::<_, _, _, Transcr>(&setup_precomp, ¶ms, &worker, &omegas_bitreversed, &omegas_inv_bitreversed, &omegas_inv_bitreversed_for_fri) + .unwrap(); println!("Proving taken {:?} for size {}", start.elapsed(), size); - // { // let mut tester = TestingAssembly::::new(); @@ -1791,18 +1735,18 @@ mod test { #[test] fn test_ifft_using_ntt() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use crate::plonk::fft::cooley_tukey_ntt::*; - use crate::plonk::commitments::transparent::fri::coset_combining_fri::*; + use crate::ff::ScalarEngine; + use crate::pairing::Engine; use crate::plonk::commitments::transparent::fri::coset_combining_fri::fri::*; use crate::plonk::commitments::transparent::fri::coset_combining_fri::precomputation::*; - use crate::pairing::Engine; - use crate::ff::ScalarEngine; - use crate::plonk::transparent_engine::{TransparentEngine, PartialTwoBitReductionField}; + use crate::plonk::commitments::transparent::fri::coset_combining_fri::*; + use crate::plonk::fft::cooley_tukey_ntt::*; use crate::plonk::transparent_engine::proth_engine::Transparent252; + use crate::plonk::transparent_engine::{PartialTwoBitReductionField, TransparentEngine}; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; - use crate::worker::*; use crate::source::*; + use crate::worker::*; type Fr = ::Fr; @@ -1816,7 +1760,7 @@ mod test { let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::>(); let poly = Polynomial::::from_values(coeffs).unwrap(); let naive_result = poly.clone().icoset_fft_for_generator(&worker, &Fr::one()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size((poly_size as usize).next_power_of_two()); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size((poly_size as usize).next_power_of_two()); let ntt_result = poly.clone().ifft_using_bitreversed_ntt(&worker, &omegas_inv_bitreversed, &Fr::one()).unwrap(); assert!(naive_result == ntt_result); @@ -1826,7 +1770,7 @@ mod test { let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::>(); let poly = Polynomial::::from_values(coeffs).unwrap(); let naive_result = poly.clone().icoset_fft_for_generator(&worker, &Fr::multiplicative_generator()); - let omegas_inv_bitreversed = as CTPrecomputations::>::new_for_domain_size((poly_size as usize).next_power_of_two()); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size((poly_size as usize).next_power_of_two()); let ntt_result = poly.clone().ifft_using_bitreversed_ntt(&worker, &omegas_inv_bitreversed, &Fr::multiplicative_generator()).unwrap(); assert!(naive_result == ntt_result); @@ -1835,15 +1779,15 @@ mod test { #[test] fn test_fft_test_vectors() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use crate::plonk::fft::*; - use crate::pairing::Engine; use crate::ff::ScalarEngine; - use crate::plonk::transparent_engine::{TransparentEngine}; + use crate::pairing::Engine; + use crate::plonk::fft::*; use crate::plonk::transparent_engine::proth_engine::Transparent252; + use crate::plonk::transparent_engine::TransparentEngine; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; - use crate::worker::*; use crate::source::*; + use crate::worker::*; type Fr = ::Fr; @@ -1875,4 +1819,4 @@ mod test { } } } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/tester/mod.rs b/crates/bellman/src/plonk/tester/mod.rs index 24e0b70..841f620 100644 --- a/crates/bellman/src/plonk/tester/mod.rs +++ b/crates/bellman/src/plonk/tester/mod.rs @@ -1,20 +1,19 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use crate::plonk::cs::gates::*; use crate::plonk::cs::*; -use crate::worker::*; -use super::polynomials::*; use super::domains::*; -use crate::plonk::commitments::*; +use super::polynomials::*; use crate::plonk::commitments::transcript::*; -use crate::plonk::utils::*; +use crate::plonk::commitments::*; use crate::plonk::generator::*; - +use crate::plonk::utils::*; +use crate::worker::*; #[derive(Debug)] pub struct TestingAssembly { @@ -31,14 +30,14 @@ pub struct TestingAssembly { inputs_map: Vec, - is_finalized: bool + is_finalized: bool, } impl ConstraintSystem for TestingAssembly { // allocate a variable fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -52,7 +51,7 @@ impl ConstraintSystem for TestingAssembly { // allocate an input variable fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let value = value()?; @@ -67,7 +66,6 @@ impl ConstraintSystem for TestingAssembly { self.input_gates.push(gate); Ok(input_var) - } // enforce variable as boolean @@ -80,9 +78,7 @@ impl ConstraintSystem for TestingAssembly { } // allocate an abstract gate - fn new_gate(&mut self, variables: (Variable, Variable, Variable), - coeffs:(E::Fr,E::Fr,E::Fr,E::Fr,E::Fr)) -> Result<(), SynthesisError> - { + fn new_gate(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; @@ -91,8 +87,7 @@ impl ConstraintSystem for TestingAssembly { } // allocate a constant - fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> - { + fn enforce_constant(&mut self, variable: Variable, constant: E::Fr) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_constant_gate(variable, Some(constant), self.dummy_variable()); self.aux_gates.push(gate); self.n += 1; @@ -124,8 +119,7 @@ impl ConstraintSystem for TestingAssembly { } // allocate a linear combination gate - fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs:(E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_2(&mut self, variables: (Variable, Variable), coeffs: (E::Fr, E::Fr)) -> Result<(), SynthesisError> { let (v_0, v_1) = variables; let (c_0, c_1) = coeffs; let zero = E::Fr::zero(); @@ -138,8 +132,7 @@ impl ConstraintSystem for TestingAssembly { } // allocate a linear combination gate - fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs:(E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> - { + fn enforce_zero_3(&mut self, variables: (Variable, Variable, Variable), coeffs: (E::Fr, E::Fr, E::Fr)) -> Result<(), SynthesisError> { let gate = Gate::::new_enforce_zero_gate(variables, coeffs); self.aux_gates.push(gate); self.n += 1; @@ -175,8 +168,8 @@ impl TestingAssembly { tmp.enforce_constant(zero, E::Fr::zero()).expect("should have no issues"); match (tmp.dummy_variable(), zero) { - (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {}, - _ => panic!("zero variable is incorrect") + (Variable(Index::Aux(1)), Variable(Index::Aux(1))) => {} + _ => panic!("zero variable is incorrect"), } tmp @@ -199,13 +192,13 @@ impl TestingAssembly { return; } let n = self.input_gates.len() + self.aux_gates.len(); - if (n+1).is_power_of_two() { + if (n + 1).is_power_of_two() { return; } let empty_gate = Gate::::new_empty_gate(self.dummy_variable()); - let new_aux_len = (n+1).next_power_of_two() - 1 - self.input_gates.len(); + let new_aux_len = (n + 1).next_power_of_two() - 1 - self.input_gates.len(); self.aux_gates.resize(new_aux_len, empty_gate); @@ -214,12 +207,8 @@ impl TestingAssembly { fn get_value(&self, var: &Variable) -> E::Fr { match var { - Variable(Index::Input(input)) => { - self.input_assingments[*input - 1] - }, - Variable(Index::Aux(aux)) => { - self.aux_assingments[*aux - 1] - } + Variable(Index::Input(input)) => self.input_assingments[*input - 1], + Variable(Index::Aux(aux)) => self.aux_assingments[*aux - 1], } } @@ -227,29 +216,22 @@ impl TestingAssembly { self.finalize(); assert!(self.is_finalized); - fn coeff_into_field_element(coeff: & Coeff) -> F { + fn coeff_into_field_element(coeff: &Coeff) -> F { match coeff { - Coeff::Zero => { - F::zero() - }, - Coeff::One => { - F::one() - }, + Coeff::Zero => F::zero(), + Coeff::One => F::one(), Coeff::NegativeOne => { let mut tmp = F::one(); tmp.negate(); tmp - }, - Coeff::Full(c) => { - *c - }, + } + Coeff::Full(c) => *c, } } // expect a small number of inputs - for (i, gate) in self.input_gates.iter().enumerate() - { + for (i, gate) in self.input_gates.iter().enumerate() { let q_l = coeff_into_field_element(&gate.q_l); let q_r = coeff_into_field_element(&gate.q_r); let q_o = coeff_into_field_element(&gate.q_o); @@ -280,13 +262,12 @@ impl TestingAssembly { res.add_assign(&tmp); if !res.is_zero() { - println!("Unsatisfied at input gate {}", i+1); + println!("Unsatisfied at input gate {}", i + 1); return false; } } - for (i, gate) in self.aux_gates.iter().enumerate() - { + for (i, gate) in self.aux_gates.iter().enumerate() { let q_l = coeff_into_field_element(&gate.q_l); let q_r = coeff_into_field_element(&gate.q_r); let q_o = coeff_into_field_element(&gate.q_o); @@ -317,7 +298,7 @@ impl TestingAssembly { res.add_assign(&tmp); if !res.is_zero() { - println!("Unsatisfied at aux gate {}", i+1); + println!("Unsatisfied at aux gate {}", i + 1); println!("Gate {:?}", *gate); println!("A = {}, B = {}, C = {}", a_value, b_value, c_value); return false; @@ -326,4 +307,4 @@ impl TestingAssembly { true } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/transparent_engine/impl_macro.rs b/crates/bellman/src/plonk/transparent_engine/impl_macro.rs index e6cf0da..9922bf2 100644 --- a/crates/bellman/src/plonk/transparent_engine/impl_macro.rs +++ b/crates/bellman/src/plonk/transparent_engine/impl_macro.rs @@ -20,22 +20,23 @@ macro_rules! transparent_engine_impl { type Fqk = $fr; fn miller_loop<'a, I>(_i: I) -> Self::Fqk - where I: IntoIterator::Prepared, - &'a ::Prepared - )> + where + I: IntoIterator< + Item = &'a ( + &'a ::Prepared, + &'a ::Prepared, + ), + >, { <$fr as crate::ff::Field>::zero() } /// Perform final exponentiation of the result of a miller loop. - fn final_exponentiation(this: &Self::Fqk) -> Option - { + fn final_exponentiation(this: &Self::Fqk) -> Option { Some(*this) } } - impl crate::pairing::CurveProjective for $fr { type Affine = $fr; type Base = $fr; @@ -54,9 +55,7 @@ macro_rules! transparent_engine_impl { <$fr as crate::ff::Field>::is_zero(self) } - fn batch_normalization(_: &mut [Self]) { - - } + fn batch_normalization(_: &mut [Self]) {} fn is_normalized(&self) -> bool { true @@ -78,8 +77,7 @@ macro_rules! transparent_engine_impl { <$fr as crate::ff::Field>::negate(self); } - fn mul_assign::Repr>>(self: &mut Self, other: S) - { + fn mul_assign::Repr>>(self: &mut Self, other: S) { let tmp = <$fr as crate::ff::PrimeField>::from_repr(other.into()).unwrap(); <$fr as crate::ff::Field>::mul_assign(self, &tmp); @@ -164,8 +162,7 @@ macro_rules! transparent_engine_impl { <$fr as crate::ff::Field>::negate(self); } - fn mul::Repr>>(&self, other: S) -> Self::Projective - { + fn mul::Repr>>(&self, other: S) -> Self::Projective { let mut res = *self; let tmp = <$fr as crate::ff::PrimeField>::from_repr(other.into()).unwrap(); @@ -217,10 +214,7 @@ macro_rules! transparent_engine_impl { Self::Uncompressed::empty() } - fn from_raw_uncompressed_le_unchecked( - _encoded: &Self::Uncompressed, - _infinity: bool - ) -> Result { + fn from_raw_uncompressed_le_unchecked(_encoded: &Self::Uncompressed, _infinity: bool) -> Result { Ok(::zero()) } @@ -228,5 +222,5 @@ macro_rules! transparent_engine_impl { Self::from_raw_uncompressed_le_unchecked(&encoded, _infinity) } } - } -} \ No newline at end of file + }; +} diff --git a/crates/bellman/src/plonk/transparent_engine/mod.rs b/crates/bellman/src/plonk/transparent_engine/mod.rs index 1bea069..125020a 100644 --- a/crates/bellman/src/plonk/transparent_engine/mod.rs +++ b/crates/bellman/src/plonk/transparent_engine/mod.rs @@ -47,7 +47,7 @@ pub mod engine { use super::impl_macro::*; - transparent_engine_impl!{Transparent252, Fr} + transparent_engine_impl! {Transparent252, Fr} } pub use self::engine::Transparent252; @@ -59,13 +59,13 @@ pub(crate) mod proth_engine; mod test { #[test] fn test_bench_proth_lde() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use super::Fr as FrMontNaive; use super::proth::Fr as FrOptimized; + use super::Fr as FrMontNaive; + use crate::plonk::commitments::transparent::utils::*; use crate::plonk::polynomials::*; - use std::time::Instant; use crate::worker::*; - use crate::plonk::commitments::transparent::utils::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; let poly_sizes = vec![1_000_000, 2_000_000, 4_000_000]; @@ -75,7 +75,7 @@ mod test { let res1 = { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..poly_size).map(|_| FrMontNaive::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let start = Instant::now(); let eval_result = poly.lde(&worker, 16).unwrap(); @@ -87,7 +87,7 @@ mod test { let res2 = { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..poly_size).map(|_| FrOptimized::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let start = Instant::now(); let eval_result = poly.lde(&worker, 16).unwrap(); @@ -97,15 +97,14 @@ mod test { }; assert_eq!(format!("{}", res1[0]), format!("{}", res2[0])); - } } #[test] fn test_proth_field() { - use crate::ff::{Field, PrimeField, to_hex}; - use super::Fr as FrMontNaive; use super::proth::Fr as FrOptimized; + use super::Fr as FrMontNaive; + use crate::ff::{to_hex, Field, PrimeField}; let one_naive = FrMontNaive::from_str("1").unwrap(); let one_optimized = FrOptimized::from_str("1").unwrap(); @@ -129,18 +128,18 @@ mod test { #[test] fn test_bench_precomputations_for_proth_fft() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use super::Fr as FrMontNaive; use super::proth::Fr as FrOptimized; - use crate::plonk::polynomials::*; - use std::time::Instant; - use crate::worker::*; + use super::Fr as FrMontNaive; + use crate::plonk::commitments::transparent::precomputations::*; use crate::plonk::commitments::transparent::utils::*; + use crate::plonk::domains::Domain; use crate::plonk::fft::fft::best_fft; - use crate::plonk::fft::with_precomputation::FftPrecomputations; use crate::plonk::fft::with_precomputation::fft::best_fft as best_fft_with_precomputations; - use crate::plonk::commitments::transparent::precomputations::*; - use crate::plonk::domains::Domain; + use crate::plonk::fft::with_precomputation::FftPrecomputations; + use crate::plonk::polynomials::*; + use crate::worker::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; let poly_sizes = vec![32_000_000, 64_000_000]; let worker = Worker::new(); @@ -174,21 +173,20 @@ mod test { }; assert!(res1 == res2); - } } #[test] fn test_bench_precomputations_for_proth_lde() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use super::Fr as FrMontNaive; use super::proth::Fr as FrOptimized; - use crate::plonk::polynomials::*; - use std::time::Instant; - use crate::worker::*; + use super::Fr as FrMontNaive; + use crate::plonk::commitments::transparent::precomputations::*; use crate::plonk::commitments::transparent::utils::*; use crate::plonk::fft::with_precomputation::FftPrecomputations; - use crate::plonk::commitments::transparent::precomputations::*; + use crate::plonk::polynomials::*; + use crate::worker::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; let poly_sizes = vec![1_000_000, 2_000_000, 4_000_000]; @@ -198,7 +196,7 @@ mod test { let res1 = { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..poly_size).map(|_| FrMontNaive::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let start = Instant::now(); let eval_result = poly.lde(&worker, 16).unwrap(); @@ -210,7 +208,7 @@ mod test { let res2 = { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..poly_size).map(|_| FrOptimized::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let precomp = PrecomputedOmegas::::new_for_domain_size(poly.size()); let start = Instant::now(); @@ -221,19 +219,18 @@ mod test { }; assert_eq!(format!("{}", res1[0]), format!("{}", res2[0])); - } } #[test] fn test_bench_ct_ploth_lde() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use super::proth::Fr as Fr; + use super::proth::Fr; + use crate::plonk::commitments::transparent::utils::*; + use crate::plonk::fft::cooley_tukey_ntt::{BitReversedOmegas, CTPrecomputations}; use crate::plonk::polynomials::*; - use std::time::Instant; use crate::worker::*; - use crate::plonk::commitments::transparent::utils::*; - use crate::plonk::fft::cooley_tukey_ntt::{CTPrecomputations, BitReversedOmegas}; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; let poly_sizes = vec![1_000_000, 2_000_000, 4_000_000]; @@ -247,7 +244,7 @@ mod test { let res1 = { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let start = Instant::now(); let eval_result = poly.lde_using_multiple_cosets(&worker, 16).unwrap(); @@ -259,7 +256,7 @@ mod test { let res2 = { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let precomp = BitReversedOmegas::::new_for_domain_size(poly.size()); let start = Instant::now(); @@ -295,7 +292,7 @@ mod test { // let res1 = { // let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); // let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::>(); - + // let poly = Polynomial::::from_coeffs(coeffs).unwrap(); // let start = Instant::now(); // let eval_result = poly.lde(&worker, 16).unwrap(); @@ -307,7 +304,7 @@ mod test { // let res2 = { // let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); // let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::>(); - + // let poly = Polynomial::::from_coeffs(coeffs).unwrap(); // let precomp = BitReversedOmegas::::new_for_domain_size(poly.size()); // let start = Instant::now(); @@ -354,16 +351,16 @@ mod test { #[test] fn test_bench_partial_reduction_bitreversed_lde() { + use super::proth::Fr; + use super::PartialTwoBitReductionField; use crate::ff::Field; use crate::ff::PrimeField; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use super::proth::Fr as Fr; - use super::PartialTwoBitReductionField; + use crate::plonk::commitments::transparent::utils::*; + use crate::plonk::fft::cooley_tukey_ntt::{BitReversedOmegas, CTPrecomputations}; use crate::plonk::polynomials::*; - use std::time::Instant; use crate::worker::*; - use crate::plonk::commitments::transparent::utils::*; - use crate::plonk::fft::cooley_tukey_ntt::{CTPrecomputations, BitReversedOmegas}; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; let poly_sizes = vec![32, 64, 1_000_000, 2_000_000, 4_000_000]; @@ -375,7 +372,7 @@ mod test { let res1 = { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let start = Instant::now(); let eval_result = poly.lde(&worker, 16).unwrap(); @@ -387,7 +384,7 @@ mod test { let mut res2 = { let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let precomp = BitReversedOmegas::::new_for_domain_size(poly.size()); let start = Instant::now(); @@ -406,15 +403,15 @@ mod test { #[test] fn test_bench_ct_proth_fft() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use super::proth::Fr as Fr; - use crate::plonk::polynomials::*; - use std::time::Instant; - use crate::worker::*; + use super::proth::Fr; use crate::plonk::commitments::transparent::utils::*; - use crate::plonk::fft::cooley_tukey_ntt::{CTPrecomputations, BitReversedOmegas, best_ct_ntt}; - use crate::plonk::fft::fft::best_fft; use crate::plonk::domains::Domain; + use crate::plonk::fft::cooley_tukey_ntt::{best_ct_ntt, BitReversedOmegas, CTPrecomputations}; + use crate::plonk::fft::fft::best_fft; + use crate::plonk::polynomials::*; + use crate::worker::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; // let poly_sizes = vec![1_000_000, 2_000_000]; let poly_sizes = vec![1_000_000]; @@ -454,14 +451,11 @@ mod test { (input, coeffs) }; - let mut writer = std::io::BufWriter::with_capacity( - 1<<24, - std::fs::File::create("./fft_test_input.data").unwrap() - ); + let mut writer = std::io::BufWriter::with_capacity(1 << 24, std::fs::File::create("./fft_test_input.data").unwrap()); + use crate::pairing::ff::PrimeFieldRepr; use crate::pairing::ff::{Field, PrimeField}; use std::io::Write; - use crate::pairing::ff::PrimeFieldRepr; let mut scratch = vec![]; for el in input.into_iter() { @@ -480,7 +474,7 @@ mod test { println!("Omegas"); - assert!(domain.generator.pow(&[1u64<<20]) == Fr::one()); + assert!(domain.generator.pow(&[1u64 << 20]) == Fr::one()); for i in 0..=20 { let pow = 1u64 << i; @@ -490,9 +484,4 @@ mod test { println!("Idenity = {}", Fr::one().into_raw_repr()); } } - } - - - - diff --git a/crates/bellman/src/plonk/transparent_engine/proth.rs b/crates/bellman/src/plonk/transparent_engine/proth.rs index 73fdc90..cb4bc69 100644 --- a/crates/bellman/src/plonk/transparent_engine/proth.rs +++ b/crates/bellman/src/plonk/transparent_engine/proth.rs @@ -1,5 +1,5 @@ -use crate::ff::*; use super::{PartialReductionField, PartialTwoBitReductionField}; +use crate::ff::*; #[derive(Copy, Clone, PartialEq, Eq, Default, Hash, ::serde::Serialize, ::serde::Deserialize)] pub struct FrRepr(pub [u64; 4usize]); @@ -25,41 +25,15 @@ const K: u64 = 576460752303423505u64; const K_U128: u128 = 576460752303423505u128; -const NU: [u64; 5] = [ - 0x0000028c81fffbff, - 0xfffffffeccf00000, - 0x0000000000907fff, - 0xffffffffffffbc00, - 0x1f -]; - -const R: FrRepr = FrRepr([ - 18446744073709551585u64, - 18446744073709551615u64, - 18446744073709551615u64, - 576460752303422960u64, -]); - -const R2: FrRepr = FrRepr([ - 18446741271209837569u64, - 5151653887u64, - 18446744073700081664u64, - 576413109808302096u64, -]); - -const GENERATOR: FrRepr = FrRepr([ - 18446744073709551521u64, - 18446744073709551615u64, - 18446744073709551615u64, - 576460752303421872u64, -]); - -const ROOT_OF_UNITY: FrRepr = FrRepr([ - 4685640052668284376u64, - 12298664652803292137u64, - 735711535595279732u64, - 514024103053294630u64, -]); +const NU: [u64; 5] = [0x0000028c81fffbff, 0xfffffffeccf00000, 0x0000000000907fff, 0xffffffffffffbc00, 0x1f]; + +const R: FrRepr = FrRepr([18446744073709551585u64, 18446744073709551615u64, 18446744073709551615u64, 576460752303422960u64]); + +const R2: FrRepr = FrRepr([18446741271209837569u64, 5151653887u64, 18446744073700081664u64, 576413109808302096u64]); + +const GENERATOR: FrRepr = FrRepr([18446744073709551521u64, 18446744073709551615u64, 18446744073709551615u64, 576460752303421872u64]); + +const ROOT_OF_UNITY: FrRepr = FrRepr([4685640052668284376u64, 12298664652803292137u64, 735711535595279732u64, 514024103053294630u64]); // const INV: u64 = 18446744073709551615u64; @@ -104,7 +78,7 @@ fn sub_borrow(a: u64, borrow: &mut u64) -> u64 { // tmp as u64 } - + impl ::std::fmt::Debug for FrRepr { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "0x")?; @@ -338,7 +312,7 @@ impl ::std::cmp::PartialEq for Fr { } } impl ::std::cmp::Eq for Fr {} - + impl ::std::fmt::Debug for Fr { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "{}({:?})", "Fr", self.into_repr()) @@ -382,7 +356,7 @@ impl From for FrRepr { e.into_repr() } } - + impl crate::ff::PrimeField for Fr { type Repr = FrRepr; @@ -407,16 +381,7 @@ impl crate::ff::PrimeField for Fr { fn into_repr(&self) -> FrRepr { let mut r = *self; - r.mont_reduce( - (self.0).0[0usize], - (self.0).0[1usize], - (self.0).0[2usize], - (self.0).0[3usize], - 0, - 0, - 0, - 0, - ); + r.mont_reduce((self.0).0[0usize], (self.0).0[1usize], (self.0).0[2usize], (self.0).0[3usize], 0, 0, 0, 0); r.0 } @@ -443,7 +408,6 @@ impl crate::ff::PrimeField for Fr { } } - impl crate::ff::Field for Fr { #[inline] fn zero() -> Self { @@ -542,44 +506,28 @@ impl crate::ff::Field for Fr { #[inline] fn mul_assign(&mut self, other: &Fr) { let mut carry = 0; - let r0 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[0usize], &mut carry); - let r1 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[1usize], &mut carry); - let r2 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[2usize], &mut carry); - let r3 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[3usize], &mut carry); + let r0 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[0usize], &mut carry); + let r1 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[1usize], &mut carry); + let r2 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[2usize], &mut carry); + let r3 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[3usize], &mut carry); let r4 = carry; let mut carry = 0; - let r1 = - crate::ff::mac_with_carry(r1, (self.0).0[1usize], (other.0).0[0usize], &mut carry); - let r2 = - crate::ff::mac_with_carry(r2, (self.0).0[1usize], (other.0).0[1usize], &mut carry); - let r3 = - crate::ff::mac_with_carry(r3, (self.0).0[1usize], (other.0).0[2usize], &mut carry); - let r4 = - crate::ff::mac_with_carry(r4, (self.0).0[1usize], (other.0).0[3usize], &mut carry); + let r1 = crate::ff::mac_with_carry(r1, (self.0).0[1usize], (other.0).0[0usize], &mut carry); + let r2 = crate::ff::mac_with_carry(r2, (self.0).0[1usize], (other.0).0[1usize], &mut carry); + let r3 = crate::ff::mac_with_carry(r3, (self.0).0[1usize], (other.0).0[2usize], &mut carry); + let r4 = crate::ff::mac_with_carry(r4, (self.0).0[1usize], (other.0).0[3usize], &mut carry); let r5 = carry; let mut carry = 0; - let r2 = - crate::ff::mac_with_carry(r2, (self.0).0[2usize], (other.0).0[0usize], &mut carry); - let r3 = - crate::ff::mac_with_carry(r3, (self.0).0[2usize], (other.0).0[1usize], &mut carry); - let r4 = - crate::ff::mac_with_carry(r4, (self.0).0[2usize], (other.0).0[2usize], &mut carry); - let r5 = - crate::ff::mac_with_carry(r5, (self.0).0[2usize], (other.0).0[3usize], &mut carry); + let r2 = crate::ff::mac_with_carry(r2, (self.0).0[2usize], (other.0).0[0usize], &mut carry); + let r3 = crate::ff::mac_with_carry(r3, (self.0).0[2usize], (other.0).0[1usize], &mut carry); + let r4 = crate::ff::mac_with_carry(r4, (self.0).0[2usize], (other.0).0[2usize], &mut carry); + let r5 = crate::ff::mac_with_carry(r5, (self.0).0[2usize], (other.0).0[3usize], &mut carry); let r6 = carry; let mut carry = 0; - let r3 = - crate::ff::mac_with_carry(r3, (self.0).0[3usize], (other.0).0[0usize], &mut carry); - let r4 = - crate::ff::mac_with_carry(r4, (self.0).0[3usize], (other.0).0[1usize], &mut carry); - let r5 = - crate::ff::mac_with_carry(r5, (self.0).0[3usize], (other.0).0[2usize], &mut carry); - let r6 = - crate::ff::mac_with_carry(r6, (self.0).0[3usize], (other.0).0[3usize], &mut carry); + let r3 = crate::ff::mac_with_carry(r3, (self.0).0[3usize], (other.0).0[0usize], &mut carry); + let r4 = crate::ff::mac_with_carry(r4, (self.0).0[3usize], (other.0).0[1usize], &mut carry); + let r5 = crate::ff::mac_with_carry(r5, (self.0).0[3usize], (other.0).0[2usize], &mut carry); + let r6 = crate::ff::mac_with_carry(r6, (self.0).0[3usize], (other.0).0[3usize], &mut carry); let r7 = carry; self.mont_reduce(r0, r1, r2, r3, r4, r5, r6, r7); } @@ -587,22 +535,16 @@ impl crate::ff::Field for Fr { #[inline] fn square(&mut self) { let mut carry = 0; - let r1 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (self.0).0[1usize], &mut carry); - let r2 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (self.0).0[2usize], &mut carry); - let r3 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (self.0).0[3usize], &mut carry); + let r1 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (self.0).0[1usize], &mut carry); + let r2 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (self.0).0[2usize], &mut carry); + let r3 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (self.0).0[3usize], &mut carry); let r4 = carry; let mut carry = 0; - let r3 = - crate::ff::mac_with_carry(r3, (self.0).0[1usize], (self.0).0[2usize], &mut carry); - let r4 = - crate::ff::mac_with_carry(r4, (self.0).0[1usize], (self.0).0[3usize], &mut carry); + let r3 = crate::ff::mac_with_carry(r3, (self.0).0[1usize], (self.0).0[2usize], &mut carry); + let r4 = crate::ff::mac_with_carry(r4, (self.0).0[1usize], (self.0).0[3usize], &mut carry); let r5 = carry; let mut carry = 0; - let r5 = - crate::ff::mac_with_carry(r5, (self.0).0[2usize], (self.0).0[3usize], &mut carry); + let r5 = crate::ff::mac_with_carry(r5, (self.0).0[2usize], (self.0).0[3usize], &mut carry); let r6 = carry; let r7 = r6 >> 63; let r6 = (r6 << 1) | (r5 >> 63); @@ -612,17 +554,13 @@ impl crate::ff::Field for Fr { let r2 = (r2 << 1) | (r1 >> 63); let r1 = r1 << 1; let mut carry = 0; - let r0 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (self.0).0[0usize], &mut carry); + let r0 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (self.0).0[0usize], &mut carry); let r1 = crate::ff::adc(r1, 0, &mut carry); - let r2 = - crate::ff::mac_with_carry(r2, (self.0).0[1usize], (self.0).0[1usize], &mut carry); + let r2 = crate::ff::mac_with_carry(r2, (self.0).0[1usize], (self.0).0[1usize], &mut carry); let r3 = crate::ff::adc(r3, 0, &mut carry); - let r4 = - crate::ff::mac_with_carry(r4, (self.0).0[2usize], (self.0).0[2usize], &mut carry); + let r4 = crate::ff::mac_with_carry(r4, (self.0).0[2usize], (self.0).0[2usize], &mut carry); let r5 = crate::ff::adc(r5, 0, &mut carry); - let r6 = - crate::ff::mac_with_carry(r6, (self.0).0[3usize], (self.0).0[3usize], &mut carry); + let r6 = crate::ff::mac_with_carry(r6, (self.0).0[3usize], (self.0).0[3usize], &mut carry); let r7 = crate::ff::adc(r7, 0, &mut carry); self.mont_reduce(r0, r1, r2, r3, r4, r5, r6, r7); } @@ -654,17 +592,7 @@ impl Fr { } #[inline(always)] - fn mont_reduce_unreduced( - &mut self, - r0: u64, - mut r1: u64, - mut r2: u64, - mut r3: u64, - mut r4: u64, - mut r5: u64, - mut r6: u64, - mut r7: u64, - ) { + fn mont_reduce_unreduced(&mut self, r0: u64, mut r1: u64, mut r2: u64, mut r3: u64, mut r4: u64, mut r5: u64, mut r6: u64, mut r7: u64) { let k = (!r0).wrapping_add(1); let mut carry = 0; crate::ff::adc(r0, k, &mut carry); @@ -707,16 +635,7 @@ impl Fr { } #[inline(always)] - fn mont_reduce(&mut self, - r0: u64, - r1: u64, - r2: u64, - r3: u64, - r4: u64, - r5: u64, - r6: u64, - r7: u64, - ) { + fn mont_reduce(&mut self, r0: u64, r1: u64, r2: u64, r3: u64, r4: u64, r5: u64, r6: u64, r7: u64) { self.mont_reduce_unreduced(r0, r1, r2, r3, r4, r5, r6, r7); self.reduce(); } @@ -729,7 +648,9 @@ impl Fr { pub fn from_hex(value: &str) -> Result { let value = if value.starts_with("0x") { &value[2..] } else { value }; - if value.len() % 2 != 0 {return Err(format!("hex length must be even for full byte encoding: {}", value))} + if value.len() % 2 != 0 { + return Err(format!("hex length must be even for full byte encoding: {}", value)); + } let mut buf = crate::ff::hex::decode(&value).map_err(|_| format!("could not decode hex: {}", value))?; buf.reverse(); buf.resize(32, 0); @@ -786,7 +707,6 @@ impl crate::ff::SqrtField for Fr { } } - impl PartialReductionField for Fr { #[inline(always)] fn add_assign_unreduced(&mut self, other: &Fr) { @@ -802,44 +722,28 @@ impl PartialReductionField for Fr { #[inline] fn mul_assign_unreduced(&mut self, other: &Fr) { let mut carry = 0; - let r0 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[0usize], &mut carry); - let r1 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[1usize], &mut carry); - let r2 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[2usize], &mut carry); - let r3 = - crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[3usize], &mut carry); + let r0 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[0usize], &mut carry); + let r1 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[1usize], &mut carry); + let r2 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[2usize], &mut carry); + let r3 = crate::ff::mac_with_carry(0, (self.0).0[0usize], (other.0).0[3usize], &mut carry); let r4 = carry; let mut carry = 0; - let r1 = - crate::ff::mac_with_carry(r1, (self.0).0[1usize], (other.0).0[0usize], &mut carry); - let r2 = - crate::ff::mac_with_carry(r2, (self.0).0[1usize], (other.0).0[1usize], &mut carry); - let r3 = - crate::ff::mac_with_carry(r3, (self.0).0[1usize], (other.0).0[2usize], &mut carry); - let r4 = - crate::ff::mac_with_carry(r4, (self.0).0[1usize], (other.0).0[3usize], &mut carry); + let r1 = crate::ff::mac_with_carry(r1, (self.0).0[1usize], (other.0).0[0usize], &mut carry); + let r2 = crate::ff::mac_with_carry(r2, (self.0).0[1usize], (other.0).0[1usize], &mut carry); + let r3 = crate::ff::mac_with_carry(r3, (self.0).0[1usize], (other.0).0[2usize], &mut carry); + let r4 = crate::ff::mac_with_carry(r4, (self.0).0[1usize], (other.0).0[3usize], &mut carry); let r5 = carry; let mut carry = 0; - let r2 = - crate::ff::mac_with_carry(r2, (self.0).0[2usize], (other.0).0[0usize], &mut carry); - let r3 = - crate::ff::mac_with_carry(r3, (self.0).0[2usize], (other.0).0[1usize], &mut carry); - let r4 = - crate::ff::mac_with_carry(r4, (self.0).0[2usize], (other.0).0[2usize], &mut carry); - let r5 = - crate::ff::mac_with_carry(r5, (self.0).0[2usize], (other.0).0[3usize], &mut carry); + let r2 = crate::ff::mac_with_carry(r2, (self.0).0[2usize], (other.0).0[0usize], &mut carry); + let r3 = crate::ff::mac_with_carry(r3, (self.0).0[2usize], (other.0).0[1usize], &mut carry); + let r4 = crate::ff::mac_with_carry(r4, (self.0).0[2usize], (other.0).0[2usize], &mut carry); + let r5 = crate::ff::mac_with_carry(r5, (self.0).0[2usize], (other.0).0[3usize], &mut carry); let r6 = carry; let mut carry = 0; - let r3 = - crate::ff::mac_with_carry(r3, (self.0).0[3usize], (other.0).0[0usize], &mut carry); - let r4 = - crate::ff::mac_with_carry(r4, (self.0).0[3usize], (other.0).0[1usize], &mut carry); - let r5 = - crate::ff::mac_with_carry(r5, (self.0).0[3usize], (other.0).0[2usize], &mut carry); - let r6 = - crate::ff::mac_with_carry(r6, (self.0).0[3usize], (other.0).0[3usize], &mut carry); + let r3 = crate::ff::mac_with_carry(r3, (self.0).0[3usize], (other.0).0[0usize], &mut carry); + let r4 = crate::ff::mac_with_carry(r4, (self.0).0[3usize], (other.0).0[1usize], &mut carry); + let r5 = crate::ff::mac_with_carry(r5, (self.0).0[3usize], (other.0).0[2usize], &mut carry); + let r6 = crate::ff::mac_with_carry(r6, (self.0).0[3usize], (other.0).0[3usize], &mut carry); let r7 = carry; self.mont_reduce_unreduced(r0, r1, r2, r3, r4, r5, r6, r7); } @@ -885,4 +789,4 @@ impl PartialTwoBitReductionField for Fr { self.reduce_twice(); self.reduce_once(); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/plonk/transparent_engine/proth_engine.rs b/crates/bellman/src/plonk/transparent_engine/proth_engine.rs index b9f9163..6bfa339 100644 --- a/crates/bellman/src/plonk/transparent_engine/proth_engine.rs +++ b/crates/bellman/src/plonk/transparent_engine/proth_engine.rs @@ -4,6 +4,6 @@ use super::impl_macro::*; use super::TransparentEngine; -transparent_engine_impl!{Transparent252, Fr} +transparent_engine_impl! {Transparent252, Fr} -impl TransparentEngine for Transparent252 {} \ No newline at end of file +impl TransparentEngine for Transparent252 {} diff --git a/crates/bellman/src/plonk/utils.rs b/crates/bellman/src/plonk/utils.rs index 580177b..2808795 100644 --- a/crates/bellman/src/plonk/utils.rs +++ b/crates/bellman/src/plonk/utils.rs @@ -1,12 +1,11 @@ -use crate::worker::*; use crate::pairing::ff::PrimeField; +use crate::worker::*; pub(crate) fn convert_to_field_elements(indexes: &[usize], worker: &Worker) -> Vec { let mut result = vec![F::zero(); indexes.len()]; - + worker.scope(indexes.len(), |scope, chunk| { - for (idx, fe) in indexes.chunks(chunk) - .zip(result.chunks_mut(chunk)) { + for (idx, fe) in indexes.chunks(chunk).zip(result.chunks_mut(chunk)) { scope.spawn(move |_| { let mut repr = F::zero().into_repr(); for (idx, fe) in idx.iter().zip(fe.iter_mut()) { @@ -19,4 +18,3 @@ pub(crate) fn convert_to_field_elements(indexes: &[usize], worker result } - diff --git a/crates/bellman/src/plonk/verifier/mod.rs b/crates/bellman/src/plonk/verifier/mod.rs index 8e1eb4c..2101148 100644 --- a/crates/bellman/src/plonk/verifier/mod.rs +++ b/crates/bellman/src/plonk/verifier/mod.rs @@ -1,20 +1,20 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine}; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; use crate::plonk::cs::gates::*; use crate::plonk::cs::*; -use crate::worker::*; -use super::polynomials::*; use super::domains::*; -use crate::plonk::commitments::*; +use super::polynomials::*; use crate::plonk::commitments::transcript::*; -use crate::plonk::utils::*; +use crate::plonk::commitments::*; use crate::plonk::generator::*; use crate::plonk::prover::*; +use crate::plonk::utils::*; +use crate::worker::*; fn evaluate_inverse_vanishing_poly(vahisning_size: usize, point: E::Fr) -> E::Fr { assert!(vahisning_size.is_power_of_two()); @@ -40,7 +40,7 @@ fn evaluate_inverse_vanishing_poly(vahisning_size: usize, point: E::F numerator } -fn evaluate_lagrange_poly(vahisning_size:usize, poly_number: usize, at: E::Fr) -> E::Fr { +fn evaluate_lagrange_poly(vahisning_size: usize, poly_number: usize, at: E::Fr) -> E::Fr { assert!(vahisning_size.is_power_of_two()); let mut repr = E::Fr::zero().into_repr(); @@ -77,9 +77,9 @@ fn evaluate_lagrange_poly(vahisning_size:usize, poly_number: usize, a pub fn verify_nonhomomorphic, T: Transcript>( setup: &PlonkSetup, - proof: &PlonkNonhomomorphicProof, + proof: &PlonkNonhomomorphicProof, meta: S::Meta, - large_meta: S::Meta + large_meta: S::Meta, ) -> Result { assert!(S::IS_HOMOMORPHIC == false); @@ -334,28 +334,7 @@ pub fn verify_nonhomomorphic, T: z_2_shifted_at_z, ]; - let opening_points = vec![ - z, - z, - z, - - z, - z, - z, - z, - z, - - z, - z, - z, - z, - - z, - z, - - z_by_omega, - z_by_omega - ]; + let opening_points = vec![z, z, z, z, z, z, z, z, z, z, z, z, z, z, z_by_omega, z_by_omega]; if t_1 != t_at_z { println!("Recalculated t(z) is not equal to the provided value"); @@ -376,8 +355,6 @@ pub fn verify_nonhomomorphic, T: return Ok(false); } - - // let mut opening_point = z; // opening_point.mul_assign(&domain.generator); @@ -399,8 +376,8 @@ pub fn verify_nonhomomorphic, T: #[track_caller] pub fn verify_nonhomomorphic_chunked, T: Transcript>( setup: &PlonkSetup, - proof: &PlonkChunkedNonhomomorphicProof, - meta: S::Meta + proof: &PlonkChunkedNonhomomorphicProof, + meta: S::Meta, ) -> Result { assert!(S::IS_HOMOMORPHIC == false); @@ -644,24 +621,19 @@ pub fn verify_nonhomomorphic_chunked{ - _marker: PhantomData + struct TestCircuit { + _marker: PhantomData, } impl Circuit for TestCircuit { fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let a = cs.alloc(|| { - Ok(E::Fr::from_str("10").unwrap()) - })?; + let a = cs.alloc(|| Ok(E::Fr::from_str("10").unwrap()))?; - let b = cs.alloc(|| { - Ok(E::Fr::from_str("20").unwrap()) - })?; + let b = cs.alloc(|| Ok(E::Fr::from_str("20").unwrap()))?; - let c = cs.alloc(|| { - Ok(E::Fr::from_str("200").unwrap()) - })?; + let c = cs.alloc(|| Ok(E::Fr::from_str("200").unwrap()))?; let one = E::Fr::one(); @@ -801,23 +730,17 @@ mod test { } } - struct InvalidTestCircuit{ - _marker: PhantomData + struct InvalidTestCircuit { + _marker: PhantomData, } impl Circuit for InvalidTestCircuit { fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let a = cs.alloc(|| { - Ok(E::Fr::from_str("11").unwrap()) - })?; + let a = cs.alloc(|| Ok(E::Fr::from_str("11").unwrap()))?; - let b = cs.alloc(|| { - Ok(E::Fr::from_str("20").unwrap()) - })?; + let b = cs.alloc(|| Ok(E::Fr::from_str("20").unwrap()))?; - let c = cs.alloc(|| { - Ok(E::Fr::from_str("200").unwrap()) - })?; + let c = cs.alloc(|| Ok(E::Fr::from_str("200").unwrap()))?; let one = E::Fr::one(); @@ -841,14 +764,14 @@ mod test { #[test] fn test_small_circuit_transparent_verification() { use crate::pairing::bn256::{Bn256, Fr}; - use crate::plonk::utils::*; - use crate::plonk::commitments::transparent::fri::*; - use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*; + use crate::plonk::commitments::transparent::fri::*; use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*; - use crate::plonk::commitments::*; + use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transparent::*; + use crate::plonk::commitments::*; + use crate::plonk::utils::*; type Iop = TrivialBlake2sIOP; type Fri = NaiveFriIop; @@ -858,19 +781,17 @@ mod test { lde_factor: 16, num_queries: 2, output_coeffs_at_degree_plus_one: 1, - fri_params: () + fri_params: (), }; let meta_large = TransparentCommitterParameters { lde_factor: 16, num_queries: 2, output_coeffs_at_degree_plus_one: 1, - fri_params: () + fri_params: (), }; - let circuit = TestCircuit:: { - _marker: PhantomData - }; + let circuit = TestCircuit:: { _marker: PhantomData }; let (setup, aux) = setup::(&circuit, meta).unwrap(); @@ -878,17 +799,16 @@ mod test { lde_factor: 16, num_queries: 2, output_coeffs_at_degree_plus_one: 1, - fri_params: () + fri_params: (), }; println!("Proving"); - let proof = prove_nonhomomorphic::, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap(); - + let proof = prove_nonhomomorphic::, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap(); println!("Verifying"); - let valid = verify_nonhomomorphic::>(&setup, &proof, meta, meta_large).unwrap(); + let valid = verify_nonhomomorphic::>(&setup, &proof, meta, meta_large).unwrap(); assert!(valid); } @@ -896,14 +816,14 @@ mod test { #[test] fn test_small_circuit_invalid_witness_transparent_verification() { use crate::pairing::bn256::{Bn256, Fr}; - use crate::plonk::utils::*; - use crate::plonk::commitments::transparent::fri::*; - use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*; + use crate::plonk::commitments::transparent::fri::*; use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*; - use crate::plonk::commitments::*; + use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transparent::*; + use crate::plonk::commitments::*; + use crate::plonk::utils::*; type Iop = TrivialBlake2sIOP; type Fri = NaiveFriIop; @@ -913,37 +833,35 @@ mod test { lde_factor: 16, num_queries: 2, output_coeffs_at_degree_plus_one: 1, - fri_params: () + fri_params: (), }; let meta_large = TransparentCommitterParameters { lde_factor: 16, num_queries: 2, output_coeffs_at_degree_plus_one: 1, - fri_params: () + fri_params: (), }; - let circuit = InvalidTestCircuit:: { - _marker: PhantomData - }; + let circuit = InvalidTestCircuit:: { _marker: PhantomData }; let (setup, aux) = setup::(&circuit, meta.clone()).unwrap(); println!("Proving"); - let proof = prove_nonhomomorphic::, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap(); + let proof = prove_nonhomomorphic::, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap(); println!("Verifying"); - let valid = verify_nonhomomorphic::>(&setup, &proof, meta, meta_large).unwrap(); + let valid = verify_nonhomomorphic::>(&setup, &proof, meta, meta_large).unwrap(); assert!(!valid); } #[derive(Clone)] - struct BenchmarkCircuit{ + struct BenchmarkCircuit { num_steps: usize, - _marker: PhantomData + _marker: PhantomData, } impl Circuit for BenchmarkCircuit { @@ -956,21 +874,15 @@ mod test { let mut two = one; two.double(); - - let mut a = cs.alloc(|| { - Ok(E::Fr::one()) - })?; - let mut b = cs.alloc(|| { - Ok(E::Fr::one()) - })?; + let mut a = cs.alloc(|| Ok(E::Fr::one()))?; + + let mut b = cs.alloc(|| Ok(E::Fr::one()))?; cs.enforce_constant(a, E::Fr::one())?; cs.enforce_constant(b, E::Fr::one())?; - let mut c = cs.alloc(|| { - Ok(two) - })?; + let mut c = cs.alloc(|| Ok(two))?; cs.enforce_zero_3((a, b, c), (one, one, negative_one))?; @@ -986,9 +898,7 @@ mod test { b_value = c_value; c_value.add_assign(&a_value); - c = cs.alloc(|| { - Ok(c_value) - })?; + c = cs.alloc(|| Ok(c_value))?; cs.enforce_zero_3((a, b, c), (one, one, negative_one))?; } @@ -1000,15 +910,15 @@ mod test { #[test] fn test_bench_fibonacci_circuit() { use crate::pairing::bn256::{Bn256, Fr}; - use crate::plonk::utils::*; - use crate::plonk::commitments::transparent::fri::*; - use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*; + use crate::plonk::commitments::transparent::fri::*; use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*; - use crate::plonk::commitments::*; + use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transparent::*; + use crate::plonk::commitments::*; use crate::plonk::tester::*; + use crate::plonk::utils::*; use std::time::Instant; @@ -1020,19 +930,19 @@ mod test { lde_factor: 16, num_queries: 10, output_coeffs_at_degree_plus_one: 16, - fri_params: () + fri_params: (), }; let meta_large = TransparentCommitterParameters { lde_factor: 16, num_queries: 10, output_coeffs_at_degree_plus_one: 16, - fri_params: () + fri_params: (), }; let circuit = BenchmarkCircuit:: { num_steps: 1_000_000, - _marker: PhantomData + _marker: PhantomData, }; { @@ -1058,17 +968,17 @@ mod test { lde_factor: 16, num_queries: 10, output_coeffs_at_degree_plus_one: 16, - fri_params: () + fri_params: (), }; println!("Start proving"); let start = Instant::now(); - let proof = prove_nonhomomorphic::, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap(); + let proof = prove_nonhomomorphic::, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap(); println!("Proof taken {:?}", start.elapsed()); println!("Start verifying"); let start = Instant::now(); - let valid = verify_nonhomomorphic::>(&setup, &proof, meta, meta_large).unwrap(); + let valid = verify_nonhomomorphic::>(&setup, &proof, meta, meta_large).unwrap(); println!("Verification with unnecessary precomputation taken {:?}", start.elapsed()); assert!(valid); @@ -1149,16 +1059,16 @@ mod test { #[test] fn test_bench_homomorphic_plonk() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use crate::multiexp::*; use crate::pairing::bn256::Bn256; - use num_cpus; use crate::pairing::ff::ScalarEngine; use crate::pairing::CurveProjective; - use crate::multiexp::*; - use crate::worker::*; use crate::source::*; + use crate::worker::*; + use futures::Future; + use num_cpus; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; use std::sync::Arc; - use futures::{Future}; const SAMPLES: usize = 1 << 20; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -1171,31 +1081,26 @@ mod test { let pool = Worker::new(); let start = std::time::Instant::now(); - let _sparse = multiexp( - &pool, - (Arc::new(g), 0), - FullDensity, - Arc::new(v) - ).wait().unwrap(); + let _sparse = multiexp(&pool, (Arc::new(g), 0), FullDensity, Arc::new(v)).wait().unwrap(); let per_one_poly = start.elapsed().as_micros(); // a, b, c, z_1, z_2, t, opening at z (of length t), opening at z*omega(of length a) - let total_expected_plonk = per_one_poly * (5 + 1 + 3 + 3 + 1); - println!("{} ms for expected plonk with ~ {} gates", total_expected_plonk/1000u128, SAMPLES); + let total_expected_plonk = per_one_poly * (5 + 1 + 3 + 3 + 1); + println!("{} ms for expected plonk with ~ {} gates", total_expected_plonk / 1000u128, SAMPLES); } #[test] fn test_bench_transparent_engine() { - use crate::plonk::transparent_engine::proth_engine::*; - use crate::plonk::utils::*; - use crate::plonk::commitments::transparent::fri::*; - use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*; + use crate::plonk::commitments::transparent::fri::*; use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*; - use crate::plonk::commitments::*; + use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transparent::*; + use crate::plonk::commitments::*; use crate::plonk::tester::*; + use crate::plonk::transparent_engine::proth_engine::*; + use crate::plonk::utils::*; use std::time::Instant; @@ -1211,20 +1116,17 @@ mod test { lde_factor: 16, num_queries: 10, output_coeffs_at_degree_plus_one: 16, - fri_params: () + fri_params: (), }; let meta_large = TransparentCommitterParameters { lde_factor: 16, num_queries: 10, output_coeffs_at_degree_plus_one: 16, - fri_params: () + fri_params: (), }; - let circuit = BenchmarkCircuit:: { - num_steps: 20, - _marker: PhantomData - }; + let circuit = BenchmarkCircuit:: { num_steps: 20, _marker: PhantomData }; { let mut tester = TestingAssembly::::new(); @@ -1249,17 +1151,17 @@ mod test { lde_factor: 16, num_queries: 10, output_coeffs_at_degree_plus_one: 16, - fri_params: () + fri_params: (), }; println!("Start proving"); let start = Instant::now(); - let proof = prove_nonhomomorphic::, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap(); + let proof = prove_nonhomomorphic::, _>(&circuit, &setup, &aux, meta.clone(), meta_large.clone()).unwrap(); println!("Proof taken {:?}", start.elapsed()); println!("Start verifying"); let start = Instant::now(); - let valid = verify_nonhomomorphic::>(&setup, &proof, meta, meta_large).unwrap(); + let valid = verify_nonhomomorphic::>(&setup, &proof, meta, meta_large).unwrap(); println!("Verification with unnecessary precomputation taken {:?}", start.elapsed()); assert!(valid); @@ -1267,16 +1169,16 @@ mod test { #[test] fn test_bench_chunked_proof_on_transparent_engine() { - use crate::plonk::transparent_engine::proth_engine::*; - use crate::plonk::utils::*; - use crate::plonk::commitments::transparent::fri::*; - use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*; + use crate::plonk::commitments::transparent::fri::*; use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*; - use crate::plonk::commitments::*; + use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transparent::*; + use crate::plonk::commitments::*; use crate::plonk::tester::*; + use crate::plonk::transparent_engine::proth_engine::*; + use crate::plonk::utils::*; use std::time::Instant; @@ -1293,13 +1195,10 @@ mod test { lde_factor: 16, num_queries: 10, output_coeffs_at_degree_plus_one: 2, - fri_params: params + fri_params: params, }; - let circuit = BenchmarkCircuit:: { - num_steps: 20, - _marker: PhantomData - }; + let circuit = BenchmarkCircuit:: { num_steps: 20, _marker: PhantomData }; { let mut tester = TestingAssembly::::new(); @@ -1322,7 +1221,7 @@ mod test { println!("Start proving"); let start = Instant::now(); - let proof = prove_nonhomomorphic_chunked::, _>(&circuit, &aux, meta.clone()).unwrap(); + let proof = prove_nonhomomorphic_chunked::, _>(&circuit, &aux, meta.clone()).unwrap(); println!("Proof taken {:?}", start.elapsed()); let proof_size = proof.estimate_proof_size(); @@ -1330,25 +1229,24 @@ mod test { println!("Start verifying"); let start = Instant::now(); - let valid = verify_nonhomomorphic_chunked::>(&setup, &proof, meta).unwrap(); + let valid = verify_nonhomomorphic_chunked::>(&setup, &proof, meta).unwrap(); println!("Verification with unnecessary precomputation taken {:?}", start.elapsed()); assert!(valid); } - #[test] fn test_bench_chunked_proof_on_transparent_engine_over_sizes() { - use crate::plonk::transparent_engine::proth_engine::*; - use crate::plonk::utils::*; - use crate::plonk::commitments::transparent::fri::*; - use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transcript::*; use crate::plonk::commitments::transparent::fri::naive_fri::naive_fri::*; + use crate::plonk::commitments::transparent::fri::*; use crate::plonk::commitments::transparent::iop::blake2s_trivial_iop::*; - use crate::plonk::commitments::*; + use crate::plonk::commitments::transparent::iop::*; use crate::plonk::commitments::transparent::*; + use crate::plonk::commitments::*; use crate::plonk::tester::*; + use crate::plonk::transparent_engine::proth_engine::*; + use crate::plonk::utils::*; use std::time::Instant; @@ -1364,18 +1262,18 @@ mod test { let num_queries = 20; for log2 in 10..=20 { - let size = (1< { num_steps: size, - _marker: PhantomData + _marker: PhantomData, }; { @@ -1401,7 +1299,7 @@ mod test { println!("Start proving"); let start = Instant::now(); - let proof = prove_nonhomomorphic_chunked::, _>(&circuit, &aux, meta.clone()).unwrap(); + let proof = prove_nonhomomorphic_chunked::, _>(&circuit, &aux, meta.clone()).unwrap(); println!("Proof taken {:?} for 2^{}", start.elapsed(), size_log_2); let proof_size = proof.estimate_proof_size(); @@ -1409,26 +1307,25 @@ mod test { println!("Start verifying"); let start = Instant::now(); - let valid = verify_nonhomomorphic_chunked::>(&setup, &proof, meta).unwrap(); + let valid = verify_nonhomomorphic_chunked::>(&setup, &proof, meta).unwrap(); println!("Verification with unnecessary precomputation taken {:?} for 2^{}", start.elapsed(), size_log_2); assert!(valid); } } - #[test] fn test_poly_eval_correctness() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use crate::multiexp::*; use crate::pairing::bn256::Fr; - use num_cpus; use crate::pairing::ff::ScalarEngine; use crate::pairing::CurveProjective; - use crate::multiexp::*; - use crate::worker::*; use crate::source::*; + use crate::worker::*; + use futures::Future; + use num_cpus; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; use std::sync::Arc; - use futures::{Future}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -1458,16 +1355,16 @@ mod test { #[test] fn test_poly_grand_product_correctness() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use crate::multiexp::*; use crate::pairing::bn256::Fr; - use num_cpus; use crate::pairing::ff::ScalarEngine; use crate::pairing::CurveProjective; - use crate::multiexp::*; - use crate::worker::*; use crate::source::*; + use crate::worker::*; + use futures::Future; + use num_cpus; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; use std::sync::Arc; - use futures::{Future}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -1482,10 +1379,7 @@ mod test { let serial_result = poly.calculate_grand_product_serial().unwrap(); if palallel_result != serial_result { - for (i, (c0, c1)) in palallel_result.as_ref().iter() - .zip(serial_result.as_ref().iter()) - .enumerate() - { + for (i, (c0, c1)) in palallel_result.as_ref().iter().zip(serial_result.as_ref().iter()).enumerate() { assert!(c0 == c1, "failed at value number {} for size {}", i, poly_size); } } @@ -1494,13 +1388,13 @@ mod test { #[test] fn test_bench_lde() { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; use crate::pairing::bn256::Fr; use crate::pairing::ff::ScalarEngine; use crate::pairing::CurveProjective; - use std::time::Instant; - use crate::worker::*; use crate::plonk::commitments::transparent::utils::*; + use crate::worker::*; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; + use std::time::Instant; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -1510,14 +1404,14 @@ mod test { for poly_size in poly_sizes.into_iter() { let coeffs = (0..poly_size).map(|_| Fr::rand(rng)).collect::>(); - + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let start = Instant::now(); let _eval_result = poly.lde(&worker, 16); println!("LDE with factor 16 for size {} taken {:?}", poly_size, start.elapsed()); - let coeffs = (0..(16*poly_size)).map(|_| Fr::rand(rng)).collect::>(); - + let coeffs = (0..(16 * poly_size)).map(|_| Fr::rand(rng)).collect::>(); + let poly = Polynomial::::from_coeffs(coeffs).unwrap(); let start = Instant::now(); let eval_result = poly.clone().fft(&worker); @@ -1533,8 +1427,6 @@ mod test { let to_compare = eval_result.into_coeffs(); assert!(to_compare == coeffs); } - - } } -} \ No newline at end of file +} diff --git a/crates/bellman/src/prefetch.rs b/crates/bellman/src/prefetch.rs index 74c8fa3..6f46b89 100644 --- a/crates/bellman/src/prefetch.rs +++ b/crates/bellman/src/prefetch.rs @@ -11,7 +11,7 @@ cfg_if! { use std::arch::x86::_mm_prefetch; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::_mm_prefetch; - + unsafe { #[cfg(target_arch = "x86_64")] @@ -27,7 +27,7 @@ cfg_if! { use std::arch::x86::_mm_prefetch; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::_mm_prefetch; - + unsafe { #[cfg(target_arch = "x86_64")] @@ -43,7 +43,7 @@ cfg_if! { use std::arch::x86::_mm_prefetch; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::_mm_prefetch; - + unsafe { #[cfg(target_arch = "x86_64")] @@ -59,7 +59,7 @@ cfg_if! { use std::arch::x86::_mm_prefetch; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::_mm_prefetch; - + unsafe { #[cfg(target_arch = "x86_64")] @@ -75,7 +75,7 @@ cfg_if! { use std::arch::x86::_mm_prefetch; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::_mm_prefetch; - + unsafe { #[cfg(target_arch = "x86_64")] @@ -91,7 +91,7 @@ cfg_if! { use std::arch::x86::_mm_prefetch; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::_mm_prefetch; - + unsafe { #[cfg(target_arch = "x86_64")] diff --git a/crates/bellman/src/singlecore.rs b/crates/bellman/src/singlecore.rs index 6708bd9..bb01c9c 100644 --- a/crates/bellman/src/singlecore.rs +++ b/crates/bellman/src/singlecore.rs @@ -4,12 +4,12 @@ extern crate futures; use std::marker::PhantomData; -use std::future::{Future}; +use std::future::Future; +use std::pin::Pin; use std::task::{Context, Poll}; -use std::pin::{Pin}; -use self::futures::channel::oneshot::{channel, Sender, Receiver}; -use self::futures::executor::{block_on}; +use self::futures::channel::oneshot::{channel, Receiver, Sender}; +use self::futures::executor::block_on; #[derive(Clone)] pub struct Worker { @@ -21,9 +21,7 @@ impl Worker { // all `Worker` instances have the same number of // CPUs configured. pub(crate) fn new_with_cpus(_cpus: usize) -> Worker { - Worker { - cpus: 1, - } + Worker { cpus: 1 } } pub fn new() -> Worker { @@ -34,52 +32,38 @@ impl Worker { 0u32 } - pub fn compute( - &self, f: F - ) -> WorkerFuture - where F: FnOnce() -> Result + Send + 'static, - T: Send + 'static, - E: Send + 'static + pub fn compute(&self, f: F) -> WorkerFuture + where + F: FnOnce() -> Result + Send + 'static, + T: Send + 'static, + E: Send + 'static, { let result = f(); let (sender, receiver) = channel(); let _ = sender.send(result); - let worker_future = WorkerFuture { - receiver - }; + let worker_future = WorkerFuture { receiver }; worker_future } - pub fn scope<'a, F, R>( - &self, - elements: usize, - f: F - ) -> R - where F: FnOnce(&Scope<'a>, usize) -> R + pub fn scope<'a, F, R>(&self, elements: usize, f: F) -> R + where + F: FnOnce(&Scope<'a>, usize) -> R, { let chunk_size = if elements == 0 { 1 } else { elements }; - let scope = Scope{ - _marker: PhantomData - }; + let scope = Scope { _marker: PhantomData }; f(&scope, chunk_size) } - pub fn get_chunk_size( - &self, - elements: usize - ) -> usize { + pub fn get_chunk_size(&self, elements: usize) -> usize { elements } - pub fn get_num_spawned_threads( - &self, - elements: usize - ) -> usize { + pub fn get_num_spawned_threads(&self, elements: usize) -> usize { 1 } @@ -94,38 +78,35 @@ impl Worker { } #[derive(Clone)] pub struct Scope<'a> { - _marker: PhantomData<& 'a usize> + _marker: PhantomData<&'a usize>, } impl<'a> Scope<'a> { - pub fn spawn( - &self, - f: F - ) -> R - where F: FnOnce(&Scope<'a>) -> R + pub fn spawn(&self, f: F) -> R + where + F: FnOnce(&Scope<'a>) -> R, { f(&self) } } pub struct WorkerFuture { - receiver: Receiver> + receiver: Receiver>, } impl Future for WorkerFuture { type Output = Result; - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll - { + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { let rec = unsafe { self.map_unchecked_mut(|s| &mut s.receiver) }; match rec.poll(cx) { Poll::Ready(v) => { if let Ok(v) = v { - return Poll::Ready(v) + return Poll::Ready(v); } else { panic!("Worker future can not have canceled sender"); } - }, + } Poll::Pending => { return Poll::Pending; } @@ -139,7 +120,6 @@ impl WorkerFuture { } } - #[test] fn test_trivial_singlecore_spawning() { use self::futures::executor::block_on; @@ -168,4 +148,4 @@ fn test_trivial_singlecore_spawning() { println!("Done sleeping"); let _ = block_on(fut); -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/cs/lc.rs b/crates/bellman/src/sonic/cs/lc.rs index 0bb32e5..e94742d 100644 --- a/crates/bellman/src/sonic/cs/lc.rs +++ b/crates/bellman/src/sonic/cs/lc.rs @@ -1,6 +1,6 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine}; -use std::ops::{Add, Sub, Neg}; +use crate::pairing::ff::Field; +use crate::pairing::Engine; +use std::ops::{Add, Neg, Sub}; /// This represents a linear combination of some variables, with coefficients /// in the scalar field of a pairing-friendly elliptic curve group. @@ -113,11 +113,11 @@ impl Coeff { match self { Coeff::Zero => { *with = E::Fr::zero(); - }, - Coeff::One => {}, + } + Coeff::One => {} Coeff::NegativeOne => { with.negate(); - }, + } Coeff::Full(val) => { with.mul_assign(val); } @@ -146,4 +146,4 @@ impl Neg for Coeff { } } } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/cs/mod.rs b/crates/bellman/src/sonic/cs/mod.rs index d7ad271..0021b54 100644 --- a/crates/bellman/src/sonic/cs/mod.rs +++ b/crates/bellman/src/sonic/cs/mod.rs @@ -1,11 +1,11 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine}; +use crate::pairing::ff::Field; +use crate::pairing::Engine; -use crate::{SynthesisError}; +use crate::SynthesisError; use std::marker::PhantomData; mod lc; -pub use self::lc::{Coeff, Variable, LinearCombination}; +pub use self::lc::{Coeff, LinearCombination, Variable}; pub trait Circuit { fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError>; @@ -34,8 +34,6 @@ pub trait ConstraintSystem { } } - - /// This is a backend for the `SynthesisDriver` to relay information about /// the concrete circuit. One backend might just collect basic information /// about the circuit for verification, while another actually constructs @@ -44,30 +42,36 @@ pub trait Backend { type LinearConstraintIndex; /// Get the value of a variable. Can return None if we don't know. - fn get_var(&self, _variable: Variable) -> Option { None } + fn get_var(&self, _variable: Variable) -> Option { + None + } /// Set the value of a variable. Might error if this backend expects to know it. fn set_var(&mut self, _variable: Variable, _value: F) -> Result<(), SynthesisError> - where F: FnOnce() -> Result { Ok(()) } + where + F: FnOnce() -> Result, + { + Ok(()) + } /// Create a new multiplication gate. - fn new_multiplication_gate(&mut self) { } + fn new_multiplication_gate(&mut self) {} /// Create a new linear constraint, returning the power of Y for caching purposes. fn new_linear_constraint(&mut self) -> Self::LinearConstraintIndex; /// Insert a term into a linear constraint. TODO: bad name of function - fn insert_coefficient(&mut self, _var: Variable, _coeff: Coeff, _y: &Self::LinearConstraintIndex) { } + fn insert_coefficient(&mut self, _var: Variable, _coeff: Coeff, _y: &Self::LinearConstraintIndex) {} /// Compute a `LinearConstraintIndex` from `q`. fn get_for_q(&self, q: usize) -> Self::LinearConstraintIndex; /// Mark y^{_index} as the power of y cooresponding to the public input /// coefficient for the next public input, in the k(Y) polynomial. - fn new_k_power(&mut self, _index: usize) { } + fn new_k_power(&mut self, _index: usize) {} } /// This is an abstraction which synthesizes circuits. pub trait SynthesisDriver { fn synthesize, B: Backend>(backend: B, circuit: &C) -> Result<(), SynthesisError>; -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/helped/adapted_helper.rs b/crates/bellman/src/sonic/helped/adapted_helper.rs index 197f1b1..bd740a1 100644 --- a/crates/bellman/src/sonic/helped/adapted_helper.rs +++ b/crates/bellman/src/sonic/helped/adapted_helper.rs @@ -1,32 +1,27 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use std::marker::PhantomData; use rand::{Rand, Rng}; -use super::{Proof, SxyAdvice}; use super::batch::Batch; +use super::helper::Aggregate; +use super::parameters::Parameters; use super::poly::{SxEval, SyEval}; -use super::parameters::{Parameters}; -use super::helper::{Aggregate}; +use super::{Proof, SxyAdvice}; use crate::SynthesisError; -use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use crate::sonic::util::*; +use super::helper::create_aggregate as create_aggregate_sonic_circuit; use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::{Circuit}; use crate::sonic::sonic::AdaptorCircuit; -use crate::sonic::srs::SRS; use crate::sonic::sonic::Nonassigning; -use super::helper::create_aggregate as create_aggregate_sonic_circuit; +use crate::sonic::srs::SRS; +use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; +use crate::Circuit; -pub fn create_aggregate + Clone>( - circuit: C, - inputs: &[(Proof, SxyAdvice)], - params: &Parameters, -) -> Aggregate -{ +pub fn create_aggregate + Clone>(circuit: C, inputs: &[(Proof, SxyAdvice)], params: &Parameters) -> Aggregate { let adapted_circuit = AdaptorCircuit(circuit); create_aggregate_sonic_circuit::<_, _, Nonassigning>(&adapted_circuit, inputs, params) diff --git a/crates/bellman/src/sonic/helped/adapted_prover.rs b/crates/bellman/src/sonic/helped/adapted_prover.rs index 62b6b12..0feba9a 100644 --- a/crates/bellman/src/sonic/helped/adapted_prover.rs +++ b/crates/bellman/src/sonic/helped/adapted_prover.rs @@ -1,57 +1,41 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use std::marker::PhantomData; -use super::{Proof, SxyAdvice}; use super::batch::Batch; +use super::parameters::Parameters; use super::poly::{SxEval, SyEval}; -use super::parameters::{Parameters}; +use super::{Proof, SxyAdvice}; use crate::SynthesisError; -use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use crate::sonic::util::*; -use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::{Circuit}; -use crate::sonic::sonic::AdaptorCircuit; -use crate::sonic::srs::SRS; -use crate::sonic::sonic::Basic; use super::prover::create_advice as create_advice_sonic_circuit; use super::prover::create_advice_on_information_and_srs as create_advice_on_information_and_srs_sonic_circuit; use super::prover::create_proof_on_srs as create_proof_on_srs_sonic_circuit; +use crate::sonic::cs::{Backend, SynthesisDriver}; +use crate::sonic::sonic::AdaptorCircuit; +use crate::sonic::sonic::Basic; use crate::sonic::sonic::CountN; +use crate::sonic::srs::SRS; +use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; +use crate::Circuit; // pub fn create_advice_on_information_and_srs + Clone, S: SynthesisDriver>( -pub fn create_advice_on_information_and_srs + Clone>( - circuit: C, - proof: &Proof, - srs: &SRS, - n: usize -) -> Result, SynthesisError> -{ +pub fn create_advice_on_information_and_srs + Clone>(circuit: C, proof: &Proof, srs: &SRS, n: usize) -> Result, SynthesisError> { let adapted_circuit = AdaptorCircuit(circuit); create_advice_on_information_and_srs_sonic_circuit::<_, _, Basic>(&adapted_circuit, proof, srs, n) } // pub fn create_advice + Clone, S: SynthesisDriver>( -pub fn create_advice + Clone>( - circuit: C, - proof: &Proof, - parameters: &Parameters, -) -> Result, SynthesisError> -{ +pub fn create_advice + Clone>(circuit: C, proof: &Proof, parameters: &Parameters) -> Result, SynthesisError> { let n = parameters.vk.n; - create_advice_on_information_and_srs::(circuit, proof, ¶meters.srs, n) + create_advice_on_information_and_srs::(circuit, proof, ¶meters.srs, n) } // pub fn create_advice_on_srs + Clone, S: SynthesisDriver>( -pub fn create_advice_on_srs + Clone>( - circuit: C, - proof: &Proof, - srs: &SRS -) -> Result, SynthesisError> -{ +pub fn create_advice_on_srs + Clone>(circuit: C, proof: &Proof, srs: &SRS) -> Result, SynthesisError> { use crate::sonic::sonic::Nonassigning; let adapted_circuit = AdaptorCircuit(circuit.clone()); @@ -64,23 +48,16 @@ pub fn create_advice_on_srs + Clone>( tmp.n }; - create_advice_on_information_and_srs::(circuit, proof, srs, n) + create_advice_on_information_and_srs::(circuit, proof, srs, n) } // pub fn create_proof + Clone, S: SynthesisDriver>( -pub fn create_proof + Clone>( - circuit: C, - parameters: &Parameters -) -> Result, SynthesisError> { +pub fn create_proof + Clone>(circuit: C, parameters: &Parameters) -> Result, SynthesisError> { create_proof_on_srs::(circuit, ¶meters.srs) } // pub fn create_proof_on_srs + Clone, S: SynthesisDriver>( -pub fn create_proof_on_srs + Clone>( - circuit: C, - srs: &SRS -) -> Result, SynthesisError> -{ +pub fn create_proof_on_srs + Clone>(circuit: C, srs: &SRS) -> Result, SynthesisError> { let adapted_circuit = AdaptorCircuit(circuit); create_proof_on_srs_sonic_circuit::<_, _, Basic>(&adapted_circuit, srs) diff --git a/crates/bellman/src/sonic/helped/adapted_verifier.rs b/crates/bellman/src/sonic/helped/adapted_verifier.rs index c796506..5f38f9e 100644 --- a/crates/bellman/src/sonic/helped/adapted_verifier.rs +++ b/crates/bellman/src/sonic/helped/adapted_verifier.rs @@ -1,41 +1,34 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use std::marker::PhantomData; use rand::{Rand, Rng}; -use super::{Proof, SxyAdvice}; use super::batch::Batch; +use super::helper::Aggregate; +use super::parameters::Parameters; use super::poly::{SxEval, SyEval}; -use super::parameters::{Parameters}; -use super::helper::{Aggregate}; +use super::{Proof, SxyAdvice}; use crate::SynthesisError; -use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use crate::sonic::util::*; +use super::verifier::verify_aggregate_on_srs as verify_aggregate_on_srs_sonic_circuit; +use super::verifier::verify_proofs_on_srs as verify_proofs_on_srs_sonic_circuit; use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::{Circuit}; use crate::sonic::sonic::AdaptorCircuit; -use crate::sonic::srs::SRS; use crate::sonic::sonic::Nonassigning; -use super::verifier::verify_aggregate_on_srs as verify_aggregate_on_srs_sonic_circuit; -use super::verifier::verify_proofs_on_srs as verify_proofs_on_srs_sonic_circuit; +use crate::sonic::srs::SRS; +use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; +use crate::Circuit; -pub fn verify_proofs + Clone, R: Rng>( - proofs: &[Proof], - inputs: &[Vec], - circuit: C, - rng: R, - params: &Parameters, -) -> Result -{ +pub fn verify_proofs + Clone, R: Rng>(proofs: &[Proof], inputs: &[Vec], circuit: C, rng: R, params: &Parameters) -> Result { let adapted_circuit = AdaptorCircuit(circuit); verify_proofs_on_srs_sonic_circuit::<_, _, Nonassigning, _>(proofs, inputs, adapted_circuit, rng, ¶ms.srs) } -/// Check multiple proofs with aggregation. Verifier's work is +/// Check multiple proofs with aggregation. Verifier's work is /// not succint due to `S(X, Y)` evaluation pub fn verify_aggregate + Clone, R: Rng>( proofs: &[(Proof, SxyAdvice)], @@ -50,7 +43,6 @@ pub fn verify_aggregate + Clone, R: Rng>( verify_aggregate_on_srs_sonic_circuit::<_, _, Nonassigning, _>(proofs, aggregate, inputs, adapted_circuit, rng, ¶ms.srs) } - // #[test] // fn my_fun_circuit_test() { // use crate::pairing::ff::PrimeField; diff --git a/crates/bellman/src/sonic/helped/batch.rs b/crates/bellman/src/sonic/helped/batch.rs index 6160e23..adfb92c 100644 --- a/crates/bellman/src/sonic/helped/batch.rs +++ b/crates/bellman/src/sonic/helped/batch.rs @@ -8,13 +8,13 @@ //! This submodule contains the `Batch` abstraction for creating a //! context for batch verification. -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveAffine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; use crate::SynthesisError; +use crate::sonic::cs::Circuit; use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::sonic::cs::{Circuit}; use super::parameters::VerifyingKey; @@ -104,7 +104,7 @@ impl Batch { } } - /// add `(r*P) to the h^(alpha*x) terms, add -(r*point)*P to h^(alpha) terms + /// add `(r*P) to the h^(alpha*x) terms, add -(r*point)*P to h^(alpha) terms pub fn add_opening(&mut self, p: E::G1Affine, mut r: E::Fr, point: E::Fr) { self.alpha_x.push((p, r)); r.mul_assign(&point); @@ -131,31 +131,19 @@ impl Batch { pub fn check_all(mut self) -> bool { self.alpha.push((self.g, self.value)); - let alpha_x = multiexp( - self.alpha_x.iter().map(|x| &x.0), - self.alpha_x.iter().map(|x| &x.1), - ).into_affine(); + let alpha_x = multiexp(self.alpha_x.iter().map(|x| &x.0), self.alpha_x.iter().map(|x| &x.1)).into_affine(); let alpha_x = alpha_x.prepare(); - let alpha = multiexp( - self.alpha.iter().map(|x| &x.0), - self.alpha.iter().map(|x| &x.1), - ).into_affine(); + let alpha = multiexp(self.alpha.iter().map(|x| &x.0), self.alpha.iter().map(|x| &x.1)).into_affine(); let alpha = alpha.prepare(); - let neg_h = multiexp( - self.neg_h.iter().map(|x| &x.0), - self.neg_h.iter().map(|x| &x.1), - ).into_affine(); + let neg_h = multiexp(self.neg_h.iter().map(|x| &x.0), self.neg_h.iter().map(|x| &x.1)).into_affine(); let neg_h = neg_h.prepare(); - let neg_x_n_minus_d = multiexp( - self.neg_x_n_minus_d.iter().map(|x| &x.0), - self.neg_x_n_minus_d.iter().map(|x| &x.1), - ).into_affine(); + let neg_x_n_minus_d = multiexp(self.neg_x_n_minus_d.iter().map(|x| &x.0), self.neg_x_n_minus_d.iter().map(|x| &x.1)).into_affine(); let neg_x_n_minus_d = neg_x_n_minus_d.prepare(); @@ -164,6 +152,8 @@ impl Batch { (&alpha, &self.alpha_precomp), (&neg_h, &self.neg_h_precomp), (&neg_x_n_minus_d, &self.neg_x_n_minus_d_precomp), - ])).unwrap() == E::Fqk::one() + ])) + .unwrap() + == E::Fqk::one() } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/helped/generator.rs b/crates/bellman/src/sonic/helped/generator.rs index b2e3357..66235fa 100644 --- a/crates/bellman/src/sonic/helped/generator.rs +++ b/crates/bellman/src/sonic/helped/generator.rs @@ -2,73 +2,47 @@ use rand::Rng; use std::sync::Arc; -use crate::pairing::{ - Engine, - Wnaf, - CurveProjective, - CurveAffine -}; - -use crate::pairing::ff::{ - PrimeField, - Field -}; - -use super::{ - Parameters, - VerifyingKey -}; - -use crate::{ - SynthesisError, - Circuit, - ConstraintSystem, - LinearCombination, - Variable, - Index -}; - -use crate::domain::{ - Scalar -}; - -use crate::worker::{ - Worker -}; +use crate::pairing::{CurveAffine, CurveProjective, Engine, Wnaf}; + +use crate::pairing::ff::{Field, PrimeField}; + +use super::{Parameters, VerifyingKey}; + +use crate::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; + +use crate::domain::Scalar; + +use crate::worker::Worker; use std::marker::PhantomData; -use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::sonic::srs::SRS; -use crate::sonic::cs::LinearCombination as SonicLinearCombination; +use super::parameters::NUM_BLINDINGS; use crate::sonic::cs::Circuit as SonicCircuit; +use crate::sonic::cs::Coeff; use crate::sonic::cs::ConstraintSystem as SonicConstraintSystem; +use crate::sonic::cs::LinearCombination as SonicLinearCombination; use crate::sonic::cs::Variable as SonicVariable; -use crate::sonic::cs::Coeff; -use crate::sonic::sonic::{AdaptorCircuit}; -use super::parameters::NUM_BLINDINGS; +use crate::sonic::cs::{Backend, SynthesisDriver}; +use crate::sonic::sonic::AdaptorCircuit; use crate::sonic::sonic::NonassigningSynthesizer; use crate::sonic::sonic::PermutationSynthesizer; use crate::sonic::sonic::{Basic, Preprocess}; +use crate::sonic::srs::SRS; use crate::verbose_flag; /// Generates a random common reference string for /// a circuit. -pub fn generate_random_parameters( - circuit: C, - rng: &mut R -) -> Result, SynthesisError> - where E: Engine, C: Circuit, R: Rng +pub fn generate_random_parameters(circuit: C, rng: &mut R) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, + R: Rng, { let alpha = rng.gen(); let x = rng.gen(); - generate_parameters::( - circuit, - alpha, - x - ) + generate_parameters::(circuit, alpha, x) } /// This is our assembly structure that we'll use to synthesize the @@ -81,7 +55,7 @@ pub struct CircuitParameters { pub k_map: Vec, pub n: usize, pub q: usize, - _marker: PhantomData + _marker: PhantomData, } /// This is our assembly structure that we'll use to synthesize the @@ -91,12 +65,10 @@ struct GeneratorAssembly<'a, E: Engine, CS: SonicConstraintSystem + 'a> { num_inputs: usize, num_aux: usize, num_constraints: usize, - _marker: PhantomData + _marker: PhantomData, } -impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem - for GeneratorAssembly<'a, E, CS> -{ +impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem for GeneratorAssembly<'a, E, CS> { type Root = Self; // this is an important change @@ -112,9 +84,10 @@ impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem crate::Variable::new_unchecked(crate::Index::Input(index)), @@ -123,11 +96,7 @@ impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem( - &mut self, - _: A, - f: F, - ) -> Result + fn alloc_input(&mut self, _: A, f: F) -> Result where F: FnOnce() -> Result, A: FnOnce() -> AR, @@ -135,9 +104,10 @@ impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem crate::Variable::new_unchecked(crate::Index::Input(index)), @@ -169,10 +139,7 @@ impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem>( - lc: &SonicLinearCombination, - cs: &CS, - ) -> Option { + fn eval>(lc: &SonicLinearCombination, cs: &CS) -> Option { let mut ret = E::Fr::zero(); for &(v, coeff) in lc.as_ref().iter() { @@ -196,10 +163,7 @@ impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem + 'a> crate::ConstraintSystem( - circuit: C, -) -> Result, SynthesisError> - where E: Engine, C: Circuit - +pub fn get_circuit_parameters(circuit: C) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, { let mut preprocess = Preprocess::new(); let (num_inputs, num_aux, num_constraints) = { - let mut cs: NonassigningSynthesizer> = NonassigningSynthesizer::new(&mut preprocess); let one = cs.alloc_input(|| Ok(E::Fr::one())).expect("should have no issues"); match (one, > as SonicConstraintSystem>::ONE) { - (SonicVariable::A(1), SonicVariable::A(1)) => {}, - _ => return Err(SynthesisError::UnconstrainedVariable) + (SonicVariable::A(1), SonicVariable::A(1)) => {} + _ => return Err(SynthesisError::UnconstrainedVariable), } let mut assembly = GeneratorAssembly::<'_, E, _> { @@ -252,7 +212,7 @@ pub fn get_circuit_parameters( num_inputs: 0, num_aux: 0, num_constraints: 0, - _marker: PhantomData + _marker: PhantomData, }; circuit.synthesize(&mut assembly)?; @@ -267,30 +227,28 @@ pub fn get_circuit_parameters( k_map: preprocess.k_map, n: preprocess.n, q: preprocess.q, - _marker: PhantomData + _marker: PhantomData, }) } -/// Get circuit information such as number of input, variables, +/// Get circuit information such as number of input, variables, /// constraints, and the corresponding SONIC parameters /// k_map, n, q -pub fn get_circuit_parameters_for_succinct_sonic( - circuit: C, -) -> Result, SynthesisError> - where E: Engine, C: Circuit - +pub fn get_circuit_parameters_for_succinct_sonic(circuit: C) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, { let mut preprocess = Preprocess::new(); let (num_inputs, num_aux, num_constraints) = { - let mut cs: PermutationSynthesizer> = PermutationSynthesizer::new(&mut preprocess); let one = cs.alloc_input(|| Ok(E::Fr::one())).expect("should have no issues"); match (one, > as SonicConstraintSystem>::ONE) { - (SonicVariable::A(1), SonicVariable::A(1)) => {}, - _ => return Err(SynthesisError::UnconstrainedVariable) + (SonicVariable::A(1), SonicVariable::A(1)) => {} + _ => return Err(SynthesisError::UnconstrainedVariable), } let mut assembly = GeneratorAssembly::<'_, E, _> { @@ -298,7 +256,7 @@ pub fn get_circuit_parameters_for_succinct_sonic( num_inputs: 0, num_aux: 0, num_constraints: 0, - _marker: PhantomData + _marker: PhantomData, }; circuit.synthesize(&mut assembly)?; @@ -313,19 +271,17 @@ pub fn get_circuit_parameters_for_succinct_sonic( k_map: preprocess.k_map, n: preprocess.n, q: preprocess.q, - _marker: PhantomData + _marker: PhantomData, }) } -pub fn generate_parameters( - circuit: C, - alpha: E::Fr, - x: E::Fr -) -> Result, SynthesisError> - where E: Engine, C: Circuit +pub fn generate_parameters(circuit: C, alpha: E::Fr, x: E::Fr) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, { - let circuit_parameters = get_circuit_parameters::(circuit)?; - let min_d = circuit_parameters.n * 4 + 2*NUM_BLINDINGS; + let circuit_parameters = get_circuit_parameters::(circuit)?; + let min_d = circuit_parameters.n * 4 + 2 * NUM_BLINDINGS; let srs = generate_srs(alpha, x, min_d)?; @@ -334,11 +290,10 @@ pub fn generate_parameters( Ok(parameters) } -pub fn generate_parameters_on_srs( - circuit: C, - srs: &SRS, -) -> Result, SynthesisError> - where E: Engine, C: Circuit +pub fn generate_parameters_on_srs(circuit: C, srs: &SRS) -> Result, SynthesisError> +where + E: Engine, + C: Circuit, { let circuit_parameters = get_circuit_parameters::(circuit)?; let parameters = generate_parameters_on_srs_and_information(&srs, circuit_parameters)?; @@ -346,28 +301,23 @@ pub fn generate_parameters_on_srs( Ok(parameters) } -pub fn generate_parameters_on_srs_and_information( - srs: &SRS, - information: CircuitParameters -) -> Result, SynthesisError> -{ - assert!(srs.d >= information.n * 4 + 2*NUM_BLINDINGS); - let min_d = information.n * 4 + 2*NUM_BLINDINGS; +pub fn generate_parameters_on_srs_and_information(srs: &SRS, information: CircuitParameters) -> Result, SynthesisError> { + assert!(srs.d >= information.n * 4 + 2 * NUM_BLINDINGS); + let min_d = information.n * 4 + 2 * NUM_BLINDINGS; let trimmed_srs: SRS = SRS { d: min_d, - g_negative_x: srs.g_negative_x[0..min_d+1].to_vec(), - g_positive_x: srs.g_positive_x[0..min_d+1].to_vec().clone(), + g_negative_x: srs.g_negative_x[0..min_d + 1].to_vec(), + g_positive_x: srs.g_positive_x[0..min_d + 1].to_vec().clone(), - h_negative_x: srs.h_negative_x[0..min_d+1].to_vec(), - h_positive_x: srs.h_positive_x[0..min_d+1].to_vec(), + h_negative_x: srs.h_negative_x[0..min_d + 1].to_vec(), + h_positive_x: srs.h_positive_x[0..min_d + 1].to_vec(), g_negative_x_alpha: srs.g_negative_x_alpha[0..min_d].to_vec(), g_positive_x_alpha: srs.g_positive_x_alpha[0..min_d].to_vec(), - h_negative_x_alpha: srs.h_negative_x_alpha[0..min_d+1].to_vec(), - h_positive_x_alpha: srs.h_positive_x_alpha[0..min_d+1].to_vec(), - + h_negative_x_alpha: srs.h_negative_x_alpha[0..min_d + 1].to_vec(), + h_positive_x_alpha: srs.h_positive_x_alpha[0..min_d + 1].to_vec(), }; let vk = VerifyingKey { @@ -391,20 +341,13 @@ pub fn generate_parameters_on_srs_and_information( k_map: information.k_map, n: information.n, - q: information.q + q: information.q, }; - Ok(Parameters{ - vk: vk, - srs: trimmed_srs - }) + Ok(Parameters { vk: vk, srs: trimmed_srs }) } -pub fn generate_srs( - alpha: E::Fr, - x: E::Fr, - d: usize -) -> Result, SynthesisError> { +pub fn generate_srs(alpha: E::Fr, x: E::Fr, d: usize) -> Result, SynthesisError> { let verbose = verbose_flag(); let g1 = E::G1Affine::one().into_projective(); @@ -412,11 +355,11 @@ pub fn generate_srs( // Compute G1 window table let mut g1_wnaf = Wnaf::new(); - let g1_wnaf = g1_wnaf.base(g1, 4*d); + let g1_wnaf = g1_wnaf.base(g1, 4 * d); // Compute G2 window table let mut g2_wnaf = Wnaf::new(); - let g2_wnaf = g2_wnaf.base(g2, 4*d); + let g2_wnaf = g2_wnaf.base(g2, 4 * d); let x_inverse = x.inverse().ok_or(SynthesisError::UnexpectedIdentity)?; @@ -426,16 +369,17 @@ pub fn generate_srs( let mut x_powers_negative = vec![Scalar::(E::Fr::zero()); d]; { // Compute powers of tau - if verbose {eprintln!("computing powers of x...")}; + if verbose { + eprintln!("computing powers of x...") + }; let start = std::time::Instant::now(); { worker.scope(d, |scope, chunk| { - for (i, x_powers) in x_powers_positive.chunks_mut(chunk).enumerate() - { + for (i, x_powers) in x_powers_positive.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut current_power = x.pow(&[(i*chunk + 1) as u64]); + let mut current_power = x.pow(&[(i * chunk + 1) as u64]); for p in x_powers { p.0 = current_power; @@ -447,10 +391,9 @@ pub fn generate_srs( } { worker.scope(d, |scope, chunk| { - for (i, x_powers) in x_powers_negative.chunks_mut(chunk).enumerate() - { + for (i, x_powers) in x_powers_negative.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut current_power = x_inverse.pow(&[(i*chunk + 1) as u64]); + let mut current_power = x_inverse.pow(&[(i * chunk + 1) as u64]); for p in x_powers { p.0 = current_power; @@ -460,7 +403,9 @@ pub fn generate_srs( } }); } - if verbose {eprintln!("powers of x done in {} s", start.elapsed().as_millis() as f64 / 1000.0);}; + if verbose { + eprintln!("powers of x done in {} s", start.elapsed().as_millis() as f64 / 1000.0); + }; } // we will later add zero powers to g_x, h_x, h_x_alpha @@ -492,10 +437,8 @@ pub fn generate_srs( alpha: &E::Fr, // Worker - worker: &Worker - ) - - { + worker: &Worker, + ) { // Sanity check assert_eq!(g_x.len(), powers_of_x.len()); assert_eq!(g_x.len(), g_x_alpha.len()); @@ -504,22 +447,18 @@ pub fn generate_srs( // Evaluate polynomials in multiple threads worker.scope(g_x.len(), |scope, chunk| { - for ((((x, g_x), g_x_alpha), h_x), h_x_alpha) in powers_of_x.chunks(chunk) - .zip(g_x.chunks_mut(chunk)) - .zip(g_x_alpha.chunks_mut(chunk)) - .zip(h_x.chunks_mut(chunk)) - .zip(h_x_alpha.chunks_mut(chunk)) + for ((((x, g_x), g_x_alpha), h_x), h_x_alpha) in powers_of_x + .chunks(chunk) + .zip(g_x.chunks_mut(chunk)) + .zip(g_x_alpha.chunks_mut(chunk)) + .zip(h_x.chunks_mut(chunk)) + .zip(h_x_alpha.chunks_mut(chunk)) { let mut g1_wnaf = g1_wnaf.shared(); let mut g2_wnaf = g2_wnaf.shared(); scope.spawn(move |_| { - for ((((x, g_x), g_x_alpha), h_x), h_x_alpha) in x.iter() - .zip(g_x.iter_mut()) - .zip(g_x_alpha.iter_mut()) - .zip(h_x.iter_mut()) - .zip(h_x_alpha.iter_mut()) - { + for ((((x, g_x), g_x_alpha), h_x), h_x_alpha) in x.iter().zip(g_x.iter_mut()).zip(g_x_alpha.iter_mut()).zip(h_x.iter_mut()).zip(h_x_alpha.iter_mut()) { let mut x_alpha = x.0; x_alpha.mul_assign(&alpha); @@ -536,7 +475,7 @@ pub fn generate_srs( E::G2::batch_normalization(h_x); E::G2::batch_normalization(h_x_alpha); }); - }; + } }); } @@ -552,7 +491,7 @@ pub fn generate_srs( &mut h_positive_x[..], &mut h_positive_x_alpha[..], &alpha, - &worker + &worker, ); // Evaluate for negative powers @@ -565,10 +504,12 @@ pub fn generate_srs( &mut h_negative_x[..], &mut h_negative_x_alpha[..], &alpha, - &worker + &worker, ); - if verbose {eprintln!("evaluating points done in {} s", start.elapsed().as_millis() as f64 / 1000.0);}; + if verbose { + eprintln!("evaluating points done in {} s", start.elapsed().as_millis() as f64 / 1000.0); + }; let g1 = g1.into_affine(); let g2 = g2.into_affine(); @@ -618,18 +559,17 @@ pub fn generate_srs( }; Ok(SRS { - d: d, - g_negative_x: g_negative_x, - g_positive_x: g_positive_x, + d: d, + g_negative_x: g_negative_x, + g_positive_x: g_positive_x, - h_negative_x: h_negative_x, - h_positive_x: h_positive_x, + h_negative_x: h_negative_x, + h_positive_x: h_positive_x, - g_negative_x_alpha: g_negative_x_alpha, - g_positive_x_alpha: g_positive_x_alpha, + g_negative_x_alpha: g_negative_x_alpha, + g_positive_x_alpha: g_positive_x_alpha, - h_negative_x_alpha: h_negative_x_alpha, - h_positive_x_alpha: h_positive_x_alpha, - } - ) -} \ No newline at end of file + h_negative_x_alpha: h_negative_x_alpha, + h_positive_x_alpha: h_positive_x_alpha, + }) +} diff --git a/crates/bellman/src/sonic/helped/helper.rs b/crates/bellman/src/sonic/helped/helper.rs index 30a0a3a..f11b308 100644 --- a/crates/bellman/src/sonic/helped/helper.rs +++ b/crates/bellman/src/sonic/helped/helper.rs @@ -1,20 +1,20 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use std::marker::PhantomData; -use super::{Proof, SxyAdvice}; use super::batch::Batch; use super::poly::{SxEval, SyEval}; use super::Parameters; +use super::{Proof, SxyAdvice}; use crate::SynthesisError; -use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use crate::sonic::util::*; use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::sonic::cs::{Circuit, Variable, Coeff}; -use crate::sonic::srs::SRS; +use crate::sonic::cs::{Circuit, Coeff, Variable}; use crate::sonic::sonic::CountNandQ; +use crate::sonic::srs::SRS; +use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; #[derive(Clone)] pub struct Aggregate { @@ -31,24 +31,14 @@ pub struct Aggregate { pub w: E::Fr, } -pub fn create_aggregate, S: SynthesisDriver>( - circuit: &C, - inputs: &[(Proof, SxyAdvice)], - params: &Parameters, -) -> Aggregate -{ +pub fn create_aggregate, S: SynthesisDriver>(circuit: &C, inputs: &[(Proof, SxyAdvice)], params: &Parameters) -> Aggregate { let n = params.vk.n; let q = params.vk.q; create_aggregate_on_srs_using_information::(circuit, inputs, ¶ms.srs, n, q) } -pub fn create_aggregate_on_srs, S: SynthesisDriver>( - circuit: &C, - inputs: &[(Proof, SxyAdvice)], - srs: &SRS, -) -> Aggregate -{ +pub fn create_aggregate_on_srs, S: SynthesisDriver>(circuit: &C, inputs: &[(Proof, SxyAdvice)], srs: &SRS) -> Aggregate { // TODO: precompute this? let (n, q) = { let mut tmp = CountNandQ::::new(); @@ -61,14 +51,7 @@ pub fn create_aggregate_on_srs, S: SynthesisDriver>( create_aggregate_on_srs_using_information::(circuit, inputs, srs, n, q) } -pub fn create_aggregate_on_srs_using_information, S: SynthesisDriver>( - circuit: &C, - inputs: &[(Proof, SxyAdvice)], - srs: &SRS, - n: usize, - q: usize, -) -> Aggregate -{ +pub fn create_aggregate_on_srs_using_information, S: SynthesisDriver>(circuit: &C, inputs: &[(Proof, SxyAdvice)], srs: &SRS, n: usize, q: usize) -> Aggregate { let mut transcript = Transcript::new(&[]); let mut y_values: Vec = Vec::with_capacity(inputs.len()); for &(ref proof, ref sxyadvice) in inputs { @@ -93,11 +76,10 @@ pub fn create_aggregate_on_srs_using_information, S: Sy // Compute C = g^{s(z, x)} let c = multiexp( - srs.g_positive_x_alpha[0..(n + q)] - .iter() - .chain_ext(srs.g_negative_x_alpha[0..n].iter()), - s_poly_positive.iter().chain_ext(s_poly_negative.iter()) - ).into_affine(); + srs.g_positive_x_alpha[0..(n + q)].iter().chain_ext(srs.g_negative_x_alpha[0..n].iter()), + s_poly_positive.iter().chain_ext(s_poly_negative.iter()), + ) + .into_affine(); transcript.commit_point(&c); @@ -110,13 +92,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy let mut value = value; value.negate(); - polynomial_commitment_opening( - n, - 0, - s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()), - w, - &srs - ) + polynomial_commitment_opening(n, 0, s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()), w, &srs) }; // Let's open up C to every y. @@ -143,13 +119,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy let mut value = value; value.negate(); - polynomial_commitment_opening( - n, - 0, - s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()), - *y, - &srs - ) + polynomial_commitment_opening(n, 0, s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()), *y, &srs) }; c_openings.push((opening, value)); @@ -162,7 +132,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy // challenges instead and open up a random linear combination. let mut poly_negative = vec![E::Fr::zero(); n]; - let mut poly_positive = vec![E::Fr::zero(); 2*n]; + let mut poly_positive = vec![E::Fr::zero(); 2 * n]; let mut expected_value = E::Fr::zero(); // TODO: this part can be further parallelized due to synthesis of S(X, y) being singlethreaded @@ -182,9 +152,8 @@ pub fn create_aggregate_on_srs_using_information, S: Sy value.mul_assign(&r); expected_value.add_assign(&value); - mul_add_polynomials(& mut poly_negative[..], &s_poly_negative[..], r); - mul_add_polynomials(& mut poly_positive[..], &s_poly_positive[..], r); - + mul_add_polynomials(&mut poly_negative[..], &s_poly_negative[..], r); + mul_add_polynomials(&mut poly_positive[..], &s_poly_positive[..], r); } println!("Re-evaluation of {} S polynomials taken {:?}", y_values.len(), start.elapsed()); @@ -193,14 +162,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy let mut value = expected_value; value.negate(); - polynomial_commitment_opening( - n, - 0, - poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(poly_positive.iter()), - z, - &srs - ) - + polynomial_commitment_opening(n, 0, poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(poly_positive.iter()), z, &srs) }; Aggregate { @@ -215,6 +177,6 @@ pub fn create_aggregate_on_srs_using_information, S: Sy z: z, - w: w + w: w, } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/helped/mod.rs b/crates/bellman/src/sonic/helped/mod.rs index c73396a..386f4ec 100644 --- a/crates/bellman/src/sonic/helped/mod.rs +++ b/crates/bellman/src/sonic/helped/mod.rs @@ -1,51 +1,28 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use std::marker::PhantomData; +mod adapted_helper; +mod adapted_prover; +mod adapted_verifier; pub mod batch; +pub mod generator; +pub mod helper; +pub mod parameters; pub mod poly; pub mod prover; pub mod verifier; -pub mod helper; -pub mod parameters; -pub mod generator; -mod adapted_prover; -mod adapted_verifier; -mod adapted_helper; -pub use self::batch::{Batch}; -pub use self::verifier::{MultiVerifier}; +pub use self::batch::Batch; +pub use self::verifier::MultiVerifier; +pub use self::adapted_prover::{create_advice, create_advice_on_information_and_srs, create_advice_on_srs, create_proof, create_proof_on_srs}; pub use self::generator::{ - CircuitParameters, - generate_parameters, - generate_parameters_on_srs, - generate_parameters_on_srs_and_information, - generate_random_parameters, - generate_srs, - get_circuit_parameters, - get_circuit_parameters_for_succinct_sonic -}; -pub use self::parameters::{ - Proof, - SxyAdvice, - Parameters, - VerifyingKey, - PreparedVerifyingKey -}; -pub use self::adapted_prover::{ - create_advice, - create_advice_on_srs, - create_advice_on_information_and_srs, - create_proof, - create_proof_on_srs, + generate_parameters, generate_parameters_on_srs, generate_parameters_on_srs_and_information, generate_random_parameters, generate_srs, get_circuit_parameters, + get_circuit_parameters_for_succinct_sonic, CircuitParameters, }; +pub use self::parameters::{Parameters, PreparedVerifyingKey, Proof, SxyAdvice, VerifyingKey}; -pub use self::adapted_verifier::{ - verify_proofs, - verify_aggregate -}; +pub use self::adapted_verifier::{verify_aggregate, verify_proofs}; -pub use self::adapted_helper::{ - create_aggregate -}; \ No newline at end of file +pub use self::adapted_helper::create_aggregate; diff --git a/crates/bellman/src/sonic/helped/parameters.rs b/crates/bellman/src/sonic/helped/parameters.rs index cdf6e0f..738e89c 100644 --- a/crates/bellman/src/sonic/helped/parameters.rs +++ b/crates/bellman/src/sonic/helped/parameters.rs @@ -1,23 +1,13 @@ -use crate::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr -}; - -use crate::pairing::{ - Engine, - CurveAffine, - EncodedPoint -}; - -use crate::{ - SynthesisError -}; +use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; + +use crate::pairing::{CurveAffine, EncodedPoint, Engine}; + +use crate::SynthesisError; use crate::source::SourceBuilder; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use std::io::{self, Read, Write}; use std::sync::Arc; -use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt}; pub const NUM_BLINDINGS: usize = 6; // pub const NUM_BLINDINGS: usize = 0; @@ -31,9 +21,7 @@ pub struct SxyAdvice { impl PartialEq for SxyAdvice { fn eq(&self, other: &SxyAdvice) -> bool { - self.s == other.s && - self.opening == other.opening && - self.szy == other.szy + self.s == other.s && self.opening == other.opening && self.szy == other.szy } } @@ -44,26 +32,17 @@ pub struct Proof { pub rz: E::Fr, pub rzy: E::Fr, pub z_opening: E::G1Affine, - pub zy_opening: E::G1Affine + pub zy_opening: E::G1Affine, } impl PartialEq for Proof { fn eq(&self, other: &Proof) -> bool { - self.r == other.r && - self.t == other.t && - self.rz == other.rz && - self.rzy == other.rzy && - self.z_opening == other.z_opening && - self.zy_opening == other.zy_opening + self.r == other.r && self.t == other.t && self.rz == other.rz && self.rzy == other.rzy && self.z_opening == other.z_opening && self.zy_opening == other.zy_opening } } impl Proof { - pub fn write( - &self, - mut writer: W - ) -> io::Result<()> - { + pub fn write(&self, mut writer: W) -> io::Result<()> { use crate::pairing::ff::{PrimeField, PrimeFieldRepr}; writer.write_all(self.r.into_compressed().as_ref())?; writer.write_all(self.t.into_compressed().as_ref())?; @@ -79,71 +58,63 @@ impl Proof { Ok(()) } - pub fn read( - mut reader: R - ) -> io::Result - { + pub fn read(mut reader: R) -> io::Result { let mut g1_repr = ::Compressed::empty(); let mut fr_repr = E::Fr::zero().into_repr(); reader.read_exact(g1_repr.as_mut())?; - let r = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let r = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; reader.read_exact(g1_repr.as_mut())?; - let t = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let t = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; fr_repr.read_be(&mut reader)?; - let rz = E::Fr::from_repr(fr_repr) - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "field element is zero")) - } else { - Ok(e) - })?; + let rz = E::Fr::from_repr(fr_repr).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "field element is zero")) + } else { + Ok(e) + } + })?; fr_repr.read_be(&mut reader)?; - let rzy = E::Fr::from_repr(fr_repr) - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "field element is zero")) - } else { - Ok(e) - })?; - - + let rzy = E::Fr::from_repr(fr_repr).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "field element is zero")) + } else { + Ok(e) + } + })?; + reader.read_exact(g1_repr.as_mut())?; - let z_opening = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let z_opening = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; reader.read_exact(g1_repr.as_mut())?; - let zy_opening = g1_repr - .into_affine() - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - })?; + let zy_opening = g1_repr.into_affine().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)).and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + })?; Ok(Proof { r: r, @@ -151,7 +122,7 @@ impl Proof { rz: rz, rzy: rzy, z_opening: z_opening, - zy_opening: zy_opening + zy_opening: zy_opening, }) } } @@ -170,27 +141,23 @@ pub struct VerifyingKey { pub n: usize, - pub q: usize + pub q: usize, } impl PartialEq for VerifyingKey { fn eq(&self, other: &VerifyingKey) -> bool { - self.alpha_x == other.alpha_x && - self.alpha == other.alpha && - self.neg_h == other.neg_h && - self.neg_x_n_minus_d == other.neg_x_n_minus_d && - self.k_map == other.k_map && - self.n == other.n && - self.q == other.q + self.alpha_x == other.alpha_x + && self.alpha == other.alpha + && self.neg_h == other.neg_h + && self.neg_x_n_minus_d == other.neg_x_n_minus_d + && self.k_map == other.k_map + && self.n == other.n + && self.q == other.q } } impl VerifyingKey { - pub fn write( - &self, - mut writer: W - ) -> io::Result<()> - { + pub fn write(&self, mut writer: W) -> io::Result<()> { writer.write_all(self.alpha_x.into_uncompressed().as_ref())?; writer.write_all(self.alpha.into_uncompressed().as_ref())?; writer.write_all(self.neg_h.into_uncompressed().as_ref())?; @@ -206,10 +173,7 @@ impl VerifyingKey { Ok(()) } - pub fn read( - mut reader: R - ) -> io::Result - { + pub fn read(mut reader: R) -> io::Result { let mut g2_repr = ::Uncompressed::empty(); reader.read_exact(g2_repr.as_mut())?; @@ -245,18 +209,17 @@ impl VerifyingKey { neg_x_n_minus_d: neg_x_n_minus_d, k_map: k_map, n: n, - q: q + q: q, }) } } -use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::sonic::srs::SRS; use crate::sonic::cs::Circuit as SonicCircuit; +use crate::sonic::cs::{Backend, SynthesisDriver}; use crate::sonic::sonic::{Basic, Preprocess}; +use crate::sonic::srs::SRS; use std::marker::PhantomData; - impl VerifyingKey { pub fn new, S: SynthesisDriver>(circuit: C, srs: &SRS) -> Result { let mut preprocess = Preprocess::new(); @@ -284,7 +247,7 @@ impl VerifyingKey { k_map: preprocess.k_map, n: preprocess.n, - q: preprocess.q + q: preprocess.q, }) } } @@ -296,7 +259,7 @@ pub struct PreparedVerifyingKey { neg_x_n_minus_d: ::Prepared, k_map: Vec, n: usize, - q: usize + q: usize, } #[derive(Clone, Eq)] @@ -333,80 +296,62 @@ pub struct Parameters { impl PartialEq for Parameters { fn eq(&self, other: &Parameters) -> bool { - self.vk == other.vk && - self.srs == other.srs + self.vk == other.vk && self.srs == other.srs } } impl Parameters { - pub fn write( - &self, - mut writer: W - ) -> io::Result<()> - { + pub fn write(&self, mut writer: W) -> io::Result<()> { self.vk.write(&mut writer)?; self.srs.write(&mut writer)?; Ok(()) } - pub fn read( - mut reader: R, - checked: bool - ) -> io::Result - { + pub fn read(mut reader: R, checked: bool) -> io::Result { let vk = VerifyingKey::::read(&mut reader)?; let srs = SRS::::read(&mut reader, checked)?; - Ok(Parameters { - vk: vk, - srs: srs - }) + Ok(Parameters { vk: vk, srs: srs }) } } #[test] fn parameters_generation() { - use crate::{ConstraintSystem, Circuit}; + use crate::{Circuit, ConstraintSystem}; use crate::pairing::bls12_381::{Bls12, Fr}; #[derive(Clone)] struct MySillyCircuit { a: Option, - b: Option + b: Option, } impl Circuit for MySillyCircuit { - fn synthesize>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError> - { + fn synthesize>(self, cs: &mut CS) -> Result<(), SynthesisError> { let a = cs.alloc(|| "a", || self.a.ok_or(SynthesisError::AssignmentMissing))?; let b = cs.alloc(|| "b", || self.b.ok_or(SynthesisError::AssignmentMissing))?; - let c = cs.alloc_input(|| "c", || { - let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?; - let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; + let c = cs.alloc_input( + || "c", + || { + let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?; + let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; - a.mul_assign(&b); - Ok(a) - })?; + a.mul_assign(&b); + Ok(a) + }, + )?; - cs.enforce( - || "a*b=c", - |lc| lc + a, - |lc| lc + b, - |lc| lc + c - ); + cs.enforce(|| "a*b=c", |lc| lc + a, |lc| lc + b, |lc| lc + c); Ok(()) } } - use rand::{Rng, Rand, thread_rng}; - use super::{generate_parameters, get_circuit_parameters, generate_srs, generate_parameters_on_srs_and_information}; use super::adapted_prover::create_proof; + use super::{generate_parameters, generate_parameters_on_srs_and_information, generate_srs, get_circuit_parameters}; + use rand::{thread_rng, Rand, Rng}; let info = get_circuit_parameters::(MySillyCircuit { a: None, b: None }).expect("Must get circuit info"); println!("{:?}", info); @@ -417,11 +362,7 @@ fn parameters_generation() { let params = generate_parameters::(MySillyCircuit { a: None, b: None }, alpha, x).unwrap(); let srs = generate_srs::(alpha, x, info.n * 100).unwrap(); - let naive_srs = SRS::::new( - info.n * 100, - x, - alpha, - ); + let naive_srs = SRS::::new(info.n * 100, x, alpha); assert!(srs == naive_srs); @@ -447,13 +388,7 @@ fn parameters_generation() { let mut c = a; c.mul_assign(&b); - let proof = create_proof ( - MySillyCircuit { - a: Some(a), - b: Some(b) - }, - ¶ms, - ).unwrap(); + let proof = create_proof(MySillyCircuit { a: Some(a), b: Some(b) }, ¶ms).unwrap(); let mut v = vec![]; proof.write(&mut v).unwrap(); @@ -466,4 +401,4 @@ fn parameters_generation() { // assert!(verify_proof(&pvk, &proof, &[c]).unwrap()); // assert!(!verify_proof(&pvk, &proof, &[a]).unwrap()); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/helped/poly.rs b/crates/bellman/src/sonic/helped/poly.rs index e54b276..3db0490 100644 --- a/crates/bellman/src/sonic/helped/poly.rs +++ b/crates/bellman/src/sonic/helped/poly.rs @@ -1,9 +1,9 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use std::marker::PhantomData; -use crate::sonic::cs::{Backend}; -use crate::sonic::cs::{Coeff, Variable, LinearCombination}; +use crate::sonic::cs::Backend; +use crate::sonic::cs::{Coeff, LinearCombination, Variable}; use crate::sonic::util::*; /* @@ -65,14 +65,7 @@ impl SxEval { // tmp2.mul_assign(&y_inv); // } - SxEval { - y, - yqn, - u, - v, - w, - max_n: n - } + SxEval { y, yqn, u, v, w, max_n: n } } pub fn poly(mut self) -> (Vec, Vec) { @@ -87,11 +80,11 @@ impl SxEval { let mut acc = E::Fr::zero(); let tmp = x_inv; - acc.add_assign(&evaluate_at_consequitive_powers(& self.u[..], tmp, tmp)); + acc.add_assign(&evaluate_at_consequitive_powers(&self.u[..], tmp, tmp)); let tmp = x; - acc.add_assign(&evaluate_at_consequitive_powers(& self.v[..], tmp, tmp)); - let tmp = x.pow(&[(self.v.len()+1) as u64]); - acc.add_assign(&evaluate_at_consequitive_powers(& self.w[..], tmp, x)); + acc.add_assign(&evaluate_at_consequitive_powers(&self.v[..], tmp, tmp)); + let tmp = x.pow(&[(self.v.len() + 1) as u64]); + acc.add_assign(&evaluate_at_consequitive_powers(&self.w[..], tmp, x)); // let mut tmp = x_inv; // for mut u in self.u { @@ -131,25 +124,19 @@ impl<'a, E: Engine> Backend for &'a mut SxEval { fn insert_coefficient(&mut self, var: Variable, coeff: Coeff, y: &E::Fr) { let acc = match var { - Variable::A(index) => { - &mut self.u[index - 1] - } - Variable::B(index) => { - &mut self.v[index - 1] - } - Variable::C(index) => { - &mut self.w[index - 1] - } + Variable::A(index) => &mut self.u[index - 1], + Variable::B(index) => &mut self.v[index - 1], + Variable::C(index) => &mut self.w[index - 1], }; match coeff { - Coeff::Zero => { }, + Coeff::Zero => {} Coeff::One => { acc.add_assign(&y); - }, + } Coeff::NegativeOne => { acc.sub_assign(&y); - }, + } Coeff::Full(mut val) => { val.mul_assign(&y); acc.add_assign(&val); @@ -185,7 +172,6 @@ pub struct SyEval { negative_coeffs: Vec, } - impl SyEval { pub fn new(x: E::Fr, n: usize, q: usize) -> Self { let xinv = x.inverse().unwrap(); @@ -196,13 +182,13 @@ impl SyEval { mut_distribute_consequitive_powers(&mut b[..], x, x); let mut c = vec![E::Fr::one(); n]; - mut_distribute_consequitive_powers(&mut c[..], x.pow(&[(n+1) as u64]), x); + mut_distribute_consequitive_powers(&mut c[..], x.pow(&[(n + 1) as u64]), x); let mut minus_one = E::Fr::one(); minus_one.negate(); let mut positive_coeffs = vec![minus_one; n]; - mut_distribute_consequitive_powers(&mut positive_coeffs[..], x.pow(&[(n+1) as u64]), x); + mut_distribute_consequitive_powers(&mut positive_coeffs[..], x.pow(&[(n + 1) as u64]), x); let negative_coeffs = positive_coeffs.clone(); positive_coeffs.resize(n + q, E::Fr::zero()); @@ -257,8 +243,8 @@ impl SyEval { let mut acc = E::Fr::zero(); let yinv = y.inverse().unwrap(); // TODO - let positive_powers_contrib = evaluate_at_consequitive_powers(& self.positive_coeffs[..], y, y); - let negative_powers_contrib = evaluate_at_consequitive_powers(& self.negative_coeffs[..], yinv, yinv); + let positive_powers_contrib = evaluate_at_consequitive_powers(&self.positive_coeffs[..], y, y); + let negative_powers_contrib = evaluate_at_consequitive_powers(&self.negative_coeffs[..], yinv, yinv); acc.add_assign(&positive_powers_contrib); acc.add_assign(&negative_powers_contrib); @@ -320,4 +306,4 @@ impl<'a, E: Engine> Backend for &'a mut SyEval { } }; } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/helped/prover.rs b/crates/bellman/src/sonic/helped/prover.rs index eec3e1e..c6e9303 100644 --- a/crates/bellman/src/sonic/helped/prover.rs +++ b/crates/bellman/src/sonic/helped/prover.rs @@ -1,28 +1,22 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use std::marker::PhantomData; -use super::{Proof, SxyAdvice}; use super::batch::Batch; -use super::poly::{SxEval, SyEval}; use super::parameters::{Parameters, NUM_BLINDINGS}; +use super::poly::{SxEval, SyEval}; +use super::{Proof, SxyAdvice}; use crate::SynthesisError; -use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use crate::sonic::util::*; use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::sonic::cs::{Circuit, Variable, Coeff}; +use crate::sonic::cs::{Circuit, Coeff, Variable}; +use crate::sonic::sonic::{Basic, CountN}; use crate::sonic::srs::SRS; -use crate::sonic::sonic::{CountN, Basic}; - -pub fn create_advice_on_information_and_srs, S: SynthesisDriver>( - circuit: &C, - proof: &Proof, - srs: &SRS, - n: usize -) -> Result, SynthesisError> -{ +use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; + +pub fn create_advice_on_information_and_srs, S: SynthesisDriver>(circuit: &C, proof: &Proof, srs: &SRS, n: usize) -> Result, SynthesisError> { let z: E::Fr; let y: E::Fr; { @@ -44,17 +38,16 @@ pub fn create_advice_on_information_and_srs, S: Synthes // Compute S commitment let s = multiexp( - srs.g_positive_x_alpha[0..(2 * n)] - .iter() - .chain_ext(srs.g_negative_x_alpha[0..(n)].iter()), - s_poly_positive.iter().chain_ext(s_poly_negative.iter()) - ).into_affine(); + srs.g_positive_x_alpha[0..(2 * n)].iter().chain_ext(srs.g_negative_x_alpha[0..(n)].iter()), + s_poly_positive.iter().chain_ext(s_poly_negative.iter()), + ) + .into_affine(); // Compute s(z, y) let mut szy = E::Fr::zero(); { - szy.add_assign(& evaluate_at_consequitive_powers(& s_poly_positive[..], z, z)); - szy.add_assign(& evaluate_at_consequitive_powers(& s_poly_negative[..], z_inv, z_inv)); + szy.add_assign(&evaluate_at_consequitive_powers(&s_poly_positive[..], z, z)); + szy.add_assign(&evaluate_at_consequitive_powers(&s_poly_negative[..], z_inv, z_inv)); } // let mut szy = E::Fr::zero(); @@ -80,44 +73,26 @@ pub fn create_advice_on_information_and_srs, S: Synthes let mut open = szy; open.negate(); - let poly = kate_divison( - s_poly_negative.iter().rev().chain_ext(Some(open).iter()).chain_ext(s_poly_positive.iter()), - z, - ); + let poly = kate_divison(s_poly_negative.iter().rev().chain_ext(Some(open).iter()).chain_ext(s_poly_positive.iter()), z); let negative_poly = poly[0..n].iter().rev(); let positive_poly = poly[n..].iter(); multiexp( - srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext( - srs.g_positive_x[0..positive_poly.len()].iter() - ), - negative_poly.chain_ext(positive_poly) - ).into_affine() + srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(srs.g_positive_x[0..positive_poly.len()].iter()), + negative_poly.chain_ext(positive_poly), + ) + .into_affine() }; - Ok(SxyAdvice { - s, - szy, - opening - }) + Ok(SxyAdvice { s, szy, opening }) } -pub fn create_advice, S: SynthesisDriver>( - circuit: &C, - proof: &Proof, - parameters: &Parameters, -) -> Result, SynthesisError> -{ +pub fn create_advice, S: SynthesisDriver>(circuit: &C, proof: &Proof, parameters: &Parameters) -> Result, SynthesisError> { let n = parameters.vk.n; - create_advice_on_information_and_srs::(circuit, proof, ¶meters.srs, n) + create_advice_on_information_and_srs::(circuit, proof, ¶meters.srs, n) } -pub fn create_advice_on_srs, S: SynthesisDriver>( - circuit: &C, - proof: &Proof, - srs: &SRS -) -> Result, SynthesisError> -{ +pub fn create_advice_on_srs, S: SynthesisDriver>(circuit: &C, proof: &Proof, srs: &SRS) -> Result, SynthesisError> { // annoying, but we need n to compute s(z, y), and this isn't // precomputed anywhere yet let n = { @@ -127,25 +102,18 @@ pub fn create_advice_on_srs, S: SynthesisDriver>( tmp.n }; - create_advice_on_information_and_srs::(circuit, proof, srs, n) + create_advice_on_information_and_srs::(circuit, proof, srs, n) } -pub fn create_proof, S: SynthesisDriver>( - circuit: &C, - parameters: &Parameters -) -> Result, SynthesisError> { +pub fn create_proof, S: SynthesisDriver>(circuit: &C, parameters: &Parameters) -> Result, SynthesisError> { create_proof_on_srs::(circuit, ¶meters.srs) } extern crate rand; -use self::rand::{Rand, Rng, thread_rng}; +use self::rand::{thread_rng, Rand, Rng}; use crate::sonic::sonic::Wires; -pub fn create_proof_on_srs, S: SynthesisDriver>( - circuit: &C, - srs: &SRS -) -> Result, SynthesisError> -{ +pub fn create_proof_on_srs, S: SynthesisDriver>(circuit: &C, srs: &SRS) -> Result, SynthesisError> { let mut wires = Wires::new(); S::synthesize(&mut wires, circuit)?; @@ -161,11 +129,13 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( // r is a commitment to r(X, 1) let r = polynomial_commitment::( - n, - 2*n + NUM_BLINDINGS, - n, + n, + 2 * n + NUM_BLINDINGS, + n, &srs, - blindings.iter().rev() + blindings + .iter() + .rev() .chain_ext(wires.c.iter().rev()) .chain_ext(wires.b.iter().rev()) .chain_ext(Some(E::Fr::zero()).iter()) @@ -181,7 +151,7 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( // Same representation is ok for r(X, Y) too cause powers always match let mut rx1 = wires.b; rx1.extend(wires.c); - rx1.extend(blindings.clone()); + rx1.extend(blindings.clone()); rx1.reverse(); rx1.push(E::Fr::zero()); rx1.extend(wires.a); @@ -191,13 +161,9 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( let y_inv = y.inverse().ok_or(SynthesisError::DivisionByZero)?; // y^(-2n - num blindings) - let tmp = y_inv.pow(&[(2*n + NUM_BLINDINGS) as u64]); - mut_distribute_consequitive_powers( - &mut rxy, - tmp, - y, - ); - + let tmp = y_inv.pow(&[(2 * n + NUM_BLINDINGS) as u64]); + mut_distribute_consequitive_powers(&mut rxy, tmp, y); + // negative powers [-1, -2n], positive [1, n] let (mut s_poly_negative, s_poly_positive) = { let mut tmp = SxEval::new(y, n); @@ -214,11 +180,11 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( s_poly_negative.reverse(); let neg_poly_len = s_poly_negative.len(); - add_polynomials(&mut rxy_prime[(NUM_BLINDINGS+neg_poly_len)..(2 * n + NUM_BLINDINGS)], &s_poly_negative[..]); + add_polynomials(&mut rxy_prime[(NUM_BLINDINGS + neg_poly_len)..(2 * n + NUM_BLINDINGS)], &s_poly_negative[..]); s_poly_negative.reverse(); add_polynomials(&mut rxy_prime[(2 * n + 1 + NUM_BLINDINGS)..], &s_poly_positive[..]) - + // // add coefficients in front of X^{-2n}...X^{-n-1}, X^{-n}...X^{-1} // for (r, s) in rxy_prime[NUM_BLINDINGS..(2 * n + NUM_BLINDINGS)] // .iter_mut() @@ -242,13 +208,12 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( // commit to t(X, y) to later open at z let t = polynomial_commitment( - srs.d, - (4 * n) + 2*NUM_BLINDINGS, + srs.d, + (4 * n) + 2 * NUM_BLINDINGS, 3 * n, srs, // skip what would be zero power - txy[0..(4 * n) + 2*NUM_BLINDINGS].iter() - .chain_ext(txy[(4 * n + 2*NUM_BLINDINGS + 1)..].iter()), + txy[0..(4 * n) + 2 * NUM_BLINDINGS].iter().chain_ext(txy[(4 * n + 2 * NUM_BLINDINGS + 1)..].iter()), ); transcript.commit_point(&t); @@ -257,18 +222,18 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( let z_inv = z.inverse().ok_or(SynthesisError::DivisionByZero)?; let rz = { - let tmp = z_inv.pow(&[(2*n + NUM_BLINDINGS) as u64]); + let tmp = z_inv.pow(&[(2 * n + NUM_BLINDINGS) as u64]); evaluate_at_consequitive_powers(&rx1, tmp, z) }; // rzy is evaluation of r(X, Y) at z, y let rzy = { - let tmp = z_inv.pow(&[(2*n + NUM_BLINDINGS) as u64]); + let tmp = z_inv.pow(&[(2 * n + NUM_BLINDINGS) as u64]); evaluate_at_consequitive_powers(&rxy, tmp, z) }; - + transcript.commit_scalar(&rz); transcript.commit_scalar(&rzy); @@ -282,16 +247,10 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( let mut point = y; point.mul_assign(&z); - polynomial_commitment_opening( - 2 * n + NUM_BLINDINGS, - n, - &rx1, - point, - srs - ) + polynomial_commitment_opening(2 * n + NUM_BLINDINGS, n, &rx1, point, srs) }; - assert_eq!(rx1.len(), 3*n + NUM_BLINDINGS + 1); + assert_eq!(rx1.len(), 3 * n + NUM_BLINDINGS + 1); // it's an opening of t(X, y) at z let z_opening = { @@ -308,46 +267,33 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( // } let val = { - let tmp = z_inv.pow(&[(4*n + 2*NUM_BLINDINGS) as u64]); + let tmp = z_inv.pow(&[(4 * n + 2 * NUM_BLINDINGS) as u64]); evaluate_at_consequitive_powers(&txy, tmp, z) }; - txy[(4 * n + 2*NUM_BLINDINGS)].sub_assign(&val); + txy[(4 * n + 2 * NUM_BLINDINGS)].sub_assign(&val); - polynomial_commitment_opening( - 4*n + 2*NUM_BLINDINGS, - 3*n, - &txy, - z, - srs) + polynomial_commitment_opening(4 * n + 2 * NUM_BLINDINGS, 3 * n, &txy, z, srs) }; - Ok(Proof { - r, rz, rzy, t, z_opening, zy_opening - }) + Ok(Proof { r, rz, rzy, t, z_opening, zy_opening }) } #[test] fn my_fun_circuit_test() { - use crate::pairing::ff::PrimeField; - use crate::pairing::bls12_381::{Bls12, Fr}; use super::*; + use crate::pairing::bls12_381::{Bls12, Fr}; + use crate::pairing::ff::PrimeField; use crate::sonic::cs::{ConstraintSystem, LinearCombination}; use crate::sonic::sonic::Basic; - use rand::{thread_rng}; + use rand::thread_rng; struct MyCircuit; impl Circuit for MyCircuit { fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let (a, b, _) = cs.multiply(|| { - Ok(( - E::Fr::from_str("10").unwrap(), - E::Fr::from_str("20").unwrap(), - E::Fr::from_str("200").unwrap(), - )) - })?; + let (a, b, _) = cs.multiply(|| Ok((E::Fr::from_str("10").unwrap(), E::Fr::from_str("20").unwrap(), E::Fr::from_str("200").unwrap())))?; cs.enforce_zero(LinearCombination::from(a) + a - b); @@ -359,14 +305,10 @@ fn my_fun_circuit_test() { } } - let srs = SRS::::new( - 20, - Fr::from_str("22222").unwrap(), - Fr::from_str("33333333").unwrap(), - ); + let srs = SRS::::new(20, Fr::from_str("22222").unwrap(), Fr::from_str("33333333").unwrap()); let proof = self::create_proof_on_srs::(&MyCircuit, &srs).unwrap(); - use std::time::{Instant}; + use std::time::Instant; let start = Instant::now(); let rng = thread_rng(); let mut batch = MultiVerifier::::new(MyCircuit, &srs, rng).unwrap(); @@ -383,20 +325,16 @@ fn my_fun_circuit_test() { #[test] fn polynomial_commitment_test() { + use super::*; + use crate::pairing::bls12_381::{Bls12, Fr}; use crate::pairing::ff::PrimeField; use crate::pairing::ff::PrimeFieldRepr; - use crate::pairing::bls12_381::{Bls12, Fr}; - use super::*; + use crate::pairing::CurveAffine; use crate::sonic::cs::{ConstraintSystem, LinearCombination}; use crate::sonic::sonic::Basic; - use rand::{thread_rng}; - use crate::pairing::{CurveAffine}; + use rand::thread_rng; - let srs = SRS::::new( - 20, - Fr::from_str("22222").unwrap(), - Fr::from_str("33333333").unwrap(), - ); + let srs = SRS::::new(20, Fr::from_str("22222").unwrap(), Fr::from_str("33333333").unwrap()); let mut rng = thread_rng(); // x^-4 + x^-3 + x^-2 + x^-1 + x + x^2 @@ -432,9 +370,11 @@ fn polynomial_commitment_test() { let gv = gv.into_affine().prepare(); - assert!(Bls12::final_exponentiation(&Bls12::miller_loop(&[ - (&w, &alpha_x_precomp), - (&gv, &alpha_precomp), - (&commitment.prepare(), &neg_x_n_minus_d_precomp), - ])).unwrap() == ::Fqk::one()); + assert!( + Bls12::final_exponentiation(&Bls12::miller_loop( + &[(&w, &alpha_x_precomp), (&gv, &alpha_precomp), (&commitment.prepare(), &neg_x_n_minus_d_precomp),] + )) + .unwrap() + == ::Fqk::one() + ); } diff --git a/crates/bellman/src/sonic/helped/verifier.rs b/crates/bellman/src/sonic/helped/verifier.rs index da150e7..f7273ec 100644 --- a/crates/bellman/src/sonic/helped/verifier.rs +++ b/crates/bellman/src/sonic/helped/verifier.rs @@ -1,22 +1,22 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; -use std::marker::PhantomData; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use rand::{Rand, Rng}; +use std::marker::PhantomData; -use super::{Proof, SxyAdvice}; use super::batch::Batch; -use super::poly::{SxEval, SyEval}; use super::helper::Aggregate; -use super::parameters::{Parameters}; +use super::parameters::Parameters; +use super::poly::{SxEval, SyEval}; +use super::{Proof, SxyAdvice}; use crate::SynthesisError; -use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use crate::sonic::util::*; use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::sonic::cs::{Circuit, Variable, Coeff}; -use crate::sonic::srs::SRS; +use crate::sonic::cs::{Circuit, Coeff, Variable}; use crate::sonic::sonic::Preprocess; +use crate::sonic::srs::SRS; +use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; pub struct MultiVerifier, S: SynthesisDriver, R: Rng> { circuit: C, @@ -25,7 +25,7 @@ pub struct MultiVerifier, S: SynthesisDriver, R: Rng> { n: usize, q: usize, randomness_source: R, - _marker: PhantomData<(E, S)> + _marker: PhantomData<(E, S)>, } impl, S: SynthesisDriver, R: Rng> MultiVerifier { @@ -42,16 +42,11 @@ impl, S: SynthesisDriver, R: Rng> MultiVerifier, SxyAdvice)], - aggregate: &Aggregate, - ) - { + pub fn add_aggregate(&mut self, proofs: &[(Proof, SxyAdvice)], aggregate: &Aggregate) { let mut transcript = Transcript::new(&[]); let mut y_values: Vec = Vec::with_capacity(proofs.len()); for &(ref proof, ref sxyadvice) in proofs { @@ -116,13 +111,7 @@ impl, S: SynthesisDriver, R: Rng> MultiVerifier, - inputs: &[E::Fr], - advice: &SxyAdvice, - ) - { + pub fn add_proof_with_advice(&mut self, proof: &Proof, inputs: &[E::Fr], advice: &SxyAdvice) { let mut z = None; self.add_proof(proof, inputs, |_z, _y| { @@ -144,13 +133,9 @@ impl, S: SynthesisDriver, R: Rng> MultiVerifier( - &mut self, - proof: &Proof, - inputs: &[E::Fr], - sxy: F - ) - where F: FnOnce(E::Fr, E::Fr) -> Option + pub fn add_proof(&mut self, proof: &Proof, inputs: &[E::Fr], sxy: F) + where + F: FnOnce(E::Fr, E::Fr) -> Option, { let mut transcript = Transcript::new(&[]); @@ -242,27 +227,15 @@ impl, S: SynthesisDriver, R: Rng> MultiVerifier, S: SynthesisDriver, R: Rng>( - proofs: &[Proof], - inputs: &[Vec], - circuit: C, - rng: R, - params: &Parameters, -) -> Result { +pub fn verify_proofs, S: SynthesisDriver, R: Rng>(proofs: &[Proof], inputs: &[Vec], circuit: C, rng: R, params: &Parameters) -> Result { verify_proofs_on_srs::(proofs, inputs, circuit, rng, ¶ms.srs) } -/// Check multiple proofs without aggregation. Verifier's work is +/// Check multiple proofs without aggregation. Verifier's work is /// not succint due to `S(X, Y)` evaluation -pub fn verify_proofs_on_srs, S: SynthesisDriver, R: Rng>( - proofs: &[Proof], - inputs: &[Vec], - circuit: C, - rng: R, - srs: &SRS, -) -> Result { +pub fn verify_proofs_on_srs, S: SynthesisDriver, R: Rng>(proofs: &[Proof], inputs: &[Vec], circuit: C, rng: R, srs: &SRS) -> Result { let mut verifier = MultiVerifier::::new(circuit, srs, rng)?; let expected_inputs_size = verifier.get_k_map().len() - 1; for (proof, inputs) in proofs.iter().zip(inputs.iter()) { @@ -275,9 +248,9 @@ pub fn verify_proofs_on_srs, S: SynthesisDriver, R: Rng Ok(verifier.check_all()) } -/// Check multiple proofs with aggregation. Verifier's work is +/// Check multiple proofs with aggregation. Verifier's work is /// not succint due to `S(X, Y)` evaluation -pub fn verify_aggregate, S: SynthesisDriver,R: Rng>( +pub fn verify_aggregate, S: SynthesisDriver, R: Rng>( proofs: &[(Proof, SxyAdvice)], aggregate: &Aggregate, inputs: &[Vec], @@ -288,7 +261,7 @@ pub fn verify_aggregate, S: SynthesisDriver,R: Rng>( verify_aggregate_on_srs::(proofs, aggregate, inputs, circuit, rng, ¶ms.srs) } -/// Check multiple proofs with aggregation. Verifier's work is +/// Check multiple proofs with aggregation. Verifier's work is /// not succint due to `S(X, Y)` evaluation pub fn verify_aggregate_on_srs, S: SynthesisDriver, R: Rng>( proofs: &[(Proof, SxyAdvice)], @@ -310,4 +283,3 @@ pub fn verify_aggregate_on_srs, S: SynthesisDriver, R: Ok(verifier.check_all()) } - diff --git a/crates/bellman/src/sonic/mod.rs b/crates/bellman/src/sonic/mod.rs index 54c2005..2d8b16e 100644 --- a/crates/bellman/src/sonic/mod.rs +++ b/crates/bellman/src/sonic/mod.rs @@ -1,15 +1,13 @@ -pub use crate::{SynthesisError}; +pub use crate::SynthesisError; +pub mod cs; +pub mod helped; pub mod sonic; pub mod srs; -pub mod util; -pub mod helped; -pub mod cs; pub mod unhelped; +pub mod util; mod transcript; #[cfg(test)] mod tests; - - diff --git a/crates/bellman/src/sonic/sonic/adaptor.rs b/crates/bellman/src/sonic/sonic/adaptor.rs index e57fb37..d534237 100644 --- a/crates/bellman/src/sonic/sonic/adaptor.rs +++ b/crates/bellman/src/sonic/sonic/adaptor.rs @@ -1,17 +1,17 @@ use crate::pairing::ff::{Field, PrimeField}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::{CurveProjective, Engine}; // this one is for all external interfaces // use crate::{LinearCombination, ConstraintSystem, Circuit, Variable}; use crate::SynthesisError; -use crate::sonic::srs::SRS; -use crate::sonic::cs::LinearCombination as SonicLinearCombination; use crate::sonic::cs::Circuit as SonicCircuit; +use crate::sonic::cs::Coeff; use crate::sonic::cs::ConstraintSystem as SonicConstraintSystem; +use crate::sonic::cs::LinearCombination as SonicLinearCombination; use crate::sonic::cs::Variable as SonicVariable; -use crate::sonic::cs::Coeff; +use crate::sonic::srs::SRS; use std::marker::PhantomData; pub struct Adaptor<'a, E: Engine, CS: SonicConstraintSystem + 'a> { @@ -19,9 +19,7 @@ pub struct Adaptor<'a, E: Engine, CS: SonicConstraintSystem + 'a> { _marker: PhantomData, } -impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem - for Adaptor<'a, E, CS> -{ +impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem for Adaptor<'a, E, CS> { type Root = Self; // this is an important change @@ -35,9 +33,10 @@ impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem AR, AR: Into, { - let var = self.cs.alloc(|| { - f().map_err(|_| crate::SynthesisError::AssignmentMissing) - }).map_err(|_| crate::SynthesisError::AssignmentMissing)?; + let var = self + .cs + .alloc(|| f().map_err(|_| crate::SynthesisError::AssignmentMissing)) + .map_err(|_| crate::SynthesisError::AssignmentMissing)?; Ok(match var { SonicVariable::A(index) => crate::Variable::new_unchecked(crate::Index::Input(index)), @@ -46,19 +45,16 @@ impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem( - &mut self, - _: A, - f: F, - ) -> Result + fn alloc_input(&mut self, _: A, f: F) -> Result where F: FnOnce() -> Result, A: FnOnce() -> AR, AR: Into, { - let var = self.cs.alloc_input(|| { - f().map_err(|_| crate::SynthesisError::AssignmentMissing) - }).map_err(|_| crate::SynthesisError::AssignmentMissing)?; + let var = self + .cs + .alloc_input(|| f().map_err(|_| crate::SynthesisError::AssignmentMissing)) + .map_err(|_| crate::SynthesisError::AssignmentMissing)?; Ok(match var { SonicVariable::A(index) => crate::Variable::new_unchecked(crate::Index::Input(index)), @@ -90,10 +86,7 @@ impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem>( - lc: &SonicLinearCombination, - cs: &CS, - ) -> Option { + fn eval>(lc: &SonicLinearCombination, cs: &CS) -> Option { let mut ret = E::Fr::zero(); for &(v, coeff) in lc.as_ref().iter() { @@ -115,10 +108,7 @@ impl<'a, E: Engine, CS: SonicConstraintSystem + 'a> crate::ConstraintSystem(pub T); impl<'a, E: Engine, C: crate::Circuit + Clone> SonicCircuit for AdaptorCircuit { fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let mut adaptor = Adaptor { - cs: cs, - _marker: PhantomData, - }; + let mut adaptor = Adaptor { cs: cs, _marker: PhantomData }; match self.0.clone().synthesize(&mut adaptor) { Err(_) => return Err(SynthesisError::AssignmentMissing), @@ -159,4 +146,4 @@ impl<'a, E: Engine, C: crate::Circuit + Clone> SonicCircuit for AdaptorCir Ok(()) } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/sonic/backends.rs b/crates/bellman/src/sonic/sonic/backends.rs index f8b3e48..99d9ada 100644 --- a/crates/bellman/src/sonic/sonic/backends.rs +++ b/crates/bellman/src/sonic/sonic/backends.rs @@ -1,10 +1,10 @@ -use crate::pairing::{Engine}; +use crate::pairing::Engine; use crate::sonic::cs::Backend; -use std::marker::PhantomData; -use crate::SynthesisError; use crate::sonic::cs::SynthesisDriver; +use crate::SynthesisError; +use std::marker::PhantomData; -use crate::sonic::cs::{Circuit, ConstraintSystem, Variable, LinearCombination}; +use crate::sonic::cs::{Circuit, ConstraintSystem, LinearCombination, Variable}; use crate::pairing::ff::Field; @@ -12,13 +12,15 @@ pub struct Preprocess { pub k_map: Vec, pub n: usize, pub q: usize, - _marker: PhantomData + _marker: PhantomData, } impl<'a, E: Engine> Backend for &'a mut Preprocess { type LinearConstraintIndex = (); - fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { () } + fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { + () + } fn new_k_power(&mut self, index: usize) { self.k_map.push(index); @@ -37,11 +39,11 @@ impl<'a, E: Engine> Backend for &'a mut Preprocess { impl Preprocess { pub fn new() -> Self { - Preprocess { - k_map: vec![], - n: 0, - q: 0, - _marker: PhantomData + Preprocess { + k_map: vec![], + n: 0, + q: 0, + _marker: PhantomData, } } } @@ -49,15 +51,19 @@ impl Preprocess { pub struct Wires { pub a: Vec, pub b: Vec, - pub c: Vec + pub c: Vec, } impl<'a, E: Engine> Backend for &'a mut Wires { type LinearConstraintIndex = (); - fn new_linear_constraint(&mut self) -> Self::LinearConstraintIndex { () } + fn new_linear_constraint(&mut self) -> Self::LinearConstraintIndex { + () + } - fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { () } + fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { + () + } fn new_multiplication_gate(&mut self) { self.a.push(E::Fr::zero()); @@ -67,30 +73,25 @@ impl<'a, E: Engine> Backend for &'a mut Wires { fn get_var(&self, variable: Variable) -> Option { Some(match variable { - Variable::A(index) => { - self.a[index - 1] - }, - Variable::B(index) => { - self.b[index - 1] - }, - Variable::C(index) => { - self.c[index - 1] - } + Variable::A(index) => self.a[index - 1], + Variable::B(index) => self.b[index - 1], + Variable::C(index) => self.c[index - 1], }) } fn set_var(&mut self, variable: Variable, value: F) -> Result<(), SynthesisError> - where F: FnOnce() -> Result + where + F: FnOnce() -> Result, { let value = value()?; match variable { Variable::A(index) => { self.a[index - 1] = value; - }, + } Variable::B(index) => { self.b[index - 1] = value; - }, + } Variable::C(index) => { self.c[index - 1] = value; } @@ -102,24 +103,22 @@ impl<'a, E: Engine> Backend for &'a mut Wires { impl Wires { pub fn new() -> Self { - Wires { - a: vec![], - b: vec![], - c: vec![], - } + Wires { a: vec![], b: vec![], c: vec![] } } } pub struct CountNandQ { pub n: usize, pub q: usize, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl<'a, E: Engine, S: SynthesisDriver> Backend for &'a mut CountNandQ { type LinearConstraintIndex = (); - fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { () } + fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { + () + } fn new_multiplication_gate(&mut self) { self.n += 1; @@ -137,22 +136,26 @@ impl CountNandQ { Self { n: 0, q: 0, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } } pub struct CountN { pub n: usize, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl<'a, E: Engine, S: SynthesisDriver> Backend for &'a mut CountN { type LinearConstraintIndex = (); - fn new_linear_constraint(&mut self) -> Self::LinearConstraintIndex { () } + fn new_linear_constraint(&mut self) -> Self::LinearConstraintIndex { + () + } - fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { () } + fn get_for_q(&self, _q: usize) -> Self::LinearConstraintIndex { + () + } fn new_multiplication_gate(&mut self) { self.n += 1; @@ -163,8 +166,7 @@ impl CountN { pub fn new() -> Self { Self { n: 0, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } } - diff --git a/crates/bellman/src/sonic/sonic/constraint_systems.rs b/crates/bellman/src/sonic/sonic/constraint_systems.rs index 1bdf4f7..7284736 100644 --- a/crates/bellman/src/sonic/sonic/constraint_systems.rs +++ b/crates/bellman/src/sonic/sonic/constraint_systems.rs @@ -1,12 +1,12 @@ -use crate::pairing::{Engine}; +use crate::pairing::Engine; use crate::sonic::cs::Backend; -use std::marker::PhantomData; use std::iter::Peekable; +use std::marker::PhantomData; -use crate::SynthesisError; use crate::sonic::cs::SynthesisDriver; +use crate::SynthesisError; -use crate::sonic::cs::{Circuit, ConstraintSystem, Variable, LinearCombination, Coeff}; +use crate::sonic::cs::{Circuit, Coeff, ConstraintSystem, LinearCombination, Variable}; use crate::pairing::ff::Field; @@ -20,7 +20,7 @@ pub struct NonassigningSynthesizer> { n: usize, } -impl>NonassigningSynthesizer { +impl> NonassigningSynthesizer { pub fn new(backend: B) -> Self { Self { backend: backend, @@ -37,7 +37,7 @@ impl> ConstraintSystem for NonassigningSynthesizer(&mut self, _value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { match self.current_variable.take() { Some(index) => { @@ -46,7 +46,7 @@ impl> ConstraintSystem for NonassigningSynthesizer { self.n += 1; let index = self.n; @@ -63,7 +63,7 @@ impl> ConstraintSystem for NonassigningSynthesizer(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let input_var = self.alloc(value)?; @@ -73,8 +73,7 @@ impl> ConstraintSystem for NonassigningSynthesizer) - { + fn enforce_zero(&mut self, lc: LinearCombination) { self.q += 1; let y = self.backend.new_linear_constraint(); @@ -85,7 +84,7 @@ impl> ConstraintSystem for NonassigningSynthesizer(&mut self, _values: F) -> Result<(Variable, Variable, Variable), SynthesisError> where - F: FnOnce() -> Result<(E::Fr, E::Fr, E::Fr), SynthesisError> + F: FnOnce() -> Result<(E::Fr, E::Fr, E::Fr), SynthesisError>, { self.n += 1; let index = self.n; @@ -116,7 +115,7 @@ impl> ConstraintSystem for Synthesizer { fn alloc(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { match self.current_variable.take() { Some(index) => { @@ -136,14 +135,12 @@ impl> ConstraintSystem for Synthesizer { Ok(value_b) })?; - self.backend.set_var(var_c, || { - product.ok_or(SynthesisError::AssignmentMissing) - })?; + self.backend.set_var(var_c, || product.ok_or(SynthesisError::AssignmentMissing))?; self.current_variable = None; Ok(var_b) - }, + } None => { self.n += 1; let index = self.n; @@ -162,7 +159,7 @@ impl> ConstraintSystem for Synthesizer { fn alloc_input(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let input_var = self.alloc(value)?; @@ -172,8 +169,7 @@ impl> ConstraintSystem for Synthesizer { Ok(input_var) } - fn enforce_zero(&mut self, lc: LinearCombination) - { + fn enforce_zero(&mut self, lc: LinearCombination) { self.q += 1; let y = self.backend.new_linear_constraint(); @@ -184,7 +180,7 @@ impl> ConstraintSystem for Synthesizer { fn multiply(&mut self, values: F) -> Result<(Variable, Variable, Variable), SynthesisError> where - F: FnOnce() -> Result<(E::Fr, E::Fr, E::Fr), SynthesisError> + F: FnOnce() -> Result<(E::Fr, E::Fr, E::Fr), SynthesisError>, { self.n += 1; let index = self.n; @@ -206,13 +202,9 @@ impl> ConstraintSystem for Synthesizer { Ok(a) })?; - self.backend.set_var(b, || { - b_val.ok_or(SynthesisError::AssignmentMissing) - })?; + self.backend.set_var(b, || b_val.ok_or(SynthesisError::AssignmentMissing))?; - self.backend.set_var(c, || { - c_val.ok_or(SynthesisError::AssignmentMissing) - })?; + self.backend.set_var(c, || c_val.ok_or(SynthesisError::AssignmentMissing))?; Ok((a, b, c)) } @@ -222,7 +214,7 @@ impl> ConstraintSystem for Synthesizer { } } -impl>Synthesizer { +impl> Synthesizer { pub fn new(backend: B) -> Self { Self { backend: backend, @@ -255,7 +247,7 @@ impl> ConstraintSystem for PermutationSynthesizer(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { match self.current_variable.take() { Some(index) => { @@ -275,14 +267,12 @@ impl> ConstraintSystem for PermutationSynthesizer { self.n += 1; let index = self.n; @@ -306,7 +296,7 @@ impl> ConstraintSystem for PermutationSynthesizer(&mut self, value: F) -> Result where - F: FnOnce() -> Result + F: FnOnce() -> Result, { let input_var = self.alloc(value)?; @@ -318,8 +308,7 @@ impl> ConstraintSystem for PermutationSynthesizer) - { + fn enforce_zero(&mut self, lc: LinearCombination) { // We just redirect things into the (recursing) enforce_equals method which // does the actual work. Annoyingly, we need to use dynamic dispatch on the // underlying iterator because once you've taken a Peekable you can't get @@ -327,7 +316,7 @@ impl> ConstraintSystem for PermutationSynthesizer)> = &mut lc.into_iter(); + let lc: &mut Iterator)> = &mut lc.into_iter(); let lc = lc.peekable(); self.enforce_equals(lc, None); @@ -335,7 +324,7 @@ impl> ConstraintSystem for PermutationSynthesizer(&mut self, values: F) -> Result<(Variable, Variable, Variable), SynthesisError> where - F: FnOnce() -> Result<(E::Fr, E::Fr, E::Fr), SynthesisError> + F: FnOnce() -> Result<(E::Fr, E::Fr, E::Fr), SynthesisError>, { self.n += 1; let index = self.n; @@ -362,13 +351,9 @@ impl> ConstraintSystem for PermutationSynthesizer> PermutationSynthesizer { _marker: PhantomData, q: 0, n: 0, - + a: vec![], b: vec![], c: vec![], @@ -397,12 +382,7 @@ impl> PermutationSynthesizer { // of `rhs`, returning the value of the left hand side // as determined by the assignment. If rhs is none, it // is interpreted to be zero. - fn enforce_equals<'a>( - &mut self, - mut lhs: Peekable<&mut Iterator)>>, - rhs: Option - ) -> Option - { + fn enforce_equals<'a>(&mut self, mut lhs: Peekable<&mut Iterator)>>, rhs: Option) -> Option { // First, let's create a new linear constraint. We'll save its y value // for the backend and q as well. self.q += 1; @@ -442,13 +422,13 @@ impl> PermutationSynthesizer { // duplicated; otherwise, the duplicate variable will have a value of zero // and we'd have to somehow track all of the duplicates when we later assign. let mut iter = Some(term).into_iter().chain(lhs); - let iter: &mut Iterator)> = &mut iter; + let iter: &mut Iterator)> = &mut iter; let value = self.enforce_equals(iter.peekable(), Some(ephemeral)); // Set the correct ephemeral value right away - self.backend.set_var(ephemeral, || { - value.ok_or(SynthesisError::AssignmentMissing) - }).expect("assignment is provided so this should not fail"); + self.backend + .set_var(ephemeral, || value.ok_or(SynthesisError::AssignmentMissing)) + .expect("assignment is provided so this should not fail"); // Fix the underlying assignment -- the c-wire value will change if the ephemeral // value was a b-wire. @@ -461,7 +441,7 @@ impl> PermutationSynthesizer { match (&mut current_value, &value) { (Some(ref mut current_value), Some(ref value)) => { current_value.add_assign(&value); - }, + } _ => { current_value = None; } @@ -479,7 +459,7 @@ impl> PermutationSynthesizer { (Some(ref mut current_value), Some(mut value)) => { term.1.multiply(&mut value); current_value.add_assign(&value); - }, + } _ => { current_value = None; } @@ -495,8 +475,7 @@ impl> PermutationSynthesizer { // This takes a variable and coefficient and places it into a linear combination, // given a set of slots that are available, and updates the slot availability to // reflect which slot was chosen. - fn emplace_variable(&mut self, slots_available: &mut [bool; M], y: &B::LinearConstraintIndex, var: Variable, coeff: Coeff, q: usize) - { + fn emplace_variable(&mut self, slots_available: &mut [bool; M], y: &B::LinearConstraintIndex, var: Variable, coeff: Coeff, q: usize) { // Get the slots for this wire. let wire_slots = self.get_wire_slots(var); @@ -521,9 +500,9 @@ impl> PermutationSynthesizer { // combination; clearly, it is not available for the wire. In order // to rectify this, we will create a new wire with the same value. let ephemeral_value = self.backend.get_var(var); - let ephemeral = self.alloc(|| { - ephemeral_value.ok_or(SynthesisError::AssignmentMissing) - }).expect("assignment is provided so this should not fail"); + let ephemeral = self + .alloc(|| ephemeral_value.ok_or(SynthesisError::AssignmentMissing)) + .expect("assignment is provided so this should not fail"); // Now, we'll emplace the slot for _this_ variable. self.emplace_slot(ephemeral, available_i, coeff, y, q); @@ -543,7 +522,7 @@ impl> PermutationSynthesizer { // original. let iter = [(var, Coeff::One), (ephemeral, Coeff::NegativeOne)]; let mut iter = iter.into_iter(); - let iter: &mut Iterator)> = &mut iter; + let iter: &mut Iterator)> = &mut iter; self.enforce_equals(iter.peekable(), None); } @@ -571,7 +550,7 @@ impl> PermutationSynthesizer { let y = self.backend.get_for_q(slot_val.1); self.backend.insert_coefficient(from, -slot_val.0, &y); // Negate coefficient to undo - + { let to_vals = match to { Variable::A(index) => &mut self.a[index - 1], @@ -585,8 +564,7 @@ impl> PermutationSynthesizer { } // Place a coefficient in a slot - fn emplace_slot(&mut self, var: Variable, slot_index: usize, coeff: Coeff, y: &B::LinearConstraintIndex, q: usize) - { + fn emplace_slot(&mut self, var: Variable, slot_index: usize, coeff: Coeff, y: &B::LinearConstraintIndex, q: usize) { let vals = match var { Variable::A(index) => &mut self.a[index - 1], Variable::B(index) => &mut self.b[index - 1], @@ -627,12 +605,12 @@ impl> PermutationSynthesizer { (Some(mut a), Some(b)) => { a.mul_assign(&b); Some(a) - }, - _ => { None } + } + _ => None, }; - self.backend.set_var(Variable::C(index), || { - c_value.ok_or(SynthesisError::AssignmentMissing) - }).expect("assignment exists if the closure is called"); + self.backend + .set_var(Variable::C(index), || c_value.ok_or(SynthesisError::AssignmentMissing)) + .expect("assignment exists if the closure is called"); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/sonic/mod.rs b/crates/bellman/src/sonic/sonic/mod.rs index 00f32c4..6a727c7 100644 --- a/crates/bellman/src/sonic/sonic/mod.rs +++ b/crates/bellman/src/sonic/sonic/mod.rs @@ -1,11 +1,11 @@ mod adaptor; -mod synthesis_drivers; mod backends; mod constraint_systems; +mod synthesis_drivers; pub use self::adaptor::{Adaptor, AdaptorCircuit}; +pub use self::backends::{CountN, CountNandQ, Preprocess, Wires}; +pub use self::constraint_systems::{NonassigningSynthesizer, PermutationSynthesizer, Synthesizer}; pub use self::synthesis_drivers::{Basic, Nonassigning, Permutation3}; -pub use self::backends::{CountNandQ, CountN, Preprocess, Wires}; -pub use self::constraint_systems::{NonassigningSynthesizer, Synthesizer, PermutationSynthesizer}; -pub const M: usize = 3; \ No newline at end of file +pub const M: usize = 3; diff --git a/crates/bellman/src/sonic/sonic/synthesis_drivers.rs b/crates/bellman/src/sonic/sonic/synthesis_drivers.rs index 1ca7e5c..7a63d18 100644 --- a/crates/bellman/src/sonic/sonic/synthesis_drivers.rs +++ b/crates/bellman/src/sonic/sonic/synthesis_drivers.rs @@ -1,12 +1,12 @@ -use std::marker::PhantomData; +use crate::pairing::Engine; use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::pairing::{Engine}; -use crate::sonic::cs::{Variable, Circuit, ConstraintSystem, LinearCombination}; +use crate::sonic::cs::{Circuit, ConstraintSystem, LinearCombination, Variable}; use crate::SynthesisError; +use std::marker::PhantomData; -use crate::pairing::ff::{Field}; +use crate::pairing::ff::Field; -use super::constraint_systems::{NonassigningSynthesizer, Synthesizer, PermutationSynthesizer}; +use super::constraint_systems::{NonassigningSynthesizer, PermutationSynthesizer, Synthesizer}; pub struct Basic; @@ -17,8 +17,8 @@ impl SynthesisDriver for Basic { let one = tmp.alloc_input(|| Ok(E::Fr::one())).expect("should have no issues"); match (one, as ConstraintSystem>::ONE) { - (Variable::A(1), Variable::A(1)) => {}, - _ => panic!("one variable is incorrect") + (Variable::A(1), Variable::A(1)) => {} + _ => panic!("one variable is incorrect"), } circuit.synthesize(&mut tmp)?; @@ -36,8 +36,8 @@ impl SynthesisDriver for Nonassigning { let one = tmp.alloc_input(|| Ok(E::Fr::one())).expect("should have no issues"); match (one, as ConstraintSystem>::ONE) { - (Variable::A(1), Variable::A(1)) => {}, - _ => panic!("one variable is incorrect") + (Variable::A(1), Variable::A(1)) => {} + _ => panic!("one variable is incorrect"), } circuit.synthesize(&mut tmp)?; @@ -115,8 +115,8 @@ impl SynthesisDriver for Permutation3 { let one = tmp.alloc_input(|| Ok(E::Fr::one())).expect("should have no issues"); match (one, as ConstraintSystem>::ONE) { - (Variable::A(1), Variable::A(1)) => {}, - _ => panic!("one variable is incorrect") + (Variable::A(1), Variable::A(1)) => {} + _ => panic!("one variable is incorrect"), } circuit.synthesize(&mut tmp)?; diff --git a/crates/bellman/src/sonic/srs/mod.rs b/crates/bellman/src/sonic/srs/mod.rs index db33799..2212183 100644 --- a/crates/bellman/src/sonic/srs/mod.rs +++ b/crates/bellman/src/sonic/srs/mod.rs @@ -1,2 +1,2 @@ mod srs; -pub use self::srs::SRS; \ No newline at end of file +pub use self::srs::SRS; diff --git a/crates/bellman/src/sonic/srs/srs.rs b/crates/bellman/src/sonic/srs/srs.rs index 16c8887..9909c3e 100644 --- a/crates/bellman/src/sonic/srs/srs.rs +++ b/crates/bellman/src/sonic/srs/srs.rs @@ -1,9 +1,9 @@ use crate::pairing::ff::{Field, PrimeField}; use crate::pairing::{CurveAffine, CurveProjective, Engine, Wnaf}; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use std::io::{self, Read, Write}; use std::sync::Arc; -use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt}; #[derive(Clone, Eq)] pub struct SRS { @@ -36,15 +36,15 @@ pub struct SRS { impl PartialEq for SRS { fn eq(&self, other: &SRS) -> bool { - self.d == other.d && - self.g_negative_x == other.g_negative_x && - self.g_positive_x == other.g_positive_x && - self.h_negative_x == other.h_negative_x && - self.h_positive_x == other.h_positive_x && - self.g_negative_x_alpha == other.g_negative_x_alpha && - self.g_positive_x_alpha == other.g_positive_x_alpha && - self.h_negative_x_alpha == other.h_negative_x_alpha && - self.h_positive_x_alpha == other.h_positive_x_alpha + self.d == other.d + && self.g_negative_x == other.g_negative_x + && self.g_positive_x == other.g_positive_x + && self.h_negative_x == other.h_negative_x + && self.h_positive_x == other.h_positive_x + && self.g_negative_x_alpha == other.g_negative_x_alpha + && self.g_positive_x_alpha == other.g_positive_x_alpha + && self.h_negative_x_alpha == other.h_negative_x_alpha + && self.h_positive_x_alpha == other.h_positive_x_alpha } } @@ -72,12 +72,7 @@ impl SRS { let mut g2 = Wnaf::new(); let mut g2 = g2.base(E::G2::one(), d * 4); - fn table( - mut cur: C::Scalar, - step: C::Scalar, - num: usize, - table: &mut Wnaf>, - ) -> Vec { + fn table(mut cur: C::Scalar, step: C::Scalar, num: usize, table: &mut Wnaf>) -> Vec { let mut v = vec![]; for _ in 0..num { v.push(table.scalar(cur.into_repr())); @@ -114,11 +109,7 @@ impl SRS { } impl SRS { - pub fn write( - &self, - mut writer: W - ) -> io::Result<()> - { + pub fn write(&self, mut writer: W) -> io::Result<()> { assert_eq!(self.d + 1, self.g_negative_x.len()); assert_eq!(self.d + 1, self.g_positive_x.len()); @@ -164,49 +155,37 @@ impl SRS { Ok(()) } - pub fn read( - mut reader: R, - checked: bool - ) -> io::Result - { + pub fn read(mut reader: R, checked: bool) -> io::Result { use crate::pairing::EncodedPoint; let read_g1 = |reader: &mut R| -> io::Result { let mut repr = ::Uncompressed::empty(); reader.read_exact(repr.as_mut())?; - if checked { - repr - .into_affine() - } else { - repr - .into_affine_unchecked() - } - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - }) + if checked { repr.into_affine() } else { repr.into_affine_unchecked() } + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + .and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + }) }; let read_g2 = |reader: &mut R| -> io::Result { let mut repr = ::Uncompressed::empty(); reader.read_exact(repr.as_mut())?; - if checked { - repr - .into_affine() - } else { - repr - .into_affine_unchecked() - } - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) - .and_then(|e| if e.is_zero() { - Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) - } else { - Ok(e) - }) + if checked { repr.into_affine() } else { repr.into_affine_unchecked() } + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + .and_then(|e| { + if e.is_zero() { + Err(io::Error::new(io::ErrorKind::InvalidData, "point at infinity")) + } else { + Ok(e) + } + }) }; let mut g_negative_x = vec![]; @@ -224,19 +203,19 @@ impl SRS { let d = reader.read_u32::()? as usize; { - for _ in 0..(d+1) { + for _ in 0..(d + 1) { g_negative_x.push(read_g1(&mut reader)?); } - for _ in 0..(d+1) { + for _ in 0..(d + 1) { g_positive_x.push(read_g1(&mut reader)?); } } - + { - for _ in 0..(d+1) { + for _ in 0..(d + 1) { h_negative_x.push(read_g2(&mut reader)?); } - for _ in 0..(d+1) { + for _ in 0..(d + 1) { h_positive_x.push(read_g2(&mut reader)?); } } @@ -251,14 +230,14 @@ impl SRS { } { - for _ in 0..(d+1) { + for _ in 0..(d + 1) { h_negative_x_alpha.push(read_g2(&mut reader)?); } - for _ in 0..(d+1) { + for _ in 0..(d + 1) { h_positive_x_alpha.push(read_g2(&mut reader)?); } } - + Ok(Self { d: d, g_negative_x: g_negative_x, @@ -268,7 +247,7 @@ impl SRS { g_negative_x_alpha: g_negative_x_alpha, g_positive_x_alpha: g_positive_x_alpha, h_negative_x_alpha: h_negative_x_alpha, - h_positive_x_alpha: h_positive_x_alpha + h_positive_x_alpha: h_positive_x_alpha, }) } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/tests/mod.rs b/crates/bellman/src/sonic/tests/mod.rs index 075a109..101bee0 100644 --- a/crates/bellman/src/sonic/tests/mod.rs +++ b/crates/bellman/src/sonic/tests/mod.rs @@ -1 +1 @@ -mod sonics; \ No newline at end of file +mod sonics; diff --git a/crates/bellman/src/sonic/tests/sonics.rs b/crates/bellman/src/sonic/tests/sonics.rs index 3c406df..e9ca101 100644 --- a/crates/bellman/src/sonic/tests/sonics.rs +++ b/crates/bellman/src/sonic/tests/sonics.rs @@ -7,40 +7,23 @@ use rand::{thread_rng, Rng}; use std::time::{Duration, Instant}; // Bring in some tools for using pairing-friendly curves -use crate::pairing::{ - Engine -}; +use crate::pairing::Engine; -use crate::pairing::ff::{ - Field, -}; +use crate::pairing::ff::Field; // We're going to use the BLS12-381 pairing-friendly elliptic curve. -use crate::pairing::bls12_381::{ - Bls12 -}; +use crate::pairing::bls12_381::Bls12; -use crate::pairing::bn256::{ - Bn256 -}; +use crate::pairing::bn256::Bn256; // We'll use these interfaces to construct our circuit. -use crate::{ - Circuit, - ConstraintSystem, - SynthesisError -}; +use crate::{Circuit, ConstraintSystem, SynthesisError}; // const MIMC_ROUNDS: usize = 322; const MIMC_ROUNDS: usize = 1000000; -fn mimc( - mut xl: E::Fr, - mut xr: E::Fr, - constants: &[E::Fr] -) -> E::Fr -{ +fn mimc(mut xl: E::Fr, mut xr: E::Fr, constants: &[E::Fr]) -> E::Fr { assert_eq!(constants.len(), MIMC_ROUNDS); for i in 0..MIMC_ROUNDS { @@ -63,31 +46,23 @@ fn mimc( struct MiMCDemo<'a, E: Engine> { xl: Option, xr: Option, - constants: &'a [E::Fr] + constants: &'a [E::Fr], } /// Our demo circuit implements this `Circuit` trait which /// is used during paramgen and proving in order to /// synthesize the constraint system. impl<'a, E: Engine> Circuit for MiMCDemo<'a, E> { - fn synthesize>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError> - { + fn synthesize>(self, cs: &mut CS) -> Result<(), SynthesisError> { assert_eq!(self.constants.len(), MIMC_ROUNDS); // Allocate the first component of the preimage. let mut xl_value = self.xl; - let mut xl = cs.alloc(|| "preimage xl", || { - xl_value.ok_or(SynthesisError::AssignmentMissing) - })?; + let mut xl = cs.alloc(|| "preimage xl", || xl_value.ok_or(SynthesisError::AssignmentMissing))?; // Allocate the second component of the preimage. let mut xr_value = self.xr; - let mut xr = cs.alloc(|| "preimage xr", || { - xr_value.ok_or(SynthesisError::AssignmentMissing) - })?; + let mut xr = cs.alloc(|| "preimage xr", || xr_value.ok_or(SynthesisError::AssignmentMissing))?; for i in 0..MIMC_ROUNDS { // xL, xR := xR + (xL + Ci)^3, xL @@ -99,15 +74,13 @@ impl<'a, E: Engine> Circuit for MiMCDemo<'a, E> { e.square(); e }); - let tmp = cs.alloc(|| "tmp", || { - tmp_value.ok_or(SynthesisError::AssignmentMissing) - })?; + let tmp = cs.alloc(|| "tmp", || tmp_value.ok_or(SynthesisError::AssignmentMissing))?; cs.enforce( || "tmp = (xL + Ci)^2", |lc| lc + xl + (self.constants[i], CS::one()), |lc| lc + xl + (self.constants[i], CS::one()), - |lc| lc + tmp + |lc| lc + tmp, ); // new_xL = xR + (xL + Ci)^3 @@ -120,24 +93,15 @@ impl<'a, E: Engine> Circuit for MiMCDemo<'a, E> { e }); - let new_xl = if i == (MIMC_ROUNDS-1) { + let new_xl = if i == (MIMC_ROUNDS - 1) { // This is the last round, xL is our image and so // we allocate a public input. - cs.alloc_input(|| "image", || { - new_xl_value.ok_or(SynthesisError::AssignmentMissing) - })? + cs.alloc_input(|| "image", || new_xl_value.ok_or(SynthesisError::AssignmentMissing))? } else { - cs.alloc(|| "new_xl", || { - new_xl_value.ok_or(SynthesisError::AssignmentMissing) - })? + cs.alloc(|| "new_xl", || new_xl_value.ok_or(SynthesisError::AssignmentMissing))? }; - cs.enforce( - || "new_xL = xR + (xL + Ci)^3", - |lc| lc + tmp, - |lc| lc + xl + (self.constants[i], CS::one()), - |lc| lc + new_xl - xr - ); + cs.enforce(|| "new_xL = xR + (xL + Ci)^3", |lc| lc + tmp, |lc| lc + xl + (self.constants[i], CS::one()), |lc| lc + new_xl - xr); // xR = xL xr = xl; @@ -159,31 +123,23 @@ struct MiMCDemoNoInputs<'a, E: Engine> { xl: Option, xr: Option, image: Option, - constants: &'a [E::Fr] + constants: &'a [E::Fr], } /// Our demo circuit implements this `Circuit` trait which /// is used during paramgen and proving in order to /// synthesize the constraint system. impl<'a, E: Engine> Circuit for MiMCDemoNoInputs<'a, E> { - fn synthesize>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError> - { + fn synthesize>(self, cs: &mut CS) -> Result<(), SynthesisError> { assert_eq!(self.constants.len(), MIMC_ROUNDS); // Allocate the first component of the preimage. let mut xl_value = self.xl; - let mut xl = cs.alloc(|| "preimage xl", || { - xl_value.ok_or(SynthesisError::AssignmentMissing) - })?; + let mut xl = cs.alloc(|| "preimage xl", || xl_value.ok_or(SynthesisError::AssignmentMissing))?; // Allocate the second component of the preimage. let mut xr_value = self.xr; - let mut xr = cs.alloc(|| "preimage xr", || { - xr_value.ok_or(SynthesisError::AssignmentMissing) - })?; + let mut xr = cs.alloc(|| "preimage xr", || xr_value.ok_or(SynthesisError::AssignmentMissing))?; for i in 0..MIMC_ROUNDS { // xL, xR := xR + (xL + Ci)^3, xL @@ -195,15 +151,13 @@ impl<'a, E: Engine> Circuit for MiMCDemoNoInputs<'a, E> { e.square(); e }); - let tmp = cs.alloc(|| "tmp", || { - tmp_value.ok_or(SynthesisError::AssignmentMissing) - })?; + let tmp = cs.alloc(|| "tmp", || tmp_value.ok_or(SynthesisError::AssignmentMissing))?; cs.enforce( || "tmp = (xL + Ci)^2", |lc| lc + xl + (self.constants[i], CS::one()), |lc| lc + xl + (self.constants[i], CS::one()), - |lc| lc + tmp + |lc| lc + tmp, ); // new_xL = xR + (xL + Ci)^3 @@ -216,25 +170,16 @@ impl<'a, E: Engine> Circuit for MiMCDemoNoInputs<'a, E> { e }); - let new_xl = if i == (MIMC_ROUNDS-1) { + let new_xl = if i == (MIMC_ROUNDS - 1) { // This is the last round, xL is our image and so // we use the image let image_value = self.image; - cs.alloc(|| "image", || { - image_value.ok_or(SynthesisError::AssignmentMissing) - })? + cs.alloc(|| "image", || image_value.ok_or(SynthesisError::AssignmentMissing))? } else { - cs.alloc(|| "new_xl", || { - new_xl_value.ok_or(SynthesisError::AssignmentMissing) - })? + cs.alloc(|| "new_xl", || new_xl_value.ok_or(SynthesisError::AssignmentMissing))? }; - cs.enforce( - || "new_xL = xR + (xL + Ci)^3", - |lc| lc + tmp, - |lc| lc + xl + (self.constants[i], CS::one()), - |lc| lc + new_xl - xr - ); + cs.enforce(|| "new_xL = xR + (xL + Ci)^3", |lc| lc + tmp, |lc| lc + xl + (self.constants[i], CS::one()), |lc| lc + new_xl - xr); // xR = xL xr = xl; @@ -251,11 +196,11 @@ impl<'a, E: Engine> Circuit for MiMCDemoNoInputs<'a, E> { #[test] fn test_sonic_mimc() { - use crate::pairing::ff::{Field, PrimeField}; - use crate::pairing::{Engine, CurveAffine, CurveProjective}; use crate::pairing::bls12_381::{Bls12, Fr}; - use std::time::{Instant}; + use crate::pairing::ff::{Field, PrimeField}; + use crate::pairing::{CurveAffine, CurveProjective, Engine}; use crate::sonic::srs::SRS; + use std::time::Instant; let srs_x = Fr::from_str("23923").unwrap(); let srs_alpha = Fr::from_str("23728792").unwrap(); @@ -283,14 +228,14 @@ fn test_sonic_mimc() { xl: Some(xl), xr: Some(xr), image: Some(image), - constants: &constants + constants: &constants, }; - use crate::sonic::sonic::Basic; - use crate::sonic::sonic::AdaptorCircuit; + use crate::sonic::helped::helper::create_aggregate_on_srs; use crate::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs}; - use crate::sonic::helped::{MultiVerifier, get_circuit_parameters}; - use crate::sonic::helped::helper::{create_aggregate_on_srs}; + use crate::sonic::helped::{get_circuit_parameters, MultiVerifier}; + use crate::sonic::sonic::AdaptorCircuit; + use crate::sonic::sonic::Basic; println!("creating proof"); let start = Instant::now(); @@ -335,7 +280,7 @@ fn test_sonic_mimc() { } println!("done in {:?}", start.elapsed()); } - + { let rng = thread_rng(); let mut verifier = MultiVerifier::::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap(); @@ -353,14 +298,13 @@ fn test_sonic_mimc() { } } - #[test] fn test_sonic_mimc_in_permutation_driver() { - use crate::pairing::ff::{Field, PrimeField}; - use crate::pairing::{Engine, CurveAffine, CurveProjective}; use crate::pairing::bls12_381::{Bls12, Fr}; - use std::time::{Instant}; + use crate::pairing::ff::{Field, PrimeField}; + use crate::pairing::{CurveAffine, CurveProjective, Engine}; use crate::sonic::srs::SRS; + use std::time::Instant; let srs_x = Fr::from_str("23923").unwrap(); let srs_alpha = Fr::from_str("23728792").unwrap(); @@ -388,14 +332,14 @@ fn test_sonic_mimc_in_permutation_driver() { xl: Some(xl), xr: Some(xr), image: Some(image), - constants: &constants + constants: &constants, }; - use crate::sonic::sonic::Basic; - use crate::sonic::sonic::AdaptorCircuit; + use crate::sonic::helped::helper::create_aggregate_on_srs; use crate::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs}; - use crate::sonic::helped::{MultiVerifier, get_circuit_parameters}; - use crate::sonic::helped::helper::{create_aggregate_on_srs}; + use crate::sonic::helped::{get_circuit_parameters, MultiVerifier}; + use crate::sonic::sonic::AdaptorCircuit; + use crate::sonic::sonic::Basic; use crate::sonic::sonic::Permutation3; println!("creating proof"); @@ -441,7 +385,7 @@ fn test_sonic_mimc_in_permutation_driver() { } println!("done in {:?}", start.elapsed()); } - + { let rng = thread_rng(); let mut verifier = MultiVerifier::::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap(); @@ -461,11 +405,11 @@ fn test_sonic_mimc_in_permutation_driver() { #[test] fn test_succinct_sonic_mimc() { - use crate::pairing::ff::{Field, PrimeField}; - use crate::pairing::{Engine, CurveAffine, CurveProjective}; use crate::pairing::bls12_381::{Bls12, Fr}; - use std::time::{Instant}; + use crate::pairing::ff::{Field, PrimeField}; + use crate::pairing::{CurveAffine, CurveProjective, Engine}; use crate::sonic::srs::SRS; + use std::time::Instant; let srs_x = Fr::from_str("23923").unwrap(); let srs_alpha = Fr::from_str("23728792").unwrap(); @@ -476,7 +420,7 @@ fn test_succinct_sonic_mimc() { println!("done in {:?}", start.elapsed()); { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); // Generate the MiMC round constants @@ -494,19 +438,19 @@ fn test_succinct_sonic_mimc() { xl: Some(xl), xr: Some(xr), image: Some(image), - constants: &constants + constants: &constants, }; - use crate::sonic::sonic::Basic; - use crate::sonic::sonic::AdaptorCircuit; use crate::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs}; use crate::sonic::helped::{get_circuit_parameters_for_succinct_sonic, MultiVerifier}; + use crate::sonic::sonic::AdaptorCircuit; + use crate::sonic::sonic::Basic; use crate::sonic::sonic::Permutation3; + use crate::sonic::unhelped::create_aggregate_on_srs; use crate::sonic::unhelped::permutation_structure::*; use crate::sonic::unhelped::SuccinctMultiVerifier; - use crate::sonic::unhelped::{create_aggregate_on_srs}; - use crate::sonic::cs::{Circuit, ConstraintSystem, LinearCombination, Coeff}; + use crate::sonic::cs::{Circuit, Coeff, ConstraintSystem, LinearCombination}; let perm_structure = create_permutation_structure::(&AdaptorCircuit(circuit.clone())); let s1_srs = perm_structure.create_permutation_special_reference(&srs); @@ -560,7 +504,7 @@ fn test_succinct_sonic_mimc() { // } { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let mut verifier = SuccinctMultiVerifier::::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap(); @@ -570,11 +514,7 @@ fn test_succinct_sonic_mimc() { for (ref proof, ref advice) in &proofs { verifier.add_proof_with_advice(proof, &[], advice); } - verifier.add_aggregate( - &proofs, - &aggregate, - &srs, - ); + verifier.add_aggregate(&proofs, &aggregate, &srs); assert_eq!(verifier.check_all(), true); // TODO } println!("done in {:?}", start.elapsed()); @@ -584,12 +524,12 @@ fn test_succinct_sonic_mimc() { #[test] fn test_inputs_into_sonic_mimc() { - use crate::pairing::ff::{Field, PrimeField}; - use crate::pairing::{Engine, CurveAffine, CurveProjective}; use crate::pairing::bn256::{Bn256, Fr}; + use crate::pairing::ff::{Field, PrimeField}; + use crate::pairing::{CurveAffine, CurveProjective, Engine}; // use crate::pairing::bls12_381::{Bls12, Fr}; - use std::time::{Instant}; use crate::sonic::srs::SRS; + use std::time::Instant; let srs_x = Fr::from_str("23923").unwrap(); let srs_alpha = Fr::from_str("23728792").unwrap(); @@ -616,14 +556,14 @@ fn test_inputs_into_sonic_mimc() { let circuit = MiMCDemo { xl: Some(xl), xr: Some(xr), - constants: &constants + constants: &constants, }; - use crate::sonic::sonic::Basic; - use crate::sonic::sonic::AdaptorCircuit; + use crate::sonic::helped::helper::create_aggregate_on_srs; use crate::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs}; - use crate::sonic::helped::{MultiVerifier, get_circuit_parameters}; - use crate::sonic::helped::helper::{create_aggregate_on_srs}; + use crate::sonic::helped::{get_circuit_parameters, MultiVerifier}; + use crate::sonic::sonic::AdaptorCircuit; + use crate::sonic::sonic::Basic; let info = get_circuit_parameters::(circuit.clone()).expect("Must get circuit info"); println!("{:?}", info); @@ -671,7 +611,7 @@ fn test_inputs_into_sonic_mimc() { } println!("done in {:?}", start.elapsed()); } - + { let rng = thread_rng(); let mut verifier = MultiVerifier::::new(AdaptorCircuit(circuit.clone()), &srs, rng).unwrap(); @@ -691,17 +631,9 @@ fn test_inputs_into_sonic_mimc() { #[test] fn test_high_level_sonic_api() { - use crate::pairing::bn256::{Bn256}; - use std::time::{Instant}; - use crate::sonic::helped::{ - generate_random_parameters, - verify_aggregate, - verify_proofs, - create_proof, - create_advice, - create_aggregate, - get_circuit_parameters - }; + use crate::pairing::bn256::Bn256; + use crate::sonic::helped::{create_advice, create_aggregate, create_proof, generate_random_parameters, get_circuit_parameters, verify_aggregate, verify_proofs}; + use std::time::Instant; { // This may not be cryptographically safe, use @@ -721,7 +653,7 @@ fn test_high_level_sonic_api() { let circuit = MiMCDemo { xl: Some(xl), xr: Some(xr), - constants: &constants + constants: &constants, }; let info = get_circuit_parameters::(circuit.clone()).expect("Must get circuit info"); @@ -761,12 +693,15 @@ fn test_high_level_sonic_api() { assert_eq!(verify_proofs(&vec![proof.clone(); 100], &vec![vec![image.clone()]; 100], circuit.clone(), rng, ¶ms).unwrap(), true); println!("done in {:?}", start.elapsed()); } - + { println!("verifying 100 proofs with advice and aggregate"); let rng = thread_rng(); let start = Instant::now(); - assert_eq!(verify_aggregate(&vec![(proof.clone(), advice.clone()); 100], &aggregate, &vec![vec![image.clone()]; 100], circuit.clone(), rng, ¶ms).unwrap(), true); + assert_eq!( + verify_aggregate(&vec![(proof.clone(), advice.clone()); 100], &aggregate, &vec![vec![image.clone()]; 100], circuit.clone(), rng, ¶ms).unwrap(), + true + ); println!("done in {:?}", start.elapsed()); } } @@ -868,4 +803,4 @@ fn test_high_level_sonic_api() { // println!("done in {:?}", start.elapsed()); // } // } -// } \ No newline at end of file +// } diff --git a/crates/bellman/src/sonic/transcript/hasher.rs b/crates/bellman/src/sonic/transcript/hasher.rs index 351a3a9..271b037 100644 --- a/crates/bellman/src/sonic/transcript/hasher.rs +++ b/crates/bellman/src/sonic/transcript/hasher.rs @@ -1,8 +1,8 @@ -extern crate tiny_keccak; extern crate blake2_rfc; +extern crate tiny_keccak; +use self::blake2_rfc::blake2s::{blake2s, Blake2s}; use self::tiny_keccak::Keccak; -use self::blake2_rfc::blake2s::{Blake2s, blake2s}; pub trait Hasher { fn new(personalization: &[u8]) -> Self; @@ -12,7 +12,7 @@ pub trait Hasher { #[derive(Clone)] pub struct BlakeHasher { - h: Blake2s + h: Blake2s, } impl Hasher for BlakeHasher { @@ -20,9 +20,7 @@ impl Hasher for BlakeHasher { let mut h = Blake2s::new(32); h.update(personalization); - Self { - h: h - } + Self { h: h } } fn update(&mut self, data: &[u8]) { @@ -43,7 +41,7 @@ impl Hasher for BlakeHasher { #[derive(Clone)] pub struct Keccak256Hasher { - h: Keccak + h: Keccak, } impl Hasher for Keccak256Hasher { @@ -51,9 +49,7 @@ impl Hasher for Keccak256Hasher { let mut h = Keccak::new_keccak256(); h.update(personalization); - Self { - h: h - } + Self { h: h } } fn update(&mut self, data: &[u8]) { @@ -71,4 +67,4 @@ impl Hasher for Keccak256Hasher { res[..].to_vec() } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/transcript/mod.rs b/crates/bellman/src/sonic/transcript/mod.rs index 744fdc7..e44344b 100644 --- a/crates/bellman/src/sonic/transcript/mod.rs +++ b/crates/bellman/src/sonic/transcript/mod.rs @@ -4,17 +4,17 @@ use std::io; mod hasher; -use self::hasher::{Hasher, Keccak256Hasher, BlakeHasher}; +use self::hasher::{BlakeHasher, Hasher, Keccak256Hasher}; #[derive(Clone)] pub struct Transcript { - transcriptor: RollingHashTranscript + transcriptor: RollingHashTranscript, } impl Transcript { pub fn new(personalization: &[u8]) -> Self { Self { - transcriptor: RollingHashTranscript::new(personalization) + transcriptor: RollingHashTranscript::new(personalization), } } } @@ -40,7 +40,7 @@ pub struct RollingHashTranscript { buffer: Vec, last_finalized_value: Vec, repeated_request_nonce: u32, - _marker: PhantomData + _marker: PhantomData, } impl RollingHashTranscript { @@ -52,7 +52,7 @@ impl RollingHashTranscript { buffer: buffer, last_finalized_value: vec![], repeated_request_nonce: 0u32, - _marker: PhantomData + _marker: PhantomData, } } @@ -84,7 +84,7 @@ pub trait TranscriptProtocol { fn get_challenge_scalar(&mut self) -> F; } -impl TranscriptProtocol for RollingHashTranscript { +impl TranscriptProtocol for RollingHashTranscript { fn commit_point(&mut self, point: &G) { self.commit_bytes(b"point", point.into_uncompressed().as_ref()); // self.commit_bytes(b"point", point.into_compressed().as_ref()); @@ -131,4 +131,4 @@ impl TranscriptProtocol for RollingHashTranscript { // Ok(buf.len()) // } -// } \ No newline at end of file +// } diff --git a/crates/bellman/src/sonic/unhelped/aggregate.rs b/crates/bellman/src/sonic/unhelped/aggregate.rs index 1375c4c..0a0fa12 100644 --- a/crates/bellman/src/sonic/unhelped/aggregate.rs +++ b/crates/bellman/src/sonic/unhelped/aggregate.rs @@ -1,26 +1,26 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use std::marker::PhantomData; -use crate::sonic::helped::{Proof, SxyAdvice}; use crate::sonic::helped::batch::Batch; use crate::sonic::helped::poly::{SxEval, SyEval}; use crate::sonic::helped::Parameters; +use crate::sonic::helped::{Proof, SxyAdvice}; use crate::SynthesisError; -use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use crate::sonic::util::*; -use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::sonic::cs::{Circuit, Variable, Coeff}; -use crate::sonic::srs::SRS; -use crate::sonic::sonic::CountNandQ; -use crate::sonic::sonic::M; -use super::s2_proof::{S2Eval, S2Proof}; -use super::permutation_structure::create_permutation_structure; use super::permutation_argument::PermutationArgument; use super::permutation_argument::SignatureOfCorrectComputation; use super::permutation_argument::SpecializedSRS; +use super::permutation_structure::create_permutation_structure; +use super::s2_proof::{S2Eval, S2Proof}; +use crate::sonic::cs::{Backend, SynthesisDriver}; +use crate::sonic::cs::{Circuit, Coeff, Variable}; +use crate::sonic::sonic::CountNandQ; +use crate::sonic::sonic::M; +use crate::sonic::srs::SRS; +use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; #[derive(Clone)] pub struct SuccinctAggregate { @@ -36,7 +36,6 @@ pub struct SuccinctAggregate { pub z: E::Fr, pub w: E::Fr, - } // pub fn create_aggregate, S: SynthesisDriver>( @@ -55,9 +54,8 @@ pub fn create_aggregate_on_srs, S: SynthesisDriver>( circuit: &C, inputs: &[(Proof, SxyAdvice)], srs: &SRS, - specialized_srs: &SpecializedSRS -) -> SuccinctAggregate -{ + specialized_srs: &SpecializedSRS, +) -> SuccinctAggregate { // TODO: precompute this? let (n, q) = { let mut tmp = CountNandQ::::new(); @@ -77,8 +75,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy _specialized_srs: &SpecializedSRS, n: usize, q: usize, -) -> SuccinctAggregate -{ +) -> SuccinctAggregate { use std::time::Instant; let start = Instant::now(); // take few proofs that are to be evaluated at some y_i and make an aggregate from them @@ -106,11 +103,10 @@ pub fn create_aggregate_on_srs_using_information, S: Sy // Compute C = g^{s(z, x)} let c = multiexp( - srs.g_positive_x_alpha[0..(n + q)] - .iter() - .chain_ext(srs.g_negative_x_alpha[0..n].iter()), - s_poly_positive.iter().chain_ext(s_poly_negative.iter()) - ).into_affine(); + srs.g_positive_x_alpha[0..(n + q)].iter().chain_ext(srs.g_negative_x_alpha[0..n].iter()), + s_poly_positive.iter().chain_ext(s_poly_negative.iter()), + ) + .into_affine(); transcript.commit_point(&c); @@ -123,19 +119,13 @@ pub fn create_aggregate_on_srs_using_information, S: Sy let mut value = value; value.negate(); - polynomial_commitment_opening( - n, - 0, - s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()), - w, - &srs - ) + polynomial_commitment_opening(n, 0, s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()), w, &srs) }; println!("Commit and opening of for s(z, w) taken {:?}", start.elapsed()); - // now we need signature of correct computation. For this purpose - // verifier already knows specialized SRS, so we can just commit to + // now we need signature of correct computation. For this purpose + // verifier already knows specialized SRS, so we can just commit to // s1 and s2 parts of such signature to get `w` and later open at this point! // Commit! @@ -157,13 +147,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy println!("Permutation vectors synthesis taken {:?}", start.elapsed()); let start = Instant::now(); - let signature = PermutationArgument::make_signature( - non_permuted_coeffs, - permutations, - w, - z, - &srs, - ); + let signature = PermutationArgument::make_signature(non_permuted_coeffs, permutations, w, z, &srs); println!("Succinct signature for s(z, Y) taken {:?}", start.elapsed()); @@ -192,13 +176,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy let mut value = value; value.negate(); - polynomial_commitment_opening( - n, - 0, - s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()), - *y, - &srs - ) + polynomial_commitment_opening(n, 0, s_poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(s_poly_positive.iter()), *y, &srs) }; c_openings.push((opening, value)); @@ -211,7 +189,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy // challenges instead and open up a random linear combination. let mut poly_negative = vec![E::Fr::zero(); n]; - let mut poly_positive = vec![E::Fr::zero(); 2*n]; + let mut poly_positive = vec![E::Fr::zero(); 2 * n]; let mut expected_value = E::Fr::zero(); // TODO: this part can be further parallelized due to synthesis of S(X, y) being singlethreaded @@ -231,8 +209,8 @@ pub fn create_aggregate_on_srs_using_information, S: Sy value.mul_assign(&r); expected_value.add_assign(&value); - mul_add_polynomials(& mut poly_negative[..], &s_poly_negative[..], r); - mul_add_polynomials(& mut poly_positive[..], &s_poly_positive[..], r); + mul_add_polynomials(&mut poly_negative[..], &s_poly_negative[..], r); + mul_add_polynomials(&mut poly_positive[..], &s_poly_positive[..], r); } println!("Re-evaluation of {} S polynomials taken {:?}", y_values.len(), start.elapsed()); @@ -241,13 +219,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy let mut value = expected_value; value.negate(); - polynomial_commitment_opening( - n, - 0, - poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(poly_positive.iter()), - z, - &srs - ) + polynomial_commitment_opening(n, 0, poly_negative.iter().rev().chain_ext(Some(value).iter()).chain_ext(poly_positive.iter()), z, &srs) }; SuccinctAggregate { @@ -257,8 +229,7 @@ pub fn create_aggregate_on_srs_using_information, S: Sy s_opening, c_openings, opening, - z: z, w: w, } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/unhelped/grand_product_argument.rs b/crates/bellman/src/sonic/unhelped/grand_product_argument.rs index 3c31ea0..21b9df4 100644 --- a/crates/bellman/src/sonic/unhelped/grand_product_argument.rs +++ b/crates/bellman/src/sonic/unhelped/grand_product_argument.rs @@ -1,15 +1,14 @@ -/// One must prove that for commitments to two polynomials of degree n products of the coefficients +/// One must prove that for commitments to two polynomials of degree n products of the coefficients /// in those two polynomials are equal (part of the permutation argument) with additional assumption that /// those coefficients are never equal to zero - use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use crate::pairing::{Engine, CurveProjective, CurveAffine}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; use std::marker::PhantomData; +use super::wellformed_argument::{WellformednessArgument, WellformednessSignature}; use crate::sonic::srs::SRS; -use crate::sonic::util::*; use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use super::wellformed_argument::{WellformednessSignature, WellformednessArgument}; +use crate::sonic::util::*; #[derive(Clone)] pub struct GrandProductArgument { @@ -17,7 +16,7 @@ pub struct GrandProductArgument { c_polynomials: Vec>, v_elements: Vec, t_polynomial: Option>, - n: usize + n: usize, } #[derive(Clone)] @@ -39,13 +38,7 @@ pub struct GrandProductSignature { } impl GrandProductArgument { - pub fn create_signature( - transcript: &mut Transcript, - grand_products: Vec<(Vec, Vec)>, - y: E::Fr, - z: E::Fr, - srs: &SRS, - ) -> GrandProductSignature { + pub fn create_signature(transcript: &mut Transcript, grand_products: Vec<(Vec, Vec)>, y: E::Fr, z: E::Fr, srs: &SRS) -> GrandProductSignature { let mut grand_product_challenges = vec![]; for _ in 0..grand_products.len() { @@ -55,7 +48,7 @@ impl GrandProductArgument { let mut all_polys = vec![]; let mut wellformed_challenges = vec![]; - for _ in 0..(grand_products.len()*2) { + for _ in 0..(grand_products.len() * 2) { let c = transcript.get_challenge_scalar(); wellformed_challenges.push(c); } @@ -66,11 +59,7 @@ impl GrandProductArgument { all_polys.push(b.clone()); } - let wellformedness_signature = WellformednessArgument::create_signature( - all_polys, - wellformed_challenges, - &srs - ); + let wellformedness_signature = WellformednessArgument::create_signature(all_polys, wellformed_challenges, &srs); let mut grand_product_argument = GrandProductArgument::new(grand_products); let c_commitments = grand_product_argument.commit_to_individual_c_polynomials(&srs); @@ -85,12 +74,10 @@ impl GrandProductArgument { grand_product_openings, // a_zy, proof, - wellformedness_signature + wellformedness_signature, } - } - pub fn new(polynomials: Vec<(Vec, Vec)>) -> Self { assert!(polynomials.len() > 0); @@ -120,8 +107,8 @@ impl GrandProductArgument { let (p0, p1) = p; assert!(p0.len() == p1.len()); assert!(p0.len() == n); - let mut c_poly: Vec = Vec::with_capacity(2*n + 1); - let mut a_poly: Vec = Vec::with_capacity(2*n + 1); + let mut c_poly: Vec = Vec::with_capacity(2 * n + 1); + let mut a_poly: Vec = Vec::with_capacity(2 * n + 1); let mut c_coeff = E::Fr::one(); // add a for a in p0.iter() { @@ -151,10 +138,10 @@ impl GrandProductArgument { c_coeff.mul_assign(b); c_poly.push(c_coeff); } - assert_eq!(c_poly.len(), 2*n + 1); + assert_eq!(c_poly.len(), 2 * n + 1); a_poly.extend(p1); - assert_eq!(c_poly[n-1], c_poly[2*n]); + assert_eq!(c_poly[n - 1], c_poly[2 * n]); assert_eq!(c_poly[n], E::Fr::one()); a_polynomials.push(a_poly); @@ -167,7 +154,7 @@ impl GrandProductArgument { c_polynomials: c_polynomials, v_elements: v_elements, t_polynomial: None, - n: n + n: n, } } @@ -185,20 +172,14 @@ impl GrandProductArgument { // ).into_affine() // } - pub fn commit_for_individual_products(a: &[E::Fr], b: &[E::Fr], srs: &SRS) -> (E::G1Affine, E::G1Affine) { assert_eq!(a.len(), b.len()); let n = a.len(); - let a = multiexp( - srs.g_positive_x_alpha[0..n].iter(), - a.iter()).into_affine(); + let a = multiexp(srs.g_positive_x_alpha[0..n].iter(), a.iter()).into_affine(); - - let b = multiexp( - srs.g_positive_x_alpha[0..n].iter(), - b.iter()).into_affine(); + let b = multiexp(srs.g_positive_x_alpha[0..n].iter(), b.iter()).into_affine(); (a, b) } @@ -229,14 +210,7 @@ impl GrandProductArgument { let mut constant_term = val; constant_term.negate(); - let opening = polynomial_commitment_opening( - 0, - 2*n + 1, - Some(constant_term).iter() - .chain_ext(a_poly.iter()), - yz, - &srs - ); + let opening = polynomial_commitment_opening(0, 2 * n + 1, Some(constant_term).iter().chain_ext(a_poly.iter()), yz, &srs); // let opening = polynomial_commitment_opening( // 0, @@ -245,19 +219,17 @@ impl GrandProductArgument { // .chain_ext(a.iter()) // .chain_ext(Some(E::Fr::zero()).iter()) // .chain_ext(b.iter()), - // yz, + // yz, // &srs); results.push((val, opening)); - } results - } + } // Make a commitment for the begining of the protocol, returns commitment and `v` scalar pub fn commit_to_individual_c_polynomials(&self, srs: &SRS) -> Vec<(E::G1Affine, E::Fr)> { - let mut results = vec![]; let two_n_plus_1 = self.c_polynomials[0].len(); @@ -266,11 +238,8 @@ impl GrandProductArgument { let n = self.n; assert_eq!(p[n], E::Fr::one(), "C_(n+1) must be one"); - let c = multiexp( - srs.g_positive_x_alpha[0..two_n_plus_1].iter(), - p.iter() - ).into_affine(); - + let c = multiexp(srs.g_positive_x_alpha[0..two_n_plus_1].iter(), p.iter()).into_affine(); + results.push((c, *v)); } @@ -278,24 +247,20 @@ impl GrandProductArgument { } // Argument is based on an approach of main SONIC construction, but with a custom S(X,Y) polynomial of a simple form - pub fn commit_to_t_polynomial(&mut self, challenges: & Vec, y: E::Fr, srs: &SRS) -> E::G1Affine { + pub fn commit_to_t_polynomial(&mut self, challenges: &Vec, y: E::Fr, srs: &SRS) -> E::G1Affine { assert_eq!(challenges.len(), self.a_polynomials.len()); let n = self.n; let mut t_polynomial: Option> = None; - for (((a, c), v), challenge) in self.a_polynomials.iter() - .zip(self.c_polynomials.iter()) - .zip(self.v_elements.iter()) - .zip(challenges.iter()) - { + for (((a, c), v), challenge) in self.a_polynomials.iter().zip(self.c_polynomials.iter()).zip(self.v_elements.iter()).zip(challenges.iter()) { let mut a_xy = a.clone(); let c_xy = c.clone(); let v = *v; - assert_eq!(a_xy.len(), 2*n + 1); - assert_eq!(c_xy.len(), 2*n + 1); + assert_eq!(a_xy.len(), 2 * n + 1); + assert_eq!(c_xy.len(), 2 * n + 1); // make a T polynomial @@ -305,28 +270,28 @@ impl GrandProductArgument { tmp.square(); mut_distribute_consequitive_powers(&mut a_xy[..], tmp, y); - // add extra terms + // add extra terms //v*(XY)^{n+1}*Y + X^{n+2} + X^{n+1}Y − X^{2n+2}*Y - // n+1 term v*(XY)^{n+1}*Y + X^{n+1}Y - let tmp = y.pow(&[(n+2) as u64]); + // n+1 term v*(XY)^{n+1}*Y + X^{n+1}Y + let tmp = y.pow(&[(n + 2) as u64]); let mut x_n_plus_one_term = v; x_n_plus_one_term.mul_assign(&tmp); x_n_plus_one_term.add_assign(&y); a_xy[n].add_assign(&x_n_plus_one_term); - // n+2 term - a_xy[n+1].add_assign(&E::Fr::one()); + // n+2 term + a_xy[n + 1].add_assign(&E::Fr::one()); - // 2n+2 term + // 2n+2 term let mut tmp = y; tmp.negate(); a_xy.push(tmp); - assert_eq!(a_xy.len(), 2*n + 2); + assert_eq!(a_xy.len(), 2 * n + 2); - let mut r = vec![E::Fr::zero(); 2*n + 3]; + let mut r = vec![E::Fr::zero(); 2 * n + 3]; r.extend(a_xy); r @@ -337,7 +302,7 @@ impl GrandProductArgument { c_prime.push(E::Fr::one()); c_prime.push(E::Fr::zero()); - assert_eq!(c_prime.len(), 2*n + 3); + assert_eq!(c_prime.len(), 2 * n + 3); c_prime }; @@ -346,18 +311,18 @@ impl GrandProductArgument { // expect result to be [-2n+1, 2n+1] let mut t: Vec = multiply_polynomials::(r, r_prime); - assert_eq!(t.len(), 6*n + 7); + assert_eq!(t.len(), 6 * n + 7); // drain first powers due to the padding and last element due to requirement of being zero - for (i, el) in t[0..(2*n+3)].iter().enumerate() { + for (i, el) in t[0..(2 * n + 3)].iter().enumerate() { assert_eq!(*el, E::Fr::zero(), "{}", format!("Element {} is non-zero", i)); - } + } - t.drain(0..(2*n+3)); + t.drain(0..(2 * n + 3)); let last = t.pop(); assert_eq!(last.unwrap(), E::Fr::zero(), "last element should be zero"); - assert_eq!(t.len(), 4*n + 3); + assert_eq!(t.len(), 4 * n + 3); let mut val = { let mut tmp = y; @@ -368,14 +333,14 @@ impl GrandProductArgument { val.add_assign(&E::Fr::one()); // subtract a constant term - assert_eq!(t[2*n+1], val); + assert_eq!(t[2 * n + 1], val); - t[2*n+1].sub_assign(&val); + t[2 * n + 1].sub_assign(&val); if t_polynomial.is_some() { if let Some(t_poly) = t_polynomial.as_mut() { mul_add_polynomials(&mut t_poly[..], &t, *challenge); - } + } } else { mul_polynomial_by_scalar(&mut t, *challenge); t_polynomial = Some(t); @@ -384,10 +349,11 @@ impl GrandProductArgument { let t_polynomial = t_polynomial.unwrap(); - let c = multiexp(srs.g_negative_x_alpha[0..(2*n+1)].iter().rev() - .chain_ext(srs.g_positive_x_alpha[0..(2*n+1)].iter()), - t_polynomial[0..(2*n+1)].iter() - .chain_ext(t_polynomial[(2*n+2)..].iter())).into_affine(); + let c = multiexp( + srs.g_negative_x_alpha[0..(2 * n + 1)].iter().rev().chain_ext(srs.g_positive_x_alpha[0..(2 * n + 1)].iter()), + t_polynomial[0..(2 * n + 1)].iter().chain_ext(t_polynomial[(2 * n + 2)..].iter()), + ) + .into_affine(); self.t_polynomial = Some(t_polynomial); @@ -395,7 +361,7 @@ impl GrandProductArgument { } // Argument is based on an approach of main SONIC construction, but with a custom S(X,Y) polynomial of a simple form - pub fn make_argument(self, a_zy: & Vec, challenges: & Vec, y: E::Fr, z: E::Fr, srs: &SRS) -> GrandProductProof { + pub fn make_argument(self, a_zy: &Vec, challenges: &Vec, y: E::Fr, z: E::Fr, srs: &SRS) -> GrandProductProof { assert_eq!(a_zy.len(), self.a_polynomials.len()); assert_eq!(challenges.len(), self.a_polynomials.len()); @@ -412,11 +378,7 @@ impl GrandProductArgument { let mut t_subcomponent = E::Fr::zero(); - for (((a, c), challenge), v) in a_zy.iter() - .zip(c_polynomials.into_iter()) - .zip(challenges.iter()) - .zip(self.v_elements.iter()) - { + for (((a, c), challenge), v) in a_zy.iter().zip(c_polynomials.into_iter()).zip(challenges.iter()).zip(self.v_elements.iter()) { // cj = ((aj + vj(yz)n+1)y + zn+2 + zn+1y − z2n+2y)z−1 let mut c_zy = yz.pow([(n + 1) as u64]); c_zy.mul_assign(v); @@ -455,7 +417,7 @@ impl GrandProductArgument { mul_add_polynomials(&mut e_poly[..], &c, rc); mul_add_polynomials(&mut f_poly[..], &c, ry); } - } + } } else { let mut e = c.clone(); let mut f = c; @@ -479,19 +441,9 @@ impl GrandProductArgument { let mut f_val = evaluate_at_consequitive_powers(&f_polynomial, y, y); f_val.negate(); - let e_opening = polynomial_commitment_opening( - 0, - 2*n + 1, - Some(e_val).iter().chain_ext(e_polynomial.iter()), - z_inv, - srs); + let e_opening = polynomial_commitment_opening(0, 2 * n + 1, Some(e_val).iter().chain_ext(e_polynomial.iter()), z_inv, srs); - let f_opening = polynomial_commitment_opening( - 0, - 2*n + 1, - Some(f_val).iter().chain_ext(f_polynomial.iter()), - y, - srs); + let f_opening = polynomial_commitment_opening(0, 2 * n + 1, Some(f_val).iter().chain_ext(f_polynomial.iter()), y, srs); e_val.negate(); f_val.negate(); @@ -500,28 +452,23 @@ impl GrandProductArgument { t_subcomponent.sub_assign(&f_val); let mut t_poly = self.t_polynomial.unwrap(); - assert_eq!(t_poly.len(), 4*n + 3); + assert_eq!(t_poly.len(), 4 * n + 3); - assert!(t_poly[2*n + 1].is_zero()); + assert!(t_poly[2 * n + 1].is_zero()); // largest negative power of t is -2n-1 let t_zy = { - let tmp = z_inv.pow([(2*n+1) as u64]); + let tmp = z_inv.pow([(2 * n + 1) as u64]); evaluate_at_consequitive_powers(&t_poly, tmp, z) }; assert_eq!(t_zy, t_subcomponent); - assert!(t_poly[2*n + 1].is_zero()); + assert!(t_poly[2 * n + 1].is_zero()); - t_poly[2*n + 1].sub_assign(&t_zy); + t_poly[2 * n + 1].sub_assign(&t_zy); - let t_opening = polynomial_commitment_opening( - 2*n + 1, - 2*n + 1, - t_poly.iter(), - z, - srs); + let t_opening = polynomial_commitment_opening(2 * n + 1, 2 * n + 1, t_poly.iter(), z, srs); GrandProductProof { t_opening: t_opening, @@ -533,14 +480,14 @@ impl GrandProductArgument { } pub fn verify_ab_commitment( - n: usize, - randomness: & Vec, + n: usize, + randomness: &Vec, a_commitments: &Vec, - b_commitments: &Vec, + b_commitments: &Vec, openings: &Vec<(E::Fr, E::G1Affine)>, y: E::Fr, z: E::Fr, - srs: &SRS + srs: &SRS, ) -> bool { assert_eq!(randomness.len(), a_commitments.len()); assert_eq!(openings.len(), a_commitments.len()); @@ -555,7 +502,7 @@ impl GrandProductArgument { let h_alpha_precomp = srs.h_positive_x_alpha[0].prepare(); // H^(x^(n+1)) is n+1 indexed - let mut h_x_n_plus_one_precomp = srs.h_positive_x[n+1]; + let mut h_x_n_plus_one_precomp = srs.h_positive_x[n + 1]; h_x_n_plus_one_precomp.negate(); let h_x_n_plus_one_precomp = h_x_n_plus_one_precomp.prepare(); @@ -563,17 +510,11 @@ impl GrandProductArgument { h_prep.negate(); let h_prep = h_prep.prepare(); - let a = multiexp( - a_commitments.iter(), - randomness.iter(), - ).into_affine(); + let a = multiexp(a_commitments.iter(), randomness.iter()).into_affine(); let a = a.prepare(); - let b = multiexp( - b_commitments.iter(), - randomness.iter(), - ).into_affine(); + let b = multiexp(b_commitments.iter(), randomness.iter()).into_affine(); let b = b.prepare(); @@ -594,37 +535,35 @@ impl GrandProductArgument { let value = g.mul(value.into_repr()).into_affine().prepare(); - let openings = multiexp( - ops.iter(), - randomness.iter(), - ).into_affine(); + let openings = multiexp(ops.iter(), randomness.iter()).into_affine(); let openings_zy = openings.mul(yz_neg.into_repr()).into_affine().prepare(); let openings = openings.prepare(); - // e(Dj,hαx)e(D−yz,hα) = e(Aj,h)e(Bj,hxn+1)e(g−aj ,hα) E::final_exponentiation(&E::miller_loop(&[ - (&openings, &h_alpha_x_precomp), - (&openings_zy, &h_alpha_precomp), - (&a, &h_prep), - (&b, &h_x_n_plus_one_precomp), - (&value, &h_alpha_precomp) - ])).unwrap() == E::Fqk::one() + (&openings, &h_alpha_x_precomp), + (&openings_zy, &h_alpha_precomp), + (&a, &h_prep), + (&b, &h_x_n_plus_one_precomp), + (&value, &h_alpha_precomp), + ])) + .unwrap() + == E::Fqk::one() } pub fn verify( - n: usize, - randomness: & Vec, - a_zy: & Vec, - challenges: &Vec, - t_commitment: E::G1Affine, - commitments: &Vec<(E::G1Affine, E::Fr)>, - proof: &GrandProductProof, - y: E::Fr, + n: usize, + randomness: &Vec, + a_zy: &Vec, + challenges: &Vec, + t_commitment: E::G1Affine, + commitments: &Vec<(E::G1Affine, E::Fr)>, + proof: &GrandProductProof, + y: E::Fr, z: E::Fr, - srs: &SRS + srs: &SRS, ) -> bool { assert_eq!(randomness.len(), 3); assert_eq!(a_zy.len(), challenges.len()); @@ -655,12 +594,10 @@ impl GrandProductArgument { let mut rc_vec = vec![]; let mut ry_vec = vec![]; - for ((r, commitment), a) in challenges.iter() - .zip(commitments.iter()) - .zip(a_zy.iter()) { + for ((r, commitment), a) in challenges.iter().zip(commitments.iter()).zip(a_zy.iter()) { let (c, v) = commitment; commitments_points.push(c.clone()); - + // cj = ((aj + vj(yz)n+1)y + zn+2 + zn+1y − z2n+2y)z−1 let mut c_zy = yz.pow([(n + 1) as u64]); c_zy.mul_assign(v); @@ -697,15 +634,9 @@ impl GrandProductArgument { t_zy.add_assign(&val); } - let c_rc = multiexp( - commitments_points.iter(), - rc_vec.iter(), - ).into_affine(); + let c_rc = multiexp(commitments_points.iter(), rc_vec.iter()).into_affine(); - let c_ry = multiexp( - commitments_points.iter(), - ry_vec.iter(), - ).into_affine(); + let c_ry = multiexp(commitments_points.iter(), ry_vec.iter()).into_affine(); let mut minus_y = y; minus_y.negate(); @@ -728,40 +659,31 @@ impl GrandProductArgument { let g_e = g.mul(proof.e_zinv.into_repr()); e_z_inv.add_assign(&g_e); - let h_alpha_term = multiexp( - vec![e_z_inv.into_affine(), f_y.into_affine(), t_z.into_affine()].iter(), - randomness.iter(), - ).into_affine(); + let h_alpha_term = multiexp(vec![e_z_inv.into_affine(), f_y.into_affine(), t_z.into_affine()].iter(), randomness.iter()).into_affine(); let h_alpha_x_term = multiexp( - Some(proof.e_opening).iter() - .chain_ext(Some(proof.f_opening).iter()) - .chain_ext(Some(proof.t_opening).iter()), + Some(proof.e_opening).iter().chain_ext(Some(proof.f_opening).iter()).chain_ext(Some(proof.t_opening).iter()), randomness.iter(), - ).into_affine(); + ) + .into_affine(); - - let h_term = multiexp( - Some(c_rc).iter() - .chain_ext(Some(c_ry).iter()) - .chain_ext(Some(t_commitment).iter()), - randomness.iter(), - ).into_affine(); + let h_term = multiexp(Some(c_rc).iter().chain_ext(Some(c_ry).iter()).chain_ext(Some(t_commitment).iter()), randomness.iter()).into_affine(); E::final_exponentiation(&E::miller_loop(&[ - (&h_alpha_x_term.prepare(), &h_alpha_x_precomp), - (&h_alpha_term.prepare(), &h_alpha_precomp), - (&h_term.prepare(), &h_prep), - ])).unwrap() == E::Fqk::one() - + (&h_alpha_x_term.prepare(), &h_alpha_x_precomp), + (&h_alpha_term.prepare(), &h_alpha_precomp), + (&h_term.prepare(), &h_prep), + ])) + .unwrap() + == E::Fqk::one() } } #[test] fn test_grand_product_argument() { - use crate::pairing::bls12_381::{Fr, G1Affine, G1, Bls12}; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use crate::pairing::bls12_381::{Bls12, Fr, G1Affine, G1}; use crate::sonic::srs::SRS; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let srs_x = Fr::from_str("23923").unwrap(); let srs_alpha = Fr::from_str("23728792").unwrap(); @@ -803,28 +725,19 @@ fn test_grand_product_argument() { assert_eq!(commitments_and_v_values.len(), 1); - let y : Fr = rng.gen(); + let y: Fr = rng.gen(); let challenges = (0..1).map(|_| Fr::rand(rng)).collect::>(); let t_commitment = argument.commit_to_t_polynomial(&challenges, y, &srs); - let z : Fr = rng.gen(); + let z: Fr = rng.gen(); let grand_product_openings = argument.open_commitments_for_grand_product(y, z, &srs); let randomness = (0..1).map(|_| Fr::rand(rng)).collect::>(); - let valid = GrandProductArgument::verify_ab_commitment( - n, - &randomness, - &vec![a_commitment], - &vec![b_commitment], - &grand_product_openings, - y, - z, - &srs - ); + let valid = GrandProductArgument::verify_ab_commitment(n, &randomness, &vec![a_commitment], &vec![b_commitment], &grand_product_openings, y, z, &srs); assert!(valid, "grand product commitments should be valid"); @@ -834,18 +747,7 @@ fn test_grand_product_argument() { let randomness = (0..3).map(|_| Fr::rand(rng)).collect::>(); - let valid = GrandProductArgument::verify( - n, - &randomness, - &a_zy, - &challenges, - t_commitment, - &commitments_and_v_values, - &proof, - y, - z, - &srs); + let valid = GrandProductArgument::verify(n, &randomness, &a_zy, &challenges, t_commitment, &commitments_and_v_values, &proof, y, z, &srs); assert!(valid, "t commitment should be valid"); } - diff --git a/crates/bellman/src/sonic/unhelped/mod.rs b/crates/bellman/src/sonic/unhelped/mod.rs index 454a48d..c54b6b4 100644 --- a/crates/bellman/src/sonic/unhelped/mod.rs +++ b/crates/bellman/src/sonic/unhelped/mod.rs @@ -1,17 +1,16 @@ +mod aggregate; +pub mod grand_product_argument; +mod permutation_argument; +pub mod permutation_structure; /// Largeley this module is implementation of provable evaluation of s(z, y), that is represented in two parts /// s2(X, Y) = \sum_{i=1}^{N} (Y^{-i} + Y^{i})X^{i} /// s1(X, Y) = ... /// s1 part requires grand product and permutation arguments, that are also implemented - mod s2_proof; -mod wellformed_argument; -pub mod grand_product_argument; -mod permutation_argument; mod verifier; -pub mod permutation_structure; -mod aggregate; +mod wellformed_argument; -pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof}; -pub use self::permutation_argument::{PermutationArgument, PermutationProof, PermutationArgumentProof}; +pub use self::aggregate::*; +pub use self::permutation_argument::{PermutationArgument, PermutationArgumentProof, PermutationProof}; pub use self::verifier::SuccinctMultiVerifier; -pub use self::aggregate::*; \ No newline at end of file +pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof}; diff --git a/crates/bellman/src/sonic/unhelped/permutation_argument.rs b/crates/bellman/src/sonic/unhelped/permutation_argument.rs index 5c3466e..86bb0e8 100644 --- a/crates/bellman/src/sonic/unhelped/permutation_argument.rs +++ b/crates/bellman/src/sonic/unhelped/permutation_argument.rs @@ -1,15 +1,14 @@ -/// Permutation argument allows to prove that a commitment to a vector A is +/// Permutation argument allows to prove that a commitment to a vector A is /// actually a commitment to a vector of values that are equal to `(s^{perm})_i * y^{perm(i)}` /// for some fixed permutation `perm` - use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine}; -use crate::pairing::{Engine, CurveProjective, CurveAffine}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; use std::marker::PhantomData; +use super::grand_product_argument::{GrandProductArgument, GrandProductSignature}; +use super::wellformed_argument::{WellformednessArgument, WellformednessProof}; use crate::sonic::srs::SRS; use crate::sonic::util::*; -use super::wellformed_argument::{WellformednessArgument, WellformednessProof}; -use super::grand_product_argument::{GrandProductArgument, GrandProductSignature}; use crate::sonic::transcript::{Transcript, TranscriptProtocol}; @@ -19,7 +18,7 @@ pub struct SpecializedSRS { pub p_2: Vec, pub p_3: E::G1Affine, pub p_4: Vec, - n: usize + n: usize, } #[derive(Clone)] @@ -29,7 +28,7 @@ pub struct PermutationArgument { permuted_at_y_coefficients: Vec>, inverse_permuted_at_y_coefficients: Vec>, permutations: Vec>, - n: usize + n: usize, } #[derive(Clone)] @@ -43,7 +42,7 @@ pub struct PermutationProof { pub struct PermutationArgumentProof { pub j: usize, pub s_opening: E::G1Affine, - pub s_zy: E::Fr + pub s_zy: E::Fr, } #[derive(Clone)] @@ -52,7 +51,7 @@ pub struct SignatureOfCorrectComputation { pub s_prime_commitments: Vec, pub perm_argument_proof: PermutationArgumentProof, pub perm_proof: PermutationProof, - pub grand_product_signature: GrandProductSignature + pub grand_product_signature: GrandProductSignature, } // fn permute(coeffs: &[F], permutation: & [usize]) -> Vec{ @@ -69,7 +68,7 @@ pub struct SignatureOfCorrectComputation { // result // } -fn permute_inverse(permuted_coeffs: &[F], permutation: & [usize]) -> Vec{ +fn permute_inverse(permuted_coeffs: &[F], permutation: &[usize]) -> Vec { assert_eq!(permuted_coeffs.len(), permutation.len()); let mut result: Vec = vec![F::zero(); permuted_coeffs.len()]; for (i, j) in permutation.iter().enumerate() { @@ -102,7 +101,7 @@ impl PermutationArgument { permuted_at_y_coefficients: vec![], inverse_permuted_at_y_coefficients: vec![], permutations: permutations, - n: n + n: n, } } @@ -118,13 +117,15 @@ impl PermutationArgument { let mut p_2 = vec![]; let p_3 = { - let values: Vec = (1..=n).map(|el| { - let mut repr = <::Fr as PrimeField>::Repr::default(); - repr.as_mut()[0] = el as u64; - let fe = E::Fr::from_repr(repr).unwrap(); + let values: Vec = (1..=n) + .map(|el| { + let mut repr = <::Fr as PrimeField>::Repr::default(); + repr.as_mut()[0] = el as u64; + let fe = E::Fr::from_repr(repr).unwrap(); - fe - }).collect(); + fe + }) + .collect(); multiexp(srs.g_positive_x_alpha[0..n].iter(), values.iter()).into_affine() }; @@ -142,13 +143,16 @@ impl PermutationArgument { } { - let values: Vec = p.iter().map(|el| { - let mut repr = <::Fr as PrimeField>::Repr::default(); - repr.as_mut()[0] = *el as u64; - let fe = E::Fr::from_repr(repr).unwrap(); + let values: Vec = p + .iter() + .map(|el| { + let mut repr = <::Fr as PrimeField>::Repr::default(); + repr.as_mut()[0] = *el as u64; + let fe = E::Fr::from_repr(repr).unwrap(); - fe - }).collect(); + fe + }) + .collect(); let p4 = multiexp(srs.g_positive_x_alpha[0..n].iter(), values.iter()).into_affine(); @@ -161,7 +165,7 @@ impl PermutationArgument { p_2: p_2, p_3: p_3, p_4: p_4, - n: n + n: n, } } @@ -178,7 +182,7 @@ impl PermutationArgument { let mut inverse_permuted_at_y_coefficients = vec![]; // naive algorithms - // for every permutation poly + // for every permutation poly // -- go throught all variable_idx // - take coeff from non-permuted coeffs[permutation[variable_idx]] // - mul by Y^{permutation[variable_idx]} @@ -224,13 +228,7 @@ impl PermutationArgument { result } - pub fn open_commitments_to_s_prime( - &self, - challenges: &Vec, - y: E::Fr, - z_prime: E::Fr, - srs: &SRS - ) -> PermutationProof { + pub fn open_commitments_to_s_prime(&self, challenges: &Vec, y: E::Fr, z_prime: E::Fr, srs: &SRS) -> PermutationProof { let n = self.non_permuted_coefficients[0].len(); let mut yz = y; @@ -238,8 +236,7 @@ impl PermutationArgument { let mut polynomial: Option> = None; - for (p, r) in self.non_permuted_coefficients.iter() - .zip(challenges.iter()) { + for (p, r) in self.non_permuted_coefficients.iter().zip(challenges.iter()) { if polynomial.is_some() { if let Some(poly) = polynomial.as_mut() { mul_add_polynomials(&mut poly[..], &p[..], *r); @@ -257,41 +254,26 @@ impl PermutationArgument { let mut v_neg = v; v_neg.negate(); - let f = polynomial_commitment_opening( - 0, - n, - Some(v_neg).iter().chain_ext(polynomial.iter()), - yz, - &srs - ); + let f = polynomial_commitment_opening(0, n, Some(v_neg).iter().chain_ext(polynomial.iter()), yz, &srs); mut_distribute_consequitive_powers(&mut polynomial[..], y, y); - let e = polynomial_commitment_opening( - 0, - n, - Some(v_neg).iter().chain_ext(polynomial.iter()), - z_prime, - &srs - ); - - PermutationProof { - v_zy: v, - e_opening: e, - f_opening: f - } - } + let e = polynomial_commitment_opening(0, n, Some(v_neg).iter().chain_ext(polynomial.iter()), z_prime, &srs); + + PermutationProof { v_zy: v, e_opening: e, f_opening: f } + } // Argument a permutation argument. Current implementation consumes, cause extra arguments are required - pub fn make_argument(self, - beta: E::Fr, - gamma: E::Fr, - grand_product_challenges: & Vec, - wellformed_challenges: & Vec, - y: E::Fr, - z: E::Fr, + pub fn make_argument( + self, + beta: E::Fr, + gamma: E::Fr, + grand_product_challenges: &Vec, + wellformed_challenges: &Vec, + y: E::Fr, + z: E::Fr, _specialized_srs: &SpecializedSRS, - srs: &SRS + srs: &SRS, ) -> PermutationArgumentProof { // Sj(P4j)β(P1j)γ is equal to the product of the coefficients of Sj′(P3j)β(P1j)γ // also open s = \sum self.permuted_coefficients(X, y) at z @@ -299,87 +281,83 @@ impl PermutationArgument { let n = self.n; let j = self.non_permuted_coefficients.len(); assert_eq!(j, grand_product_challenges.len()); - assert_eq!(2*j, wellformed_challenges.len()); + assert_eq!(2 * j, wellformed_challenges.len()); let mut s_polynomial: Option> = None; - for c in self.inverse_permuted_at_y_coefficients.iter() - { - if s_polynomial.is_some() { + for c in self.inverse_permuted_at_y_coefficients.iter() { + if s_polynomial.is_some() { if let Some(poly) = s_polynomial.as_mut() { - add_polynomials(&mut poly[..], & c[..]); - } + add_polynomials(&mut poly[..], &c[..]); + } } else { s_polynomial = Some(c.clone()); } } let s_polynomial = s_polynomial.unwrap(); // evaluate at z - let s_zy = evaluate_at_consequitive_powers(& s_polynomial[..], z, z); + let s_zy = evaluate_at_consequitive_powers(&s_polynomial[..], z, z); let mut s_zy_neg = s_zy; s_zy_neg.negate(); - let s_zy_opening = polynomial_commitment_opening( - 0, - n, - Some(s_zy_neg).iter().chain_ext(s_polynomial.iter()), - z, - &srs - ); + let s_zy_opening = polynomial_commitment_opening(0, n, Some(s_zy_neg).iter().chain_ext(s_polynomial.iter()), z, &srs); // Sj(P4j)^β (P1j)^γ is equal to the product of the coefficients of Sj′(P3j)^β (P1j)^γ let p_1_values = vec![E::Fr::one(); n]; - let p_3_values: Vec = (1..=n).map(|el| { - let mut repr = <::Fr as PrimeField>::Repr::default(); - repr.as_mut()[0] = el as u64; - let fe = E::Fr::from_repr(repr).unwrap(); + let p_3_values: Vec = (1..=n) + .map(|el| { + let mut repr = <::Fr as PrimeField>::Repr::default(); + repr.as_mut()[0] = el as u64; + let fe = E::Fr::from_repr(repr).unwrap(); - fe - }).collect(); + fe + }) + .collect(); let mut grand_products = vec![]; - for ((non_permuted, inv_permuted), permutation) in self.non_permuted_at_y_coefficients.into_iter() - .zip(self.inverse_permuted_at_y_coefficients.into_iter()) - .zip(self.permutations.into_iter()) - + for ((non_permuted, inv_permuted), permutation) in self + .non_permuted_at_y_coefficients + .into_iter() + .zip(self.inverse_permuted_at_y_coefficients.into_iter()) + .zip(self.permutations.into_iter()) { - // in S combination at the place i there should be term coeff[sigma(i)] * Y^sigma(i), that we can take + // in S combination at the place i there should be term coeff[sigma(i)] * Y^sigma(i), that we can take // from non-permuted by inverse_permuting it // let mut s_combination = permute_inverse(&non_permuted[..], &permutation); let mut s_combination = inv_permuted; { - let p_4_values: Vec = permutation.into_iter().map(|el| { - let mut repr = <::Fr as PrimeField>::Repr::default(); - repr.as_mut()[0] = el as u64; - let fe = E::Fr::from_repr(repr).unwrap(); + let p_4_values: Vec = permutation + .into_iter() + .map(|el| { + let mut repr = <::Fr as PrimeField>::Repr::default(); + repr.as_mut()[0] = el as u64; + let fe = E::Fr::from_repr(repr).unwrap(); - fe - }).collect(); - mul_add_polynomials(&mut s_combination[..], & p_4_values[..], beta); - mul_add_polynomials(&mut s_combination[..], & p_1_values[..], gamma); + fe + }) + .collect(); + mul_add_polynomials(&mut s_combination[..], &p_4_values[..], beta); + mul_add_polynomials(&mut s_combination[..], &p_1_values[..], gamma); } // combination of coeff[i]*Y^i + beta * i + gamma let mut s_prime_combination = non_permuted.clone(); { - - mul_add_polynomials(&mut s_prime_combination[..], & p_3_values[..], beta); - mul_add_polynomials(&mut s_prime_combination[..], & p_1_values[..], gamma); + mul_add_polynomials(&mut s_prime_combination[..], &p_3_values[..], beta); + mul_add_polynomials(&mut s_prime_combination[..], &p_1_values[..], gamma); } // Sanity check - let s_prime_product = s_prime_combination.iter().fold(E::Fr::one(), |mut sum, x| - { + let s_prime_product = s_prime_combination.iter().fold(E::Fr::one(), |mut sum, x| { sum.mul_assign(&x); sum }); - let s_product = s_combination.iter().fold(E::Fr::one(), |mut sum, x| - { + let s_product = s_combination.iter().fold(E::Fr::one(), |mut sum, x| { sum.mul_assign(&x); sum @@ -390,11 +368,11 @@ impl PermutationArgument { grand_products.push((s_combination, s_prime_combination)); } - let mut a_commitments = vec![]; - let mut b_commitments = vec![]; + let mut a_commitments = vec![]; + let mut b_commitments = vec![]; for (a, b) in grand_products.iter() { - let (c_a, c_b) = GrandProductArgument::commit_for_individual_products(& a[..], & b[..], &srs); + let (c_a, c_b) = GrandProductArgument::commit_for_individual_products(&a[..], &b[..], &srs); a_commitments.push(c_a); b_commitments.push(c_b); } @@ -423,52 +401,36 @@ impl PermutationArgument { let proof = grand_product_argument.make_argument(&a_zy, &grand_product_challenges, y, z, &srs); { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let randomness = (0..j).map(|_| E::Fr::rand(rng)).collect::>(); - let valid = GrandProductArgument::verify_ab_commitment(n, - & randomness, - & a_commitments, - & b_commitments, - &grand_product_openings, - y, - z, - &srs); + let valid = GrandProductArgument::verify_ab_commitment(n, &randomness, &a_commitments, &b_commitments, &grand_product_openings, y, z, &srs); assert!(valid, "ab part of grand product argument must be valid"); let randomness = (0..3).map(|_| E::Fr::rand(rng)).collect::>(); - let valid = GrandProductArgument::verify(n, - &randomness, - &a_zy, - &grand_product_challenges, - t_commitment, - &c_commitments, - &proof, - y, - z, - &srs); + let valid = GrandProductArgument::verify(n, &randomness, &a_zy, &grand_product_challenges, t_commitment, &c_commitments, &proof, y, z, &srs); assert!(valid, "grand product argument must be valid"); } - + PermutationArgumentProof { j: j, s_opening: s_zy_opening, - s_zy: s_zy + s_zy: s_zy, } } pub fn verify_s_prime_commitment( - _n: usize, - randomness: & Vec, - challenges: & Vec, + _n: usize, + randomness: &Vec, + challenges: &Vec, commitments: &Vec, proof: &PermutationProof, y: E::Fr, z_prime: E::Fr, specialized_srs: &SpecializedSRS, - srs: &SRS + srs: &SRS, ) -> bool { assert_eq!(randomness.len(), 2); assert_eq!(challenges.len(), commitments.len()); @@ -503,51 +465,30 @@ impl PermutationArgument { let f_yz = proof.f_opening.mul(minus_yz.into_repr()); let e_z = proof.e_opening.mul(minus_z_prime.into_repr()); - let mut h_alpha_term = multiexp( - vec![e_z.into_affine(), f_yz.into_affine()].iter(), - randomness.iter(), - ); + let mut h_alpha_term = multiexp(vec![e_z.into_affine(), f_yz.into_affine()].iter(), randomness.iter()); let g_v = g.mul(value.into_repr()); h_alpha_term.add_assign(&g_v); - let h_alpha_x_term = multiexp( - Some(proof.e_opening).iter() - .chain_ext(Some(proof.f_opening).iter()), - randomness.iter(), - ).into_affine(); + let h_alpha_x_term = multiexp(Some(proof.e_opening).iter().chain_ext(Some(proof.f_opening).iter()), randomness.iter()).into_affine(); - let s_r = multiexp( - commitments.iter(), - challenges.iter() - ).into_affine(); + let s_r = multiexp(commitments.iter(), challenges.iter()).into_affine(); - let p2_r = multiexp( - specialized_srs.p_2.iter(), - challenges.iter() - ).into_affine(); + let p2_r = multiexp(specialized_srs.p_2.iter(), challenges.iter()).into_affine(); - let h_term = multiexp( - Some(s_r).iter() - .chain_ext(Some(p2_r).iter()), - randomness.iter() - ).into_affine(); + let h_term = multiexp(Some(s_r).iter().chain_ext(Some(p2_r).iter()), randomness.iter()).into_affine(); E::final_exponentiation(&E::miller_loop(&[ - (&h_alpha_x_term.prepare(), &h_alpha_x_precomp), - (&h_alpha_term.into_affine().prepare(), &h_alpha_precomp), - (&h_term.prepare(), &h_prep), - ])).unwrap() == E::Fqk::one() + (&h_alpha_x_term.prepare(), &h_alpha_x_precomp), + (&h_alpha_term.into_affine().prepare(), &h_alpha_precomp), + (&h_term.prepare(), &h_prep), + ])) + .unwrap() + == E::Fqk::one() } - pub fn verify( - s_commitments: &Vec, - proof: &PermutationArgumentProof, - z: E::Fr, - srs: &SRS - ) -> bool { - + pub fn verify(s_commitments: &Vec, proof: &PermutationArgumentProof, z: E::Fr, srs: &SRS) -> bool { let g = srs.g_positive_x[0]; let h_alpha_x_precomp = srs.h_positive_x_alpha[1].prepare(); @@ -556,7 +497,7 @@ impl PermutationArgument { let mut h_prep = srs.h_positive_x[0]; h_prep.negate(); - let h_prep = h_prep.prepare(); + let h_prep = h_prep.prepare(); let mut minus_z = z; minus_z.negate(); @@ -578,19 +519,15 @@ impl PermutationArgument { let h_term = s.into_affine(); E::final_exponentiation(&E::miller_loop(&[ - (&h_alpha_x_term.prepare(), &h_alpha_x_precomp), - (&h_alpha_term.into_affine().prepare(), &h_alpha_precomp), - (&h_term.prepare(), &h_prep), - ])).unwrap() == E::Fqk::one() + (&h_alpha_x_term.prepare(), &h_alpha_x_precomp), + (&h_alpha_term.into_affine().prepare(), &h_alpha_precomp), + (&h_term.prepare(), &h_prep), + ])) + .unwrap() + == E::Fqk::one() } - pub fn make_signature( - coefficients: Vec>, - permutations: Vec>, - y: E::Fr, - z: E::Fr, - srs: &SRS, - ) -> SignatureOfCorrectComputation { + pub fn make_signature(coefficients: Vec>, permutations: Vec>, y: E::Fr, z: E::Fr, srs: &SRS) -> SignatureOfCorrectComputation { let mut argument = PermutationArgument::new(coefficients, permutations); let commitments = argument.commit(y, &srs); let mut transcript = Transcript::new(&[]); @@ -617,12 +554,7 @@ impl PermutationArgument { let s_prime_commitments_opening = argument.open_commitments_to_s_prime(&challenges, y, z_prime, &srs); let (proof, grand_product_signature) = { - let (proof, grand_product_signature) = argument.make_argument_with_transcript( - &mut transcript, - y, - z, - &srs - ); + let (proof, grand_product_signature) = argument.make_argument_with_transcript(&mut transcript, y, z, &srs); (proof, grand_product_signature) }; @@ -632,18 +564,12 @@ impl PermutationArgument { s_prime_commitments, perm_argument_proof: proof, perm_proof: s_prime_commitments_opening, - grand_product_signature + grand_product_signature, } - } // Argument a permutation argument. Current implementation consumes, cause extra arguments are required - pub fn make_argument_with_transcript(self, - transcript: &mut Transcript, - y: E::Fr, - z: E::Fr, - srs: &SRS - ) -> (PermutationArgumentProof, GrandProductSignature) { + pub fn make_argument_with_transcript(self, transcript: &mut Transcript, y: E::Fr, z: E::Fr, srs: &SRS) -> (PermutationArgumentProof, GrandProductSignature) { // create random beta and gamma for every single permutation argument let mut betas = vec![]; let mut gammas = vec![]; @@ -664,86 +590,81 @@ impl PermutationArgument { let mut s_polynomial: Option> = None; - for c in self.inverse_permuted_at_y_coefficients.iter() - { - if s_polynomial.is_some() { + for c in self.inverse_permuted_at_y_coefficients.iter() { + if s_polynomial.is_some() { if let Some(poly) = s_polynomial.as_mut() { - add_polynomials(&mut poly[..], & c[..]); - } + add_polynomials(&mut poly[..], &c[..]); + } } else { s_polynomial = Some(c.clone()); } } let s_polynomial = s_polynomial.unwrap(); // evaluate at z - let s_zy = evaluate_at_consequitive_powers(& s_polynomial[..], z, z); + let s_zy = evaluate_at_consequitive_powers(&s_polynomial[..], z, z); let mut s_zy_neg = s_zy; s_zy_neg.negate(); - let s_zy_opening = polynomial_commitment_opening( - 0, - n, - Some(s_zy_neg).iter().chain_ext(s_polynomial.iter()), - z, - &srs - ); + let s_zy_opening = polynomial_commitment_opening(0, n, Some(s_zy_neg).iter().chain_ext(s_polynomial.iter()), z, &srs); // Sj(P4j)^β (P1j)^γ is equal to the product of the coefficients of Sj′(P3j)^β (P1j)^γ let p_1_values = vec![E::Fr::one(); n]; - let p_3_values: Vec = (1..=n).map(|el| { - let mut repr = <::Fr as PrimeField>::Repr::default(); - repr.as_mut()[0] = el as u64; - let fe = E::Fr::from_repr(repr).unwrap(); + let p_3_values: Vec = (1..=n) + .map(|el| { + let mut repr = <::Fr as PrimeField>::Repr::default(); + repr.as_mut()[0] = el as u64; + let fe = E::Fr::from_repr(repr).unwrap(); - fe - }).collect(); + fe + }) + .collect(); let mut grand_products = vec![]; - for ((((non_permuted, inv_permuted), permutation), beta), gamma) in - self.non_permuted_at_y_coefficients.into_iter() - .zip(self.inverse_permuted_at_y_coefficients.into_iter()) - .zip(self.permutations.into_iter()) - .zip(betas.into_iter()) - .zip(gammas.into_iter()) - + for ((((non_permuted, inv_permuted), permutation), beta), gamma) in self + .non_permuted_at_y_coefficients + .into_iter() + .zip(self.inverse_permuted_at_y_coefficients.into_iter()) + .zip(self.permutations.into_iter()) + .zip(betas.into_iter()) + .zip(gammas.into_iter()) { - // in S combination at the place i there should be term coeff[sigma(i)] * Y^sigma(i), that we can take + // in S combination at the place i there should be term coeff[sigma(i)] * Y^sigma(i), that we can take // from non-permuted by inverse_permuting it // let mut s_combination = permute_inverse(&non_permuted[..], &permutation); let mut s_combination = inv_permuted; { - let p_4_values: Vec = permutation.into_iter().map(|el| { - let mut repr = <::Fr as PrimeField>::Repr::default(); - repr.as_mut()[0] = el as u64; - let fe = E::Fr::from_repr(repr).unwrap(); + let p_4_values: Vec = permutation + .into_iter() + .map(|el| { + let mut repr = <::Fr as PrimeField>::Repr::default(); + repr.as_mut()[0] = el as u64; + let fe = E::Fr::from_repr(repr).unwrap(); - fe - }).collect(); - mul_add_polynomials(&mut s_combination[..], & p_4_values[..], beta); - mul_add_polynomials(&mut s_combination[..], & p_1_values[..], gamma); + fe + }) + .collect(); + mul_add_polynomials(&mut s_combination[..], &p_4_values[..], beta); + mul_add_polynomials(&mut s_combination[..], &p_1_values[..], gamma); } // combination of coeff[i]*Y^i + beta * i + gamma let mut s_prime_combination = non_permuted.clone(); { - - mul_add_polynomials(&mut s_prime_combination[..], & p_3_values[..], beta); - mul_add_polynomials(&mut s_prime_combination[..], & p_1_values[..], gamma); + mul_add_polynomials(&mut s_prime_combination[..], &p_3_values[..], beta); + mul_add_polynomials(&mut s_prime_combination[..], &p_1_values[..], gamma); } // Sanity check - let s_prime_product = s_prime_combination.iter().fold(E::Fr::one(), |mut sum, x| - { + let s_prime_product = s_prime_combination.iter().fold(E::Fr::one(), |mut sum, x| { sum.mul_assign(&x); sum }); - let s_product = s_combination.iter().fold(E::Fr::one(), |mut sum, x| - { + let s_product = s_combination.iter().fold(E::Fr::one(), |mut sum, x| { sum.mul_assign(&x); sum @@ -755,30 +676,23 @@ impl PermutationArgument { grand_products.push((s_combination, s_prime_combination)); } - let grand_product_signature = GrandProductArgument::create_signature( - transcript, - grand_products, - y, - z, - &srs - ); + let grand_product_signature = GrandProductArgument::create_signature(transcript, grand_products, y, z, &srs); let proof = PermutationArgumentProof { j: j, s_opening: s_zy_opening, - s_zy: s_zy + s_zy: s_zy, }; (proof, grand_product_signature) } - } #[test] fn test_permutation_argument() { - use crate::pairing::bls12_381::{Fr, G1Affine, G1, Bls12}; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use crate::pairing::bls12_381::{Bls12, Fr, G1Affine, G1}; use crate::sonic::srs::SRS; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let srs_x = Fr::from_str("23923").unwrap(); let srs_alpha = Fr::from_str("23728792").unwrap(); @@ -799,7 +713,7 @@ fn test_permutation_argument() { let mut argument = PermutationArgument::new(coeffs, permutations); - let y : Fr = rng.gen(); + let y: Fr = rng.gen(); let challenges = (0..1).map(|_| Fr::rand(rng)).collect::>(); @@ -811,43 +725,27 @@ fn test_permutation_argument() { s_prime_commitments.push(s_prime); } - let z_prime : Fr = rng.gen(); + let z_prime: Fr = rng.gen(); let opening = argument.open_commitments_to_s_prime(&challenges, y, z_prime, &srs); let randomness = (0..2).map(|_| Fr::rand(rng)).collect::>(); - let valid = PermutationArgument::verify_s_prime_commitment(n, - &randomness, - &challenges, - &s_prime_commitments, - &opening, - y, - z_prime, - &specialized_srs, - &srs); + let valid = PermutationArgument::verify_s_prime_commitment(n, &randomness, &challenges, &s_prime_commitments, &opening, y, z_prime, &specialized_srs, &srs); assert!(valid, "s' commitment must be valid"); - let beta : Fr = rng.gen(); - let gamma : Fr = rng.gen(); + let beta: Fr = rng.gen(); + let gamma: Fr = rng.gen(); let grand_product_challenges = (0..1).map(|_| Fr::rand(rng)).collect::>(); let wellformed_challenges = (0..2).map(|_| Fr::rand(rng)).collect::>(); - let z : Fr = rng.gen(); + let z: Fr = rng.gen(); - let proof = argument.make_argument( - beta, - gamma, - & grand_product_challenges, - & wellformed_challenges, - y, - z, - &specialized_srs, &srs); + let proof = argument.make_argument(beta, gamma, &grand_product_challenges, &wellformed_challenges, y, z, &specialized_srs, &srs); let valid = PermutationArgument::verify(&s_commitments, &proof, z, &srs); assert!(valid, "permutation argument must be valid"); } - diff --git a/crates/bellman/src/sonic/unhelped/permutation_structure.rs b/crates/bellman/src/sonic/unhelped/permutation_structure.rs index f7270ef..47d9479 100644 --- a/crates/bellman/src/sonic/unhelped/permutation_structure.rs +++ b/crates/bellman/src/sonic/unhelped/permutation_structure.rs @@ -1,25 +1,25 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use std::marker::PhantomData; -use crate::sonic::helped::{Proof, SxyAdvice}; use crate::sonic::helped::batch::Batch; use crate::sonic::helped::poly::{SxEval, SyEval}; use crate::sonic::helped::Parameters; +use crate::sonic::helped::{Proof, SxyAdvice}; use crate::SynthesisError; -use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use crate::sonic::util::*; -use crate::sonic::cs::{Backend, SynthesisDriver, ConstraintSystem}; -use crate::sonic::cs::{Circuit, Variable, Coeff}; -use crate::sonic::srs::SRS; +use crate::sonic::cs::{Backend, ConstraintSystem, SynthesisDriver}; +use crate::sonic::cs::{Circuit, Coeff, Variable}; +use crate::sonic::sonic::PermutationSynthesizer; use crate::sonic::sonic::Preprocess; use crate::sonic::sonic::M; -use crate::sonic::sonic::PermutationSynthesizer; +use crate::sonic::srs::SRS; +use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; -use super::s2_proof::*; use super::permutation_argument::*; +use super::s2_proof::*; #[derive(Clone)] pub struct PermutationStructure { @@ -30,26 +30,21 @@ pub struct PermutationStructure { pub c: Vec<[Option<(Coeff, usize)>; M]>, } -pub fn create_permutation_structure>( - circuit: &C, -) -> PermutationStructure -{ +pub fn create_permutation_structure>(circuit: &C) -> PermutationStructure { let mut backend: Preprocess = Preprocess::new(); let (a, b, c) = { - let mut cs: PermutationSynthesizer> = PermutationSynthesizer::new(&mut backend); let one = cs.alloc_input(|| Ok(E::Fr::one())).expect("should have no issues"); match (one, > as ConstraintSystem>::ONE) { - (Variable::A(1), Variable::A(1)) => {}, - _ => panic!("one variable is incorrect") + (Variable::A(1), Variable::A(1)) => {} + _ => panic!("one variable is incorrect"), } circuit.synthesize(&mut cs).expect("should synthesize"); - (cs.a, cs.b, cs.c) }; @@ -58,16 +53,10 @@ pub fn create_permutation_structure>( // println!("Will have {} gates and {} linear constraints", n, q); - PermutationStructure:: { - n: n, - q: q, - a: a, - b: b, - c: c - } + PermutationStructure:: { n: n, q: q, a: a, b: b, c: c } } -use rand::{Rng, Rand}; +use rand::{Rand, Rng}; impl PermutationStructure { pub fn calculate_s2_commitment_value(&self, srs: &SRS) -> E::G1Affine { @@ -83,8 +72,8 @@ impl PermutationStructure { pub fn create_inverse_permutation_vectors(&self) -> (Vec>, Vec>) { // we have to form non-permuted coefficients, as well as permutation structures; let n = self.n; - let mut non_permuted_coeffs = vec![vec![E::Fr::zero(); 3*n+1]; M]; - let mut permutations = vec![vec![0usize; 3*n+1]; M]; + let mut non_permuted_coeffs = vec![vec![E::Fr::zero(); 3 * n + 1]; M]; + let mut permutations = vec![vec![0usize; 3 * n + 1]; M]; let one = E::Fr::one(); let mut minus_one = E::Fr::one(); @@ -93,7 +82,7 @@ impl PermutationStructure { let mut not_empty = [false; M]; // go other the permutations for (gate_index, info) in self.a.iter().enumerate() { - let offset = n-1; + let offset = n - 1; for i in 0..M { // coefficients of A are placed at the offset = 0 from the beginning of the vector if let Some((coeff, place)) = info[i].as_ref() { @@ -103,21 +92,20 @@ impl PermutationStructure { let place_coeff_into = &mut non_permuted_coeffs[i]; let place_permutation_into = &mut permutations[i]; match coeff { - Coeff::Zero => { - }, + Coeff::Zero => {} Coeff::One => { not_empty[i] = true; - place_coeff_into[array_position] = one; + place_coeff_into[array_position] = one; place_permutation_into[array_position] = *place; - }, + } Coeff::NegativeOne => { not_empty[i] = true; - place_coeff_into[array_position] = minus_one; + place_coeff_into[array_position] = minus_one; place_permutation_into[array_position] = *place; - }, + } Coeff::Full(value) => { not_empty[i] = true; - place_coeff_into[array_position] = *value; + place_coeff_into[array_position] = *value; place_permutation_into[array_position] = *place; } } @@ -135,21 +123,20 @@ impl PermutationStructure { let place_coeff_into = &mut non_permuted_coeffs[i]; let place_permutation_into = &mut permutations[i]; match coeff { - Coeff::Zero => { - }, + Coeff::Zero => {} Coeff::One => { not_empty[i] = true; - place_coeff_into[array_position] = one; + place_coeff_into[array_position] = one; place_permutation_into[array_position] = *place; - }, + } Coeff::NegativeOne => { not_empty[i] = true; - place_coeff_into[array_position] = minus_one; + place_coeff_into[array_position] = minus_one; place_permutation_into[array_position] = *place; - }, + } Coeff::Full(value) => { not_empty[i] = true; - place_coeff_into[array_position] = *value; + place_coeff_into[array_position] = *value; place_permutation_into[array_position] = *place; } } @@ -158,7 +145,7 @@ impl PermutationStructure { } for (gate_index, info) in self.c.iter().enumerate() { - let offset = 2*n + 1; + let offset = 2 * n + 1; for i in 0..M { // coefficients of A are placed at the offset = 0 from the beginning of the vector if let Some((coeff, place)) = info[i].as_ref() { @@ -168,21 +155,20 @@ impl PermutationStructure { let place_coeff_into = &mut non_permuted_coeffs[i]; let place_permutation_into = &mut permutations[i]; match coeff { - Coeff::Zero => { - }, + Coeff::Zero => {} Coeff::One => { not_empty[i] = true; - place_coeff_into[array_position] = one; + place_coeff_into[array_position] = one; place_permutation_into[array_position] = *place; - }, + } Coeff::NegativeOne => { not_empty[i] = true; - place_coeff_into[array_position] = minus_one; + place_coeff_into[array_position] = minus_one; place_permutation_into[array_position] = *place; - }, + } Coeff::Full(value) => { not_empty[i] = true; - place_coeff_into[array_position] = *value; + place_coeff_into[array_position] = *value; place_permutation_into[array_position] = *place; } } @@ -216,7 +202,7 @@ impl PermutationStructure { // find something faster, although it's still linear for i in 0..m { - let mut fillers: Vec = (1..=(3*n+1)).map(|el| el).collect(); + let mut fillers: Vec = (1..=(3 * n + 1)).map(|el| el).collect(); for (p, c) in permutations[i].iter_mut().zip(non_permuted_coeffs[i].iter()) { if *p == 0 { assert!(c.is_zero()); @@ -246,8 +232,8 @@ impl PermutationStructure { pub fn create_permutation_vectors(&self) -> (Vec>, Vec>) { // we have to form non-permuted coefficients, as well as permutation structures; let n = self.n; - let mut non_permuted_coeffs = vec![vec![E::Fr::zero(); 3*n+1]; M]; - let mut permutations = vec![vec![0usize; 3*n+1]; M]; + let mut non_permuted_coeffs = vec![vec![E::Fr::zero(); 3 * n + 1]; M]; + let mut permutations = vec![vec![0usize; 3 * n + 1]; M]; let one = E::Fr::one(); let mut minus_one = E::Fr::one(); @@ -256,7 +242,7 @@ impl PermutationStructure { let mut not_empty = [false; M]; // go other the permutations for (gate_index, info) in self.a.iter().enumerate() { - let offset = n-1; + let offset = n - 1; for i in 0..M { // coefficients of A are placed at the offset = 0 from the beginning of the vector if let Some((coeff, place)) = info[i].as_ref() { @@ -267,21 +253,20 @@ impl PermutationStructure { let place_coeff_into = &mut non_permuted_coeffs[i]; let place_permutation_into = &mut permutations[i]; match coeff { - Coeff::Zero => { - }, + Coeff::Zero => {} Coeff::One => { not_empty[i] = true; - place_coeff_into[coeff_position] = one; + place_coeff_into[coeff_position] = one; place_permutation_into[array_position] = *place; - }, + } Coeff::NegativeOne => { not_empty[i] = true; - place_coeff_into[coeff_position] = minus_one; + place_coeff_into[coeff_position] = minus_one; place_permutation_into[array_position] = *place; - }, + } Coeff::Full(value) => { not_empty[i] = true; - place_coeff_into[coeff_position] = *value; + place_coeff_into[coeff_position] = *value; place_permutation_into[array_position] = *place; } } @@ -300,21 +285,20 @@ impl PermutationStructure { let place_coeff_into = &mut non_permuted_coeffs[i]; let place_permutation_into = &mut permutations[i]; match coeff { - Coeff::Zero => { - }, + Coeff::Zero => {} Coeff::One => { not_empty[i] = true; - place_coeff_into[coeff_position] = one; + place_coeff_into[coeff_position] = one; place_permutation_into[array_position] = *place; - }, + } Coeff::NegativeOne => { not_empty[i] = true; - place_coeff_into[coeff_position] = minus_one; + place_coeff_into[coeff_position] = minus_one; place_permutation_into[array_position] = *place; - }, + } Coeff::Full(value) => { not_empty[i] = true; - place_coeff_into[coeff_position] = *value; + place_coeff_into[coeff_position] = *value; place_permutation_into[array_position] = *place; } } @@ -323,7 +307,7 @@ impl PermutationStructure { } for (gate_index, info) in self.c.iter().enumerate() { - let offset = 2*n + 1; + let offset = 2 * n + 1; for i in 0..M { // coefficients of A are placed at the offset = 0 from the beginning of the vector if let Some((coeff, place)) = info[i].as_ref() { @@ -334,21 +318,20 @@ impl PermutationStructure { let place_coeff_into = &mut non_permuted_coeffs[i]; let place_permutation_into = &mut permutations[i]; match coeff { - Coeff::Zero => { - }, + Coeff::Zero => {} Coeff::One => { not_empty[i] = true; - place_coeff_into[coeff_position] = one; + place_coeff_into[coeff_position] = one; place_permutation_into[array_position] = *place; - }, + } Coeff::NegativeOne => { not_empty[i] = true; - place_coeff_into[coeff_position] = minus_one; + place_coeff_into[coeff_position] = minus_one; place_permutation_into[array_position] = *place; - }, + } Coeff::Full(value) => { not_empty[i] = true; - place_coeff_into[coeff_position] = *value; + place_coeff_into[coeff_position] = *value; place_permutation_into[array_position] = *place; } } @@ -382,7 +365,7 @@ impl PermutationStructure { // find something faster, although it's still linear for i in 0..m { - let mut fillers: Vec = (1..=(3*n+1)).map(|el| el).collect(); + let mut fillers: Vec = (1..=(3 * n + 1)).map(|el| el).collect(); for (p, _c) in permutations[i].iter_mut().zip(non_permuted_coeffs[i].iter()) { if *p == 0 { continue; @@ -410,7 +393,7 @@ impl PermutationStructure { (non_permuted_coeffs, permutations) } - pub fn print_constraints(n:usize, q: usize, coeffs: &Vec>, permutations: &Vec>) { + pub fn print_constraints(n: usize, q: usize, coeffs: &Vec>, permutations: &Vec>) { let m = coeffs.len(); for constraint_idx in 1..=q { @@ -425,25 +408,20 @@ impl PermutationStructure { for (var_idx, coeff) in terms.into_iter() { if var_idx < n + 1 { print!("{} * A({})", coeff, n - var_idx); - } else if var_idx < 2*n + 1 { + } else if var_idx < 2 * n + 1 { print!("{} * B({})", coeff, var_idx - n); } else { - print!("{} * C({})", coeff, var_idx - 2*n); + print!("{} * C({})", coeff, var_idx - 2 * n); } print!("\n"); } } } - pub fn create_permutation_special_reference(&self, srs: &SRS) -> SpecializedSRS - { + pub fn create_permutation_special_reference(&self, srs: &SRS) -> SpecializedSRS { let (non_permuted_coeffs, permutations) = self.create_permutation_vectors(); - let specialized_srs = PermutationArgument::make_specialized_srs( - &non_permuted_coeffs, - &permutations, - &srs - ); + let specialized_srs = PermutationArgument::make_specialized_srs(&non_permuted_coeffs, &permutations, &srs); specialized_srs } @@ -455,7 +433,7 @@ impl PermutationStructure { for permutation_index in 0..permutations.len() { for (variable_index, sigma_i) in permutations[permutation_index].iter().enumerate() { let y_power = y.pow([*sigma_i as u64]); - let x_power = z.pow([(variable_index+1) as u64]); + let x_power = z.pow([(variable_index + 1) as u64]); let coeff = non_permuted_coeffs[permutation_index][*sigma_i - 1]; let mut result = coeff; @@ -476,39 +454,33 @@ impl PermutationStructure { println!("Naive S contribution scaled = {}", s_contrib); // let specialized_srs = PermutationArgument::make_specialized_srs( - // &non_permuted_coeffs, - // &permutations, + // &non_permuted_coeffs, + // &permutations, // &srs // ); - let signature = PermutationArgument::make_signature( - non_permuted_coeffs, - permutations, - y, - z, - &srs, - ); + let signature = PermutationArgument::make_signature(non_permuted_coeffs, permutations, y, z, &srs); signature - } + } - pub fn create_permutation_arguments(&self, y: E::Fr, z: E::Fr, rng: &mut R, srs: &SRS) - -> (Vec<(E::G1Affine, E::G1Affine)>, Vec, PermutationProof, PermutationArgumentProof, E::Fr, usize, E::Fr) - { + pub fn create_permutation_arguments( + &self, + y: E::Fr, + z: E::Fr, + rng: &mut R, + srs: &SRS, + ) -> (Vec<(E::G1Affine, E::G1Affine)>, Vec, PermutationProof, PermutationArgumentProof, E::Fr, usize, E::Fr) { // we have to form non-permuted coefficients, as well as permutation structures; let n = self.n; - + let (non_permuted_coeffs, permutations) = self.create_permutation_vectors(); let m = non_permuted_coeffs.len(); println!("Will need {} permutation polynomials", m); - let specialized_srs = PermutationArgument::make_specialized_srs( - &non_permuted_coeffs, - &permutations, - &srs - ); + let specialized_srs = PermutationArgument::make_specialized_srs(&non_permuted_coeffs, &permutations, &srs); // evaluate S naively @@ -516,7 +488,7 @@ impl PermutationStructure { for permutation_index in 0..m { for (variable_index, sigma_i) in permutations[permutation_index].iter().enumerate() { let y_power = y.pow([*sigma_i as u64]); - let x_power = z.pow([(variable_index+1) as u64]); + let x_power = z.pow([(variable_index + 1) as u64]); let coeff = non_permuted_coeffs[permutation_index][*sigma_i - 1]; let mut result = coeff; @@ -538,41 +510,25 @@ impl PermutationStructure { s_commitments.push(s); // println!("S' = {}", s_prime); s_prime_commitments.push(s_prime); - } - let z_prime : E::Fr = rng.gen(); + let z_prime: E::Fr = rng.gen(); let opening = argument.open_commitments_to_s_prime(&challenges, y, z_prime, &srs); let randomness = (0..2).map(|_| E::Fr::rand(rng)).collect::>(); - let valid = PermutationArgument::verify_s_prime_commitment(n, - &randomness, - &challenges, - &s_prime_commitments, - &opening, - y, - z_prime, - &specialized_srs, - &srs); + let valid = PermutationArgument::verify_s_prime_commitment(n, &randomness, &challenges, &s_prime_commitments, &opening, y, z_prime, &specialized_srs, &srs); assert!(valid, "s' commitment must be valid"); - let beta : E::Fr = rng.gen(); - let gamma : E::Fr = rng.gen(); + let beta: E::Fr = rng.gen(); + let gamma: E::Fr = rng.gen(); let grand_product_challenges = (0..m).map(|_| E::Fr::rand(rng)).collect::>(); - let wellformed_challenges = (0..(2*m)).map(|_| E::Fr::rand(rng)).collect::>(); + let wellformed_challenges = (0..(2 * m)).map(|_| E::Fr::rand(rng)).collect::>(); - let proof = argument.make_argument( - beta, - gamma, - & grand_product_challenges, - & wellformed_challenges, - y, - z, - &specialized_srs, &srs); + let proof = argument.make_argument(beta, gamma, &grand_product_challenges, &wellformed_challenges, y, z, &specialized_srs, &srs); let valid = PermutationArgument::verify(&s_commitments, &proof, z, &srs); @@ -584,24 +540,18 @@ impl PermutationStructure { #[test] fn test_simple_succinct_sonic() { - use crate::pairing::ff::{Field, PrimeField}; - use crate::pairing::{Engine, CurveAffine, CurveProjective}; use crate::pairing::bls12_381::{Bls12, Fr}; - use std::time::{Instant}; - use crate::sonic::srs::SRS; + use crate::pairing::ff::{Field, PrimeField}; + use crate::pairing::{CurveAffine, CurveProjective, Engine}; use crate::sonic::cs::{Circuit, ConstraintSystem, LinearCombination}; + use crate::sonic::srs::SRS; + use std::time::Instant; struct MyCircuit; impl Circuit for MyCircuit { fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let (a, b, c) = cs.multiply(|| { - Ok(( - E::Fr::from_str("10").unwrap(), - E::Fr::from_str("20").unwrap(), - E::Fr::from_str("200").unwrap(), - )) - })?; + let (a, b, c) = cs.multiply(|| Ok((E::Fr::from_str("10").unwrap(), E::Fr::from_str("20").unwrap(), E::Fr::from_str("200").unwrap())))?; cs.enforce_zero(LinearCombination::zero() + (Coeff::Full(E::Fr::from_str("2").unwrap()), a) - b); cs.enforce_zero(LinearCombination::zero() + (Coeff::Full(E::Fr::from_str("20").unwrap()), a) - c); @@ -636,22 +586,22 @@ fn test_simple_succinct_sonic() { println!("done in {:?}", start.elapsed()); { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let _rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - - use crate::sonic::sonic::Basic; - use crate::sonic::sonic::AdaptorCircuit; + + use crate::sonic::helped::helper::create_aggregate_on_srs; use crate::sonic::helped::prover::{create_advice_on_srs, create_proof_on_srs}; - use crate::sonic::helped::{MultiVerifier, get_circuit_parameters_for_succinct_sonic}; - use crate::sonic::helped::helper::{create_aggregate_on_srs}; + use crate::sonic::helped::{get_circuit_parameters_for_succinct_sonic, MultiVerifier}; + use crate::sonic::sonic::AdaptorCircuit; + use crate::sonic::sonic::Basic; use crate::sonic::sonic::Permutation3; use crate::sonic::unhelped::permutation_structure::*; // let z: Fr = rng.gen(); - // let y: Fr = rng.gen(); + // let y: Fr = rng.gen(); let z: Fr = Fr::from_str("2").unwrap(); - let y: Fr = Fr::one(); + let y: Fr = Fr::one(); let perm_structure = create_permutation_structure::(&MyCircuit); let (non_permuted_coeffs, permutations) = perm_structure.create_permutation_vectors(); @@ -674,7 +624,7 @@ fn test_simple_succinct_sonic() { // let coeff_sigma_i = non_permuted_coeffs[j][sigma_i - 1]; let y_power = y.pow([sigma_i as u64]); - let x_power = z.pow([(i+1) as u64]); + let x_power = z.pow([(i + 1) as u64]); // let mut result = coeff_sigma_i; let mut result = coeff_i; result.mul_assign(&y_power); @@ -740,4 +690,4 @@ fn test_simple_succinct_sonic() { assert_eq!(s1, szy); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/unhelped/s2_proof.rs b/crates/bellman/src/sonic/unhelped/s2_proof.rs index 6cbaf9b..f076099 100644 --- a/crates/bellman/src/sonic/unhelped/s2_proof.rs +++ b/crates/bellman/src/sonic/unhelped/s2_proof.rs @@ -1,5 +1,5 @@ use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use crate::pairing::{Engine, CurveProjective, CurveAffine}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; use std::marker::PhantomData; use crate::sonic::srs::SRS; @@ -8,7 +8,7 @@ use crate::sonic::util::*; #[derive(Clone)] pub struct S2Eval { n: usize, - _marker: PhantomData + _marker: PhantomData, } #[derive(Clone)] @@ -17,7 +17,7 @@ pub struct S2Proof { pub c_value: E::Fr, pub d_value: E::Fr, pub c_opening: E::G1Affine, - pub d_opening: E::G1Affine + pub d_opening: E::G1Affine, } impl S2Eval { @@ -32,10 +32,7 @@ impl S2Eval { } pub fn new(n: usize) -> Self { - S2Eval { - n: n, - _marker: PhantomData - } + S2Eval { n: n, _marker: PhantomData } } pub fn evaluate(&self, x: E::Fr, y: E::Fr, srs: &SRS) -> S2Proof { @@ -43,7 +40,7 @@ impl S2Eval { let o = Self::calculate_commitment_element(self.n, &srs); - let mut poly = vec![E::Fr::one(); self.n+1]; + let mut poly = vec![E::Fr::one(); self.n + 1]; let (c, c_opening) = { let mut point = y; @@ -67,18 +64,16 @@ impl S2Eval { (val, opening) }; - S2Proof { o: o, c_value: c, d_value: d, c_opening: c_opening, - d_opening: d_opening + d_opening: d_opening, } } pub fn verify(x: E::Fr, y: E::Fr, proof: &S2Proof, srs: &SRS) -> bool { - // e(C,hαx)e(C−yz,hα) = e(O,h)e(g−c,hα) let alpha_x_precomp = srs.h_positive_x_alpha[1].prepare(); @@ -98,14 +93,16 @@ impl S2Eval { let h_alpha_term = h_alpha_term.into_affine(); let valid = E::final_exponentiation(&E::miller_loop(&[ - (&proof.c_opening.prepare(), &alpha_x_precomp), - (&h_alpha_term.prepare(), &alpha_precomp), - (&proof.o.prepare(), &h_prep), - ])).unwrap() == E::Fqk::one(); + (&proof.c_opening.prepare(), &alpha_x_precomp), + (&h_alpha_term.prepare(), &alpha_precomp), + (&proof.o.prepare(), &h_prep), + ])) + .unwrap() + == E::Fqk::one(); if !valid { return false; - } + } // e(D,hαx)e(D−y−1z,hα) = e(O,h)e(g−d,hα) @@ -120,28 +117,29 @@ impl S2Eval { let h_alpha_term = h_alpha_term.into_affine(); let valid = E::final_exponentiation(&E::miller_loop(&[ - (&proof.d_opening.prepare(), &alpha_x_precomp), - (&h_alpha_term.prepare(), &alpha_precomp), - (&proof.o.prepare(), &h_prep), - ])).unwrap() == E::Fqk::one(); + (&proof.d_opening.prepare(), &alpha_x_precomp), + (&h_alpha_term.prepare(), &alpha_precomp), + (&proof.o.prepare(), &h_prep), + ])) + .unwrap() + == E::Fqk::one(); if !valid { return false; - } + } true } } - #[test] fn test_s2_proof() { - use crate::pairing::ff::{Field, PrimeField}; - use crate::pairing::{Engine, CurveAffine, CurveProjective}; use crate::pairing::bls12_381::{Bls12, Fr}; - use std::time::{Instant}; - use crate::sonic::srs::SRS; + use crate::pairing::ff::{Field, PrimeField}; + use crate::pairing::{CurveAffine, CurveProjective, Engine}; use crate::sonic::cs::{Circuit, ConstraintSystem, LinearCombination}; + use crate::sonic::srs::SRS; + use std::time::Instant; let srs_x = Fr::from_str("23923").unwrap(); let srs_alpha = Fr::from_str("23728792").unwrap(); @@ -151,7 +149,7 @@ fn test_s2_proof() { println!("done in {:?}", start.elapsed()); { - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let x: Fr = rng.gen(); @@ -164,4 +162,4 @@ fn test_s2_proof() { assert!(valid); } -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/unhelped/verifier.rs b/crates/bellman/src/sonic/unhelped/verifier.rs index 7718681..363b782 100644 --- a/crates/bellman/src/sonic/unhelped/verifier.rs +++ b/crates/bellman/src/sonic/unhelped/verifier.rs @@ -1,32 +1,27 @@ -use crate::pairing::ff::{Field}; -use crate::pairing::{Engine, CurveProjective}; -use std::marker::PhantomData; +use crate::pairing::ff::Field; +use crate::pairing::{CurveProjective, Engine}; use rand::{Rand, Rng}; +use std::marker::PhantomData; -use crate::sonic::helped::{Proof, SxyAdvice}; use crate::sonic::helped::batch::Batch; -use crate::sonic::helped::poly::{SxEval, SyEval}; use crate::sonic::helped::helper::Aggregate; -use crate::sonic::helped::parameters::{Parameters}; +use crate::sonic::helped::parameters::Parameters; +use crate::sonic::helped::poly::{SxEval, SyEval}; +use crate::sonic::helped::{Proof, SxyAdvice}; use crate::SynthesisError; -use crate::sonic::transcript::{Transcript, TranscriptProtocol}; -use crate::sonic::util::*; use crate::sonic::cs::{Backend, SynthesisDriver}; -use crate::sonic::cs::{Circuit, Variable, Coeff}; -use crate::sonic::srs::SRS; +use crate::sonic::cs::{Circuit, Coeff, Variable}; use crate::sonic::sonic::Preprocess; +use crate::sonic::srs::SRS; +use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; -use super::s2_proof::{S2Proof, S2Eval}; use super::aggregate::SuccinctAggregate; +use super::permutation_argument::{PermutationArgument, PermutationArgumentProof, PermutationProof, SpecializedSRS}; use super::permutation_structure::create_permutation_structure; -use super::permutation_argument::{ - PermutationArgumentProof, - PermutationProof, - PermutationArgument, - SpecializedSRS -}; +use super::s2_proof::{S2Eval, S2Proof}; pub struct SuccinctMultiVerifier, S: SynthesisDriver, R: Rng> { circuit: C, @@ -37,7 +32,7 @@ pub struct SuccinctMultiVerifier, S: SynthesisDriver, R n: usize, q: usize, randomness_source: R, - _marker: PhantomData<(E, S)> + _marker: PhantomData<(E, S)>, } impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier { @@ -65,17 +60,11 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier n: n, q: q, randomness_source: rng, - _marker: PhantomData + _marker: PhantomData, }) } - pub fn add_aggregate( - &mut self, - proofs: &[(Proof, SxyAdvice)], - aggregate: &SuccinctAggregate, - srs: &SRS - ) - { + pub fn add_aggregate(&mut self, proofs: &[(Proof, SxyAdvice)], aggregate: &SuccinctAggregate, srs: &SRS) { let mut transcript = Transcript::new(&[]); let mut y_values: Vec = Vec::with_capacity(proofs.len()); for &(ref proof, ref sxyadvice) in proofs { @@ -95,7 +84,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier let w: E::Fr = transcript.get_challenge_scalar(); let szw = { - // prover will supply s1 and s2, need to calculate + // prover will supply s1 and s2, need to calculate // s(z, w) = X^-(N+1) * Y^N * s1 - X^N * s2 let x_n = z.pow(&[self.n as u64]); @@ -118,7 +107,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier { let random: E::Fr = self.randomness_source.gen(); - // e(C,hαx)e(C−yz,hα) = e(O,h)e(g−c,hα) that is + // e(C,hαx)e(C−yz,hα) = e(O,h)e(g−c,hα) that is // e(C,hαx)e(C^−yz,hα)*e(O,-h)e(g^c,hα) = 1 let mut xy = z; @@ -127,13 +116,12 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier self.batch.add_opening(s2_proof.c_opening, random, xy); self.batch.add_opening_value(random, s2_proof.c_value); self.batch.add_commitment(self.s2_special_reference, random); - } { let random: E::Fr = self.randomness_source.gen(); - // e(D,hαx)e(D−y−1z,hα) = e(O,h)e(g−d,hα) that is + // e(D,hαx)e(D−y−1z,hα) = e(O,h)e(g−d,hα) that is // e(D,hαx)e(D^−y-1z,hα)*e(O,-h)e(g^d,hα) = 1 let mut y_inv_by_x = z; @@ -142,7 +130,6 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier self.batch.add_opening(s2_proof.d_opening, random, y_inv_by_x); self.batch.add_opening_value(random, s2_proof.d_value); self.batch.add_commitment(self.s2_special_reference, random); - } // now work with s1 part @@ -163,15 +150,14 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier // let s_prime_commitments = &aggregate.signature.s_prime_commitments; let mut challenges = vec![]; - for (s, s_prime) in aggregate.signature.s_commitments.iter() - .zip(aggregate.signature.s_prime_commitments.iter()) { + for (s, s_prime) in aggregate.signature.s_commitments.iter().zip(aggregate.signature.s_prime_commitments.iter()) { transcript.commit_point(s); transcript.commit_point(s_prime); - } + } for _ in 0..aggregate.signature.s_commitments.len() { let challenge = transcript.get_challenge_scalar(); - challenges.push(challenge); + challenges.push(challenge); } let z_prime: E::Fr = transcript.get_challenge_scalar(); @@ -182,16 +168,9 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier // e(E,hαx)e(E−z′,hα) = e(􏰇Mj=1Sj′rj,h)e(g−v,hα) let perm_proof = &aggregate.signature.perm_proof; - let s_r = multiexp( - aggregate.signature.s_prime_commitments.iter(), - challenges.iter() - ).into_affine(); - - let p2_r = multiexp( - self.s1_special_reference.p_2.iter(), - challenges.iter() - ).into_affine(); + let s_r = multiexp(aggregate.signature.s_prime_commitments.iter(), challenges.iter()).into_affine(); + let p2_r = multiexp(self.s1_special_reference.p_2.iter(), challenges.iter()).into_affine(); let value = perm_proof.v_zy; @@ -201,7 +180,6 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier self.batch.add_opening_value(random, value); self.batch.add_commitment(s_r, random); - // e(F,hαx)e(F−yz′,hα) = e(􏰇Mj=1P2jrj,h)e(g−v,hα) let mut y_z_prime = z_prime; @@ -212,10 +190,9 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier self.batch.add_opening(perm_proof.f_opening, random, y_z_prime); self.batch.add_opening_value(random, value); self.batch.add_commitment(p2_r, random); - } - // now we can actually take an opening of S commitments and + // now we can actually take an opening of S commitments and { // e(I,hαx)e(I−z,hα) = e(􏰇Mj=1 Sj,h)e(g−s,hα) @@ -232,7 +209,6 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier self.batch.add_opening(aggregate.signature.perm_argument_proof.s_opening, random, z); self.batch.add_opening_value(random, value); self.batch.add_commitment(s_commitment.into_affine(), random); - } // TODO: Add grand product argument! @@ -253,18 +229,20 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier betas.push(beta); gammas.push(gamma); } - + let mut wellformedness_argument_commitments = vec![]; - use crate::pairing::CurveAffine; use crate::pairing::ff::PrimeField; + use crate::pairing::CurveAffine; - for (j, (((s, s_prime), beta), gamma)) in aggregate.signature.s_commitments.iter() - .zip(aggregate.signature.s_prime_commitments.iter()) - .zip(betas.iter()) - .zip(gammas.iter()) - .enumerate() - + for (j, (((s, s_prime), beta), gamma)) in aggregate + .signature + .s_commitments + .iter() + .zip(aggregate.signature.s_prime_commitments.iter()) + .zip(betas.iter()) + .zip(gammas.iter()) + .enumerate() { // Sj(P4j)β(P1j)γ @@ -298,7 +276,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier let h_alpha_x_precomp = srs.h_positive_x_alpha[1].prepare(); let h_alpha_precomp = srs.h_positive_x_alpha[0].prepare(); - let mut h_x_n_plus_one_precomp = srs.h_positive_x[self.n+1]; + let mut h_x_n_plus_one_precomp = srs.h_positive_x[self.n + 1]; h_x_n_plus_one_precomp.negate(); let h_x_n_plus_one_precomp = h_x_n_plus_one_precomp.prepare(); @@ -306,17 +284,11 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier h_prep.negate(); let h_prep = h_prep.prepare(); - let a = multiexp( - a_commitments.iter(), - randomness.iter(), - ).into_affine(); + let a = multiexp(a_commitments.iter(), randomness.iter()).into_affine(); let a = a.prepare(); - let b = multiexp( - b_commitments.iter(), - randomness.iter(), - ).into_affine(); + let b = multiexp(b_commitments.iter(), randomness.iter()).into_affine(); let b = b.prepare(); @@ -337,10 +309,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier let value = g.mul(value.into_repr()).into_affine().prepare(); - let openings = multiexp( - ops.iter(), - randomness.iter(), - ).into_affine(); + let openings = multiexp(ops.iter(), randomness.iter()).into_affine(); let openings_zy = openings.mul(yz_neg.into_repr()).into_affine().prepare(); let openings = openings.prepare(); @@ -348,16 +317,17 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier // e(Dj,hαx)e(D−yz,hα) = e(Aj,h)e(Bj,hxn+1)e(g−aj ,hα) let valid = E::final_exponentiation(&E::miller_loop(&[ - (&openings, &h_alpha_x_precomp), - (&openings_zy, &h_alpha_precomp), - (&a, &h_prep), - (&b, &h_x_n_plus_one_precomp), - (&value, &h_alpha_precomp) - ])).unwrap() == E::Fqk::one(); + (&openings, &h_alpha_x_precomp), + (&openings_zy, &h_alpha_precomp), + (&a, &h_prep), + (&b, &h_x_n_plus_one_precomp), + (&value, &h_alpha_precomp), + ])) + .unwrap() + == E::Fqk::one(); // TODO assert!(valid, "grand product arguments must be valid for individual commitments"); - } // Now the second part of the grand product argument @@ -383,15 +353,16 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier let mut ry_vec = vec![]; // in grand product arguments n is not a number of gates, but 3n+1 - number of variables + 1 - let three_n_plus_1 = 3*self.n + 1; + let three_n_plus_1 = 3 * self.n + 1; - for ((r, commitment), (a, _)) in grand_product_challenges.iter() - .zip(aggregate.signature.grand_product_signature.c_commitments.iter()) - .zip(aggregate.signature.grand_product_signature.grand_product_openings.iter()) + for ((r, commitment), (a, _)) in grand_product_challenges + .iter() + .zip(aggregate.signature.grand_product_signature.c_commitments.iter()) + .zip(aggregate.signature.grand_product_signature.grand_product_openings.iter()) { let (c, v) = commitment; commitments_points.push(*c); - + // cj = ((aj + vj(yz)n+1)y + zn+2 + zn+1y − z2n+2y)z−1 let mut c_zy = yz.pow([(three_n_plus_1 + 1) as u64]); c_zy.mul_assign(v); @@ -433,15 +404,9 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier // t(z, y) is now calculated - let c_rc = multiexp( - commitments_points.iter(), - rc_vec.iter(), - ).into_affine(); + let c_rc = multiexp(commitments_points.iter(), rc_vec.iter()).into_affine(); - let c_ry = multiexp( - commitments_points.iter(), - ry_vec.iter(), - ).into_affine(); + let c_ry = multiexp(commitments_points.iter(), ry_vec.iter()).into_affine(); // e(E,h^alphax)e(E^-z^-1,h^alpha) = e(\sumCj^(rj*cj),h)e(g^-e,h^alpha) @@ -485,7 +450,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier } let d = srs.d; - let n = 3*self.n + 1; // same as for grand products + let n = 3 * self.n + 1; // same as for grand products let alpha_x_d_precomp = srs.h_positive_x_alpha[d].prepare(); // TODO: not strictly required @@ -496,10 +461,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier h_prep.negate(); let h_prep = h_prep.prepare(); - let a = multiexp( - wellformedness_argument_commitments.iter(), - wellformedness_challenges.iter(), - ).into_affine(); + let a = multiexp(wellformedness_argument_commitments.iter(), wellformedness_challenges.iter()).into_affine(); let r1: E::Fr = self.randomness_source.gen(); let r2: E::Fr = self.randomness_source.gen(); @@ -512,14 +474,15 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier let a_r = a.mul(r.into_repr()).into_affine(); let valid = E::final_exponentiation(&E::miller_loop(&[ - (&a_r.prepare(), &h_prep), - (&l_r1.prepare(), &alpha_x_d_precomp), - (&r_r2.prepare(), &alpha_x_n_minus_d_precomp) - ])).unwrap() == E::Fqk::one(); + (&a_r.prepare(), &h_prep), + (&l_r1.prepare(), &alpha_x_d_precomp), + (&r_r2.prepare(), &alpha_x_n_minus_d_precomp), + ])) + .unwrap() + == E::Fqk::one(); assert!(valid, "wellformedness argument must be valid"); } - } szw @@ -564,13 +527,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier } /// Caller must ensure to add aggregate after adding a proof - pub fn add_proof_with_advice( - &mut self, - proof: &Proof, - inputs: &[E::Fr], - advice: &SxyAdvice, - ) - { + pub fn add_proof_with_advice(&mut self, proof: &Proof, inputs: &[E::Fr], advice: &SxyAdvice) { let mut z = None; self.add_proof(proof, inputs, |_z, _y| { @@ -592,13 +549,9 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier self.batch.add_opening_value(advice.szy, random); } - pub fn add_proof( - &mut self, - proof: &Proof, - inputs: &[E::Fr], - sxy: F - ) - where F: FnOnce(E::Fr, E::Fr) -> Option + pub fn add_proof(&mut self, proof: &Proof, inputs: &[E::Fr], sxy: F) + where + F: FnOnce(E::Fr, E::Fr) -> Option, { let mut transcript = Transcript::new(&[]); @@ -690,7 +643,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier } } -// /// Check multiple proofs without aggregation. Verifier's work is +// /// Check multiple proofs without aggregation. Verifier's work is // /// not succint due to `S(X, Y)` evaluation // pub fn verify_proofs, S: SynthesisDriver, R: Rng>( // proofs: &[Proof], @@ -702,7 +655,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier // verify_proofs_on_srs::(proofs, inputs, circuit, rng, ¶ms.srs) // } -// /// Check multiple proofs without aggregation. Verifier's work is +// /// Check multiple proofs without aggregation. Verifier's work is // /// not succint due to `S(X, Y)` evaluation // pub fn verify_proofs_on_srs, S: SynthesisDriver, R: Rng>( // proofs: &[Proof], @@ -723,7 +676,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier // Ok(verifier.check_all()) // } -// /// Check multiple proofs with aggregation. Verifier's work is +// /// Check multiple proofs with aggregation. Verifier's work is // /// not succint due to `S(X, Y)` evaluation // pub fn verify_aggregate, S: SynthesisDriver,R: Rng>( // proofs: &[(Proof, SxyAdvice)], @@ -736,7 +689,7 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier // verify_aggregate_on_srs::(proofs, aggregate, inputs, circuit, rng, ¶ms.srs) // } -// /// Check multiple proofs with aggregation. Verifier's work is +// /// Check multiple proofs with aggregation. Verifier's work is // /// not succint due to `S(X, Y)` evaluation // pub fn verify_aggregate_on_srs, S: SynthesisDriver, R: Rng>( // proofs: &[(Proof, SxyAdvice)], @@ -758,4 +711,3 @@ impl, S: SynthesisDriver, R: Rng> SuccinctMultiVerifier // Ok(verifier.check_all()) // } - diff --git a/crates/bellman/src/sonic/unhelped/wellformed_argument.rs b/crates/bellman/src/sonic/unhelped/wellformed_argument.rs index c91c867..bce0d0f 100644 --- a/crates/bellman/src/sonic/unhelped/wellformed_argument.rs +++ b/crates/bellman/src/sonic/unhelped/wellformed_argument.rs @@ -1,44 +1,36 @@ -/// Wellformedness argument allows to verify that some committment was to multivariate polynomial of degree n, +/// Wellformedness argument allows to verify that some committment was to multivariate polynomial of degree n, /// with no constant term and negative powers - use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use crate::pairing::{Engine, CurveProjective, CurveAffine}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; use std::marker::PhantomData; use crate::sonic::srs::SRS; -use crate::sonic::util::*; use crate::sonic::transcript::{Transcript, TranscriptProtocol}; +use crate::sonic::util::*; #[derive(Clone)] pub struct WellformednessArgument { - polynomials: Vec> + polynomials: Vec>, } #[derive(Clone)] pub struct WellformednessProof { pub l: E::G1Affine, - pub r: E::G1Affine + pub r: E::G1Affine, } #[derive(Clone)] pub struct WellformednessSignature { - pub proof: WellformednessProof + pub proof: WellformednessProof, } impl WellformednessArgument { - - pub fn create_signature( - all_polys: Vec>, - wellformed_challenges: Vec, - srs: &SRS - ) -> WellformednessSignature { + pub fn create_signature(all_polys: Vec>, wellformed_challenges: Vec, srs: &SRS) -> WellformednessSignature { let wellformed_argument = WellformednessArgument::new(all_polys); - + let proof = wellformed_argument.make_argument(wellformed_challenges, &srs); - WellformednessSignature { - proof - } + WellformednessSignature { proof } } pub fn new(polynomials: Vec>) -> Self { @@ -49,23 +41,17 @@ impl WellformednessArgument { assert!(p.len() == length); } - WellformednessArgument { - polynomials: polynomials - } + WellformednessArgument { polynomials: polynomials } } pub fn commit(&self, srs: &SRS) -> Vec { - let mut results = vec![]; let n = self.polynomials[0].len(); for p in self.polynomials.iter() { - let c = multiexp( - srs.g_positive_x_alpha[0..n].iter(), - p.iter() - ).into_affine(); - + let c = multiexp(srs.g_positive_x_alpha[0..n].iter(), p.iter()).into_affine(); + results.push(c); } @@ -87,7 +73,7 @@ impl WellformednessArgument { for _ in 0..m { let p = polynomials.pop().unwrap(); let r = challenges.pop().unwrap(); - mul_add_polynomials(&mut p0[..], & p[..], r); + mul_add_polynomials(&mut p0[..], &p[..], r); } let d = srs.d; @@ -98,22 +84,13 @@ impl WellformednessArgument { // here the multiplier is x^-d, so largest negative power is -(d - 1), smallest negative power is - (d - n) // H^{x^k} are labeled from 0 power, so we need to use proper indexes - let l = multiexp( - srs.g_negative_x[(d - n)..=(d - 1)].iter().rev(), - p0.iter() - ).into_affine(); + let l = multiexp(srs.g_negative_x[(d - n)..=(d - 1)].iter().rev(), p0.iter()).into_affine(); // here the multiplier is x^d-n, so largest positive power is d, smallest positive power is d - n + 1 - let r = multiexp( - srs.g_positive_x[(d - n + 1)..=d].iter(), - p0.iter() - ).into_affine(); + let r = multiexp(srs.g_positive_x[(d - n + 1)..=d].iter(), p0.iter()).into_affine(); - WellformednessProof { - l: l, - r: r - } + WellformednessProof { l: l, r: r } } pub fn verify(n: usize, challenges: &Vec, commitments: &Vec, proof: &WellformednessProof, srs: &SRS) -> bool { @@ -128,30 +105,21 @@ impl WellformednessArgument { h_prep.negate(); let h_prep = h_prep.prepare(); - let a = multiexp( - commitments.iter(), - challenges.iter(), - ).into_affine(); + let a = multiexp(commitments.iter(), challenges.iter()).into_affine(); let a = a.prepare(); - let valid = E::final_exponentiation(&E::miller_loop(&[ - (&a, &h_prep), - (&proof.l.prepare(), &alpha_x_d_precomp) - ])).unwrap() == E::Fqk::one(); + let valid = E::final_exponentiation(&E::miller_loop(&[(&a, &h_prep), (&proof.l.prepare(), &alpha_x_d_precomp)])).unwrap() == E::Fqk::one(); if !valid { return false; - } + } - let valid = E::final_exponentiation(&E::miller_loop(&[ - (&a, &h_prep), - (&proof.r.prepare(), &alpha_x_n_minus_d_precomp) - ])).unwrap() == E::Fqk::one(); + let valid = E::final_exponentiation(&E::miller_loop(&[(&a, &h_prep), (&proof.r.prepare(), &alpha_x_n_minus_d_precomp)])).unwrap() == E::Fqk::one(); if !valid { return false; - } + } true } @@ -159,9 +127,9 @@ impl WellformednessArgument { #[test] fn test_argument() { - use crate::pairing::bls12_381::{Fr, G1Affine, G1, Bls12}; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use crate::pairing::bls12_381::{Bls12, Fr, G1Affine, G1}; use crate::sonic::srs::SRS; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let srs_x = Fr::from_str("23923").unwrap(); let srs_alpha = Fr::from_str("23728792").unwrap(); @@ -179,16 +147,16 @@ fn test_argument() { let proof = argument.make_argument(challenges.clone(), &srs); - let valid = WellformednessArgument::verify(n, &challenges, &commitments, &proof, &srs); + let valid = WellformednessArgument::verify(n, &challenges, &commitments, &proof, &srs); assert!(valid); } #[test] fn test_argument_soundness() { - use crate::pairing::bls12_381::{Fr, G1Affine, G1, Bls12}; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; + use crate::pairing::bls12_381::{Bls12, Fr, G1Affine, G1}; use crate::sonic::srs::SRS; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; let srs_x = Fr::from_str("23923").unwrap(); let srs_alpha = Fr::from_str("23728792").unwrap(); @@ -207,7 +175,7 @@ fn test_argument_soundness() { let proof = argument.make_argument(challenges.clone(), &srs); - let valid = WellformednessArgument::verify(n, &challenges, &commitments, &proof, &srs); + let valid = WellformednessArgument::verify(n, &challenges, &commitments, &proof, &srs); assert!(!valid); -} \ No newline at end of file +} diff --git a/crates/bellman/src/sonic/util.rs b/crates/bellman/src/sonic/util.rs index 3518a14..226e8f2 100644 --- a/crates/bellman/src/sonic/util.rs +++ b/crates/bellman/src/sonic/util.rs @@ -1,7 +1,7 @@ -use crate::SynthesisError; +use super::srs::SRS; use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine}; use crate::pairing::{CurveAffine, CurveProjective, Engine}; -use super::srs::SRS; +use crate::SynthesisError; pub trait ChainExt: Iterator { fn chain_ext(self, other: U) -> Chain @@ -9,10 +9,7 @@ pub trait ChainExt: Iterator { Self: Sized, U: IntoIterator, { - Chain { - t: self, - u: other.into_iter(), - } + Chain { t: self, u: other.into_iter() } } } @@ -72,88 +69,58 @@ where } } -pub fn polynomial_commitment< - 'a, - E: Engine, - IS: IntoIterator, - >( - max: usize, - largest_negative_power: usize, - largest_positive_power: usize, - srs: &'a SRS, - s: IS, - ) -> E::G1Affine - where - IS::IntoIter: ExactSizeIterator, - { - // smallest power is d - max - largest_negative_power; It should either be 0 for use of positive powers only, - // of we should use part of the negative powers - let d = srs.d; - assert!(max >= largest_positive_power); - // use both positive and negative powers for commitment - if d < max + largest_negative_power + 1 { - let min_power = largest_negative_power + max - d; - let max_power = d + largest_positive_power - max; - // need to use negative powers to make a proper commitment - return multiexp( - srs.g_negative_x_alpha[0..min_power].iter().rev() - .chain_ext(srs.g_positive_x_alpha[..max_power].iter()), - s - ).into_affine(); - } else { - return multiexp( - srs.g_positive_x_alpha[(srs.d - max - largest_negative_power - 1)..].iter(), - s - ).into_affine(); - } +pub fn polynomial_commitment<'a, E: Engine, IS: IntoIterator>(max: usize, largest_negative_power: usize, largest_positive_power: usize, srs: &'a SRS, s: IS) -> E::G1Affine +where + IS::IntoIter: ExactSizeIterator, +{ + // smallest power is d - max - largest_negative_power; It should either be 0 for use of positive powers only, + // of we should use part of the negative powers + let d = srs.d; + assert!(max >= largest_positive_power); + // use both positive and negative powers for commitment + if d < max + largest_negative_power + 1 { + let min_power = largest_negative_power + max - d; + let max_power = d + largest_positive_power - max; + // need to use negative powers to make a proper commitment + return multiexp(srs.g_negative_x_alpha[0..min_power].iter().rev().chain_ext(srs.g_positive_x_alpha[..max_power].iter()), s).into_affine(); + } else { + return multiexp(srs.g_positive_x_alpha[(srs.d - max - largest_negative_power - 1)..].iter(), s).into_affine(); } - +} /// For now this function MUST take a polynomial in a form f(x) - f(z) -pub fn polynomial_commitment_opening< - 'a, - E: Engine, - I: IntoIterator - >( - largest_negative_power: usize, - _largest_positive_power: usize, - polynomial_coefficients: I, - point: E::Fr, - srs: &'a SRS, - ) -> E::G1Affine - where I::IntoIter: DoubleEndedIterator + ExactSizeIterator, - { - // let poly = parallel_kate_divison::(polynomial_coefficients, point); - - // use std::time::Instant; - // let start = Instant::now(); - - let poly = kate_divison( - polynomial_coefficients, - point, - ); - - // println!("Kate division of size {} taken {:?}", poly.len(), start.elapsed()); - - let negative_poly = poly[0..largest_negative_power].iter().rev(); - let positive_poly = poly[largest_negative_power..].iter(); - multiexp( - srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext( - srs.g_positive_x[0..positive_poly.len()].iter() - ), - negative_poly.chain_ext(positive_poly) - ).into_affine() - } +pub fn polynomial_commitment_opening<'a, E: Engine, I: IntoIterator>( + largest_negative_power: usize, + _largest_positive_power: usize, + polynomial_coefficients: I, + point: E::Fr, + srs: &'a SRS, +) -> E::G1Affine +where + I::IntoIter: DoubleEndedIterator + ExactSizeIterator, +{ + // let poly = parallel_kate_divison::(polynomial_coefficients, point); + + // use std::time::Instant; + // let start = Instant::now(); + + let poly = kate_divison(polynomial_coefficients, point); + + // println!("Kate division of size {} taken {:?}", poly.len(), start.elapsed()); + + let negative_poly = poly[0..largest_negative_power].iter().rev(); + let positive_poly = poly[largest_negative_power..].iter(); + multiexp( + srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(srs.g_positive_x[0..positive_poly.len()].iter()), + negative_poly.chain_ext(positive_poly), + ) + .into_affine() +} extern crate crossbeam; -use self::crossbeam::channel::{unbounded}; +use self::crossbeam::channel::unbounded; -pub fn evaluate_at_consequitive_powers<'a, F: Field> ( - coeffs: &[F], - first_power: F, - base: F -) -> F - { +pub fn evaluate_at_consequitive_powers<'a, F: Field>(coeffs: &[F], first_power: F, base: F) -> F { use crate::worker::Worker; let (s, r) = unbounded(); @@ -161,11 +128,10 @@ pub fn evaluate_at_consequitive_powers<'a, F: Field> ( let worker = Worker::new(); worker.scope(coeffs.len(), |scope, chunk| { - for (i, coeffs) in coeffs.chunks(chunk).enumerate() - { + for (i, coeffs) in coeffs.chunks(chunk).enumerate() { let s = s.clone(); scope.spawn(move |_| { - let mut current_power = base.pow(&[(i*chunk) as u64]); + let mut current_power = base.pow(&[(i * chunk) as u64]); current_power.mul_assign(&first_power); let mut acc = F::zero(); @@ -199,12 +165,7 @@ pub fn evaluate_at_consequitive_powers<'a, F: Field> ( result } -pub fn mut_evaluate_at_consequitive_powers<'a, F: Field> ( - coeffs: &mut [F], - first_power: F, - base: F -) -> F - { +pub fn mut_evaluate_at_consequitive_powers<'a, F: Field>(coeffs: &mut [F], first_power: F, base: F) -> F { use crate::worker::Worker; let (s, r) = unbounded(); @@ -212,11 +173,10 @@ pub fn mut_evaluate_at_consequitive_powers<'a, F: Field> ( let worker = Worker::new(); worker.scope(coeffs.len(), |scope, chunk| { - for (i, coeffs) in coeffs.chunks_mut(chunk).enumerate() - { + for (i, coeffs) in coeffs.chunks_mut(chunk).enumerate() { let s = s.clone(); scope.spawn(move |_| { - let mut current_power = base.pow(&[(i*chunk) as u64]); + let mut current_power = base.pow(&[(i * chunk) as u64]); current_power.mul_assign(&first_power); let mut acc = F::zero(); @@ -251,21 +211,15 @@ pub fn mut_evaluate_at_consequitive_powers<'a, F: Field> ( /// Multiply each coefficient by some power of the base in a form /// `first_power * base^{i}` -pub fn mut_distribute_consequitive_powers<'a, F: Field> ( - coeffs: &mut [F], - first_power: F, - base: F -) - { +pub fn mut_distribute_consequitive_powers<'a, F: Field>(coeffs: &mut [F], first_power: F, base: F) { use crate::worker::Worker; let worker = Worker::new(); worker.scope(coeffs.len(), |scope, chunk| { - for (i, coeffs_chunk) in coeffs.chunks_mut(chunk).enumerate() - { + for (i, coeffs_chunk) in coeffs.chunks_mut(chunk).enumerate() { scope.spawn(move |_| { - let mut current_power = base.pow(&[(i*chunk) as u64]); + let mut current_power = base.pow(&[(i * chunk) as u64]); current_power.mul_assign(&first_power); for p in coeffs_chunk { @@ -321,22 +275,14 @@ pub fn mut_distribute_consequitive_powers<'a, F: Field> ( // result // } -pub fn multiexp< - 'a, - G: CurveAffine, - IB: IntoIterator, - IS: IntoIterator, ->( - g: IB, - s: IS, -) -> G::Projective +pub fn multiexp<'a, G: CurveAffine, IB: IntoIterator, IS: IntoIterator>(g: IB, s: IS) -> G::Projective where IB::IntoIter: ExactSizeIterator + Clone, IS::IntoIter: ExactSizeIterator, { - use crate::worker::Worker; use crate::multiexp::multiexp; use crate::source::FullDensity; + use crate::worker::Worker; use futures::Future; use std::sync::Arc; @@ -350,30 +296,14 @@ where // use std::time::Instant; // let start = Instant::now(); - let result = multiexp( - &pool, - (Arc::new(g), 0), - FullDensity, - Arc::new(s) - ).wait().unwrap(); + let result = multiexp(&pool, (Arc::new(g), 0), FullDensity, Arc::new(s)).wait().unwrap(); // println!("Multiexp taken {:?}", start.elapsed()); result } - - - -pub fn multiexp_serial< - 'a, - G: CurveAffine, - IB: IntoIterator, - IS: IntoIterator, ->( - g: IB, - s: IS, -) -> G::Projective +pub fn multiexp_serial<'a, G: CurveAffine, IB: IntoIterator, IS: IntoIterator>(g: IB, s: IS) -> G::Projective where IB::IntoIter: ExactSizeIterator + Clone, IS::IntoIter: ExactSizeIterator, @@ -382,11 +312,7 @@ where let s = s.into_iter(); assert_eq!(g.len(), s.len()); - let c = if s.len() < 32 { - 3u32 - } else { - (f64::from(s.len() as u32)).ln().ceil() as u32 - }; + let c = if s.len() < 32 { 3u32 } else { (f64::from(s.len() as u32)).ln().ceil() as u32 }; // Convert all of the scalars into representations let mut s = s.map(|s| s.into_repr()).collect::>(); @@ -494,12 +420,7 @@ where q } -fn kate_divison_inner( - poly: Vec, - divisor: Vec, - reciproical: Vec, - remainder: E::Fr - ) -> (Vec, Vec) { +fn kate_divison_inner(poly: Vec, divisor: Vec, reciproical: Vec, remainder: E::Fr) -> (Vec, Vec) { if poly.len() == 1 { return (vec![], poly); } @@ -511,12 +432,12 @@ fn kate_divison_inner( if poly_degree > 2 { let mut rec_step = poly.clone(); mul_polynomial_by_scalar(&mut rec_step[..], remainder); - // truncate low order terms + // truncate low order terms rec_step.drain(0..2); let (q2, _) = kate_divison_inner::(rec_step, divisor.clone(), reciproical, remainder); // length of q2 is smaller add_polynomials(&mut q[..q2.len()], &q2[..]); - } + } // although r must be zero, calculate it for now if q.len() == 0 { @@ -532,14 +453,7 @@ fn kate_divison_inner( } /// Convenience function to check polynomail commitment -pub fn check_polynomial_commitment( - commitment: &E::G1Affine, - point: &E::Fr, - value: &E::Fr, - opening: &E::G1Affine, - max: usize, - srs: &SRS -) -> bool { +pub fn check_polynomial_commitment(commitment: &E::G1Affine, point: &E::Fr, value: &E::Fr, opening: &E::G1Affine, max: usize, srs: &SRS) -> bool { // e(W , hα x )e(g^{v} * W{-z} , hα ) = e(F , h^{x^{−d +max}} ) if srs.d < max { return false; @@ -559,17 +473,13 @@ pub fn check_polynomial_commitment( let gv = gv.into_affine().prepare(); - E::final_exponentiation(&E::miller_loop(&[ - (&w, &alpha_x_precomp), - (&gv, &alpha_precomp), - (&commitment.prepare(), &neg_x_n_minus_d_precomp), - ])).unwrap() == E::Fqk::one() + E::final_exponentiation(&E::miller_loop(&[(&w, &alpha_x_precomp), (&gv, &alpha_precomp), (&commitment.prepare(), &neg_x_n_minus_d_precomp)])).unwrap() == E::Fqk::one() } #[test] fn laurent_division() { + use crate::pairing::bls12_381::Fr; use crate::pairing::ff::PrimeField; - use crate::pairing::bls12_381::{Fr}; let mut poly = vec![ Fr::from_str("328947234").unwrap(), @@ -630,8 +540,8 @@ fn laurent_division() { pub fn multiply_polynomials(a: Vec, b: Vec) -> Vec { let result_len = a.len() + b.len() - 1; - use crate::worker::Worker; use crate::domain::{EvaluationDomain, Scalar}; + use crate::worker::Worker; let worker = Worker::new(); let scalars_a: Vec> = a.into_iter().map(|e| Scalar::(e)).collect(); @@ -655,12 +565,11 @@ pub fn multiply_polynomials(a: Vec, b: Vec) -> Vec(a: Vec, b: Vec) -> Vec { - use crate::worker::Worker; use crate::domain::{best_fft, Scalar}; use crate::group::Group; + use crate::worker::Worker; let result_len = a.len() + b.len() - 1; @@ -703,7 +612,6 @@ pub fn multiply_polynomials_fft(a: Vec, b: Vec) -> Vec< scalars_a.resize(m, Scalar::(E::Fr::zero())); scalars_b.resize(m, Scalar::(E::Fr::zero())); - best_fft(&mut scalars_a[..], &worker, &omega, exp); best_fft(&mut scalars_b[..], &worker, &omega, exp); @@ -777,10 +685,7 @@ pub fn multiply_polynomials_serial(mut a: Vec, mut b: Vec(mut a: Vec, mut b: Vec(a: &mut [F], b: &[F]) { - use crate::worker::Worker; - use crate::domain::{EvaluationDomain, Scalar}; + use crate::domain::{EvaluationDomain, Scalar}; + use crate::worker::Worker; - let worker = Worker::new(); + let worker = Worker::new(); - assert_eq!(a.len(), b.len()); + assert_eq!(a.len(), b.len()); - worker.scope(a.len(), |scope, chunk| { - for (a, b) in a.chunks_mut(chunk).zip(b.chunks(chunk)) - { - scope.spawn(move |_| { - for (a, b) in a.iter_mut().zip(b.iter()) { - a.add_assign(b); - } - }); - } - }); + worker.scope(a.len(), |scope, chunk| { + for (a, b) in a.chunks_mut(chunk).zip(b.chunks(chunk)) { + scope.spawn(move |_| { + for (a, b) in a.iter_mut().zip(b.iter()) { + a.add_assign(b); + } + }); + } + }); } // subtract polynomails in coefficient form pub fn sub_polynomials(a: &mut [F], b: &[F]) { - use crate::worker::Worker; use crate::domain::{EvaluationDomain, Scalar}; + use crate::worker::Worker; let worker = Worker::new(); assert_eq!(a.len(), b.len()); worker.scope(a.len(), |scope, chunk| { - for (a, b) in a.chunks_mut(chunk).zip(b.chunks(chunk)) - { + for (a, b) in a.chunks_mut(chunk).zip(b.chunks(chunk)) { scope.spawn(move |_| { for (a, b) in a.iter_mut().zip(b.iter()) { a.sub_assign(b); @@ -833,46 +736,44 @@ pub fn sub_polynomials(a: &mut [F], b: &[F]) { // multiply coefficients of the polynomial by the scalar pub fn mul_polynomial_by_scalar(a: &mut [F], b: F) { - use crate::worker::Worker; - use crate::domain::{EvaluationDomain, Scalar}; - - let worker = Worker::new(); - - worker.scope(a.len(), |scope, chunk| { - for a in a.chunks_mut(chunk) - { - scope.spawn(move |_| { - for a in a.iter_mut() { - a.mul_assign(&b); - } - }); - } - }); + use crate::domain::{EvaluationDomain, Scalar}; + use crate::worker::Worker; + + let worker = Worker::new(); + + worker.scope(a.len(), |scope, chunk| { + for a in a.chunks_mut(chunk) { + scope.spawn(move |_| { + for a in a.iter_mut() { + a.mul_assign(&b); + } + }); + } + }); } -// elementwise add coeffs of one polynomial with coeffs of other, that are -// first multiplied by a scalar +// elementwise add coeffs of one polynomial with coeffs of other, that are +// first multiplied by a scalar pub fn mul_add_polynomials(a: &mut [F], b: &[F], c: F) { - use crate::worker::Worker; - use crate::domain::{EvaluationDomain, Scalar}; + use crate::domain::{EvaluationDomain, Scalar}; + use crate::worker::Worker; - let worker = Worker::new(); + let worker = Worker::new(); - assert_eq!(a.len(), b.len()); + assert_eq!(a.len(), b.len()); - worker.scope(a.len(), |scope, chunk| { - for (a, b) in a.chunks_mut(chunk).zip(b.chunks(chunk)) - { - scope.spawn(move |_| { - for (a, b) in a.iter_mut().zip(b.iter()) { - let mut r = *b; - r.mul_assign(&c); + worker.scope(a.len(), |scope, chunk| { + for (a, b) in a.chunks_mut(chunk).zip(b.chunks(chunk)) { + scope.spawn(move |_| { + for (a, b) in a.iter_mut().zip(b.iter()) { + let mut r = *b; + r.mul_assign(&c); - a.add_assign(&r); - } - }); - } - }); + a.add_assign(&r); + } + }); + } + }); } fn serial_fft(a: &mut [E::Fr], omega: &E::Fr, log_n: u32) { @@ -934,9 +835,9 @@ impl OptionExt for Option { #[test] fn test_mul() { - use rand::{self, Rand}; use crate::pairing::bls12_381::Bls12; use crate::pairing::bls12_381::Fr; + use rand::{self, Rand}; const SAMPLES: usize = 100; @@ -953,9 +854,9 @@ fn test_mul() { #[test] fn test_eval_at_powers() { - use rand::{self, Rand, Rng}; use crate::pairing::bls12_381::Bls12; use crate::pairing::bls12_381::Fr; + use rand::{self, Rand, Rng}; const SAMPLES: usize = 100000; @@ -985,9 +886,9 @@ fn test_eval_at_powers() { #[test] fn test_mut_eval_at_powers() { - use rand::{self, Rand, Rng}; use crate::pairing::bls12_381::Bls12; use crate::pairing::bls12_381::Fr; + use rand::{self, Rand, Rng}; const SAMPLES: usize = 100000; @@ -1018,9 +919,9 @@ fn test_mut_eval_at_powers() { #[test] fn test_mut_distribute_powers() { - use rand::{self, Rand, Rng}; use crate::pairing::bls12_381::Bls12; use crate::pairing::bls12_381::Fr; + use rand::{self, Rand, Rng}; const SAMPLES: usize = 100000; @@ -1045,11 +946,10 @@ fn test_mut_distribute_powers() { assert!(a == b); } - #[test] fn test_trivial_parallel_kate_division() { - use crate::pairing::ff::PrimeField; use crate::pairing::bls12_381::{Bls12, Fr}; + use crate::pairing::ff::PrimeField; let mut minus_one = Fr::one(); minus_one.negate(); @@ -1057,11 +957,7 @@ fn test_trivial_parallel_kate_division() { let z = Fr::one(); // this is x^2 - 1 - let poly = vec![ - minus_one, - Fr::from_str("0").unwrap(), - Fr::from_str("1").unwrap(), - ]; + let poly = vec![minus_one, Fr::from_str("0").unwrap(), Fr::from_str("1").unwrap()]; let quotient_poly = kate_divison(&poly, z); @@ -1072,8 +968,8 @@ fn test_trivial_parallel_kate_division() { #[test] fn test_less_trivial_parallel_kate_division() { - use crate::pairing::ff::PrimeField; use crate::pairing::bls12_381::{Bls12, Fr}; + use crate::pairing::ff::PrimeField; let z = Fr::one(); @@ -1094,7 +990,7 @@ fn test_less_trivial_parallel_kate_division() { acc.add_assign(&t); tmp.mul_assign(&point); } - + acc } @@ -1110,11 +1006,10 @@ fn test_less_trivial_parallel_kate_division() { assert_eq!(quotient_poly, parallel_q_poly); } - #[test] fn test_parallel_kate_division() { - use crate::pairing::ff::PrimeField; use crate::pairing::bls12_381::{Bls12, Fr}; + use crate::pairing::ff::PrimeField; let mut poly = vec![ Fr::from_str("328947234").unwrap(), @@ -1158,4 +1053,4 @@ fn test_parallel_kate_division() { let parallel_q_poly = parallel_kate_divison::(&poly, z); assert_eq!(quotient_poly, parallel_q_poly); -} \ No newline at end of file +} diff --git a/crates/bellman/src/source.rs b/crates/bellman/src/source.rs index 57102b5..7ae7282 100644 --- a/crates/bellman/src/source.rs +++ b/crates/bellman/src/source.rs @@ -1,19 +1,11 @@ -use crate::pairing::{ - CurveAffine, - CurveProjective, - Engine -}; - -use crate::pairing::ff::{ - PrimeField, - Field, - PrimeFieldRepr, - ScalarEngine}; +use crate::pairing::{CurveAffine, CurveProjective, Engine}; + +use crate::pairing::ff::{Field, PrimeField, PrimeFieldRepr, ScalarEngine}; -use std::sync::Arc; -use std::io; use bit_vec::{self, BitVec}; +use std::io; use std::iter; +use std::sync::Arc; use super::SynthesisError; @@ -48,7 +40,7 @@ impl Source for (Arc>, usize) { } if self.0[self.1].is_zero() { - return Err(SynthesisError::UnexpectedIdentity) + return Err(SynthesisError::UnexpectedIdentity); } to.add_assign_mixed(&self.0[self.1]); @@ -71,7 +63,7 @@ impl Source for (Arc>, usize) { pub trait QueryDensity { /// Returns whether the base exists. - type Iter: Iterator; + type Iter: Iterator; fn iter(self) -> Self::Iter; fn get_query_size(self) -> Option; @@ -101,7 +93,7 @@ impl<'a> QueryDensity for &'a FullDensity { #[derive(Clone)] pub struct DensityTracker { pub(crate) bv: BitVec, - total_density: usize + total_density: usize, } impl<'a> QueryDensity for &'a DensityTracker { @@ -118,10 +110,7 @@ impl<'a> QueryDensity for &'a DensityTracker { impl DensityTracker { pub fn new() -> DensityTracker { - DensityTracker { - bv: BitVec::new(), - total_density: 0 - } + DensityTracker { bv: BitVec::new(), total_density: 0 } } pub fn add_element(&mut self) { @@ -150,18 +139,14 @@ impl DensityTracker { pub struct DensityTrackerersChain { pub(crate) tracker_0: DensityTracker, pub(crate) tracker_1: DensityTracker, - total_density: usize + total_density: usize, } impl DensityTrackerersChain { pub fn new(tracker_0: DensityTracker, tracker_1: DensityTracker) -> Self { let total_density = tracker_0.total_density + tracker_1.total_density; - Self { - tracker_0, - tracker_1, - total_density - } + Self { tracker_0, tracker_1, total_density } } } @@ -175,4 +160,4 @@ impl<'a> QueryDensity for &'a DensityTrackerersChain { fn get_query_size(self) -> Option { Some(self.tracker_0.bv.len() + self.tracker_1.bv.len()) } -} \ No newline at end of file +} diff --git a/crates/bellman/src/tests/dummy_engine.rs b/crates/bellman/src/tests/dummy_engine.rs index 8689885..fdc9796 100644 --- a/crates/bellman/src/tests/dummy_engine.rs +++ b/crates/bellman/src/tests/dummy_engine.rs @@ -1,25 +1,10 @@ -use crate::pairing::{ - Engine, - CurveProjective, - CurveAffine, - GroupDecodingError, - RawEncodable, - EncodedPoint -}; - -use crate::pairing::ff::{ - PrimeField, - PrimeFieldRepr, - Field, - SqrtField, - LegendreSymbol, - ScalarEngine, - PrimeFieldDecodingError, -}; +use crate::pairing::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError, RawEncodable}; +use crate::pairing::ff::{Field, LegendreSymbol, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, ScalarEngine, SqrtField}; + +use rand::{Rand, Rng}; use std::cmp::Ordering; use std::fmt; -use rand::{Rand, Rng}; use std::num::Wrapping; const MODULUS_R: Wrapping = Wrapping(64513); @@ -96,10 +81,7 @@ impl RawEncodable for Fr { Self::Uncompressed::empty() } - fn from_raw_uncompressed_le_unchecked( - _encoded: &Self::Uncompressed, - _infinity: bool - ) -> Result { + fn from_raw_uncompressed_le_unchecked(_encoded: &Self::Uncompressed, _infinity: bool) -> Result { Ok(::zero()) } @@ -112,9 +94,13 @@ impl SqrtField for Fr { fn legendre(&self) -> LegendreSymbol { // s = self^((r - 1) // 2) let s = self.pow([32256]); - if s == ::zero() { LegendreSymbol::Zero } - else if s == ::one() { LegendreSymbol::QuadraticResidue } - else { LegendreSymbol::QuadraticNonResidue } + if s == ::zero() { + LegendreSymbol::Zero + } else if s == ::one() { + LegendreSymbol::QuadraticResidue + } else { + LegendreSymbol::QuadraticNonResidue + } } fn sqrt(&self) -> Option { @@ -132,7 +118,7 @@ impl SqrtField for Fr { let mut m = Fr::S; while t != ::one() { - let mut i = 1; + let mut i = 1; { let mut t2i = t; t2i.square(); @@ -314,15 +300,13 @@ impl Engine for DummyEngine { type G2Affine = Fr; type Fq = Fr; type Fqe = Fr; - + // TODO: This should be F_645131 or something. Doesn't matter for now. type Fqk = Fr; fn miller_loop<'a, I>(i: I) -> Self::Fqk - where I: IntoIterator::Prepared, - &'a ::Prepared - )> + where + I: IntoIterator::Prepared, &'a ::Prepared)>, { let mut acc = ::zero(); @@ -336,8 +320,7 @@ impl Engine for DummyEngine { } /// Perform final exponentiation of the result of a miller loop. - fn final_exponentiation(this: &Self::Fqk) -> Option - { + fn final_exponentiation(this: &Self::Fqk) -> Option { Some(*this) } } @@ -360,9 +343,7 @@ impl CurveProjective for Fr { ::is_zero(self) } - fn batch_normalization(_: &mut [Self]) { - - } + fn batch_normalization(_: &mut [Self]) {} fn is_normalized(&self) -> bool { true @@ -384,8 +365,7 @@ impl CurveProjective for Fr { ::negate(self); } - fn mul_assign::Repr>>(&mut self, other: S) - { + fn mul_assign::Repr>>(&mut self, other: S) { let tmp = Fr::from_repr(other.into()).unwrap(); ::mul_assign(self, &tmp); @@ -470,8 +450,7 @@ impl CurveAffine for Fr { ::negate(self); } - fn mul::Repr>>(&self, other: S) -> Self::Projective - { + fn mul::Repr>>(&self, other: S) -> Self::Projective { let mut res = *self; let tmp = Fr::from_repr(other.into()).unwrap(); @@ -508,11 +487,11 @@ impl CurveAffine for Fr { Ok(::zero()) } - fn a_coeff() -> ::Base { + fn a_coeff() -> ::Base { ::zero() } - fn b_coeff() -> ::Base { + fn b_coeff() -> ::Base { ::zero() } } diff --git a/crates/bellman/src/tests/mod.rs b/crates/bellman/src/tests/mod.rs index bf99048..248cfd5 100644 --- a/crates/bellman/src/tests/mod.rs +++ b/crates/bellman/src/tests/mod.rs @@ -1,92 +1,73 @@ -use crate::pairing::{ - Engine -}; +use crate::pairing::Engine; -use crate::pairing::ff:: { - Field, - PrimeField, -}; +use crate::pairing::ff::{Field, PrimeField}; pub mod dummy_engine; use self::dummy_engine::*; use std::marker::PhantomData; -use crate::{ - Circuit, - ConstraintSystem, - SynthesisError -}; +use crate::{Circuit, ConstraintSystem, SynthesisError}; #[derive(Clone)] pub(crate) struct XORDemo { pub(crate) a: Option, pub(crate) b: Option, - pub(crate) _marker: PhantomData + pub(crate) _marker: PhantomData, } impl Circuit for XORDemo { - fn synthesize>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError> - { - let a_var = cs.alloc(|| "a", || { - if self.a.is_some() { - if self.a.unwrap() { - Ok(E::Fr::one()) + fn synthesize>(self, cs: &mut CS) -> Result<(), SynthesisError> { + let a_var = cs.alloc( + || "a", + || { + if self.a.is_some() { + if self.a.unwrap() { + Ok(E::Fr::one()) + } else { + Ok(E::Fr::zero()) + } } else { - Ok(E::Fr::zero()) + Err(SynthesisError::AssignmentMissing) } - } else { - Err(SynthesisError::AssignmentMissing) - } - })?; - - cs.enforce( - || "a_boolean_constraint", - |lc| lc + CS::one() - a_var, - |lc| lc + a_var, - |lc| lc - ); - - let b_var = cs.alloc(|| "b", || { - if self.b.is_some() { - if self.b.unwrap() { - Ok(E::Fr::one()) + }, + )?; + + cs.enforce(|| "a_boolean_constraint", |lc| lc + CS::one() - a_var, |lc| lc + a_var, |lc| lc); + + let b_var = cs.alloc( + || "b", + || { + if self.b.is_some() { + if self.b.unwrap() { + Ok(E::Fr::one()) + } else { + Ok(E::Fr::zero()) + } } else { - Ok(E::Fr::zero()) + Err(SynthesisError::AssignmentMissing) } - } else { - Err(SynthesisError::AssignmentMissing) - } - })?; - - cs.enforce( - || "b_boolean_constraint", - |lc| lc + CS::one() - b_var, - |lc| lc + b_var, - |lc| lc - ); - - let c_var = cs.alloc_input(|| "c", || { - if self.a.is_some() && self.b.is_some() { - if self.a.unwrap() ^ self.b.unwrap() { - Ok(E::Fr::one()) + }, + )?; + + cs.enforce(|| "b_boolean_constraint", |lc| lc + CS::one() - b_var, |lc| lc + b_var, |lc| lc); + + let c_var = cs.alloc_input( + || "c", + || { + if self.a.is_some() && self.b.is_some() { + if self.a.unwrap() ^ self.b.unwrap() { + Ok(E::Fr::one()) + } else { + Ok(E::Fr::zero()) + } } else { - Ok(E::Fr::zero()) + Err(SynthesisError::AssignmentMissing) } - } else { - Err(SynthesisError::AssignmentMissing) - } - })?; - - cs.enforce( - || "c_xor_constraint", - |lc| lc + a_var + a_var, - |lc| lc + b_var, - |lc| lc + a_var + b_var - c_var - ); + }, + )?; + + cs.enforce(|| "c_xor_constraint", |lc| lc + a_var + a_var, |lc| lc + b_var, |lc| lc + a_var + b_var - c_var); Ok(()) } @@ -99,55 +80,45 @@ pub(crate) struct TranspilationTester { } impl Circuit for TranspilationTester { - fn synthesize>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError> - { - let a_var = cs.alloc(|| "a", || { - if let Some(a_value) = self.a { - Ok(a_value) - } else { - Err(SynthesisError::AssignmentMissing) - } - })?; - - cs.enforce( - || "a is zero", - |lc| lc + a_var, - |lc| lc + CS::one(), - |lc| lc - ); - - let b_var = cs.alloc(|| "b", || { - if let Some(b_value) = self.b { - Ok(b_value) - } else { - Err(SynthesisError::AssignmentMissing) - } - })?; - - cs.enforce( - || "b is one", - |lc| lc + b_var, - |lc| lc + CS::one(), - |lc| lc + CS::one() - ); - - let c_var = cs.alloc_input(|| "c", || { - if let Some(a_value) = self.a { - Ok(a_value) - } else { - Err(SynthesisError::AssignmentMissing) - } - })?; - - cs.enforce( - || "a is equal to c", - |lc| lc + a_var, - |lc| lc + CS::one(), - |lc| lc + c_var - ); + fn synthesize>(self, cs: &mut CS) -> Result<(), SynthesisError> { + let a_var = cs.alloc( + || "a", + || { + if let Some(a_value) = self.a { + Ok(a_value) + } else { + Err(SynthesisError::AssignmentMissing) + } + }, + )?; + + cs.enforce(|| "a is zero", |lc| lc + a_var, |lc| lc + CS::one(), |lc| lc); + + let b_var = cs.alloc( + || "b", + || { + if let Some(b_value) = self.b { + Ok(b_value) + } else { + Err(SynthesisError::AssignmentMissing) + } + }, + )?; + + cs.enforce(|| "b is one", |lc| lc + b_var, |lc| lc + CS::one(), |lc| lc + CS::one()); + + let c_var = cs.alloc_input( + || "c", + || { + if let Some(a_value) = self.a { + Ok(a_value) + } else { + Err(SynthesisError::AssignmentMissing) + } + }, + )?; + + cs.enforce(|| "a is equal to c", |lc| lc + a_var, |lc| lc + CS::one(), |lc| lc + c_var); Ok(()) } @@ -162,7 +133,7 @@ fn transpile_xor() { let c = XORDemo:: { a: None, b: None, - _marker: PhantomData + _marker: PhantomData, }; let mut transpiler = Transpiler::new(); @@ -199,4 +170,3 @@ fn transpile_test_circuit() { println!("Checking if is satisfied"); assert!(prover.is_satisfied()); } - diff --git a/crates/bellman/tests/mimc.rs b/crates/bellman/tests/mimc.rs index 4936adb..c1f28b6 100644 --- a/crates/bellman/tests/mimc.rs +++ b/crates/bellman/tests/mimc.rs @@ -5,49 +5,30 @@ use rand::{thread_rng, Rng}; use std::time::{Duration, Instant}; // Bring in some tools for using pairing-friendly curves -use bellman_ce::pairing::{ - Engine -}; +use bellman_ce::pairing::Engine; -use bellman_ce::pairing::ff::{ - Field, -}; +use bellman_ce::pairing::ff::Field; // We're going to use the BLS12-381 pairing-friendly elliptic curve. -use bellman_ce::pairing::bls12_381::{ - Bls12 -}; +use bellman_ce::pairing::bls12_381::Bls12; -use bellman_ce::pairing::bn256::{ - Bn256 -}; +use bellman_ce::pairing::bn256::Bn256; // We'll use these interfaces to construct our circuit. -use bellman_ce::{ - Circuit, - ConstraintSystem, - SynthesisError -}; +use bellman_ce::{Circuit, ConstraintSystem, SynthesisError}; // We're going to use the Groth16 proving system. -use bellman_ce::groth16::{ - Proof, - generate_random_parameters, - prepare_verifying_key, - create_random_proof, - verify_proof, -}; +use bellman_ce::groth16::{create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, Proof}; // const MIMC_ROUNDS: usize = 322; const MIMC_ROUNDS: usize = 1000000; - #[cfg(feature = "marlin")] #[test] fn test_bench_marlin_prover() { - use bellman_ce::pairing::bn256::{Bn256}; use bellman_ce::marlin::prover::test_over_engine_and_circuit_with_proving_key; + use bellman_ce::pairing::bn256::Bn256; { // This may not be cryptographically safe, use // `OsRng` (for example) in production software. @@ -64,7 +45,7 @@ fn test_bench_marlin_prover() { let circuit = MiMCDemo { xl: Some(xl), xr: Some(xr), - constants: &constants + constants: &constants, }; test_over_engine_and_circuit_with_proving_key::(circuit, format!("./marlin_mimc_{}", MIMC_ROUNDS)); @@ -74,8 +55,8 @@ fn test_bench_marlin_prover() { #[cfg(feature = "marlin")] #[test] fn test_create_marlin_proving_key() { - use bellman_ce::pairing::bn256::{Bn256}; use bellman_ce::marlin::prover::create_test_keys; + use bellman_ce::pairing::bn256::Bn256; { // This may not be cryptographically safe, use // `OsRng` (for example) in production software. @@ -92,7 +73,7 @@ fn test_create_marlin_proving_key() { let circuit = MiMCDemo { xl: Some(xl), xr: Some(xr), - constants: &constants + constants: &constants, }; create_test_keys::(circuit, format!("./marlin_mimc_{}", MIMC_ROUNDS)); @@ -101,7 +82,7 @@ fn test_create_marlin_proving_key() { /// This is an implementation of MiMC, specifically a /// variant named `LongsightF322p3` for BLS12-381. -/// See http://eprint.iacr.org/2016/492 for more +/// See http://eprint.iacr.org/2016/492 for more /// information about this construction. /// /// ``` @@ -112,12 +93,7 @@ fn test_create_marlin_proving_key() { /// return xL /// } /// ``` -fn mimc( - mut xl: E::Fr, - mut xr: E::Fr, - constants: &[E::Fr] -) -> E::Fr -{ +fn mimc(mut xl: E::Fr, mut xr: E::Fr, constants: &[E::Fr]) -> E::Fr { assert_eq!(constants.len(), MIMC_ROUNDS); for i in 0..MIMC_ROUNDS { @@ -140,31 +116,23 @@ fn mimc( struct MiMCDemo<'a, E: Engine> { xl: Option, xr: Option, - constants: &'a [E::Fr] + constants: &'a [E::Fr], } /// Our demo circuit implements this `Circuit` trait which /// is used during paramgen and proving in order to /// synthesize the constraint system. impl<'a, E: Engine> Circuit for MiMCDemo<'a, E> { - fn synthesize>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError> - { + fn synthesize>(self, cs: &mut CS) -> Result<(), SynthesisError> { assert_eq!(self.constants.len(), MIMC_ROUNDS); // Allocate the first component of the preimage. let mut xl_value = self.xl; - let mut xl = cs.alloc(|| "preimage xl", || { - xl_value.ok_or(SynthesisError::AssignmentMissing) - })?; + let mut xl = cs.alloc(|| "preimage xl", || xl_value.ok_or(SynthesisError::AssignmentMissing))?; // Allocate the second component of the preimage. let mut xr_value = self.xr; - let mut xr = cs.alloc(|| "preimage xr", || { - xr_value.ok_or(SynthesisError::AssignmentMissing) - })?; + let mut xr = cs.alloc(|| "preimage xr", || xr_value.ok_or(SynthesisError::AssignmentMissing))?; for i in 0..MIMC_ROUNDS { // xL, xR := xR + (xL + Ci)^3, xL @@ -176,15 +144,13 @@ impl<'a, E: Engine> Circuit for MiMCDemo<'a, E> { e.square(); e }); - let tmp = cs.alloc(|| "tmp", || { - tmp_value.ok_or(SynthesisError::AssignmentMissing) - })?; + let tmp = cs.alloc(|| "tmp", || tmp_value.ok_or(SynthesisError::AssignmentMissing))?; cs.enforce( || "tmp = (xL + Ci)^2", |lc| lc + xl + (self.constants[i], CS::one()), |lc| lc + xl + (self.constants[i], CS::one()), - |lc| lc + tmp + |lc| lc + tmp, ); // new_xL = xR + (xL + Ci)^3 @@ -197,24 +163,15 @@ impl<'a, E: Engine> Circuit for MiMCDemo<'a, E> { e }); - let new_xl = if i == (MIMC_ROUNDS-1) { + let new_xl = if i == (MIMC_ROUNDS - 1) { // This is the last round, xL is our image and so // we allocate a public input. - cs.alloc_input(|| "image", || { - new_xl_value.ok_or(SynthesisError::AssignmentMissing) - })? + cs.alloc_input(|| "image", || new_xl_value.ok_or(SynthesisError::AssignmentMissing))? } else { - cs.alloc(|| "new_xl", || { - new_xl_value.ok_or(SynthesisError::AssignmentMissing) - })? + cs.alloc(|| "new_xl", || new_xl_value.ok_or(SynthesisError::AssignmentMissing))? }; - cs.enforce( - || "new_xL = xR + (xL + Ci)^3", - |lc| lc + tmp, - |lc| lc + xl + (self.constants[i], CS::one()), - |lc| lc + new_xl - xr - ); + cs.enforce(|| "new_xL = xR + (xL + Ci)^3", |lc| lc + tmp, |lc| lc + xl + (self.constants[i], CS::one()), |lc| lc + new_xl - xr); // xR = xL xr = xl; @@ -245,7 +202,7 @@ fn test_mimc_bls12() { let c = MiMCDemo:: { xl: None, xr: None, - constants: &constants + constants: &constants, }; generate_random_parameters(c, rng).unwrap() @@ -280,7 +237,7 @@ fn test_mimc_bls12() { let c = MiMCDemo { xl: Some(xl), xr: Some(xr), - constants: &constants + constants: &constants, }; // Create a groth16 proof with our parameters. @@ -294,20 +251,14 @@ fn test_mimc_bls12() { let start = Instant::now(); let proof = Proof::read(&proof_vec[..]).unwrap(); // Check the proof - assert!(verify_proof( - &pvk, - &proof, - &[image] - ).unwrap()); + assert!(verify_proof(&pvk, &proof, &[image]).unwrap()); total_verifying += start.elapsed(); } let proving_avg = total_proving / SAMPLES; - let proving_avg = proving_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (proving_avg.as_secs() as f64); + let proving_avg = proving_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (proving_avg.as_secs() as f64); let verifying_avg = total_verifying / SAMPLES; - let verifying_avg = verifying_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (verifying_avg.as_secs() as f64); + let verifying_avg = verifying_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (verifying_avg.as_secs() as f64); println!("Average proving time: {:?} seconds", proving_avg); println!("Average verifying time: {:?} seconds", verifying_avg); @@ -329,7 +280,7 @@ fn test_mimc_bn256() { let c = MiMCDemo:: { xl: None, xr: None, - constants: &constants + constants: &constants, }; generate_random_parameters(c, rng).unwrap() @@ -365,7 +316,7 @@ fn test_mimc_bn256() { let c = MiMCDemo { xl: Some(xl), xr: Some(xr), - constants: &constants + constants: &constants, }; // Create a groth16 proof with our parameters. @@ -379,26 +330,19 @@ fn test_mimc_bn256() { let start = Instant::now(); let proof = Proof::read(&proof_vec[..]).unwrap(); // Check the proof - assert!(verify_proof( - &pvk, - &proof, - &[image] - ).unwrap()); + assert!(verify_proof(&pvk, &proof, &[image]).unwrap()); total_verifying += start.elapsed(); } let proving_avg = total_proving / SAMPLES; - let proving_avg = proving_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (proving_avg.as_secs() as f64); + let proving_avg = proving_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (proving_avg.as_secs() as f64); let verifying_avg = total_verifying / SAMPLES; - let verifying_avg = verifying_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (verifying_avg.as_secs() as f64); + let verifying_avg = verifying_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (verifying_avg.as_secs() as f64); println!("Average proving time: {:?} seconds", proving_avg); println!("Average verifying time: {:?} seconds", verifying_avg); } - #[cfg(feature = "plonk")] #[test] fn test_mimc_transpilation_into_plonk() { @@ -413,7 +357,7 @@ fn test_mimc_transpilation_into_plonk() { let c = MiMCDemo:: { xl: None, xr: None, - constants: &constants + constants: &constants, }; let mut transpiler = Transpiler::new(); diff --git a/crates/blake2s_const/src/avx2.rs b/crates/blake2s_const/src/avx2.rs index 9613522..c5b3a3c 100644 --- a/crates/blake2s_const/src/avx2.rs +++ b/crates/blake2s_const/src/avx2.rs @@ -3,10 +3,7 @@ use core::arch::x86::*; #[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; -use crate::guts::{ - assemble_count, count_high, count_low, final_block, flag_word, input_debug_asserts, Finalize, - Job, Stride, -}; +use crate::guts::{assemble_count, count_high, count_low, final_block, flag_word, input_debug_asserts, Finalize, Job, Stride}; use crate::{Word, BLOCKBYTES, IV, SIGMA}; use core::cmp; use core::mem; @@ -58,19 +55,14 @@ unsafe fn set1(x: u32) -> __m256i { #[inline(always)] unsafe fn set8(a: u32, b: u32, c: u32, d: u32, e: u32, f: u32, g: u32, h: u32) -> __m256i { - _mm256_setr_epi32( - a as i32, b as i32, c as i32, d as i32, e as i32, f as i32, g as i32, h as i32, - ) + _mm256_setr_epi32(a as i32, b as i32, c as i32, d as i32, e as i32, f as i32, g as i32, h as i32) } #[inline(always)] unsafe fn rot16(x: __m256i) -> __m256i { _mm256_shuffle_epi8( x, - _mm256_set_epi8( - 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2, 13, 12, 15, 14, 9, 8, 11, 10, 5, - 4, 7, 6, 1, 0, 3, 2, - ), + _mm256_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2, 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2), ) } @@ -83,10 +75,7 @@ unsafe fn rot12(x: __m256i) -> __m256i { unsafe fn rot8(x: __m256i) -> __m256i { _mm256_shuffle_epi8( x, - _mm256_set_epi8( - 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1, 12, 15, 14, 13, 8, 11, 10, 9, 4, - 7, 6, 5, 0, 3, 2, 1, - ), + _mm256_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1, 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1), ) } @@ -275,10 +264,7 @@ macro_rules! compress8_transposed { #[inline(always)] unsafe fn interleave128(a: __m256i, b: __m256i) -> (__m256i, __m256i) { - ( - _mm256_permute2x128_si256(a, b, 0x20), - _mm256_permute2x128_si256(a, b, 0x31), - ) + (_mm256_permute2x128_si256(a, b, 0x20), _mm256_permute2x128_si256(a, b, 0x31)) } // There are several ways to do a transposition. We could do it naively, with 8 separate @@ -288,16 +274,7 @@ unsafe fn interleave128(a: __m256i, b: __m256i) -> (__m256i, __m256i) { // fastest approach. To test this, run `cargo +nightly bench --bench libtest load_8` in the // https://github.com/oconnor663/bao_experiments repo. #[inline(always)] -unsafe fn transpose_vecs( - vec_a: __m256i, - vec_b: __m256i, - vec_c: __m256i, - vec_d: __m256i, - vec_e: __m256i, - vec_f: __m256i, - vec_g: __m256i, - vec_h: __m256i, -) -> [__m256i; 8] { +unsafe fn transpose_vecs(vec_a: __m256i, vec_b: __m256i, vec_c: __m256i, vec_d: __m256i, vec_e: __m256i, vec_f: __m256i, vec_g: __m256i, vec_h: __m256i) -> [__m256i; 8] { // Interleave 32-bit lanes. The low unpack is lanes 00/11/44/55, and the high is 22/33/66/77. let ab_0145 = _mm256_unpacklo_epi32(vec_a, vec_b); let ab_2367 = _mm256_unpackhi_epi32(vec_a, vec_b); @@ -324,10 +301,7 @@ unsafe fn transpose_vecs( let (abcdefgh_2, abcdefgh_6) = interleave128(abcd_26, efgh_26); let (abcdefgh_3, abcdefgh_7) = interleave128(abcd_37, efgh_37); - [ - abcdefgh_0, abcdefgh_1, abcdefgh_2, abcdefgh_3, abcdefgh_4, abcdefgh_5, abcdefgh_6, - abcdefgh_7, - ] + [abcdefgh_0, abcdefgh_1, abcdefgh_2, abcdefgh_3, abcdefgh_4, abcdefgh_5, abcdefgh_6, abcdefgh_7] } #[inline(always)] @@ -350,9 +324,7 @@ unsafe fn transpose_state_vecs(jobs: &[Job; DEGREE]) -> [__m256i; 8] { #[inline(always)] unsafe fn untranspose_state_vecs(h_vecs: &[__m256i; 8], jobs: &mut [Job; DEGREE]) { // Un-transpose the updated state vectors back into the caller's arrays. - let out = transpose_vecs( - h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7], - ); + let out = transpose_vecs(h_vecs[0], h_vecs[1], h_vecs[2], h_vecs[3], h_vecs[4], h_vecs[5], h_vecs[6], h_vecs[7]); storeu(out[0], jobs[0].words); storeu(out[1], jobs[1].words); storeu(out[2], jobs[2].words); @@ -395,9 +367,7 @@ unsafe fn transpose_msg_vecs(blocks: [*const [u8; BLOCKBYTES]; DEGREE]) -> [__m2 loadu(block6.add(1)), loadu(block7.add(1)), ); - [ - m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, - ] + [m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15] } #[inline(always)] @@ -503,25 +473,12 @@ pub unsafe fn compress8_loop(jobs: &mut [Job; DEGREE], finalize: Finalize, strid let (block5, len5, finalize5) = final_block(jobs[5].input, fin_offset, &mut buf5, stride); let (block6, len6, finalize6) = final_block(jobs[6].input, fin_offset, &mut buf6, stride); let (block7, len7, finalize7) = final_block(jobs[7].input, fin_offset, &mut buf7, stride); - let fin_blocks: [*const [u8; BLOCKBYTES]; DEGREE] = [ - block0, block1, block2, block3, block4, block5, block6, block7, - ]; - let fin_counts_delta = set8( - len0 as Word, - len1 as Word, - len2 as Word, - len3 as Word, - len4 as Word, - len5 as Word, - len6 as Word, - len7 as Word, - ); + let fin_blocks: [*const [u8; BLOCKBYTES]; DEGREE] = [block0, block1, block2, block3, block4, block5, block6, block7]; + let fin_counts_delta = set8(len0 as Word, len1 as Word, len2 as Word, len3 as Word, len4 as Word, len5 as Word, len6 as Word, len7 as Word); let fin_last_block; let fin_last_node; if finalize.yes() { - fin_last_block = flags_vec([ - finalize0, finalize1, finalize2, finalize3, finalize4, finalize5, finalize6, finalize7, - ]); + fin_last_block = flags_vec([finalize0, finalize1, finalize2, finalize3, finalize4, finalize5, finalize6, finalize7]); fin_last_node = flags_vec([ finalize0 && jobs[0].last_node.yes(), finalize1 && jobs[1].last_node.yes(), @@ -567,14 +524,7 @@ pub unsafe fn compress8_loop(jobs: &mut [Job; DEGREE], finalize: Finalize, strid let m_vecs = transpose_msg_vecs(blocks); add_to_counts(&mut counts_lo, &mut counts_hi, counts_delta); - compress8_transposed!( - &mut h_vecs, - &m_vecs, - counts_lo, - counts_hi, - last_block, - last_node, - ); + compress8_transposed!(&mut h_vecs, &m_vecs, counts_lo, counts_hi, last_block, last_node,); // Check for termination before bumping the offset, to avoid overflow. if offset == fin_offset { diff --git a/crates/blake2s_const/src/blake2sp.rs b/crates/blake2s_const/src/blake2sp.rs index b00a868..e7bfae6 100644 --- a/crates/blake2s_const/src/blake2sp.rs +++ b/crates/blake2s_const/src/blake2sp.rs @@ -105,16 +105,7 @@ impl Params { // because it isn't included in the state words. .to_words() }; - let leaf_words = [ - leaf_words(0), - leaf_words(1), - leaf_words(2), - leaf_words(3), - leaf_words(4), - leaf_words(5), - leaf_words(6), - leaf_words(7), - ]; + let leaf_words = [leaf_words(0), leaf_words(1), leaf_words(2), leaf_words(3), leaf_words(4), leaf_words(5), leaf_words(6), leaf_words(7)]; let root_words = base_params .clone() .node_offset(0) @@ -141,21 +132,12 @@ impl Params { input: &input[input_start..], words, count: 0, - last_node: if i == DEGREE - 1 { - LastNode::Yes - } else { - LastNode::No - }, + last_node: if i == DEGREE - 1 { LastNode::Yes } else { LastNode::No }, } }); many::compress_many(jobs, self.implementation, Finalize::Yes, Stride::Parallel); // Hash each leaf into the root. - finalize_root_words( - &leaf_words, - &mut root_words, - self.hash_length, - self.implementation, - ) + finalize_root_words(&leaf_words, &mut root_words, self.hash_length, self.implementation) } /// Construct a BLAKE2sp `State` object based on these parameters. @@ -167,11 +149,7 @@ impl Params { /// length of the final `Hash`, this is also associated data, and changing it will result in a /// totally different hash. pub fn hash_length(&mut self, length: usize) -> &mut Self { - assert!( - 1 <= length && length <= OUTBYTES, - "Bad hash length: {}", - length - ); + assert!(1 <= length && length <= OUTBYTES, "Bad hash length: {}", length); self.hash_length = length as u8; self } @@ -283,12 +261,7 @@ impl State { *input = &input[take..]; } - fn compress_to_leaves( - leaves: &mut [[Word; 8]; DEGREE], - input: &[u8], - count: &mut Count, - implementation: Implementation, - ) { + fn compress_to_leaves(leaves: &mut [[Word; 8]; DEGREE], input: &[u8], count: &mut Count, implementation: Implementation) { // Input is assumed to be an even number of blocks for each leaf. Since // we're not finilizing, debug asserts will fire otherwise. let jobs = leaves.iter_mut().enumerate().map(|(i, words)| { @@ -321,21 +294,11 @@ impl State { if !input.is_empty() { if input.len() > (DEGREE - 1) * BLOCKBYTES { // Enough input coming to do both compressions. - Self::compress_to_leaves( - &mut self.leaf_words, - &self.buf, - &mut self.count, - self.implementation, - ); + Self::compress_to_leaves(&mut self.leaf_words, &self.buf, &mut self.count, self.implementation); self.buf_len = 0; } else { // Only enough input coming for one compression. - Self::compress_to_leaves( - &mut self.leaf_words, - &self.buf[..DEGREE * BLOCKBYTES], - &mut self.count, - self.implementation, - ); + Self::compress_to_leaves(&mut self.leaf_words, &self.buf[..DEGREE * BLOCKBYTES], &mut self.count, self.implementation); self.buf_len = (DEGREE * BLOCKBYTES) as u16; let (buf_front, buf_back) = self.buf.split_at_mut(DEGREE * BLOCKBYTES); buf_front.copy_from_slice(buf_back); @@ -351,12 +314,7 @@ impl State { let mut bulk_bytes = input.len().saturating_sub(needed_tail); bulk_bytes -= bulk_bytes % (DEGREE * BLOCKBYTES); if bulk_bytes > 0 { - Self::compress_to_leaves( - &mut self.leaf_words, - &input[..bulk_bytes], - &mut self.count, - self.implementation, - ); + Self::compress_to_leaves(&mut self.leaf_words, &input[..bulk_bytes], &mut self.count, self.implementation); input = &input[bulk_bytes..]; } @@ -373,32 +331,20 @@ impl State { // Hash whatever's remaining in the buffer and finalize the leaves. let buf_len = self.buf_len as usize; let mut leaves_copy = self.leaf_words; - let jobs = leaves_copy - .iter_mut() - .enumerate() - .map(|(leaf_index, leaf_words)| { - let input = &self.buf[cmp::min(leaf_index * BLOCKBYTES, buf_len)..buf_len]; - Job { - input, - words: leaf_words, - count: self.count, - last_node: if leaf_index == DEGREE - 1 { - LastNode::Yes - } else { - LastNode::No - }, - } - }); + let jobs = leaves_copy.iter_mut().enumerate().map(|(leaf_index, leaf_words)| { + let input = &self.buf[cmp::min(leaf_index * BLOCKBYTES, buf_len)..buf_len]; + Job { + input, + words: leaf_words, + count: self.count, + last_node: if leaf_index == DEGREE - 1 { LastNode::Yes } else { LastNode::No }, + } + }); many::compress_many(jobs, self.implementation, Finalize::Yes, Stride::Parallel); // Concatenate each leaf into the root and hash that. let mut root_words_copy = self.root_words; - finalize_root_words( - &leaves_copy, - &mut root_words_copy, - self.hash_length, - self.implementation, - ) + finalize_root_words(&leaves_copy, &mut root_words_copy, self.hash_length, self.implementation) } /// Return the total number of bytes input so far. @@ -407,10 +353,7 @@ impl State { /// It's exactly the total number of input bytes fed to `update`. pub fn count(&self) -> Count { // Remember that self.count is *per-leaf*. - let mut ret = self - .count - .wrapping_mul(DEGREE as Count) - .wrapping_add(self.buf_len as Count); + let mut ret = self.count.wrapping_mul(DEGREE as Count).wrapping_add(self.buf_len as Count); if self.is_keyed { ret -= (DEGREE * BLOCKBYTES) as Count; } @@ -432,12 +375,7 @@ impl std::io::Write for State { impl fmt::Debug for State { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "State {{ count: {}, hash_length: {} }}", - self.count(), - self.hash_length, - ) + write!(f, "State {{ count: {}, hash_length: {} }}", self.count(), self.hash_length,) } } @@ -453,29 +391,13 @@ impl Default for State { // data for all nodes, this step must still use the untruncated output of each // leaf. Note also that, as mentioned above, the root node doesn't hash any key // bytes. -fn finalize_root_words( - leaf_words: &[[Word; 8]; DEGREE], - root_words: &mut [Word; 8], - hash_length: u8, - imp: Implementation, -) -> Hash { +fn finalize_root_words(leaf_words: &[[Word; 8]; DEGREE], root_words: &mut [Word; 8], hash_length: u8, imp: Implementation) -> Hash { debug_assert_eq!(OUTBYTES, 8 * size_of::()); let mut block = [0; DEGREE * OUTBYTES]; - for (word, chunk) in leaf_words - .iter() - .flat_map(|words| words.iter()) - .zip(block.chunks_exact_mut(size_of::())) - { + for (word, chunk) in leaf_words.iter().flat_map(|words| words.iter()).zip(block.chunks_exact_mut(size_of::())) { chunk.copy_from_slice(&word.to_le_bytes()); } - imp.compress1_loop( - &block, - root_words, - 0, - LastNode::Yes, - Finalize::Yes, - Stride::Serial, - ); + imp.compress1_loop(&block, root_words, 0, LastNode::Yes, Finalize::Yes, Stride::Serial); Hash { bytes: crate::state_words_to_bytes(&root_words), len: hash_length, diff --git a/crates/blake2s_const/src/guts.rs b/crates/blake2s_const/src/guts.rs index 12dfe3d..efe3688 100644 --- a/crates/blake2s_const/src/guts.rs +++ b/crates/blake2s_const/src/guts.rs @@ -81,15 +81,7 @@ impl Implementation { } } - pub fn compress1_loop( - &self, - input: &[u8], - words: &mut [Word; 8], - count: Count, - last_node: LastNode, - finalize: Finalize, - stride: Stride, - ) { + pub fn compress1_loop(&self, input: &[u8], words: &mut [Word; 8], count: Count, last_node: LastNode, finalize: Finalize, stride: Stride) { match self.0 { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] Platform::AVX2 | Platform::SSE41 => unsafe { @@ -104,9 +96,7 @@ impl Implementation { pub fn compress4_loop(&self, jobs: &mut [Job; 4], finalize: Finalize, stride: Stride) { match self.0 { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] - Platform::AVX2 | Platform::SSE41 => unsafe { - sse41::compress4_loop(jobs, finalize, stride) - }, + Platform::AVX2 | Platform::SSE41 => unsafe { sse41::compress4_loop(jobs, finalize, stride) }, _ => panic!("unsupported"), } } @@ -130,13 +120,7 @@ pub struct Job<'a, 'b> { impl<'a, 'b> core::fmt::Debug for Job<'a, 'b> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // NB: Don't print the words. Leaking them would allow length extension. - write!( - f, - "Job {{ input_len: {}, count: {}, last_node: {} }}", - self.input.len(), - self.count, - self.last_node.yes(), - ) + write!(f, "Job {{ input_len: {}, count: {}, last_node: {} }}", self.input.len(), self.count, self.last_node.yes(),) } } @@ -214,12 +198,7 @@ pub(crate) fn flag_word(flag: bool) -> Word { // input can be finalized (i.e. whether there aren't any more bytes after this // block). Note that this is written so that the optimizer can elide bounds // checks, see: https://godbolt.org/z/0hH2bC -pub fn final_block<'a>( - input: &'a [u8], - offset: usize, - buffer: &'a mut [u8; BLOCKBYTES], - stride: Stride, -) -> (&'a [u8; BLOCKBYTES], usize, bool) { +pub fn final_block<'a>(input: &'a [u8], offset: usize, buffer: &'a mut [u8; BLOCKBYTES], stride: Stride) -> (&'a [u8; BLOCKBYTES], usize, bool) { let capped_offset = cmp::min(offset, input.len()); let offset_slice = &input[capped_offset..]; if offset_slice.len() >= BLOCKBYTES { @@ -258,21 +237,12 @@ mod test { { if is_x86_feature_detected!("avx2") { assert_eq!(Platform::AVX2, Implementation::detect().0); - assert_eq!( - Platform::AVX2, - Implementation::avx2_if_supported().unwrap().0 - ); - assert_eq!( - Platform::SSE41, - Implementation::sse41_if_supported().unwrap().0 - ); + assert_eq!(Platform::AVX2, Implementation::avx2_if_supported().unwrap().0); + assert_eq!(Platform::SSE41, Implementation::sse41_if_supported().unwrap().0); } else if is_x86_feature_detected!("sse4.1") { assert_eq!(Platform::SSE41, Implementation::detect().0); assert!(Implementation::avx2_if_supported().is_none()); - assert_eq!( - Platform::SSE41, - Implementation::sse41_if_supported().unwrap().0 - ); + assert_eq!(Platform::SSE41, Implementation::sse41_if_supported().unwrap().0); } else { assert_eq!(Platform::Portable, Implementation::detect().0); assert!(Implementation::avx2_if_supported().is_none()); @@ -332,38 +302,18 @@ mod test { } fn initial_test_words(input_index: usize) -> [Word; 8] { - crate::Params::new() - .node_offset(input_index as u64) - .to_words() + crate::Params::new().node_offset(input_index as u64).to_words() } // Use the portable implementation, one block at a time, to compute the // final state words expected for a given test case. - fn reference_compression( - input: &[u8], - stride: Stride, - last_node: LastNode, - finalize: Finalize, - mut count: Count, - input_index: usize, - ) -> [Word; 8] { + fn reference_compression(input: &[u8], stride: Stride, last_node: LastNode, finalize: Finalize, mut count: Count, input_index: usize) -> [Word; 8] { let mut words = initial_test_words(input_index); let mut offset = 0; while offset == 0 || offset < input.len() { let block_size = cmp::min(BLOCKBYTES, input.len() - offset); - let maybe_finalize = if offset + stride.padded_blockbytes() < input.len() { - Finalize::No - } else { - finalize - }; - portable::compress1_loop( - &input[offset..][..block_size], - &mut words, - count, - last_node, - maybe_finalize, - Stride::Serial, - ); + let maybe_finalize = if offset + stride.padded_blockbytes() < input.len() { Finalize::No } else { finalize }; + portable::compress1_loop(&input[offset..][..block_size], &mut words, count, last_node, maybe_finalize, Stride::Serial); offset += stride.padded_blockbytes(); count = count.wrapping_add(BLOCKBYTES as Count); } @@ -381,18 +331,10 @@ mod test { paint_test_input(&mut input); exercise_cases(|stride, length, last_node, finalize, count| { - let reference_words = - reference_compression(&input[..length], stride, last_node, finalize, count, 0); + let reference_words = reference_compression(&input[..length], stride, last_node, finalize, count, 0); let mut test_words = initial_test_words(0); - implementation.compress1_loop( - &input[..length], - &mut test_words, - count, - last_node, - finalize, - stride, - ); + implementation.compress1_loop(&input[..length], &mut test_words, count, last_node, finalize, stride); assert_eq!(reference_words, test_words); }); } @@ -437,14 +379,7 @@ mod test { exercise_cases(|stride, length, last_node, finalize, count| { let mut reference_words = ArrayVec::<[_; N]>::new(); for i in 0..N { - let words = reference_compression( - &inputs[i][..length], - stride, - last_node, - finalize, - count.wrapping_add((i * BLOCKBYTES) as Count), - i, - ); + let words = reference_compression(&inputs[i][..length], stride, last_node, finalize, count.wrapping_add((i * BLOCKBYTES) as Count), i); reference_words.push(words); } @@ -502,14 +437,7 @@ mod test { exercise_cases(|stride, length, last_node, finalize, count| { let mut reference_words = ArrayVec::<[_; N]>::new(); for i in 0..N { - let words = reference_compression( - &inputs[i][..length], - stride, - last_node, - finalize, - count.wrapping_add((i * BLOCKBYTES) as Count), - i, - ); + let words = reference_compression(&inputs[i][..length], stride, last_node, finalize, count.wrapping_add((i * BLOCKBYTES) as Count), i); reference_words.push(words); } diff --git a/crates/blake2s_const/src/lib.rs b/crates/blake2s_const/src/lib.rs index 32bef2c..ed6aa1e 100644 --- a/crates/blake2s_const/src/lib.rs +++ b/crates/blake2s_const/src/lib.rs @@ -35,35 +35,21 @@ pub const PERSONALBYTES: usize = 2 * size_of::(); /// to use an even multiple of `BLOCKBYTES`, or else their apparent throughput will be low. pub const BLOCKBYTES: usize = 16 * size_of::(); -#[cfg(all( - any(target_arch = "x86", target_arch = "x86_64"), - target_feature = "avx2" -))] +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "avx2"))] const EMPTY_PARAMS: Params = Params::new_for_implementation(Implementation(Platform::AVX2)); -#[cfg(all( - any(target_arch = "x86", target_arch = "x86_64"), - all(not(target_feature = "avx2"), target_feature = "sse4.1") -))] +#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), all(not(target_feature = "avx2"), target_feature = "sse4.1")))] const EMPTY_PARAMS: Params = Params::new_for_implementation(Implementation(Platform::SSE41)); #[cfg(not(any( - all( - any(target_arch = "x86", target_arch = "x86_64"), - target_feature = "avx2" - ), - all( - any(target_arch = "x86", target_arch = "x86_64"), - target_feature = "sse4.1" - ), + all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "avx2"), + all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse4.1"), )))] const EMPTY_PARAMS: Params = Params::new_for_implementation(Implementation(Platform::Portable)); const EMPTY_WORDS: [Word; 8] = EMPTY_PARAMS.empty_words(); -const IV: [Word; 8] = [ - 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19, -]; +const IV: [Word; 8] = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19]; const SIGMA: [[u8; 16]; 10] = [ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], @@ -184,20 +170,12 @@ impl Params { #[inline(always)] fn to_words(&self) -> [Word; 8] { let (salt_left, salt_right) = array_refs!(&self.salt, SALTBYTES / 2, SALTBYTES / 2); - let (personal_left, personal_right) = - array_refs!(&self.personal, PERSONALBYTES / 2, PERSONALBYTES / 2); + let (personal_left, personal_right) = array_refs!(&self.personal, PERSONALBYTES / 2, PERSONALBYTES / 2); [ - IV[0] - ^ self.hash_length as u32 - ^ (self.key_length as u32) << 8 - ^ (self.fanout as u32) << 16 - ^ (self.max_depth as u32) << 24, + IV[0] ^ self.hash_length as u32 ^ (self.key_length as u32) << 8 ^ (self.fanout as u32) << 16 ^ (self.max_depth as u32) << 24, IV[1] ^ self.max_leaf_length, IV[2] ^ self.node_offset as u32, - IV[3] - ^ (self.node_offset >> 32) as u32 - ^ (self.node_depth as u32) << 16 - ^ (self.inner_hash_length as u32) << 24, + IV[3] ^ (self.node_offset >> 32) as u32 ^ (self.node_depth as u32) << 16 ^ (self.inner_hash_length as u32) << 24, IV[4] ^ Word::from_le_bytes(*salt_left), IV[5] ^ Word::from_le_bytes(*salt_right), IV[6] ^ Word::from_le_bytes(*personal_left), @@ -208,17 +186,10 @@ impl Params { #[inline(always)] const fn empty_words(&self) -> [Word; 8] { [ - IV[0] - ^ self.hash_length as u32 - ^ (self.key_length as u32) << 8 - ^ (self.fanout as u32) << 16 - ^ (self.max_depth as u32) << 24, + IV[0] ^ self.hash_length as u32 ^ (self.key_length as u32) << 8 ^ (self.fanout as u32) << 16 ^ (self.max_depth as u32) << 24, IV[1] ^ self.max_leaf_length, IV[2] ^ self.node_offset as u32, - IV[3] - ^ (self.node_offset >> 32) as u32 - ^ (self.node_depth as u32) << 16 - ^ (self.inner_hash_length as u32) << 24, + IV[3] ^ (self.node_offset >> 32) as u32 ^ (self.node_depth as u32) << 16 ^ (self.inner_hash_length as u32) << 24, IV[4] ^ 0, IV[5] ^ 0, IV[6] ^ 0, @@ -234,14 +205,7 @@ impl Params { return self.to_state().update(input).finalize(); } let mut words = self.to_words(); - self.implementation.compress1_loop( - input, - &mut words, - 0, - self.last_node, - guts::Finalize::Yes, - guts::Stride::Serial, - ); + self.implementation.compress1_loop(input, &mut words, 0, self.last_node, guts::Finalize::Yes, guts::Stride::Serial); Hash { bytes: state_words_to_bytes(&words), len: self.hash_length, @@ -252,14 +216,7 @@ impl Params { #[inline] pub fn hash_without_state(&self, input: &[u8]) -> Hash { let mut words = EMPTY_WORDS; - self.implementation.compress1_loop( - input, - &mut words, - 0, - self.last_node, - guts::Finalize::Yes, - guts::Stride::Serial, - ); + self.implementation.compress1_loop(input, &mut words, 0, self.last_node, guts::Finalize::Yes, guts::Stride::Serial); Hash { bytes: state_words_to_bytes(&words), len: self.hash_length, @@ -277,11 +234,7 @@ impl Params { /// will result in a totally different hash. #[inline] pub fn hash_length(&mut self, length: usize) -> &mut Self { - assert!( - 1 <= length && length <= OUTBYTES, - "Bad hash length: {}", - length - ); + assert!(1 <= length && length <= OUTBYTES, "Bad hash length: {}", length); self.hash_length = length as u8; self } @@ -311,11 +264,7 @@ impl Params { /// personalization is equivalent to having no personalization at all. #[inline] pub fn personal(&mut self, personalization: &[u8]) -> &mut Self { - assert!( - personalization.len() <= PERSONALBYTES, - "Bad personalization length: {}", - personalization.len() - ); + assert!(personalization.len() <= PERSONALBYTES, "Bad personalization length: {}", personalization.len()); self.personal = [0; PERSONALBYTES]; self.personal[..personalization.len()].copy_from_slice(personalization); self @@ -372,11 +321,7 @@ impl Params { /// [`State::set_last_node`]: struct.State.html#method.set_last_node #[inline] pub fn last_node(&mut self, last_node: bool) -> &mut Self { - self.last_node = if last_node { - guts::LastNode::Yes - } else { - guts::LastNode::No - }; + self.last_node = if last_node { guts::LastNode::Yes } else { guts::LastNode::No }; self } } @@ -477,14 +422,8 @@ impl State { if self.buflen > 0 { self.fill_buf(input); if !input.is_empty() { - self.implementation.compress1_loop( - &self.buf, - &mut self.words, - self.count, - self.last_node, - guts::Finalize::No, - guts::Stride::Serial, - ); + self.implementation + .compress1_loop(&self.buf, &mut self.words, self.count, self.last_node, guts::Finalize::No, guts::Stride::Serial); self.count = self.count.wrapping_add(BLOCKBYTES as Count); self.buflen = 0; } @@ -500,14 +439,8 @@ impl State { let mut end = input.len().saturating_sub(1); end -= end % BLOCKBYTES; if end > 0 { - self.implementation.compress1_loop( - &input[..end], - &mut self.words, - self.count, - self.last_node, - guts::Finalize::No, - guts::Stride::Serial, - ); + self.implementation + .compress1_loop(&input[..end], &mut self.words, self.count, self.last_node, guts::Finalize::No, guts::Stride::Serial); self.count = self.count.wrapping_add(end as Count); input = &input[end..]; } @@ -546,11 +479,7 @@ impl State { /// [`Params::last_node`]: struct.Params.html#method.last_node /// [the BLAKE2 spec]: https://blake2.net/blake2.pdf pub fn set_last_node(&mut self, last_node: bool) -> &mut Self { - self.last_node = if last_node { - guts::LastNode::Yes - } else { - guts::LastNode::No - }; + self.last_node = if last_node { guts::LastNode::Yes } else { guts::LastNode::No }; self } @@ -600,13 +529,7 @@ impl std::io::Write for State { impl fmt::Debug for State { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // NB: Don't print the words. Leaking them would allow length extension. - write!( - f, - "State {{ count: {}, hash_length: {}, last_node: {} }}", - self.count(), - self.hash_length, - self.last_node.yes(), - ) + write!(f, "State {{ count: {}, hash_length: {}, last_node: {} }}", self.count(), self.hash_length, self.last_node.yes(),) } } diff --git a/crates/blake2s_const/src/many.rs b/crates/blake2s_const/src/many.rs index 78736d7..f711b8a 100644 --- a/crates/blake2s_const/src/many.rs +++ b/crates/blake2s_const/src/many.rs @@ -96,11 +96,7 @@ pub fn degree() -> usize { type JobsVec<'a, 'b> = ArrayVec<[Job<'a, 'b>; guts::MAX_DEGREE]>; #[inline(always)] -fn fill_jobs_vec<'a, 'b>( - jobs_iter: &mut impl Iterator>, - vec: &mut JobsVec<'a, 'b>, - target_len: usize, -) { +fn fill_jobs_vec<'a, 'b>(jobs_iter: &mut impl Iterator>, vec: &mut JobsVec<'a, 'b>, target_len: usize) { while vec.len() < target_len { if let Some(job) = jobs_iter.next() { vec.push(job); @@ -130,12 +126,8 @@ fn evict_finished<'a, 'b>(vec: &mut JobsVec<'a, 'b>, num_jobs: usize) { } } -pub(crate) fn compress_many<'a, 'b, I>( - jobs: I, - imp: Implementation, - finalize: Finalize, - stride: Stride, -) where +pub(crate) fn compress_many<'a, 'b, I>(jobs: I, imp: Implementation, finalize: Finalize, stride: Stride) +where I: IntoIterator>, { // Fuse is important for correctness, since each of these blocks tries to @@ -168,12 +160,7 @@ pub(crate) fn compress_many<'a, 'b, I>( } for job in jobs_vec.into_iter().chain(jobs_iter) { - let Job { - input, - words, - count, - last_node, - } = job; + let Job { input, words, count, last_node } = job; imp.compress1_loop(input, words, count, last_node, finalize, stride); } } @@ -292,14 +279,7 @@ impl<'a> HashManyJob<'a> { finalization = Finalize::Yes; finished = true; } - params.implementation.compress1_loop( - ¶ms.key_block, - &mut words, - 0, - params.last_node, - finalization, - Stride::Serial, - ); + params.implementation.compress1_loop(¶ms.key_block, &mut words, 0, params.last_node, finalization, Stride::Serial); count = BLOCKBYTES as Count; } Self { diff --git a/crates/blake2s_const/src/portable.rs b/crates/blake2s_const/src/portable.rs index 23a301d..0daaad5 100644 --- a/crates/blake2s_const/src/portable.rs +++ b/crates/blake2s_const/src/portable.rs @@ -1,9 +1,7 @@ use arrayref::{array_ref, array_refs}; use super::*; -use crate::guts::{ - count_high, count_low, final_block, flag_word, input_debug_asserts, Finalize, LastNode, Stride, -}; +use crate::guts::{count_high, count_low, final_block, flag_word, input_debug_asserts, Finalize, LastNode, Stride}; // G is the mixing function, called eight times per round in the compression // function. V is the 16-word state vector of the compression function, usually @@ -42,13 +40,7 @@ fn round(r: usize, m: &[Word; 16], v: &mut [Word; 16]) { } #[inline(always)] -fn compress_block( - block: &[u8; BLOCKBYTES], - words: &mut [Word; 8], - count: Count, - last_block: Word, - last_node: Word, -) { +fn compress_block(block: &[u8; BLOCKBYTES], words: &mut [Word; 8], count: Count, last_block: Word, last_node: Word) { // Initialize the compression state. let mut v = [ words[0], @@ -112,14 +104,7 @@ fn compress_block( words[7] ^= v[7] ^ v[15]; } -pub fn compress1_loop( - input: &[u8], - words: &mut [Word; 8], - mut count: Count, - last_node: LastNode, - finalize: Finalize, - stride: Stride, -) { +pub fn compress1_loop(input: &[u8], words: &mut [Word; 8], mut count: Count, last_node: LastNode, finalize: Finalize, stride: Stride) { input_debug_asserts(input, finalize); let mut local_words = *words; diff --git a/crates/blake2s_const/src/sse41.rs b/crates/blake2s_const/src/sse41.rs index c40705d..d9caf5f 100644 --- a/crates/blake2s_const/src/sse41.rs +++ b/crates/blake2s_const/src/sse41.rs @@ -3,10 +3,7 @@ use core::arch::x86::*; #[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; -use crate::guts::{ - assemble_count, count_high, count_low, final_block, flag_word, input_debug_asserts, Finalize, - Job, LastNode, Stride, -}; +use crate::guts::{assemble_count, count_high, count_low, final_block, flag_word, input_debug_asserts, Finalize, Job, LastNode, Stride}; use crate::{Count, Word, BLOCKBYTES, IV, SIGMA}; use arrayref::{array_refs, mut_array_refs}; use core::cmp; @@ -69,10 +66,7 @@ unsafe fn rot7(a: __m128i) -> __m128i { #[inline(always)] unsafe fn rot8(a: __m128i) -> __m128i { - _mm_shuffle_epi8( - a, - _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1), - ) + _mm_shuffle_epi8(a, _mm_set_epi8(12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1)) } #[inline(always)] @@ -82,20 +76,11 @@ unsafe fn rot12(a: __m128i) -> __m128i { #[inline(always)] unsafe fn rot16(a: __m128i) -> __m128i { - _mm_shuffle_epi8( - a, - _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2), - ) + _mm_shuffle_epi8(a, _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2)) } #[inline(always)] -unsafe fn g1( - row1: &mut __m128i, - row2: &mut __m128i, - row3: &mut __m128i, - row4: &mut __m128i, - m: __m128i, -) { +unsafe fn g1(row1: &mut __m128i, row2: &mut __m128i, row3: &mut __m128i, row4: &mut __m128i, m: __m128i) { *row1 = add(add(*row1, m), *row2); *row4 = xor(*row4, *row1); *row4 = rot16(*row4); @@ -105,13 +90,7 @@ unsafe fn g1( } #[inline(always)] -unsafe fn g2( - row1: &mut __m128i, - row2: &mut __m128i, - row3: &mut __m128i, - row4: &mut __m128i, - m: __m128i, -) { +unsafe fn g2(row1: &mut __m128i, row2: &mut __m128i, row3: &mut __m128i, row4: &mut __m128i, m: __m128i) { *row1 = add(add(*row1, m), *row2); *row4 = xor(*row4, *row1); *row4 = rot8(*row4); @@ -145,23 +124,14 @@ unsafe fn undiagonalize(row1: &mut __m128i, row3: &mut __m128i, row4: &mut __m12 } #[inline(always)] -pub unsafe fn compress_block( - block: &[u8; BLOCKBYTES], - words: &mut [Word; 8], - count: Count, - last_block: Word, - last_node: Word, -) { +pub unsafe fn compress_block(block: &[u8; BLOCKBYTES], words: &mut [Word; 8], count: Count, last_block: Word, last_node: Word) { let (words_low, words_high) = mut_array_refs!(words, DEGREE, DEGREE); let (iv_low, iv_high) = array_refs!(&IV, DEGREE, DEGREE); let row1 = &mut loadu(words_low); let row2 = &mut loadu(words_high); let row3 = &mut loadu(iv_low); - let row4 = &mut xor( - loadu(iv_high), - set4(count_low(count), count_high(count), last_block, last_node), - ); + let row4 = &mut xor(loadu(iv_high), set4(count_low(count), count_high(count), last_block, last_node)); let msg_ptr = block.as_ptr() as *const [Word; DEGREE]; let m0 = loadu(msg_ptr.add(0)); @@ -170,17 +140,9 @@ pub unsafe fn compress_block( let m3 = loadu(msg_ptr.add(3)); // round 1 - let buf = _mm_castps_si128(_mm_shuffle_ps( - _mm_castsi128_ps(m0), - _mm_castsi128_ps(m1), - _MM_SHUFFLE!(2, 0, 2, 0), - )); + let buf = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(m0), _mm_castsi128_ps(m1), _MM_SHUFFLE!(2, 0, 2, 0))); g1(row1, row2, row3, row4, buf); - let buf = _mm_castps_si128(_mm_shuffle_ps( - _mm_castsi128_ps(m0), - _mm_castsi128_ps(m1), - _MM_SHUFFLE!(3, 1, 3, 1), - )); + let buf = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(m0), _mm_castsi128_ps(m1), _MM_SHUFFLE!(3, 1, 3, 1))); g2(row1, row2, row3, row4, buf); diagonalize(row1, row3, row4); let t0 = _mm_shuffle_epi32(m2, _MM_SHUFFLE!(3, 2, 0, 1)); @@ -399,14 +361,7 @@ pub unsafe fn compress_block( } #[target_feature(enable = "sse4.1")] -pub unsafe fn compress1_loop( - input: &[u8], - words: &mut [Word; 8], - mut count: Count, - last_node: LastNode, - finalize: Finalize, - stride: Stride, -) { +pub unsafe fn compress1_loop(input: &[u8], words: &mut [Word; 8], mut count: Count, last_node: LastNode, finalize: Finalize, stride: Stride) { input_debug_asserts(input, finalize); let mut local_words = *words; @@ -630,12 +585,7 @@ macro_rules! compress4_transposed { } #[inline(always)] -unsafe fn transpose_vecs( - vec_a: __m128i, - vec_b: __m128i, - vec_c: __m128i, - vec_d: __m128i, -) -> [__m128i; 4] { +unsafe fn transpose_vecs(vec_a: __m128i, vec_b: __m128i, vec_c: __m128i, vec_d: __m128i) -> [__m128i; 4] { // Interleave 32-bit lates. The low unpack is lanes 00/11 and the high is // 22/33. Note that this doesn't split the vector into two lanes, as the // AVX2 counterparts do. @@ -662,18 +612,8 @@ unsafe fn transpose_state_vecs(jobs: &[Job; DEGREE]) -> [__m128i; 8] { let words1 = array_refs!(&jobs[1].words, DEGREE, DEGREE); let words2 = array_refs!(&jobs[2].words, DEGREE, DEGREE); let words3 = array_refs!(&jobs[3].words, DEGREE, DEGREE); - let [h0, h1, h2, h3] = transpose_vecs( - loadu(words0.0), - loadu(words1.0), - loadu(words2.0), - loadu(words3.0), - ); - let [h4, h5, h6, h7] = transpose_vecs( - loadu(words0.1), - loadu(words1.1), - loadu(words2.1), - loadu(words3.1), - ); + let [h0, h1, h2, h3] = transpose_vecs(loadu(words0.0), loadu(words1.0), loadu(words2.0), loadu(words3.0)); + let [h4, h5, h6, h7] = transpose_vecs(loadu(words0.1), loadu(words1.1), loadu(words2.1), loadu(words3.1)); [h0, h1, h2, h3, h4, h5, h6, h7] } @@ -706,50 +646,18 @@ unsafe fn transpose_msg_vecs(blocks: [*const [u8; BLOCKBYTES]; DEGREE]) -> [__m1 let block1 = blocks[1] as *const [Word; DEGREE]; let block2 = blocks[2] as *const [Word; DEGREE]; let block3 = blocks[3] as *const [Word; DEGREE]; - let [m0, m1, m2, m3] = transpose_vecs( - loadu(block0.add(0)), - loadu(block1.add(0)), - loadu(block2.add(0)), - loadu(block3.add(0)), - ); - let [m4, m5, m6, m7] = transpose_vecs( - loadu(block0.add(1)), - loadu(block1.add(1)), - loadu(block2.add(1)), - loadu(block3.add(1)), - ); - let [m8, m9, m10, m11] = transpose_vecs( - loadu(block0.add(2)), - loadu(block1.add(2)), - loadu(block2.add(2)), - loadu(block3.add(2)), - ); - let [m12, m13, m14, m15] = transpose_vecs( - loadu(block0.add(3)), - loadu(block1.add(3)), - loadu(block2.add(3)), - loadu(block3.add(3)), - ); - [ - m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, - ] + let [m0, m1, m2, m3] = transpose_vecs(loadu(block0.add(0)), loadu(block1.add(0)), loadu(block2.add(0)), loadu(block3.add(0))); + let [m4, m5, m6, m7] = transpose_vecs(loadu(block0.add(1)), loadu(block1.add(1)), loadu(block2.add(1)), loadu(block3.add(1))); + let [m8, m9, m10, m11] = transpose_vecs(loadu(block0.add(2)), loadu(block1.add(2)), loadu(block2.add(2)), loadu(block3.add(2))); + let [m12, m13, m14, m15] = transpose_vecs(loadu(block0.add(3)), loadu(block1.add(3)), loadu(block2.add(3)), loadu(block3.add(3))); + [m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15] } #[inline(always)] unsafe fn load_counts(jobs: &[Job; DEGREE]) -> (__m128i, __m128i) { ( - set4( - count_low(jobs[0].count), - count_low(jobs[1].count), - count_low(jobs[2].count), - count_low(jobs[3].count), - ), - set4( - count_high(jobs[0].count), - count_high(jobs[1].count), - count_high(jobs[2].count), - count_high(jobs[3].count), - ), + set4(count_low(jobs[0].count), count_low(jobs[1].count), count_low(jobs[2].count), count_low(jobs[3].count)), + set4(count_high(jobs[0].count), count_high(jobs[1].count), count_high(jobs[2].count), count_high(jobs[3].count)), ) } @@ -775,12 +683,7 @@ unsafe fn add_to_counts(lo: &mut __m128i, hi: &mut __m128i, delta: __m128i) { #[inline(always)] unsafe fn flags_vec(flags: [bool; DEGREE]) -> __m128i { - set4( - flag_word(flags[0]), - flag_word(flags[1]), - flag_word(flags[2]), - flag_word(flags[3]), - ) + set4(flag_word(flags[0]), flag_word(flags[1]), flag_word(flags[2]), flag_word(flags[3])) } #[target_feature(enable = "sse4.1")] @@ -790,12 +693,7 @@ pub unsafe fn compress4_loop(jobs: &mut [Job; DEGREE], finalize: Finalize, strid input_debug_asserts(job.input, finalize); } - let msg_ptrs = [ - jobs[0].input.as_ptr(), - jobs[1].input.as_ptr(), - jobs[2].input.as_ptr(), - jobs[3].input.as_ptr(), - ]; + let msg_ptrs = [jobs[0].input.as_ptr(), jobs[1].input.as_ptr(), jobs[2].input.as_ptr(), jobs[3].input.as_ptr()]; let mut h_vecs = transpose_state_vecs(&jobs); let (mut counts_lo, mut counts_hi) = load_counts(&jobs); @@ -857,14 +755,7 @@ pub unsafe fn compress4_loop(jobs: &mut [Job; DEGREE], finalize: Finalize, strid let m_vecs = transpose_msg_vecs(blocks); add_to_counts(&mut counts_lo, &mut counts_hi, counts_delta); - compress4_transposed!( - &mut h_vecs, - &m_vecs, - counts_lo, - counts_hi, - last_block, - last_node, - ); + compress4_transposed!(&mut h_vecs, &m_vecs, counts_lo, counts_hi, last_block, last_node,); // Check for termination before bumping the offset, to avoid overflow. if offset == fin_offset { diff --git a/crates/blake2s_const/src/test.rs b/crates/blake2s_const/src/test.rs index 79b1974..3839b38 100644 --- a/crates/blake2s_const/src/test.rs +++ b/crates/blake2s_const/src/test.rs @@ -7,12 +7,7 @@ const THOUSAND_HASH: &str = "37e9dd47498579c5343fd282c13c62ea824cdfc9b0f4f747a41 #[test] fn test_update_state() { - let io = &[ - (&b""[..], EMPTY_HASH), - (&b"abc"[..], ABC_HASH), - (&[0; BLOCKBYTES], ONE_BLOCK_HASH), - (&[0; 1000], THOUSAND_HASH), - ]; + let io = &[(&b""[..], EMPTY_HASH), (&b"abc"[..], ABC_HASH), (&[0; BLOCKBYTES], ONE_BLOCK_HASH), (&[0; 1000], THOUSAND_HASH)]; // Test each input all at once. for &(input, output) in io { let hash = blake2s(input); @@ -46,12 +41,7 @@ fn test_update_state() { #[test] fn test_from_const_state() { - let io = &[ - (&b""[..], EMPTY_HASH), - (&b"abc"[..], ABC_HASH), - (&[0; BLOCKBYTES], ONE_BLOCK_HASH), - (&[0; 1000], THOUSAND_HASH), - ]; + let io = &[(&b""[..], EMPTY_HASH), (&b"abc"[..], ABC_HASH), (&[0; BLOCKBYTES], ONE_BLOCK_HASH), (&[0; 1000], THOUSAND_HASH)]; // Test each input all at once. for &(input, output) in io { let hash = blake2s_const(input); @@ -118,16 +108,10 @@ fn test_all_parameters() { .last_node(true); // Check the State API. - assert_eq!( - "62361e5392ab0eb7dd27e48a6809ee82dc57", - ¶ms.to_state().update(b"foo").finalize().to_hex() - ); + assert_eq!("62361e5392ab0eb7dd27e48a6809ee82dc57", ¶ms.to_state().update(b"foo").finalize().to_hex()); // Check the all-at-once API. - assert_eq!( - "62361e5392ab0eb7dd27e48a6809ee82dc57", - ¶ms.hash(b"foo").to_hex() - ); + assert_eq!("62361e5392ab0eb7dd27e48a6809ee82dc57", ¶ms.hash(b"foo").to_hex()); } #[test] @@ -140,16 +124,10 @@ fn test_all_parameters_blake2sp() { .key(b"bar"); // Check the State API. - assert_eq!( - "947d4c671e2794f5e1a57daeca97bb46ed66", - ¶ms.to_state().update(b"foo").finalize().to_hex() - ); + assert_eq!("947d4c671e2794f5e1a57daeca97bb46ed66", ¶ms.to_state().update(b"foo").finalize().to_hex()); // Check the all-at-once API. - assert_eq!( - "947d4c671e2794f5e1a57daeca97bb46ed66", - ¶ms.hash(b"foo").to_hex() - ); + assert_eq!("947d4c671e2794f5e1a57daeca97bb46ed66", ¶ms.hash(b"foo").to_hex()); } #[test] diff --git a/crates/codegen-bin/src/main.rs b/crates/codegen-bin/src/main.rs index de3ca48..a9861be 100644 --- a/crates/codegen-bin/src/main.rs +++ b/crates/codegen-bin/src/main.rs @@ -27,11 +27,7 @@ fn main() { let opts = Opts::from_args(); println!("{:#?}", opts); - let Opts { - verification_key, - output, - encoding, - } = opts; + let Opts { verification_key, output, encoding } = opts; let encoding = match encoding { Some(encoding) => match encoding.as_str() { diff --git a/crates/codegen/src/circuits.rs b/crates/codegen/src/circuits.rs index 02a2f8b..b918228 100644 --- a/crates/codegen/src/circuits.rs +++ b/crates/codegen/src/circuits.rs @@ -1,10 +1,7 @@ use franklin_crypto::{ bellman::{ plonk::better_better_cs::{ - cs::{ - Circuit, ConstraintSystem, Gate, GateInternal, LookupTableApplication, - PolyIdentifier, Width4MainGateWithDNext, - }, + cs::{Circuit, ConstraintSystem, Gate, GateInternal, LookupTableApplication, PolyIdentifier, Width4MainGateWithDNext}, gates::selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext, }, Engine, Field, PrimeField, SynthesisError, @@ -49,9 +46,9 @@ macro_rules! circuit_inner { ]) }else{ Ok(vec![ - Self::MainGate::default().into_internal(), + Self::MainGate::default().into_internal(), ]) - } + } } } }; @@ -61,27 +58,22 @@ macro_rules! circuit_inner { macro_rules! circuit { ($id:ident, $main_gate:ty) => { circuit_inner!($id, $main_gate, false, inner_circuit_main_gate_part); - paste!{ + paste! { circuit_inner!([<$id WithLookup>], $main_gate, false, inner_circuit_lookup_part); } - paste!{ + paste! { circuit_inner!([<$id WithRescue>], $main_gate, true, inner_circuit_rescue_part); } - paste!{ + paste! { circuit_inner!([<$id WithLookupAndRescue>], $main_gate, true, inner_circuit_lookup_part, inner_circuit_rescue_part); } - } + }; } circuit!(DummyCircuit, Width4MainGateWithDNext); -circuit!( - SelectorOptimizedDummyCircuit, - SelectorOptimizedWidth4MainGateWithDNext -); - -fn inner_circuit_main_gate_part>( - cs: &mut CS, -) -> Result<(), SynthesisError> { +circuit!(SelectorOptimizedDummyCircuit, SelectorOptimizedWidth4MainGateWithDNext); + +fn inner_circuit_main_gate_part>(cs: &mut CS) -> Result<(), SynthesisError> { for _ in 0..32 { let a = Num::alloc(cs, Some(E::Fr::one()))?; let b = Num::alloc(cs, Some(E::Fr::zero()))?; @@ -95,18 +87,12 @@ fn inner_circuit_main_gate_part>( Ok(()) } -fn inner_circuit_lookup_part>( - cs: &mut CS, -) -> Result<(), SynthesisError> { +fn inner_circuit_lookup_part>(cs: &mut CS) -> Result<(), SynthesisError> { // add dummy lookup table queries let dummy = CS::get_dummy_variable(); dbg!("HAS LOOKUP"); // need to create a table (any) - let columns = vec![ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2), - ]; + let columns = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; let range_table = LookupTableApplication::new_range_table_of_width_3(2, columns.clone())?; let _range_table_name = range_table.functional_name(); @@ -151,9 +137,7 @@ fn inner_circuit_lookup_part>( Ok(()) } -fn inner_circuit_rescue_part>( - cs: &mut CS, -) -> Result<(), SynthesisError> { +fn inner_circuit_rescue_part>(cs: &mut CS) -> Result<(), SynthesisError> { dbg!("HAS RESCUE"); // make single rescue hash to satisfy gate requirements of declaration let mut params = RescueParams::default(); diff --git a/crates/codegen/src/generate.rs b/crates/codegen/src/generate.rs index a2b72ed..63fa902 100644 --- a/crates/codegen/src/generate.rs +++ b/crates/codegen/src/generate.rs @@ -36,7 +36,7 @@ struct TemplateVars { d_next_coeff_idx: usize, } -pub enum Encoding{ +pub enum Encoding { Json, Default, } @@ -44,13 +44,9 @@ pub enum Encoding{ pub fn generate(vk_path: PathBuf, output_dir: PathBuf, encoding_type: Encoding, template_files_path: Vec<&str>) { let mut reader = std::fs::File::open(vk_path).expect("vk file"); - let vk = match encoding_type{ - Encoding::Json => { - serde_json::from_reader(reader).expect("read vk from json encoded data") - }, - Encoding::Default => { - VerificationKey::::read(&mut reader).expect("read vk from default encoded data") - }, + let vk = match encoding_type { + Encoding::Json => serde_json::from_reader(reader).expect("read vk from json encoded data"), + Encoding::Default => VerificationKey::::read(&mut reader).expect("read vk from default encoded data"), }; // we know from the fact that vk belongs to a // - standart main gate when there are 7 selectors @@ -64,11 +60,7 @@ pub fn generate(vk_path: PathBuf, output_dir: PathBuf, encoding_type: Encoding, unimplemented!() }; - let num_gates = if vk.gate_selectors_commitments.len() == 0 { - 1 - } else { - vk.gate_selectors_commitments.len() - }; + let num_gates = if vk.gate_selectors_commitments.len() == 0 { 1 } else { vk.gate_selectors_commitments.len() }; let has_rescue_custom_gate = if num_gates > 1 { true } else { false }; @@ -84,30 +76,25 @@ pub fn generate(vk_path: PathBuf, output_dir: PathBuf, encoding_type: Encoding, false }; - let (num_main_gate_selectors, ab_coeff_idx, constant_coeff_idx, d_next_coeff_idx, ac_coeff_idx) = - match main_gate { - MainGateType::Standard => ( - 7, - Width4MainGateWithDNext::AB_MULTIPLICATION_TERM_COEFF_INDEX, - Width4MainGateWithDNext::CONSTANT_TERM_COEFF_INDEX, - Width4MainGateWithDNext::D_NEXT_TERM_COEFF_INDEX, - None, - ), - MainGateType::SelectorOptimized => ( - 8, - SelectorOptimizedWidth4MainGateWithDNext::AB_MULTIPLICATION_TERM_COEFF_INDEX, - SelectorOptimizedWidth4MainGateWithDNext::CONSTANT_TERM_COEFF_INDEX, - SelectorOptimizedWidth4MainGateWithDNext::D_NEXT_TERM_COEFF_INDEX, - Some(SelectorOptimizedWidth4MainGateWithDNext::AC_MULTIPLICATION_TERM_COEFF_INDEX), - ), - }; + let (num_main_gate_selectors, ab_coeff_idx, constant_coeff_idx, d_next_coeff_idx, ac_coeff_idx) = match main_gate { + MainGateType::Standard => ( + 7, + Width4MainGateWithDNext::AB_MULTIPLICATION_TERM_COEFF_INDEX, + Width4MainGateWithDNext::CONSTANT_TERM_COEFF_INDEX, + Width4MainGateWithDNext::D_NEXT_TERM_COEFF_INDEX, + None, + ), + MainGateType::SelectorOptimized => ( + 8, + SelectorOptimizedWidth4MainGateWithDNext::AB_MULTIPLICATION_TERM_COEFF_INDEX, + SelectorOptimizedWidth4MainGateWithDNext::CONSTANT_TERM_COEFF_INDEX, + SelectorOptimizedWidth4MainGateWithDNext::D_NEXT_TERM_COEFF_INDEX, + Some(SelectorOptimizedWidth4MainGateWithDNext::AC_MULTIPLICATION_TERM_COEFF_INDEX), + ), + }; let is_selector_optimized_main_gate = ac_coeff_idx.is_some(); - let ac_coeff_idx = if let Some(coeff) = ac_coeff_idx { - coeff - } else { - 0 - }; + let ac_coeff_idx = if let Some(coeff) = ac_coeff_idx { coeff } else { 0 }; let vars = TemplateVars { num_gates, @@ -124,19 +111,11 @@ pub fn generate(vk_path: PathBuf, output_dir: PathBuf, encoding_type: Encoding, render(vars, vk, output_dir, template_files_path) } -fn render( - vars: TemplateVars, - vk: VerificationKey, - output_dir: PathBuf, - template_files_path: Vec<&str>, -) { +fn render(vars: TemplateVars, vk: VerificationKey, output_dir: PathBuf, template_files_path: Vec<&str>) { let mut map = MapWrapper::new(); let mut handlebars = Handlebars::new(); - map.insert( - "is_selector_optimized_main_gate", - vars.is_selector_optimized_main_gate, - ); + map.insert("is_selector_optimized_main_gate", vars.is_selector_optimized_main_gate); // main gate + custom rescue map.insert("NUM_GATES", vars.num_gates); map.insert("has_lookup", vars.has_lookup); @@ -146,10 +125,7 @@ fn render( map.insert("D_NEXT_TERM_COEFF_INDEX", vars.d_next_coeff_idx); assert_eq!(vars.ab_coeff_idx, 4); map.insert("MAIN_GATE_AC_COEFF_IDX", vars.ac_coeff_idx); - assert_eq!( - vk.gate_setup_commitments.len(), - vars.num_main_gate_selectors - ); + assert_eq!(vk.gate_setup_commitments.len(), vars.num_main_gate_selectors); map.insert("NUM_MAIN_GATE_SELECTORS", vars.num_main_gate_selectors); // a, b, c, d println!("VK STATE WIDTH {}", vk.state_width); @@ -162,25 +138,25 @@ fn render( let mut num_commitments_at_z_omega = 1 + 2; let mut num_alpha_challenges = 1 + 2; - if vars.has_rescue_custom_gate{ + if vars.has_rescue_custom_gate { num_commitments_at_z += 1; num_alpha_challenges += 3; } - if vars.has_lookup{ + if vars.has_lookup { num_commitments_at_z += 3; num_alpha_challenges += 3; num_commitments_at_z_omega += 3; } - + map.insert("rescue_alpha_idx", 1); map.insert("num_commitments_at_z", num_commitments_at_z); map.insert("num_commitments_at_z_omega", num_commitments_at_z_omega); map.insert("NUM_ALPHA_CHALLENGES", num_alpha_challenges); - if vars.has_rescue_custom_gate{ + if vars.has_rescue_custom_gate { map.insert("copy_permutation_alpha_idx", 4); map.insert("lookup_alpha_idx", 6); - }else{ - map.insert("copy_permutation_alpha_idx", 1); + } else { + map.insert("copy_permutation_alpha_idx", 1); map.insert("lookup_alpha_idx", 3); } @@ -189,10 +165,7 @@ fn render( assert!(vk.num_inputs > 0); let domain: Domain = Domain::new_for_size(vk.n as u64).expect("a domain"); map.insert("domain_size".into(), domain.size); - map.insert( - "domain_generator".into(), - FieldElement::from(domain.generator), - ); + map.insert("domain_generator".into(), FieldElement::from(domain.generator)); // G1Points let mut gate_setup_commitments = vec![]; @@ -212,7 +185,7 @@ fn render( permutation_commitments.push(G1Point::from_affine_point(cmt.clone())) } map.insert("permutation_commitments", permutation_commitments); - + if vk.total_lookup_entries_length > 0 { assert!(vk.lookup_selector_commitment.is_some()); assert!(vk.lookup_tables_commitments.len() > 0); @@ -221,10 +194,7 @@ fn render( map.insert("has_lookup", true); map.insert( "lookup_selector_commitment", - G1Point::from_affine_point( - vk.lookup_selector_commitment - .unwrap_or(::G1Affine::zero()), - ), + G1Point::from_affine_point(vk.lookup_selector_commitment.unwrap_or(::G1Affine::zero())), ); if vk.total_lookup_entries_length > 0 { assert!(vk.lookup_selector_commitment.is_some()); @@ -236,10 +206,7 @@ fn render( map.insert("lookup_tables_commitments", lookup_tables_commitments); map.insert( "lookup_table_type_commitment", - G1Point::from_affine_point( - vk.lookup_table_type_commitment - .unwrap_or(::G1Affine::zero()), - ), + G1Point::from_affine_point(vk.lookup_table_type_commitment.unwrap_or(::G1Affine::zero())), ); } @@ -264,16 +231,11 @@ fn render( // register template from a file and assign a name to it handlebars .register_template_file("contract", template_file_path.clone()) - .expect(&format!( - "must read the template at path {}", - template_file_path - )); + .expect(&format!("must read the template at path {}", template_file_path)); let rendered = handlebars.render("contract", &map.inner).unwrap(); - writer - .write(rendered.as_bytes()) - .expect("must write to file"); + writer.write(rendered.as_bytes()).expect("must write to file"); } } diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index c6dad89..fbd75e5 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -1,17 +1,17 @@ -mod generate; mod circuits; +mod generate; mod serialize; -pub use generate::{generate, MainGateType, Encoding}; +pub use generate::{generate, Encoding, MainGateType}; use ethereum_types::U256; +use franklin_crypto::bellman::pairing::bn256::{Bn256, Fr}; use franklin_crypto::bellman::pairing::ff::*; use franklin_crypto::bellman::pairing::*; -use franklin_crypto::bellman::pairing::bn256::{Bn256, Fr}; use franklin_crypto::bellman::plonk::better_better_cs::cs::Circuit; +use franklin_crypto::bellman::plonk::better_better_cs::gates::selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext; use franklin_crypto::bellman::plonk::better_better_cs::proof::Proof; use franklin_crypto::bellman::plonk::better_better_cs::setup::VerificationKey; -use franklin_crypto::bellman::plonk::better_better_cs::gates::selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext; use crate::circuits::DummyCircuit; @@ -39,17 +39,10 @@ fn render_g2_affine_to_hex(point: &::G2Affine) -> [Strin let (x, y) = <::G2Affine as CurveAffine>::into_xy_unchecked(*point); - [ - render_scalar_to_hex(&x.c0), - render_scalar_to_hex(&x.c1), - render_scalar_to_hex(&y.c0), - render_scalar_to_hex(&y.c1) - ] + [render_scalar_to_hex(&x.c0), render_scalar_to_hex(&x.c1), render_scalar_to_hex(&y.c0), render_scalar_to_hex(&y.c1)] } -fn serialize_g1_for_ethereum( - point: &::G1Affine -) -> (U256, U256) { +fn serialize_g1_for_ethereum(point: &::G1Affine) -> (U256, U256) { if <::G1Affine as CurveAffine>::is_zero(point) { return (U256::zero(), U256::zero()); } @@ -71,10 +64,7 @@ fn serialize_g1_for_ethereum( fn serialize_fe_for_ethereum(field_element: &Fr) -> U256 { let mut be_bytes = [0u8; 32]; - field_element - .into_repr() - .write_be(&mut be_bytes[..]) - .expect("get new root BE bytes"); + field_element.into_repr().write_be(&mut be_bytes[..]).expect("get new root BE bytes"); U256::from_big_endian(&be_bytes[..]) } @@ -143,7 +133,6 @@ pub fn serialize_proof>(proof: &Proof) -> (Vec serialized_proof.push(serialize_fe_for_ethereum(&proof.quotient_poly_opening_at_z)); serialized_proof.push(serialize_fe_for_ethereum(&proof.linearization_poly_opening_at_z)); - let (x, y) = serialize_g1_for_ethereum(&proof.opening_proof_at_z); serialized_proof.push(x); serialized_proof.push(y); @@ -161,14 +150,10 @@ pub fn serialize_proof>(proof: &Proof) -> (Vec fn render_simple_proof() { use franklin_crypto::bellman::pairing::bn256::*; - let mut reader = std::io::BufReader::with_capacity(1<<24, - std::fs::File::open("../data/optimized/scheduler_proof.key").unwrap() - ); + let mut reader = std::io::BufReader::with_capacity(1 << 24, std::fs::File::open("../data/optimized/scheduler_proof.key").unwrap()); let proof = Proof::::read(&mut reader).unwrap(); let (inputs, proof) = serialize_proof(&proof); - - println!("Inputs"); let mut vec = vec![]; for i in inputs.into_iter() { diff --git a/crates/codegen/src/serialize.rs b/crates/codegen/src/serialize.rs index 0ad303f..4eaedb6 100644 --- a/crates/codegen/src/serialize.rs +++ b/crates/codegen/src/serialize.rs @@ -1,5 +1,7 @@ -use franklin_crypto::bellman::{CurveAffine, Engine, PrimeField, PrimeFieldRepr, pairing::bn256::{Bn256, Fq, Fq2, Fr}}; - +use franklin_crypto::bellman::{ + pairing::bn256::{Bn256, Fq, Fq2, Fr}, + CurveAffine, Engine, PrimeField, PrimeFieldRepr, +}; use serde::ser::{Serialize, SerializeStruct, Serializer}; @@ -29,9 +31,7 @@ impl Serialize for FieldElement { fn field_element_to_hex(el: &F) -> String { let mut buf = [0u8; 32]; - el.into_repr() - .write_be(&mut buf[..]) - .expect("consume buffer"); + el.into_repr().write_be(&mut buf[..]).expect("consume buffer"); let mut result = String::from("0x"); result.push_str(&hex::encode(buf)); diff --git a/crates/franklin-crypto/src/alt_babyjubjub/fs.rs b/crates/franklin-crypto/src/alt_babyjubjub/fs.rs index 6d69a23..55b2bcf 100644 --- a/crates/franklin-crypto/src/alt_babyjubjub/fs.rs +++ b/crates/franklin-crypto/src/alt_babyjubjub/fs.rs @@ -1,16 +1,11 @@ -use byteorder::{ByteOrder, LittleEndian}; -use bellman::pairing::ff::{adc, sbb, mac_with_carry}; -use bellman::pairing::ff::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol}; -use bellman::pairing::ff::LegendreSymbol::*; use super::ToUniform; +use bellman::pairing::ff::LegendreSymbol::*; +use bellman::pairing::ff::{adc, mac_with_carry, sbb}; +use bellman::pairing::ff::{BitIterator, Field, LegendreSymbol, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField}; +use byteorder::{ByteOrder, LittleEndian}; // s = 2736030358979909402780800718157159386076813972158567259200215660948447373041 -const MODULUS: FsRepr = FsRepr([ - 0x677297dc392126f1, - 0xab3eedb83920ee0a, - 0x370a08b6d0302b0b, - 0x060c89ce5c263405, -]); +const MODULUS: FsRepr = FsRepr([0x677297dc392126f1, 0xab3eedb83920ee0a, 0x370a08b6d0302b0b, 0x060c89ce5c263405]); // The number of bits needed to represent the modulus. const MODULUS_BITS: u32 = 251; @@ -20,50 +15,25 @@ const MODULUS_BITS: u32 = 251; const REPR_SHAVE_BITS: u32 = 5; // R = 2**256 % s -const R: FsRepr = FsRepr([ - 0x073315dea08f9c76, - 0xe7acffc6a098f24b, - 0xf85a9201d818f015, - 0x01f16424e1bb7724, -]); +const R: FsRepr = FsRepr([0x073315dea08f9c76, 0xe7acffc6a098f24b, 0xf85a9201d818f015, 0x01f16424e1bb7724]); // R2 = R^2 % s -const R2: FsRepr = FsRepr([ - 0x35e44abee7ecb21e, - 0x74646cacf5f84ec4, - 0xe472df203faa158f, - 0x0445b524f1ba50a8, -]); +const R2: FsRepr = FsRepr([0x35e44abee7ecb21e, 0x74646cacf5f84ec4, 0xe472df203faa158f, 0x0445b524f1ba50a8]); // INV = -(s^{-1} mod 2^64) mod s const INV: u64 = 0x532ce5aebc48f5ef; // GENERATOR = 7 (multiplicative generator of r-1 order, that is also quadratic nonresidue) -const GENERATOR: FsRepr = FsRepr([ - 0x6380695df1aaf958, - 0xff3d22fdf1ecc3f8, - 0x5c65ec9f484e3a81, - 0x0180a96573d3d9f8, -]); +const GENERATOR: FsRepr = FsRepr([0x6380695df1aaf958, 0xff3d22fdf1ecc3f8, 0x5c65ec9f484e3a81, 0x0180a96573d3d9f8]); // 2^S * t = MODULUS - 1 with t odd const S: u32 = 4; // 2^S root of unity computed by GENERATOR^t -const ROOT_OF_UNITY: FsRepr = FsRepr([ - 0xa13885692e7afcb0, - 0xb789766cd18573ca, - 0xd5468c0174efc3b9, - 0x03534b612b0b6f7a, -]); +const ROOT_OF_UNITY: FsRepr = FsRepr([0xa13885692e7afcb0, 0xb789766cd18573ca, 0xd5468c0174efc3b9, 0x03534b612b0b6f7a]); // -((2**256) mod s) mod s -const NEGATIVE_ONE: Fs = Fs(FsRepr([ - 0x603f81fd98918a7b, - 0xc391edf19887fbbf, - 0x3eaf76b4f8173af5, - 0x041b25a97a6abce0, -])); +const NEGATIVE_ONE: Fs = Fs(FsRepr([0x603f81fd98918a7b, 0xc391edf19887fbbf, 0x3eaf76b4f8173af5, 0x041b25a97a6abce0])); /// This is the underlying representation of an element of `Fs`. #[derive(Copy, Clone, PartialEq, Eq, Default, Debug, Hash, ::serde::Serialize, ::serde::Deserialize)] @@ -76,8 +46,7 @@ impl ::rand::Rand for FsRepr { } } -impl ::std::fmt::Display for FsRepr -{ +impl ::std::fmt::Display for FsRepr { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "0x")?; for i in self.0.iter().rev() { @@ -116,9 +85,9 @@ impl Ord for FsRepr { fn cmp(&self, other: &FsRepr) -> ::std::cmp::Ordering { for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) { if a < b { - return ::std::cmp::Ordering::Less + return ::std::cmp::Ordering::Less; } else if a > b { - return ::std::cmp::Ordering::Greater + return ::std::cmp::Ordering::Greater; } } @@ -260,8 +229,7 @@ impl PrimeFieldRepr for FsRepr { #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Default)] pub struct Fs(FsRepr); -impl ::std::fmt::Display for Fs -{ +impl ::std::fmt::Display for Fs { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "Fs({})", self.into_repr()) } @@ -276,7 +244,7 @@ impl ::rand::Rand for Fs { tmp.0.as_mut()[3] &= 0xffffffffffffffff >> REPR_SHAVE_BITS; if tmp.is_valid() { - return tmp + return tmp; } } } @@ -290,7 +258,8 @@ impl From for FsRepr { impl ::serde::Serialize for Fs { fn serialize(&self, serializer: S) -> Result - where S: ::serde::Serializer + where + S: ::serde::Serializer, { let repr = self.into_repr(); repr.serialize(serializer) @@ -299,7 +268,8 @@ impl ::serde::Serialize for Fs { impl<'de> ::serde::Deserialize<'de> for Fs { fn deserialize(deserializer: D) -> Result - where D: ::serde::Deserializer<'de> + where + D: ::serde::Deserializer<'de>, { let repr = FsRepr::deserialize(deserializer)?; let new = Self::from_repr(repr).expect("serialized representation is expected to be valid"); @@ -333,9 +303,7 @@ impl PrimeField for Fs { fn into_repr(&self) -> FsRepr { let mut r = *self; - r.mont_reduce((self.0).0[0], (self.0).0[1], - (self.0).0[2], (self.0).0[3], - 0, 0, 0, 0); + r.mont_reduce((self.0).0[0], (self.0).0[1], (self.0).0[2], (self.0).0[3], 0, 0, 0, 0); r.0 } @@ -477,8 +445,7 @@ impl Field for Fs { } #[inline] - fn mul_assign(&mut self, other: &Fs) - { + fn mul_assign(&mut self, other: &Fs) { let mut carry = 0; let r0 = mac_with_carry(0, (self.0).0[0], (other.0).0[0], &mut carry); let r1 = mac_with_carry(0, (self.0).0[0], (other.0).0[1], &mut carry); @@ -507,8 +474,7 @@ impl Field for Fs { } #[inline] - fn square(&mut self) - { + fn square(&mut self) { let mut carry = 0; let r1 = mac_with_carry(0, (self.0).0[0], (self.0).0[1], &mut carry); let r2 = mac_with_carry(0, (self.0).0[0], (self.0).0[2], &mut carry); @@ -561,18 +527,7 @@ impl Fs { } #[inline(always)] - fn mont_reduce( - &mut self, - r0: u64, - mut r1: u64, - mut r2: u64, - mut r3: u64, - mut r4: u64, - mut r5: u64, - mut r6: u64, - mut r7: u64 - ) - { + fn mont_reduce(&mut self, r0: u64, mut r1: u64, mut r2: u64, mut r3: u64, mut r4: u64, mut r5: u64, mut r6: u64, mut r7: u64) { // The Montgomery reduction here is based on Algorithm 14.32 in // Handbook of Applied Cryptography // . @@ -653,18 +608,16 @@ impl ToUniform for Fs { } impl SqrtField for Fs { - fn legendre(&self) -> LegendreSymbol { // s = self^((s - 1) // 2) - let s = self.pow([ - 0x33b94bee1c909378, - 0xd59f76dc1c907705, - 0x9b85045b68181585, - 0x030644e72e131a02, - ]); - if s == Self::zero() { Zero } - else if s == Self::one() { QuadraticResidue } - else { QuadraticNonResidue } + let s = self.pow([0x33b94bee1c909378, 0xd59f76dc1c907705, 0x9b85045b68181585, 0x030644e72e131a02]); + if s == Self::zero() { + Zero + } else if s == Self::one() { + QuadraticResidue + } else { + QuadraticNonResidue + } } fn sqrt(&self) -> Option { @@ -694,7 +647,6 @@ impl SqrtField for Fs { } } - #[test] fn test_neg_one() { let mut o = Fs::one(); @@ -704,7 +656,7 @@ fn test_neg_one() { } #[cfg(test)] -use rand::{SeedableRng, XorShiftRng, Rand}; +use rand::{Rand, SeedableRng, XorShiftRng}; #[test] fn test_fs_repr_ordering() { @@ -779,30 +731,15 @@ fn test_fs_repr_div2() { fn test_fs_repr_shr() { let mut a = FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1]); a.shr(0); - assert_eq!( - a, - FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1]) - ); + assert_eq!(a, FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1])); a.shr(1); - assert_eq!( - a, - FsRepr([0xd99fdd762415141f, 0xccbef069d44659ef, 0xcd7b16954d072a92, 0x1b001d5846f386d0]) - ); + assert_eq!(a, FsRepr([0xd99fdd762415141f, 0xccbef069d44659ef, 0xcd7b16954d072a92, 0x1b001d5846f386d0])); a.shr(50); - assert_eq!( - a, - FsRepr([0xbc1a7511967bf667, 0xc5a55341caa4b32f, 0x75611bce1b4335e, 0x6c0]) - ); + assert_eq!(a, FsRepr([0xbc1a7511967bf667, 0xc5a55341caa4b32f, 0x75611bce1b4335e, 0x6c0])); a.shr(130); - assert_eq!( - a, - FsRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0]) - ); + assert_eq!(a, FsRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0])); a.shr(64); - assert_eq!( - a, - FsRepr([0x1b0, 0x0, 0x0, 0x0]) - ); + assert_eq!(a, FsRepr([0x1b0, 0x0, 0x0, 0x0])); } #[test] @@ -1276,10 +1213,7 @@ fn test_fs_repr_display() { format!("{}", FsRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])), "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff".to_string() ); - assert_eq!( - format!("{}", FsRepr([0, 0, 0, 0])), - "0x0000000000000000000000000000000000000000000000000000000000000000".to_string() - ); + assert_eq!(format!("{}", FsRepr([0, 0, 0, 0])), "0x0000000000000000000000000000000000000000000000000000000000000000".to_string()); } #[test] @@ -1305,17 +1239,9 @@ fn test_fs_root_of_unity() { // assert_eq!(Fs::S, 1); assert_eq!(Fs::multiplicative_generator(), Fs::from_repr(FsRepr::from(7)).unwrap()); assert_eq!( - Fs::multiplicative_generator().pow([ - 0xa677297dc392126f, - 0xbab3eedb83920ee0, - 0x5370a08b6d0302b0, - 0x0060c89ce5c26340, - ]), + Fs::multiplicative_generator().pow([0xa677297dc392126f, 0xbab3eedb83920ee0, 0x5370a08b6d0302b0, 0x0060c89ce5c26340,]), Fs::root_of_unity() ); - assert_eq!( - Fs::root_of_unity().pow([1 << Fs::S]), - Fs::one() - ); + assert_eq!(Fs::root_of_unity().pow([1 << Fs::S]), Fs::one()); assert!(Fs::multiplicative_generator().sqrt().is_none()); } diff --git a/crates/franklin-crypto/src/alt_babyjubjub/mod.rs b/crates/franklin-crypto/src/alt_babyjubjub/mod.rs index d55c16e..809a91e 100644 --- a/crates/franklin-crypto/src/alt_babyjubjub/mod.rs +++ b/crates/franklin-crypto/src/alt_babyjubjub/mod.rs @@ -1,16 +1,16 @@ //! Alternative Baby Jubjub is a twisted Edwards curve defined over the BN256 scalar -//! field, Fr. +//! field, Fr. //! `Fr modulus = 21888242871839275222246405745257275088548364400416034343698204186575808495617` -//! +//! //! It takes the form `-x^2 + y^2 = 1 + dx^2y^2` with -//! `d = -(168696/168700)` using the isomorphism from usual Baby Jubjub -//! with a requirement that `a' = -1, a = 168696`, that results in +//! `d = -(168696/168700)` using the isomorphism from usual Baby Jubjub +//! with a requirement that `a' = -1, a = 168696`, that results in //! ```text -//! scaling = 1911982854305225074381251344103329931637610209014896889891168275855466657090 +//! scaling = 1911982854305225074381251344103329931637610209014896889891168275855466657090 //! a' = 21888242871839275222246405745257275088548364400416034343698204186575808495616 == -1 = a*scale^2 mod P //! d' = 12181644023421730124874158521699555681764249180949974110617291017600649128846 == -(168696/168700) = d*scale^2 //! ``` -//! +//! //! It is birationally equivalent to a Montgomery //! curve of the form `y^2 = x^3 + Ax^2 + x` with `A = 168698`. This //! value `A` is the smallest integer choice such that: @@ -37,30 +37,15 @@ // JubjubParams, // }; -use bellman::pairing::ff::{ - Field, - PrimeField, -}; +use bellman::pairing::ff::{Field, PrimeField}; use group_hash::{baby_group_hash, generic_group_hash}; use constants; -use bellman::pairing::bn256::{ - Bn256, - Fr -}; - -pub use super::jubjub::{ - Unknown, - PrimeOrder, - FixedGenerators, - ToUniform, - JubjubEngine, - JubjubParams, - edwards, - montgomery -}; +use bellman::pairing::bn256::{Bn256, Fr}; + +pub use super::jubjub::{edwards, montgomery, FixedGenerators, JubjubEngine, JubjubParams, PrimeOrder, ToUniform, Unknown}; // /// This is an implementation of the twisted Edwards Jubjub curve. // pub mod edwards; @@ -97,10 +82,18 @@ pub struct AltJubjubBn256 { } impl JubjubParams for AltJubjubBn256 { - fn edwards_d(&self) -> &Fr { &self.edwards_d } - fn montgomery_a(&self) -> &Fr { &self.montgomery_a } - fn montgomery_2a(&self) -> &Fr { &self.montgomery_2a } - fn scale(&self) -> &Fr { &self.scale } + fn edwards_d(&self) -> &Fr { + &self.edwards_d + } + fn montgomery_a(&self) -> &Fr { + &self.montgomery_a + } + fn montgomery_2a(&self) -> &Fr { + &self.montgomery_2a + } + fn scale(&self) -> &Fr { + &self.scale + } fn pedersen_hash_generators(&self) -> &[edwards::Point] { &self.pedersen_hash_generators } @@ -116,12 +109,10 @@ impl JubjubParams for AltJubjubBn256 { fn pedersen_circuit_generators(&self) -> &[Vec>] { &self.pedersen_circuit_generators } - fn generator(&self, base: FixedGenerators) -> &edwards::Point - { + fn generator(&self, base: FixedGenerators) -> &edwards::Point { &self.fixed_base_generators[base as usize] } - fn circuit_generators(&self, base: FixedGenerators) -> &[Vec<(Fr, Fr)>] - { + fn circuit_generators(&self, base: FixedGenerators) -> &[Vec<(Fr, Fr)>] { &self.fixed_base_circuit_generators[base as usize][..] } fn pedersen_hash_exp_window_size(&self) -> u32 { @@ -153,22 +144,13 @@ impl AltJubjubBn256 { fixed_base_circuit_generators: vec![], }; - fn find_group_hash( - m: &[u8], - personalization: &[u8; 8], - params: &E::Params - ) -> edwards::Point - { + fn find_group_hash(m: &[u8], personalization: &[u8; 8], params: &E::Params) -> edwards::Point { let mut tag = m.to_vec(); let i = tag.len(); tag.push(0u8); loop { - let gh = baby_group_hash( - &tag, - personalization, - params - ); + let gh = baby_group_hash(&tag, personalization, params); // We don't want to overflow and start reusing generators assert!(tag[i] != u8::max_value()); @@ -185,18 +167,12 @@ impl AltJubjubBn256 { let mut pedersen_hash_generators = vec![]; for m in 0..5 { - use byteorder::{WriteBytesExt, LittleEndian}; + use byteorder::{LittleEndian, WriteBytesExt}; let mut segment_number = [0u8; 4]; (&mut segment_number[0..4]).write_u32::(m).unwrap(); - pedersen_hash_generators.push( - find_group_hash( - &segment_number, - constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, - &tmp_params - ) - ); + pedersen_hash_generators.push(find_group_hash(&segment_number, constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params)); } // Check for duplicates, far worse than spec inconsistencies! @@ -205,7 +181,7 @@ impl AltJubjubBn256 { panic!("Neutral element!"); } - for p2 in pedersen_hash_generators.iter().skip(i+1) { + for p2 in pedersen_hash_generators.iter().skip(i + 1) { if p1 == p2 { panic!("Duplicate generator!"); } @@ -255,23 +231,17 @@ impl AltJubjubBn256 { { let mut fixed_base_generators = vec![edwards::Point::zero(); FixedGenerators::Max as usize]; - fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = - find_group_hash(&[], constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = find_group_hash(&[], constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] = - find_group_hash(b"r", constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] = find_group_hash(b"r", constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::NullifierPosition as usize] = - find_group_hash(&[], constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::NullifierPosition as usize] = find_group_hash(&[], constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = - find_group_hash(b"v", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = find_group_hash(b"v", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] = - find_group_hash(b"r", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] = find_group_hash(b"r", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = - find_group_hash(&[], constants::SPENDING_KEY_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = find_group_hash(&[], constants::SPENDING_KEY_GENERATOR_PERSONALIZATION, &tmp_params); // Check for duplicates, far worse than spec inconsistencies! for (i, p1) in fixed_base_generators.iter().enumerate() { @@ -279,7 +249,7 @@ impl AltJubjubBn256 { panic!("Neutral element!"); } - for p2 in fixed_base_generators.iter().skip(i+1) { + for p2 in fixed_base_generators.iter().skip(i + 1) { if p1 == p2 { panic!("Duplicate generator!"); } @@ -372,22 +342,13 @@ impl AltJubjubBn256 { fixed_base_circuit_generators: vec![], }; - fn find_group_hash( - m: &[u8], - personalization: &[u8; 8], - params: &E::Params - ) -> edwards::Point - { + fn find_group_hash(m: &[u8], personalization: &[u8; 8], params: &E::Params) -> edwards::Point { let mut tag = m.to_vec(); let i = tag.len(); tag.push(0u8); loop { - let gh = generic_group_hash::<_, HH>( - &tag, - personalization, - params - ); + let gh = generic_group_hash::<_, HH>(&tag, personalization, params); // We don't want to overflow and start reusing generators assert!(tag[i] != u8::max_value()); @@ -404,18 +365,12 @@ impl AltJubjubBn256 { let mut pedersen_hash_generators = vec![]; for m in 0..5 { - use byteorder::{WriteBytesExt, LittleEndian}; + use byteorder::{LittleEndian, WriteBytesExt}; let mut segment_number = [0u8; 4]; (&mut segment_number[0..4]).write_u32::(m).unwrap(); - pedersen_hash_generators.push( - find_group_hash::<_, H>( - &segment_number, - constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, - &tmp_params - ) - ); + pedersen_hash_generators.push(find_group_hash::<_, H>(&segment_number, constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params)); } // Check for duplicates, far worse than spec inconsistencies! @@ -424,7 +379,7 @@ impl AltJubjubBn256 { panic!("Neutral element!"); } - for p2 in pedersen_hash_generators.iter().skip(i+1) { + for p2 in pedersen_hash_generators.iter().skip(i + 1) { if p1 == p2 { panic!("Duplicate generator!"); } @@ -474,23 +429,17 @@ impl AltJubjubBn256 { { let mut fixed_base_generators = vec![edwards::Point::zero(); FixedGenerators::Max as usize]; - fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = - find_group_hash::<_, H>(&[], constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = find_group_hash::<_, H>(&[], constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] = - find_group_hash::<_, H>(b"r", constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] = find_group_hash::<_, H>(b"r", constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::NullifierPosition as usize] = - find_group_hash::<_, H>(&[], constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::NullifierPosition as usize] = find_group_hash::<_, H>(&[], constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = - find_group_hash::<_, H>(b"v", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = find_group_hash::<_, H>(b"v", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] = - find_group_hash::<_, H>(b"r", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] = find_group_hash::<_, H>(b"r", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = - find_group_hash::<_, H>(&[], constants::SPENDING_KEY_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = find_group_hash::<_, H>(&[], constants::SPENDING_KEY_GENERATOR_PERSONALIZATION, &tmp_params); // Check for duplicates, far worse than spec inconsistencies! for (i, p1) in fixed_base_generators.iter().enumerate() { @@ -498,7 +447,7 @@ impl AltJubjubBn256 { panic!("Neutral element!"); } - for p2 in fixed_base_generators.iter().skip(i+1) { + for p2 in fixed_base_generators.iter().skip(i + 1) { if p1 == p2 { panic!("Duplicate generator!"); } diff --git a/crates/franklin-crypto/src/alt_babyjubjub/tests.rs b/crates/franklin-crypto/src/alt_babyjubjub/tests.rs index 77813b4..819ed5c 100644 --- a/crates/franklin-crypto/src/alt_babyjubjub/tests.rs +++ b/crates/franklin-crypto/src/alt_babyjubjub/tests.rs @@ -1,20 +1,8 @@ -use super::{ - JubjubEngine, - JubjubParams, - PrimeOrder, - montgomery, - edwards -}; - -use bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - SqrtField, - LegendreSymbol -}; - -use rand::{XorShiftRng, SeedableRng, Rand}; +use super::{edwards, montgomery, JubjubEngine, JubjubParams, PrimeOrder}; + +use bellman::pairing::ff::{Field, LegendreSymbol, PrimeField, PrimeFieldRepr, SqrtField}; + +use rand::{Rand, SeedableRng, XorShiftRng}; pub fn test_suite(params: &E::Params) { test_back_and_forth::(params); @@ -29,12 +17,7 @@ pub fn test_suite(params: &E::Params) { test_read_write::(params); } -fn is_on_mont_curve>( - x: E::Fr, - y: E::Fr, - params: &P -) -> bool -{ +fn is_on_mont_curve>(x: E::Fr, y: E::Fr, params: &P) -> bool { let mut lhs = y; lhs.square(); @@ -52,12 +35,7 @@ fn is_on_mont_curve>( lhs == rhs } -fn is_on_twisted_edwards_curve>( - x: E::Fr, - y: E::Fr, - params: &P -) -> bool -{ +fn is_on_twisted_edwards_curve>(x: E::Fr, y: E::Fr, params: &P) -> bool { let mut x2 = x; x2.square(); @@ -237,11 +215,7 @@ fn test_get_for(params: &E::Params) { if let Some(mut p) = edwards::Point::::get_for_y(y, sign, params) { assert!(p.into_xy().0.into_repr().is_odd() == sign); p = p.negate(); - assert!( - edwards::Point::::get_for_y(y, !sign, params).unwrap() - == - p - ); + assert!(edwards::Point::::get_for_y(y, !sign, params).unwrap() == p); } } } @@ -293,13 +267,9 @@ fn test_back_and_forth(params: &E::Params) { let mont = mont_p1.add(&mont_p2, params).mul(s, params); let edwards = edwards_p1.add(&edwards_p2, params).mul(s, params); - assert!( - montgomery::Point::from_edwards(&edwards, params) == mont - ); + assert!(montgomery::Point::from_edwards(&edwards, params) == mont); - assert!( - edwards::Point::from_montgomery(&mont, params) == edwards - ); + assert!(edwards::Point::from_montgomery(&mont, params) == edwards); } } @@ -383,8 +353,7 @@ fn test_jubjub_params(params: &E::Params) { let mut pacc = E::Fs::zero().into_repr(); let mut nacc = E::Fs::char(); - for _ in 0..params.pedersen_hash_chunks_per_generator() - { + for _ in 0..params.pedersen_hash_chunks_per_generator() { // tmp = cur * 4 let mut tmp = cur; tmp.mul2(); diff --git a/crates/franklin-crypto/src/as_waksman.rs b/crates/franklin-crypto/src/as_waksman.rs index f39fc4a..b00066d 100644 --- a/crates/franklin-crypto/src/as_waksman.rs +++ b/crates/franklin-crypto/src/as_waksman.rs @@ -1,14 +1,11 @@ -use rand::{ - Rng -}; +use rand::Rng; const EMPTY_STATE: usize = std::usize::MAX; // this is basically a grid of size x columns pub struct AsWaksmanTopology { pub topology: Vec>, - pub size: usize - // pub switches: Vec> + pub size: usize, // pub switches: Vec> } impl AsWaksmanTopology { @@ -23,23 +20,16 @@ impl AsWaksmanTopology { let destinations: Vec = (0..size).collect(); // recursively iterate and construct the topology - Self::construct_inner(0, num_colunms-1, 0, size-1, &destinations, &mut topology); + Self::construct_inner(0, num_colunms - 1, 0, size - 1, &destinations, &mut topology); - Self { - topology, - size - } + Self { topology, size } } fn calculate_top_height(size: usize) -> usize { size / 2 } - fn construct_inner(left: usize, right: usize, - low: usize, high: usize, - destinations: &[usize], - topology: &mut [Vec<(usize, usize)>]) - { + fn construct_inner(left: usize, right: usize, low: usize, high: usize, destinations: &[usize], topology: &mut [Vec<(usize, usize)>]) { if left > right { return; } @@ -52,9 +42,8 @@ impl AsWaksmanTopology { let num_columns = right - left + 1; assert!(num_columns >= columns_to_generate); - if num_columns > columns_to_generate - { - // + if num_columns > columns_to_generate { + // // If there is more space for the routing network than needed, // just add straight edges. This also handles the size-1 base case. // @@ -68,10 +57,10 @@ impl AsWaksmanTopology { let mut subdestinations = vec![EMPTY_STATE; rows_to_generate]; for idx in low..=high { - subdestinations[idx-low] = idx; + subdestinations[idx - low] = idx; } - Self::construct_inner(left+1, right-1, low, high, &subdestinations, topology); + Self::construct_inner(left + 1, right - 1, low, high, &subdestinations, topology); } else if rows_to_generate == 2 { topology[left][low].0 = destinations[0]; topology[left][high].1 = destinations[0]; @@ -82,33 +71,28 @@ impl AsWaksmanTopology { // recursion step let mut subdestinations = vec![EMPTY_STATE; rows_to_generate]; - let limit = if rows_to_generate % 2 == 1 { - high - } else { - high + 1 - }; + let limit = if rows_to_generate % 2 == 1 { high } else { high + 1 }; for idx in (low..limit).step_by(2) { let top_idx = Self::calculate_in_out_index(rows_to_generate, low, idx, true); topology[left][idx].0 = top_idx; - topology[left][idx+1].1 = top_idx; + topology[left][idx + 1].1 = top_idx; let bottom_idx = Self::calculate_in_out_index(rows_to_generate, low, idx, false); topology[left][idx].1 = bottom_idx; - topology[left][idx+1].0 = bottom_idx; + topology[left][idx + 1].0 = bottom_idx; subdestinations[(top_idx as usize) - low] = idx; subdestinations[(bottom_idx as usize) - low] = idx + 1; topology[right][idx].0 = destinations[idx - low]; - topology[right][idx+1].1 = destinations[idx - low]; + topology[right][idx + 1].1 = destinations[idx - low]; topology[right][idx].1 = destinations[idx + 1 - low]; - topology[right][idx+1].0 = destinations[idx + 1 - low]; + topology[right][idx + 1].0 = destinations[idx + 1 - low]; } - if rows_to_generate % 2 == 1 - { + if rows_to_generate % 2 == 1 { topology[left][high].0 = high; topology[left][high].1 = high; @@ -116,10 +100,8 @@ impl AsWaksmanTopology { topology[right][high].1 = destinations[high - low]; subdestinations[high - low] = high; - } - else - { - topology[left][high-1].1 = topology[left][high-1].0; + } else { + topology[left][high - 1].1 = topology[left][high - 1].0; topology[left][high].1 = topology[left][high].0; } @@ -127,8 +109,8 @@ impl AsWaksmanTopology { let top_subnet_destinations = &subdestinations[..d]; let bottom_subnet_destinations = &subdestinations[d..]; - Self::construct_inner(left+1, right-1, low, low + d - 1, top_subnet_destinations, topology); - Self::construct_inner(left+1, right-1, low + d, high, bottom_subnet_destinations, topology); + Self::construct_inner(left + 1, right - 1, low, low + d - 1, top_subnet_destinations, topology); + Self::construct_inner(left + 1, right - 1, low + d, high, bottom_subnet_destinations, topology); } } @@ -142,15 +124,10 @@ impl AsWaksmanTopology { let ceil = as_float.log(2.0).ceil(); let num_colunms = ceil as usize; - 2*num_colunms - 1 + 2 * num_colunms - 1 } - fn calculate_in_out_index( - size: usize, - offset: usize, - index: usize, - is_top: bool - ) -> usize { + fn calculate_in_out_index(size: usize, offset: usize, index: usize, is_top: bool) -> usize { let mut relative_position = index - offset; assert!(relative_position % 2 == 0 && relative_position + 1 < size); relative_position >>= 1; @@ -170,7 +147,7 @@ impl AsWaksmanTopology { pub struct IntegerPermutation { pub elements: Vec, pub min: usize, - pub max: usize + pub max: usize, } impl IntegerPermutation { @@ -185,11 +162,7 @@ impl IntegerPermutation { pub(crate) fn new_for_max_and_min(min: usize, max: usize) -> Self { let elements: Vec = (min..=max).collect(); - Self { - elements, - min: min, - max: max - } + Self { elements, min: min, max: max } } pub fn size(&self) -> usize { @@ -219,7 +192,7 @@ impl IntegerPermutation { let result = Self { elements: self.elements[(min - self.min)..(max - self.min + 1)].to_vec(), min: min, - max: max + max: max, }; assert!(result.size() == result.elements.len()); @@ -241,7 +214,7 @@ impl IntegerPermutation { return true; } - let mut set: std::collections::HashSet = std::collections::HashSet::with_capacity(self.elements.len()); + let mut set: std::collections::HashSet = std::collections::HashSet::with_capacity(self.elements.len()); for element in self.elements.iter() { if *element < self.min || *element > self.max { return false; @@ -253,13 +226,13 @@ impl IntegerPermutation { } true - } + } } // this is basically a grid of size x columns pub struct AsWaksmanRoute { pub switches: Vec>, - pub size: usize + pub size: usize, } impl AsWaksmanRoute { @@ -271,12 +244,9 @@ impl AsWaksmanRoute { let inversed_permutation = permutation.inverse(); assert!(inversed_permutation.inverse().elements == permutation.elements); - Self::construct_inner(0, num_columns-1, 0, size-1, permutation, &inversed_permutation, &mut assignments); + Self::construct_inner(0, num_columns - 1, 0, size - 1, permutation, &inversed_permutation, &mut assignments); - Self { - switches: assignments, - size - } + Self { switches: assignments, size } } fn get_canonical_row_index(offset: usize, row_index: usize) -> usize { @@ -305,14 +275,15 @@ impl AsWaksmanRoute { } fn construct_inner( - left: usize, right: usize, - low: usize, high: usize, + left: usize, + right: usize, + low: usize, + high: usize, permutation: &IntegerPermutation, permutation_inversed: &IntegerPermutation, - switches: &mut [std::collections::HashMap] + switches: &mut [std::collections::HashMap], ) { - if left > right - { + if left > right { return; } @@ -328,20 +299,15 @@ impl AsWaksmanRoute { assert!(permutation.inverse().elements == permutation_inversed.elements); assert!(permutation_inversed.inverse().elements == permutation.elements); - if num_columns > columns_to_generate - { - Self::construct_inner(left+1, right - 1, low, high, permutation, permutation_inversed, switches); - } - else if rows_to_generate == 2 - { - assert!(permutation.get(low) == low || permutation.get(low) == low+1); - assert!(permutation.get(low+1) == low || permutation.get(low+1) == low+1); - assert!(permutation.get(low) != permutation.get(low+1)); + if num_columns > columns_to_generate { + Self::construct_inner(left + 1, right - 1, low, high, permutation, permutation_inversed, switches); + } else if rows_to_generate == 2 { + assert!(permutation.get(low) == low || permutation.get(low) == low + 1); + assert!(permutation.get(low + 1) == low || permutation.get(low + 1) == low + 1); + assert!(permutation.get(low) != permutation.get(low + 1)); switches[left].insert(low, permutation.get(low) != low); - } - else - { + } else { // // The algorithm first assigns a setting to a LHS switch, // route its target to RHS, which will enforce a RHS switch setting. @@ -358,15 +324,13 @@ impl AsWaksmanRoute { let mut should_route_left; - if rows_to_generate % 2 == 1 - { + if rows_to_generate % 2 == 1 { // // ODD CASE: we first deal with the bottom-most straight wire, // which is not connected to any of the switches at this level // of recursion and just passed into the lower subnetwork. // - if permutation.get(high) == high - { + if permutation.get(high) == high { // // Easy sub-case: it is routed directly to the bottom-most // wire on RHS, so no switches need to be touched. @@ -375,9 +339,7 @@ impl AsWaksmanRoute { new_permutation_inversed.set(high, high); to_route = high - 1; should_route_left = true; - } - else - { + } else { // // Other sub-case: the straight wire is routed to a switch // on RHS, so route the other value from that switch @@ -398,9 +360,7 @@ impl AsWaksmanRoute { lhs_is_routed[high - low] = true; max_unrouted = high - 1; - } - else - { + } else { // // EVEN CASE: the bottom-most switch is fixed to a constant // straight setting. So we route wire hi accordingly. @@ -411,25 +371,21 @@ impl AsWaksmanRoute { max_unrouted = high; } - loop - { + loop { // // INVARIANT: the wire `to_route' on LHS (if route_left = true), // resp., RHS (if route_left = false) can be routed. // - if should_route_left - { + if should_route_left { // If switch value has not been assigned, assign it arbitrarily. let lhs_switch = Self::get_canonical_row_index(low, to_route); - if switches[left].get(&lhs_switch).is_none() - { + if switches[left].get(&lhs_switch).is_none() { switches[left].insert(lhs_switch, false); } let lhs_switch_setting = *switches[left].get(&lhs_switch).unwrap(); let should_use_top = Self::get_top_bottom_decision_from_switch_setting(low, to_route, lhs_switch_setting); let t = AsWaksmanTopology::calculate_in_out_index(rows_to_generate, low, lhs_switch, should_use_top); - if permutation.get(to_route) == high - { + if permutation.get(to_route) == high { // // We have routed to the straight wire for the odd case, // so now we back-route from it. @@ -439,9 +395,7 @@ impl AsWaksmanRoute { lhs_is_routed[to_route - low] = true; to_route = max_unrouted; should_route_left = true; - } - else - { + } else { let rhs_switch = Self::get_canonical_row_index(low, permutation.get(to_route)); // // We know that the corresponding switch on the right-hand side @@ -459,9 +413,7 @@ impl AsWaksmanRoute { to_route = Self::calculate_other_position(low, permutation.get(to_route)); should_route_left = false; } - } - else - { + } else { // // We have arrived on the right-hand side, so the switch setting is fixed. // Next, we back route from here. @@ -491,31 +443,25 @@ impl AsWaksmanRoute { } /* If the next packet to be routed hasn't been routed before, then try routing it. */ - if !should_route_left || !lhs_is_routed[to_route-low] - { + if !should_route_left || !lhs_is_routed[to_route - low] { continue; } /* Otherwise just find the next unrouted packet. */ - while max_unrouted > low && lhs_is_routed[max_unrouted-low] - { + while max_unrouted > low && lhs_is_routed[max_unrouted - low] { max_unrouted -= 1; } - if max_unrouted < low || (max_unrouted == low && lhs_is_routed[0]) - { + if max_unrouted < low || (max_unrouted == low && lhs_is_routed[0]) { /* All routed! */ break; - } - else - { + } else { to_route = max_unrouted; should_route_left = true; } } - if rows_to_generate % 2 == 0 - { + if rows_to_generate % 2 == 0 { /* Remove the AS-Waksman switch with the fixed value. */ switches[left].remove(&(high - 1)); } @@ -530,14 +476,12 @@ impl AsWaksmanRoute { let new_permutation_inversed_upper = new_permutation_inversed.slice(low, low + d - 1); let new_permutation_inversed_lower = new_permutation_inversed.slice(low + d, high); - Self::construct_inner(left+1, right-1, low, low + d - 1, &new_permutation_upper, &new_permutation_inversed_upper, switches); - Self::construct_inner(left+1, right-1, low + d, high, &new_permutation_lower, &new_permutation_inversed_lower, switches); + Self::construct_inner(left + 1, right - 1, low, low + d - 1, &new_permutation_upper, &new_permutation_inversed_upper, switches); + Self::construct_inner(left + 1, right - 1, low + d, high, &new_permutation_lower, &new_permutation_inversed_lower, switches); } } - fn validate_routing_for_permutation(permutation: &IntegerPermutation, - routing: &Self) -> bool - { + fn validate_routing_for_permutation(permutation: &IntegerPermutation, routing: &Self) -> bool { let size = permutation.size(); let num_columns = AsWaksmanTopology::num_colunms(size); let topology = AsWaksmanTopology::new(size); @@ -551,22 +495,12 @@ impl AsWaksmanRoute { if topology.topology[column_idx][packet_idx].0 == topology.topology[column_idx][packet_idx].1 { // straight switch routed_index = topology.topology[column_idx][packet_idx].0; - } - else - { + } else { let a = routing.switches[column_idx].get(&packet_idx); - let b = if packet_idx > 0 { - routing.switches[column_idx].get(&(packet_idx - 1)) - } else { - None - }; + let b = if packet_idx > 0 { routing.switches[column_idx].get(&(packet_idx - 1)) } else { None }; assert!(a.is_some() ^ b.is_some()); - let switch_setting = if a.is_some() { - *a.unwrap() - } else { - *b.unwrap() - }; - + let switch_setting = if a.is_some() { *a.unwrap() } else { *b.unwrap() }; + routed_index = if switch_setting { topology.topology[column_idx][packet_idx].1 } else { @@ -624,11 +558,9 @@ impl AsWaksmanRoute { result } - // this function forwards newly created ordered set [0, n) into the permutation by switches // that were supplied to the router - fn calculate_permutation(&self) -> IntegerPermutation - { + fn calculate_permutation(&self) -> IntegerPermutation { let num_columns = AsWaksmanTopology::num_colunms(self.size); let topology = AsWaksmanTopology::new(self.size); @@ -641,22 +573,12 @@ impl AsWaksmanRoute { if topology.topology[column_idx][packet_idx].0 == topology.topology[column_idx][packet_idx].1 { // straight switch routed_into = topology.topology[column_idx][packet_idx].0; - } - else - { + } else { let a = self.switches[column_idx].get(&packet_idx); - let b = if packet_idx > 0 { - self.switches[column_idx].get(&(packet_idx - 1)) - } else { - None - }; + let b = if packet_idx > 0 { self.switches[column_idx].get(&(packet_idx - 1)) } else { None }; assert!(a.is_some() ^ b.is_some()); - let switch_setting = if a.is_some() { - *a.unwrap() - } else { - *b.unwrap() - }; - + let switch_setting = if a.is_some() { *a.unwrap() } else { *b.unwrap() }; + routed_into = if switch_setting { topology.topology[column_idx][packet_idx].1 } else { @@ -667,7 +589,7 @@ impl AsWaksmanRoute { let value_at_this_level = permutation.get(packet_idx); permutation_by_this_column.set(routed_into, value_at_this_level); } - + // permutation that we keep a track on is now replaced by result of permutation by this column permutation = permutation_by_this_column; } @@ -678,7 +600,7 @@ impl AsWaksmanRoute { #[test] fn test_aswaksman() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let size = 3; let mut permutation = IntegerPermutation::new(size); @@ -697,7 +619,7 @@ fn test_aswaksman() { #[test] fn test_back_and_forward_pass() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); for size in 3..4 { let mut permutation = IntegerPermutation::new(size); @@ -717,7 +639,7 @@ fn test_back_and_forward_pass() { #[test] fn test_forward_pass() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); for size in 3..9 { let mut permutation = IntegerPermutation::new(size); @@ -740,7 +662,7 @@ fn test_forward_pass() { #[test] fn test_trivial_permutations() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); let _topology = AsWaksmanTopology::new(3); // println!("Topology = {:?}", topology.topology); @@ -755,7 +677,7 @@ fn test_trivial_permutations() { #[test] fn test_routing_for_permutation() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); let _topology = AsWaksmanTopology::new(3); // println!("Topology = {:?}", topology.topology); @@ -778,7 +700,7 @@ fn test_routing_for_permutation() { #[test] fn test_uniformity() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); let size = 64; let mut hists: Vec> = vec![std::collections::HashMap::new(); size]; @@ -813,7 +735,7 @@ fn test_uniformity() { let mut xi_squared = 0.0f64; let expected = (num_trials as f64) / (size as f64); for (_, v) in subhist.iter() { - xi_squared += (v - expected)*(v - expected)/expected; + xi_squared += (v - expected) * (v - expected) / expected; } if xi_squared > max_xi_squared { @@ -848,7 +770,7 @@ fn test_uniformity() { // let mut cdf = vec![0.0f64; size]; // cdf[0] = normalized[0]; // for k in 1..size { - // cdf[k] = normalized[k] + cdf[k-1]; + // cdf[k] = normalized[k] + cdf[k-1]; // } // assert!(cdf[size-1] >= 0.99999); // let mut max = 0.0f64; @@ -869,4 +791,4 @@ fn test_uniformity() { // // and P = 0.99 // let alpha = 0.0015f64; // assert!(global_max < alpha); -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/constants.rs b/crates/franklin-crypto/src/constants.rs index 68f38a3..00b703a 100644 --- a/crates/franklin-crypto/src/constants.rs +++ b/crates/franklin-crypto/src/constants.rs @@ -2,69 +2,53 @@ /// This is chosen to be some random string that we couldn't have anticipated when we designed /// the algorithm, for rigidity purposes. /// We deliberately use an ASCII hex string of 32 bytes here. -pub const GH_FIRST_BLOCK: &'static [u8; 64] - = b"096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0"; +pub const GH_FIRST_BLOCK: &'static [u8; 64] = b"096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0"; // BLAKE2s invocation personalizations /// BLAKE2s Personalization for CRH^ivk = BLAKE2s(ak | nk) -pub const CRH_IVK_PERSONALIZATION: &'static [u8; 8] - = b"Zcashivk"; +pub const CRH_IVK_PERSONALIZATION: &'static [u8; 8] = b"Zcashivk"; /// BLAKE2s Personalization for PRF^nf = BLAKE2s(nk | rho) -pub const PRF_NF_PERSONALIZATION: &'static [u8; 8] - = b"Zcash_nf"; +pub const PRF_NF_PERSONALIZATION: &'static [u8; 8] = b"Zcash_nf"; // Group hash personalizations /// BLAKE2s Personalization for Pedersen hash generators. -pub const PEDERSEN_HASH_GENERATORS_PERSONALIZATION: &'static [u8; 8] - = b"Zcash_PH"; +pub const PEDERSEN_HASH_GENERATORS_PERSONALIZATION: &'static [u8; 8] = b"Zcash_PH"; /// BLAKE2s Personalization for the group hash for key diversification -pub const KEY_DIVERSIFICATION_PERSONALIZATION: &'static [u8; 8] - = b"Zcash_gd"; +pub const KEY_DIVERSIFICATION_PERSONALIZATION: &'static [u8; 8] = b"Zcash_gd"; /// BLAKE2s Personalization for the spending key base point -pub const SPENDING_KEY_GENERATOR_PERSONALIZATION: &'static [u8; 8] - = b"Zcash_G_"; +pub const SPENDING_KEY_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"Zcash_G_"; /// BLAKE2s Personalization for the proof generation key base point -pub const PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION: &'static [u8; 8] - = b"Zcash_H_"; +pub const PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"Zcash_H_"; /// BLAKE2s Personalization for the value commitment generator for the value -pub const VALUE_COMMITMENT_GENERATOR_PERSONALIZATION: &'static [u8; 8] - = b"Zcash_cv"; +pub const VALUE_COMMITMENT_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"Zcash_cv"; /// BLAKE2s Personalization for the nullifier position generator (for computing rho) -pub const NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION: &'static [u8; 8] - = b"Zcash_J_"; +pub const NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION: &'static [u8; 8] = b"Zcash_J_"; /// BLAKE2s Personalization hash of (R_x || message) in EdDSA variant with 256 bit hash -pub const MATTER_EDDSA_BLAKE2S_PERSONALIZATION: &'static [u8; 8] - = b"Matter_H"; +pub const MATTER_EDDSA_BLAKE2S_PERSONALIZATION: &'static [u8; 8] = b"Matter_H"; /// Eth block hash for block 10M -pub const ETH_BLOCK_10_000_000_HASH: &'static str - = "aa20f7bde5be60603f11a45fc4923aab7552be775403fc00c2e6b805e6297dbe"; - +pub const ETH_BLOCK_10_000_000_HASH: &'static str = "aa20f7bde5be60603f11a45fc4923aab7552be775403fc00c2e6b805e6297dbe"; /// DST constant for multiexp function -pub const MULTIEXP_DST: &'static [u8; 8] = b"Multiexp"; - +pub const MULTIEXP_DST: &'static [u8; 8] = b"Multiexp"; + use bellman::CurveAffine; use crate::bellman::pairing::{Engine, GenericCurveAffine, GenericCurveProjective}; use crate::byteorder::{BigEndian, ReadBytesExt}; - -pub fn make_random_points_with_unknown_discrete_log_from_seed( - dst: &[u8], - seed: &[u8], - num_points: usize -) -> Vec { + +pub fn make_random_points_with_unknown_discrete_log_from_seed(dst: &[u8], seed: &[u8], num_points: usize) -> Vec { let mut result = vec![]; - use rand::{Rng, SeedableRng}; use rand::chacha::ChaChaRng; + use rand::{Rng, SeedableRng}; // Create an RNG based on the outcome of the random beacon let mut rng = { // if we use Blake hasher @@ -86,39 +70,20 @@ pub fn make_random_points_with_unknown_discrete_log_from_seed( - dst: &[u8], - num_points: usize -) -> Vec { - make_random_points_with_unknown_discrete_log_from_seed::( - dst, - &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), - num_points - ) -} -pub fn make_random_points_with_unknown_discrete_log_generic( - dst: &[u8], - num_points: usize -) -> Vec { - make_random_points_with_unknown_discrete_log_from_seed::( - dst, - &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), - num_points - ) +pub fn make_random_points_with_unknown_discrete_log(dst: &[u8], num_points: usize) -> Vec { + make_random_points_with_unknown_discrete_log_from_seed::(dst, &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), num_points) } +pub fn make_random_points_with_unknown_discrete_log_generic(dst: &[u8], num_points: usize) -> Vec { + make_random_points_with_unknown_discrete_log_from_seed::(dst, &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), num_points) +} -pub fn make_random_points_with_unknown_discrete_log_from_seed_proj( - dst: &[u8], - seed: &[u8], - num_points: usize -) -> Vec { +pub fn make_random_points_with_unknown_discrete_log_from_seed_proj(dst: &[u8], seed: &[u8], num_points: usize) -> Vec { let mut result = vec![]; - use rand::{Rng, SeedableRng}; use rand::chacha::ChaChaRng; + use rand::{Rng, SeedableRng}; // Create an RNG based on the outcome of the random beacon let mut rng = { // if we use Blake hasher @@ -141,26 +106,11 @@ pub fn make_random_points_with_unknown_discrete_log_from_seed_proj( - dst: &[u8], - num_points: usize -) -> Vec { - make_random_points_with_unknown_discrete_log_from_seed_proj::( - dst, - &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), - num_points - ) + +pub fn make_random_points_with_unknown_discrete_log_proj(dst: &[u8], num_points: usize) -> Vec { + make_random_points_with_unknown_discrete_log_from_seed_proj::(dst, &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), num_points) } -pub fn make_random_points_with_unknown_discrete_log_generic_proj( - dst: &[u8], - num_points: usize -) -> Vec { - make_random_points_with_unknown_discrete_log_from_seed_proj::( - dst, - &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), - num_points - ) +pub fn make_random_points_with_unknown_discrete_log_generic_proj(dst: &[u8], num_points: usize) -> Vec { + make_random_points_with_unknown_discrete_log_from_seed_proj::(dst, &hex::decode(crate::constants::ETH_BLOCK_10_000_000_HASH).unwrap(), num_points) } - \ No newline at end of file diff --git a/crates/franklin-crypto/src/generic_twisted_edwards/bn256/mod.rs b/crates/franklin-crypto/src/generic_twisted_edwards/bn256/mod.rs index 779a38f..33750c1 100644 --- a/crates/franklin-crypto/src/generic_twisted_edwards/bn256/mod.rs +++ b/crates/franklin-crypto/src/generic_twisted_edwards/bn256/mod.rs @@ -41,23 +41,14 @@ impl AltBabyJubjubBn256 { impl AltBabyJubjubParams { pub fn new() -> Self { // d = -(168696/168700) - let d = ::Fr::from_str( - "12181644023421730124874158521699555681764249180949974110617291017600649128846", - ) - .expect("field element d"); + let d = ::Fr::from_str("12181644023421730124874158521699555681764249180949974110617291017600649128846").expect("field element d"); let mut a = ::Fr::one(); a.negate(); - let generator_x = ::Fr::from_str( - "21237458262955047976410108958495203094252581401952870797780751629344472264183", - ) - .expect("field element"); + let generator_x = ::Fr::from_str("21237458262955047976410108958495203094252581401952870797780751629344472264183").expect("field element"); - let generator_y = ::Fr::from_str( - "2544379904535866821506503524998632645451772693132171985463128613946158519479", - ) - .expect("field element"); + let generator_y = ::Fr::from_str("2544379904535866821506503524998632645451772693132171985463128613946158519479").expect("field element"); let log_2_cofactor = 3; // h = 8 @@ -77,16 +68,16 @@ impl AltBabyJubjubParams { } #[cfg(test)] -mod tests{ +mod tests { use super::*; use crate::alt_babyjubjub::fs::Fs; - use rand::{XorShiftRng, SeedableRng}; - use std::time::Instant; + use rand::{SeedableRng, XorShiftRng}; + use std::time::Instant; #[test] - fn test_conditonal_select_for_point(){ + fn test_conditonal_select_for_point() { let jubjub = AltBabyJubjubBn256::get_implementor(); - + let p = TwistedEdwardsPoint::::identity(); let q = jubjub.double(&p); @@ -97,17 +88,17 @@ mod tests{ } #[test] - fn test_constant_time_mul(){ + fn test_constant_time_mul() { let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let jubjub = AltBabyJubjubBn256::get_implementor(); - for _ in 0..100{ + for _ in 0..100 { let p = jubjub.rand(rng); let scalar = Fs::rand(rng); - + let expected = jubjub.mul(&p, scalar); - + let actual = jubjub.ct_mul(&p, scalar); assert_ne!(actual, TwistedEdwardsPoint::::identity()); assert_eq!(expected, actual); @@ -115,17 +106,17 @@ mod tests{ } #[test] - fn test_constant_time_mul_running_time(){ + fn test_constant_time_mul_running_time() { let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let jubjub = AltBabyJubjubBn256::get_implementor(); - for _ in 0..10{ + for _ in 0..10 { let p = jubjub.rand(rng); let scalar = Fs::rand(rng); - + let expected = jubjub.mul(&p, scalar); - let now = Instant::now(); + let now = Instant::now(); let actual = jubjub.ct_mul(&p, scalar); println!("elapsed {}", now.elapsed().as_nanos()); assert_ne!(actual, TwistedEdwardsPoint::::identity()); diff --git a/crates/franklin-crypto/src/generic_twisted_edwards/edwards.rs b/crates/franklin-crypto/src/generic_twisted_edwards/edwards.rs index b7eb9b1..9598276 100644 --- a/crates/franklin-crypto/src/generic_twisted_edwards/edwards.rs +++ b/crates/franklin-crypto/src/generic_twisted_edwards/edwards.rs @@ -74,11 +74,7 @@ impl PartialEq for TwistedEdwardsPoint { impl Eq for TwistedEdwardsPoint {} impl> TwistedEdwardsCurveImplementor { - pub fn add( - &self, - p: &TwistedEdwardsPoint, - q: &TwistedEdwardsPoint, - ) -> TwistedEdwardsPoint { + pub fn add(&self, p: &TwistedEdwardsPoint, q: &TwistedEdwardsPoint) -> TwistedEdwardsPoint { // See "Twisted Edwards Curves Revisited" // Huseyin Hisil, Kenneth Koon-Ho Wong, Gary Carter, and Ed Dawson // 3.1 Unified Addition in E^e @@ -149,12 +145,7 @@ impl> TwistedEdwardsCurveImplementor< let mut z3 = f; z3.mul_assign(&g); - TwistedEdwardsPoint { - x: x3, - y: y3, - t: t3, - z: z3, - } + TwistedEdwardsPoint { x: x3, y: y3, t: t3, z: z3 } } pub fn double(&self, p: &TwistedEdwardsPoint) -> TwistedEdwardsPoint { @@ -180,7 +171,7 @@ impl> TwistedEdwardsCurveImplementor< let d = if self.curve_params.is_param_a_equals_minus_one() { let mut d = a; d.negate(); - + d } else { let mut d = a; @@ -224,19 +215,10 @@ impl> TwistedEdwardsCurveImplementor< let mut z3 = f; z3.mul_assign(&g); - TwistedEdwardsPoint { - x: x3, - y: y3, - t: t3, - z: z3, - } + TwistedEdwardsPoint { x: x3, y: y3, t: t3, z: z3 } } - pub fn mul::Repr>>( - &self, - p: &TwistedEdwardsPoint, - scalar: S, - ) -> TwistedEdwardsPoint { + pub fn mul::Repr>>(&self, p: &TwistedEdwardsPoint, scalar: S) -> TwistedEdwardsPoint { // Standard double-and-add scalar multiplication let mut res = TwistedEdwardsPoint::identity(); @@ -253,11 +235,7 @@ impl> TwistedEdwardsCurveImplementor< } /// expects scalar bits as MSB first - pub fn mul_by_bits( - &self, - p: &TwistedEdwardsPoint, - scalar_bits: &[bool], - ) -> TwistedEdwardsPoint { + pub fn mul_by_bits(&self, p: &TwistedEdwardsPoint, scalar_bits: &[bool]) -> TwistedEdwardsPoint { // Standard double-and-add scalar multiplication let mut res = TwistedEdwardsPoint::identity(); @@ -273,11 +251,7 @@ impl> TwistedEdwardsCurveImplementor< res } - pub fn ct_mul( - &self, - p: &TwistedEdwardsPoint, - scalar: C::Fs, - ) -> TwistedEdwardsPoint { + pub fn ct_mul(&self, p: &TwistedEdwardsPoint, scalar: C::Fs) -> TwistedEdwardsPoint { // construct table from point let table = LookupTable::from_point(&p, self); @@ -287,7 +261,7 @@ impl> TwistedEdwardsCurveImplementor< // iterate and select from table let mut q = TwistedEdwardsPoint::identity(); - for i in (0..scalar_in_base_16.len()).rev(){ + for i in (0..scalar_in_base_16.len()).rev() { let s_i = scalar_in_base_16[i]; let t = table.select(s_i, self); @@ -295,7 +269,7 @@ impl> TwistedEdwardsCurveImplementor< q = self.double(&q); } - q = self.add(&q, &t) + q = self.add(&q, &t) } q @@ -310,17 +284,11 @@ impl> TwistedEdwardsCurveImplementor< q } - pub fn mul_by_generator::Repr>>( - &self, - scalar: S, - ) -> TwistedEdwardsPoint { + pub fn mul_by_generator::Repr>>(&self, scalar: S) -> TwistedEdwardsPoint { self.mul(&self.curve_params.generator(), scalar) } - pub fn is_in_main_subgroup( - &self, - p: &TwistedEdwardsPoint - ) -> bool { + pub fn is_in_main_subgroup(&self, p: &TwistedEdwardsPoint) -> bool { use crate::plonk::circuit::utils::words_to_msb_first_bits; let mut tmp = p.clone(); @@ -349,14 +317,14 @@ pub trait TwistedEdwardsCurveParams: Clone { pub struct TwistedEdwardsCurveImplementor> { pub curve_params: C, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl> TwistedEdwardsCurveImplementor { pub fn new_from_params(params: C) -> Self { Self { curve_params: params, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } @@ -364,11 +332,7 @@ impl> TwistedEdwardsCurveImplementor< &self.curve_params } - pub fn get_for_y( - &self, - y: E::Fr, - sign: bool, - ) -> Option> { + pub fn get_for_y(&self, y: E::Fr, sign: bool) -> Option> { // Given a y on the curve, x^2 = ((y^2 - 1) / (dy^2 + 1)) / -a // This is defined for all valid y-coordinates, // as dy^2 + 1 = 0 has no solution in Fr. @@ -404,12 +368,7 @@ impl> TwistedEdwardsCurveImplementor< let mut t = x; t.mul_assign(&y); - Some(TwistedEdwardsPoint { - x: x, - y: y, - t: t, - z: one, - }) + Some(TwistedEdwardsPoint { x: x, y: y, t: t, z: one }) } None => None, } @@ -437,7 +396,7 @@ impl ConditionalSelect for u64 { fn conditional_select(flag: u8, first: u64, second: u64) -> u64 { let bit = flag as u64; - bit*first + (1-bit)*second // TODO: check correctness + bit * first + (1 - bit) * second // TODO: check correctness } } @@ -461,13 +420,8 @@ impl TwistedEdwardsPoint { pub fn from_xy(x: E::Fr, y: E::Fr) -> Self { let mut t = x; t.mul_assign(&y); - - Self { - x, - y, - z: E::Fr::one(), - t, - } + + Self { x, y, z: E::Fr::one(), t } } pub fn into_xy(&self) -> (E::Fr, E::Fr) { let zinv = self.z.inverse().unwrap(); @@ -485,24 +439,15 @@ impl TwistedEdwardsPoint { let zero = E::Fr::zero(); let one = E::Fr::one(); - TwistedEdwardsPoint { - x: zero, - y: one, - t: zero, - z: one, - } + TwistedEdwardsPoint { x: zero, y: one, t: zero, z: one } } - pub fn conditional_select( - flag: u8, - first: &Self, - second: &Self, - ) -> Self { + pub fn conditional_select(flag: u8, first: &Self, second: &Self) -> Self { fn conditional_select_fe(flag: u8, first: &E::Fr, second: &E::Fr) -> E::Fr { let first_repr = first.into_raw_repr(); let second_repr = second.into_raw_repr(); let mut result_repr = ::Repr::default(); - + result_repr.as_mut()[0] = u64::conditional_select(flag, first_repr.as_ref()[0], second_repr.as_ref()[0]); result_repr.as_mut()[1] = u64::conditional_select(flag, first_repr.as_ref()[1], second_repr.as_ref()[1]); result_repr.as_mut()[2] = u64::conditional_select(flag, first_repr.as_ref()[2], second_repr.as_ref()[2]); @@ -539,15 +484,15 @@ impl GenericTwistedEdwardsCurveParams { pub fn new(d: E::Fr, a: E::Fr, generator: TwistedEdwardsPoint, log_2_cofactor: usize) -> Self { let mut minus_one = E::Fr::one(); minus_one.negate(); - - let is_param_a_equals_minus_one = a == minus_one; - Self { + let is_param_a_equals_minus_one = a == minus_one; + + Self { param_d: d, param_a: a, is_param_a_equals_minus_one, generator, - log_2_cofactor + log_2_cofactor, } } } diff --git a/crates/franklin-crypto/src/generic_twisted_edwards/mod.rs b/crates/franklin-crypto/src/generic_twisted_edwards/mod.rs index af6dc2e..5e79d54 100644 --- a/crates/franklin-crypto/src/generic_twisted_edwards/mod.rs +++ b/crates/franklin-crypto/src/generic_twisted_edwards/mod.rs @@ -1,8 +1,8 @@ +pub mod bn256; pub mod edwards; pub mod util; -pub mod bn256; #[cfg(test)] pub mod tests; -pub use self::edwards::{GenericTwistedEdwardsCurveParams, TwistedEdwardsCurveImplementor, TwistedEdwardsPoint, TwistedEdwardsCurveParams}; \ No newline at end of file +pub use self::edwards::{GenericTwistedEdwardsCurveParams, TwistedEdwardsCurveImplementor, TwistedEdwardsCurveParams, TwistedEdwardsPoint}; diff --git a/crates/franklin-crypto/src/generic_twisted_edwards/tests.rs b/crates/franklin-crypto/src/generic_twisted_edwards/tests.rs index f668ae6..86ad761 100644 --- a/crates/franklin-crypto/src/generic_twisted_edwards/tests.rs +++ b/crates/franklin-crypto/src/generic_twisted_edwards/tests.rs @@ -3,9 +3,9 @@ mod test { use crate::alt_babyjubjub::edwards::Point; use crate::alt_babyjubjub::fs::Fs; use crate::alt_babyjubjub::AltJubjubBn256; - use crate::generic_twisted_edwards::edwards::*; - use crate::generic_twisted_edwards::bn256::*; use crate::bellman::pairing::bn256::{Bn256, Fr}; + use crate::generic_twisted_edwards::bn256::*; + use crate::generic_twisted_edwards::edwards::*; use bellman::ScalarEngine; use rand::{Rand, Rng, SeedableRng, XorShiftRng}; @@ -133,7 +133,7 @@ mod test { (expected_x, expected_y) }; - + assert_eq!(actual_x, expected_x); assert_eq!(actual_y, expected_y); } diff --git a/crates/franklin-crypto/src/group_hash.rs b/crates/franklin-crypto/src/group_hash.rs index 8dc0b71..4fef147 100644 --- a/crates/franklin-crypto/src/group_hash.rs +++ b/crates/franklin-crypto/src/group_hash.rs @@ -1,16 +1,10 @@ -use jubjub::{ - JubjubEngine, - PrimeOrder, - edwards -}; +use jubjub::{edwards, JubjubEngine, PrimeOrder}; -use bellman::pairing::ff::{ - PrimeField -}; +use bellman::pairing::ff::PrimeField; -use tiny_keccak::Keccak; use blake2_rfc::blake2s::Blake2s; use constants; +use tiny_keccak::Keccak; pub trait GroupHasher { fn new(personalization: &[u8]) -> Self; @@ -19,16 +13,14 @@ pub trait GroupHasher { } pub struct BlakeHasher { - h: Blake2s + h: Blake2s, } impl GroupHasher for BlakeHasher { fn new(personalization: &[u8]) -> Self { let h = Blake2s::with_params(32, &[], &[], personalization); - Self { - h: h - } + Self { h: h } } fn update(&mut self, data: &[u8]) { @@ -48,7 +40,7 @@ impl GroupHasher for BlakeHasher { } pub struct Keccak256Hasher { - h: Keccak + h: Keccak, } impl GroupHasher for Keccak256Hasher { @@ -56,9 +48,7 @@ impl GroupHasher for Keccak256Hasher { let mut h = Keccak::new_keccak256(); h.update(personalization); - Self { - h: h - } + Self { h: h } } fn update(&mut self, data: &[u8]) { @@ -81,12 +71,7 @@ impl GroupHasher for Keccak256Hasher { /// Produces a random point in the Jubjub curve. /// The point is guaranteed to be prime order /// and not the identity. -pub fn group_hash( - tag: &[u8], - personalization: &[u8], - params: &E::Params -) -> Option> -{ +pub fn group_hash(tag: &[u8], personalization: &[u8], params: &E::Params) -> Option> { assert_eq!(personalization.len(), 8); // Check to see that scalar field is 255 bits @@ -107,20 +92,15 @@ pub fn group_hash( } else { None } - }, - Err(_) => None + } + Err(_) => None, } } /// Produces a random point in the Alt Baby Jubjub curve. /// The point is guaranteed to be prime order /// and not the identity. -pub fn baby_group_hash( - tag: &[u8], - personalization: &[u8], - params: &E::Params -) -> Option> -{ +pub fn baby_group_hash(tag: &[u8], personalization: &[u8], params: &E::Params) -> Option> { assert_eq!(personalization.len(), 8); // Check to see that scalar field is 255 bits @@ -141,20 +121,15 @@ pub fn baby_group_hash( } else { None } - }, - Err(_) => None + } + Err(_) => None, } } /// Produces a random point in the Jubjub curve. /// The point is guaranteed to be prime order /// and not the identity. -pub fn generic_group_hash( - tag: &[u8], - personalization: &[u8], - params: &E::Params -) -> Option> -{ +pub fn generic_group_hash(tag: &[u8], personalization: &[u8], params: &E::Params) -> Option> { assert_eq!(personalization.len(), 8); // Due to small number of iterations Fr should be close to 255 bits @@ -175,16 +150,16 @@ pub fn generic_group_hash( } else { None } - }, - Err(_) => None + } + Err(_) => None, } } #[test] fn test_generic_hash() { - use bellman::pairing::bn256::Bn256; - use alt_babyjubjub::JubjubEngine; use alt_babyjubjub::AltJubjubBn256; + use alt_babyjubjub::JubjubEngine; + use bellman::pairing::bn256::Bn256; let personalization = b"Hello123"; let params = AltJubjubBn256::new(); @@ -198,9 +173,9 @@ fn test_generic_hash() { #[test] fn test_export_blake_generators() { - use bellman::pairing::bn256::Bn256; - use alt_babyjubjub::JubjubEngine; use alt_babyjubjub::AltJubjubBn256; + use alt_babyjubjub::JubjubEngine; + use bellman::pairing::bn256::Bn256; let personalization = b"Hello123"; let params = AltJubjubBn256::new(); @@ -222,4 +197,4 @@ fn blake2s_consistency_test() { let h = h.finalize().as_ref().to_vec(); //let reference = hex!("989e1d96f8d977db95b7fcb59d26fe7f66b4e21e84cdb9387b67aa78ebd07ecf"); //assert_eq!(reference[..], h[..]); -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/interpolation.rs b/crates/franklin-crypto/src/interpolation.rs index 49d8fa0..b51f30a 100644 --- a/crates/franklin-crypto/src/interpolation.rs +++ b/crates/franklin-crypto/src/interpolation.rs @@ -1,15 +1,10 @@ use bellman::pairing::Engine; -use bellman::pairing::ff::{ - Field, - PrimeField -}; +use bellman::pairing::ff::{Field, PrimeField}; /// Perform a Lagrange interpolation for a set of points /// It's O(n^2) operations, so use with caution -pub fn interpolate( - points: &[(E::Fr, E::Fr)] -) -> Option> { +pub fn interpolate(points: &[(E::Fr, E::Fr)]) -> Option> { let max_degree_plus_one = points.len(); assert!(max_degree_plus_one >= 2, "should interpolate for degree >= 1"); let mut coeffs = vec![E::Fr::zero(); max_degree_plus_one]; @@ -36,13 +31,16 @@ pub fn interpolate( contribution.get_mut(0).expect("must have enough coefficients").sub_assign(&x_j); contribution.get_mut(1).expect("must have enough coefficients").add_assign(&E::Fr::one()); } else { - let mul_by_minus_x_j: Vec = contribution.iter().map(|el| { - let mut tmp = *el; - tmp.mul_assign(&x_j); - tmp.negate(); + let mul_by_minus_x_j: Vec = contribution + .iter() + .map(|el| { + let mut tmp = *el; + tmp.mul_assign(&x_j); + tmp.negate(); - tmp - }).collect(); + tmp + }) + .collect(); contribution.insert(0, E::Fr::zero()); contribution.truncate(max_degree_plus_one); @@ -63,16 +61,12 @@ pub fn interpolate( tmp.mul_assign(&y_k); c.add_assign(&tmp); } - } Some(coeffs) } -pub fn evaluate_at_x( - coeffs: &[E::Fr], - x: &E::Fr -) -> E::Fr { +pub fn evaluate_at_x(coeffs: &[E::Fr], x: &E::Fr) -> E::Fr { let mut res = E::Fr::zero(); let mut pow = E::Fr::one(); for c in coeffs.iter() { @@ -87,7 +81,7 @@ pub fn evaluate_at_x( } #[test] -fn test_interpolation_1(){ +fn test_interpolation_1() { use bellman::pairing::bn256::{Bn256, Fr}; let points = vec![(Fr::zero(), Fr::one()), (Fr::one(), Fr::from_str("2").unwrap())]; let interpolation_res = interpolate::(&points[..]).expect("must interpolate a linear func"); @@ -105,7 +99,7 @@ fn test_interpolation_1(){ } #[test] -fn test_interpolation_powers_of_2(){ +fn test_interpolation_powers_of_2() { use bellman::pairing::bn256::{Bn256, Fr}; const MAX_POWER: u32 = Fr::CAPACITY; @@ -115,7 +109,7 @@ fn test_interpolation_powers_of_2(){ for i in 0..MAX_POWER { let x = Fr::from_str(&i.to_string()).unwrap(); let y = power.clone(); - points.push((x,y)); + points.push((x, y)); power.mul_assign(&two); } @@ -130,8 +124,5 @@ fn test_interpolation_powers_of_2(){ // println!("Eval at {} = {}, original value = {}", x, val, y); // assert!(*y == val, format!("must assert equality for x = {}", x) ); assert_eq!(*y, val); - } } - - diff --git a/crates/franklin-crypto/src/jubjub/edwards.rs b/crates/franklin-crypto/src/jubjub/edwards.rs index 692ca63..81b1ff4 100644 --- a/crates/franklin-crypto/src/jubjub/edwards.rs +++ b/crates/franklin-crypto/src/jubjub/edwards.rs @@ -1,30 +1,12 @@ -use bellman::pairing::ff::{ - Field, - SqrtField, - PrimeField, - PrimeFieldRepr, - BitIterator -}; - -use super::{ - JubjubEngine, - JubjubParams, - Unknown, - PrimeOrder, - montgomery -}; - -use rand::{ - Rng -}; +use bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; + +use super::{montgomery, JubjubEngine, JubjubParams, PrimeOrder, Unknown}; + +use rand::Rng; use std::marker::PhantomData; -use std::io::{ - self, - Write, - Read -}; +use std::io::{self, Read, Write}; // Represents the affine point (X/Z, Y/Z) via the extended // twisted Edwards coordinates. @@ -40,30 +22,26 @@ pub struct Point { #[serde(skip)] #[serde(bound = "")] - _marker: PhantomData + _marker: PhantomData, } -fn convert_subgroup(from: &Point) -> Point -{ +fn convert_subgroup(from: &Point) -> Point { Point { x: from.x, y: from.y, t: from.t, z: from.z, - _marker: PhantomData + _marker: PhantomData, } } -impl From> for Point -{ - fn from(p: Point) -> Point - { +impl From> for Point { + fn from(p: Point) -> Point { convert_subgroup(&p) } } -impl Clone for Point -{ +impl Clone for Point { fn clone(&self) -> Self { convert_subgroup(self) } @@ -94,11 +72,7 @@ impl PartialEq for Point { } impl Point { - pub fn read( - reader: R, - params: &E::Params - ) -> io::Result - { + pub fn read(reader: R, params: &E::Params) -> io::Result { let mut y_repr = ::Repr::default(); y_repr.read_le(reader)?; @@ -106,22 +80,15 @@ impl Point { y_repr.as_mut()[3] &= 0x7fffffffffffffff; match E::Fr::from_repr(y_repr) { - Ok(y) => { - match Self::get_for_y(y, x_sign, params) { - Some(p) => Ok(p), - None => { - Err(io::Error::new(io::ErrorKind::InvalidInput, "not on curve")) - } - } + Ok(y) => match Self::get_for_y(y, x_sign, params) { + Some(p) => Ok(p), + None => Err(io::Error::new(io::ErrorKind::InvalidInput, "not on curve")), }, - Err(_) => { - Err(io::Error::new(io::ErrorKind::InvalidInput, "y is not in field")) - } + Err(_) => Err(io::Error::new(io::ErrorKind::InvalidInput, "y is not in field")), } } - pub fn from_xy(x: E::Fr, y: E::Fr, params: &E::Params) -> Option - { + pub fn from_xy(x: E::Fr, y: E::Fr, params: &E::Params) -> Option { // check that a point is on curve // y^2 - x^2 = 1 + d * x^2 * y^2 @@ -143,7 +110,6 @@ impl Point { if rhs != lhs { return None; - } let mut t = x; @@ -154,12 +120,11 @@ impl Point { y: y, t: t, z: E::Fr::one(), - _marker: PhantomData + _marker: PhantomData, }) } - pub fn from_xy_unchecked(x: E::Fr, y: E::Fr, params: &E::Params) -> (Self, bool) - { + pub fn from_xy_unchecked(x: E::Fr, y: E::Fr, params: &E::Params) -> (Self, bool) { // check that a point is on curve // y^2 - x^2 = 1 + d * x^2 * y^2 @@ -182,17 +147,19 @@ impl Point { let mut t = x; t.mul_assign(&y); - (Point { - x: x, - y: y, - t: t, - z: E::Fr::one(), - _marker: PhantomData - }, rhs==lhs) + ( + Point { + x: x, + y: y, + t: t, + z: E::Fr::one(), + _marker: PhantomData, + }, + rhs == lhs, + ) } - pub fn get_for_y(y: E::Fr, sign: bool, params: &E::Params) -> Option - { + pub fn get_for_y(y: E::Fr, sign: bool, params: &E::Params) -> Option { // Given a y on the curve, x^2 = (y^2 - 1) / (dy^2 + 1) // This is defined for all valid y-coordinates, // as dy^2 + 1 = 0 has no solution in Fr. @@ -228,19 +195,18 @@ impl Point { y: y, t: t, z: E::Fr::one(), - _marker: PhantomData + _marker: PhantomData, }) - }, - None => None + } + None => None, } - }, - None => None + } + None => None, } } // compress point into single E::Fr and a sign bit - pub fn compress_into_y(&self) -> (E::Fr, bool) - { + pub fn compress_into_y(&self) -> (E::Fr, bool) { // Given a y on the curve, read the x sign and leave y coordinate only // Important - normalize from extended coordinates let (x, y) = self.into_xy(); @@ -251,17 +217,13 @@ impl Point { /// This guarantees the point is in the prime order subgroup #[must_use] - pub fn mul_by_cofactor(&self, params: &E::Params) -> Point - { - let tmp = self.double(params) - .double(params) - .double(params); + pub fn mul_by_cofactor(&self, params: &E::Params) -> Point { + let tmp = self.double(params).double(params).double(params); convert_subgroup(&tmp) } - pub fn rand(rng: &mut R, params: &E::Params) -> Self - { + pub fn rand(rng: &mut R, params: &E::Params) -> Self { loop { let y: E::Fr = rng.gen(); @@ -273,11 +235,7 @@ impl Point { } impl Point { - pub fn write( - &self, - writer: W - ) -> io::Result<()> - { + pub fn write(&self, writer: W) -> io::Result<()> { let (x, y) = self.into_xy(); assert!(E::Fr::NUM_BITS <= 255); @@ -293,16 +251,12 @@ impl Point { } /// Convert from a Montgomery point - pub fn from_montgomery( - m: &montgomery::Point, - params: &E::Params - ) -> Self - { + pub fn from_montgomery(m: &montgomery::Point, params: &E::Params) -> Self { match m.into_xy() { None => { // Map the point at infinity to the neutral element. Point::zero() - }, + } Some((x, y)) => { // The map from a Montgomery curve is defined as: // (x, y) -> (u, v) where @@ -335,7 +289,7 @@ impl Point { y: neg1, t: E::Fr::zero(), z: E::Fr::one(), - _marker: PhantomData + _marker: PhantomData, } } else { // Otherwise, as stated above, the mapping is still @@ -394,7 +348,7 @@ impl Point { y: v, t: t, z: z, - _marker: PhantomData + _marker: PhantomData, } } } @@ -417,12 +371,11 @@ impl Point { y: E::Fr::one(), t: E::Fr::zero(), z: E::Fr::one(), - _marker: PhantomData + _marker: PhantomData, } } - pub fn into_xy(&self) -> (E::Fr, E::Fr) - { + pub fn into_xy(&self) -> (E::Fr, E::Fr) { let zinv = self.z.inverse().unwrap(); let mut x = self.x; @@ -509,13 +462,12 @@ impl Point { y: y3, t: t3, z: z3, - _marker: PhantomData + _marker: PhantomData, } } #[must_use] - pub fn add(&self, other: &Self, params: &E::Params) -> Self - { + pub fn add(&self, other: &Self, params: &E::Params) -> Self { // See "Twisted Edwards Curves Revisited" // Huseyin Hisil, Kenneth Koon-Ho Wong, Gary Carter, and Ed Dawson // 3.1 Unified Addition in E^e @@ -582,17 +534,12 @@ impl Point { y: y3, t: t3, z: z3, - _marker: PhantomData + _marker: PhantomData, } } #[must_use] - pub fn mul::Repr>>( - &self, - scalar: S, - params: &E::Params - ) -> Self - { + pub fn mul::Repr>>(&self, scalar: S, params: &E::Params) -> Self { // Standard double-and-add scalar multiplication let mut res = Self::zero(); diff --git a/crates/franklin-crypto/src/jubjub/fs.rs b/crates/franklin-crypto/src/jubjub/fs.rs index 52beb25..57ad2a1 100644 --- a/crates/franklin-crypto/src/jubjub/fs.rs +++ b/crates/franklin-crypto/src/jubjub/fs.rs @@ -1,8 +1,8 @@ -use byteorder::{ByteOrder, LittleEndian}; -use bellman::pairing::ff::{adc, sbb, mac_with_carry}; -use bellman::pairing::ff::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol}; -use bellman::pairing::ff::LegendreSymbol::*; use super::ToUniform; +use bellman::pairing::ff::LegendreSymbol::*; +use bellman::pairing::ff::{adc, mac_with_carry, sbb}; +use bellman::pairing::ff::{BitIterator, Field, LegendreSymbol, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, SqrtField}; +use byteorder::{ByteOrder, LittleEndian}; // s = 6554484396890773809930967563523245729705921265872317281365359162392183254199 const MODULUS: FsRepr = FsRepr([0xd0970e5ed6f72cb7, 0xa6682093ccc81082, 0x6673b0101343b00, 0xe7db4ea6533afa9]); @@ -46,8 +46,7 @@ impl ::rand::Rand for FsRepr { } } -impl ::std::fmt::Display for FsRepr -{ +impl ::std::fmt::Display for FsRepr { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "0x")?; for i in self.0.iter().rev() { @@ -86,9 +85,9 @@ impl Ord for FsRepr { fn cmp(&self, other: &FsRepr) -> ::std::cmp::Ordering { for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) { if a < b { - return ::std::cmp::Ordering::Less + return ::std::cmp::Ordering::Less; } else if a > b { - return ::std::cmp::Ordering::Greater + return ::std::cmp::Ordering::Greater; } } @@ -230,8 +229,7 @@ impl PrimeFieldRepr for FsRepr { #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Default)] pub struct Fs(FsRepr); -impl ::std::fmt::Display for Fs -{ +impl ::std::fmt::Display for Fs { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "Fs({})", self.into_repr()) } @@ -246,7 +244,7 @@ impl ::rand::Rand for Fs { tmp.0.as_mut()[3] &= 0xffffffffffffffff >> REPR_SHAVE_BITS; if tmp.is_valid() { - return tmp + return tmp; } } } @@ -260,7 +258,8 @@ impl From for FsRepr { impl ::serde::Serialize for Fs { fn serialize(&self, serializer: S) -> Result - where S: ::serde::Serializer + where + S: ::serde::Serializer, { let repr = self.into_repr(); repr.serialize(serializer) @@ -269,7 +268,8 @@ impl ::serde::Serialize for Fs { impl<'de> ::serde::Deserialize<'de> for Fs { fn deserialize(deserializer: D) -> Result - where D: ::serde::Deserializer<'de> + where + D: ::serde::Deserializer<'de>, { let repr = FsRepr::deserialize(deserializer)?; let new = Self::from_repr(repr).expect("serialized representation is expected to be valid"); @@ -303,9 +303,7 @@ impl PrimeField for Fs { fn into_repr(&self) -> FsRepr { let mut r = *self; - r.mont_reduce((self.0).0[0], (self.0).0[1], - (self.0).0[2], (self.0).0[3], - 0, 0, 0, 0); + r.mont_reduce((self.0).0[0], (self.0).0[1], (self.0).0[2], (self.0).0[3], 0, 0, 0, 0); r.0 } @@ -447,8 +445,7 @@ impl Field for Fs { } #[inline] - fn mul_assign(&mut self, other: &Fs) - { + fn mul_assign(&mut self, other: &Fs) { let mut carry = 0; let r0 = mac_with_carry(0, (self.0).0[0], (other.0).0[0], &mut carry); let r1 = mac_with_carry(0, (self.0).0[0], (other.0).0[1], &mut carry); @@ -477,8 +474,7 @@ impl Field for Fs { } #[inline] - fn square(&mut self) - { + fn square(&mut self) { let mut carry = 0; let r1 = mac_with_carry(0, (self.0).0[0], (self.0).0[1], &mut carry); let r2 = mac_with_carry(0, (self.0).0[0], (self.0).0[2], &mut carry); @@ -531,18 +527,7 @@ impl Fs { } #[inline(always)] - fn mont_reduce( - &mut self, - r0: u64, - mut r1: u64, - mut r2: u64, - mut r3: u64, - mut r4: u64, - mut r5: u64, - mut r6: u64, - mut r7: u64 - ) - { + fn mont_reduce(&mut self, r0: u64, mut r1: u64, mut r2: u64, mut r3: u64, mut r4: u64, mut r5: u64, mut r6: u64, mut r7: u64) { // The Montgomery reduction here is based on Algorithm 14.32 in // Handbook of Applied Cryptography // . @@ -623,13 +608,16 @@ impl ToUniform for Fs { } impl SqrtField for Fs { - fn legendre(&self) -> LegendreSymbol { // s = self^((s - 1) // 2) let s = self.pow([0x684b872f6b7b965b, 0x53341049e6640841, 0x83339d80809a1d80, 0x73eda753299d7d4]); - if s == Self::zero() { Zero } - else if s == Self::one() { QuadraticResidue } - else { QuadraticNonResidue } + if s == Self::zero() { + Zero + } else if s == Self::one() { + QuadraticResidue + } else { + QuadraticNonResidue + } } fn sqrt(&self) -> Option { @@ -642,19 +630,15 @@ impl SqrtField for Fs { a0.square(); a0.mul_assign(self); - if a0 == NEGATIVE_ONE - { + if a0 == NEGATIVE_ONE { None - } - else - { + } else { a1.mul_assign(self); Some(a1) } } } - #[test] fn test_neg_one() { let mut o = Fs::one(); @@ -664,7 +648,7 @@ fn test_neg_one() { } #[cfg(test)] -use rand::{SeedableRng, XorShiftRng, Rand}; +use rand::{Rand, SeedableRng, XorShiftRng}; #[test] fn test_fs_repr_ordering() { @@ -739,30 +723,15 @@ fn test_fs_repr_div2() { fn test_fs_repr_shr() { let mut a = FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1]); a.shr(0); - assert_eq!( - a, - FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1]) - ); + assert_eq!(a, FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1])); a.shr(1); - assert_eq!( - a, - FsRepr([0xd99fdd762415141f, 0xccbef069d44659ef, 0xcd7b16954d072a92, 0x1b001d5846f386d0]) - ); + assert_eq!(a, FsRepr([0xd99fdd762415141f, 0xccbef069d44659ef, 0xcd7b16954d072a92, 0x1b001d5846f386d0])); a.shr(50); - assert_eq!( - a, - FsRepr([0xbc1a7511967bf667, 0xc5a55341caa4b32f, 0x75611bce1b4335e, 0x6c0]) - ); + assert_eq!(a, FsRepr([0xbc1a7511967bf667, 0xc5a55341caa4b32f, 0x75611bce1b4335e, 0x6c0])); a.shr(130); - assert_eq!( - a, - FsRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0]) - ); + assert_eq!(a, FsRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0])); a.shr(64); - assert_eq!( - a, - FsRepr([0x1b0, 0x0, 0x0, 0x0]) - ); + assert_eq!(a, FsRepr([0x1b0, 0x0, 0x0, 0x0])); } #[test] @@ -1236,10 +1205,7 @@ fn test_fs_repr_display() { format!("{}", FsRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])), "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff".to_string() ); - assert_eq!( - format!("{}", FsRepr([0, 0, 0, 0])), - "0x0000000000000000000000000000000000000000000000000000000000000000".to_string() - ); + assert_eq!(format!("{}", FsRepr([0, 0, 0, 0])), "0x0000000000000000000000000000000000000000000000000000000000000000".to_string()); } #[test] @@ -1268,9 +1234,6 @@ fn test_fs_root_of_unity() { Fs::multiplicative_generator().pow([0x684b872f6b7b965b, 0x53341049e6640841, 0x83339d80809a1d80, 0x73eda753299d7d4]), Fs::root_of_unity() ); - assert_eq!( - Fs::root_of_unity().pow([1 << Fs::S]), - Fs::one() - ); + assert_eq!(Fs::root_of_unity().pow([1 << Fs::S]), Fs::one()); assert!(Fs::multiplicative_generator().sqrt().is_none()); } diff --git a/crates/franklin-crypto/src/jubjub/mod.rs b/crates/franklin-crypto/src/jubjub/mod.rs index 9268092..13da60a 100644 --- a/crates/franklin-crypto/src/jubjub/mod.rs +++ b/crates/franklin-crypto/src/jubjub/mod.rs @@ -17,24 +17,15 @@ //! the Montgomery curve forms a group isomorphism, allowing points //! to be freely converted between the two forms. -use bellman::pairing::{ - Engine, -}; +use bellman::pairing::Engine; -use bellman::pairing::ff::{ - Field, - PrimeField, - SqrtField -}; +use bellman::pairing::ff::{Field, PrimeField, SqrtField}; use group_hash::group_hash; use constants; -use bellman::pairing::bls12_381::{ - Bls12, - Fr -}; +use bellman::pairing::bls12_381::{Bls12, Fr}; /// This is an implementation of the twisted Edwards Jubjub curve. pub mod edwards; @@ -50,10 +41,10 @@ pub mod fs; pub mod tests; /// Point of unknown order. -pub enum Unknown { } +pub enum Unknown {} /// Point of prime order. -pub enum PrimeOrder { } +pub enum PrimeOrder {} /// Fixed generators of the Jubjub curve of unknown /// exponent. @@ -85,7 +76,7 @@ pub enum FixedGenerators { /// base at spend time. SpendingKeyGenerator = 5, - Max = 6 + Max = 6, } pub trait ToUniform { @@ -157,10 +148,18 @@ pub struct JubjubBls12 { } impl JubjubParams for JubjubBls12 { - fn edwards_d(&self) -> &Fr { &self.edwards_d } - fn montgomery_a(&self) -> &Fr { &self.montgomery_a } - fn montgomery_2a(&self) -> &Fr { &self.montgomery_2a } - fn scale(&self) -> &Fr { &self.scale } + fn edwards_d(&self) -> &Fr { + &self.edwards_d + } + fn montgomery_a(&self) -> &Fr { + &self.montgomery_a + } + fn montgomery_2a(&self) -> &Fr { + &self.montgomery_2a + } + fn scale(&self) -> &Fr { + &self.scale + } fn pedersen_hash_generators(&self) -> &[edwards::Point] { &self.pedersen_hash_generators } @@ -176,12 +175,10 @@ impl JubjubParams for JubjubBls12 { fn pedersen_circuit_generators(&self) -> &[Vec>] { &self.pedersen_circuit_generators } - fn generator(&self, base: FixedGenerators) -> &edwards::Point - { + fn generator(&self, base: FixedGenerators) -> &edwards::Point { &self.fixed_base_generators[base as usize] } - fn circuit_generators(&self, base: FixedGenerators) -> &[Vec<(Fr, Fr)>] - { + fn circuit_generators(&self, base: FixedGenerators) -> &[Vec<(Fr, Fr)>] { &self.fixed_base_circuit_generators[base as usize][..] } fn pedersen_hash_exp_window_size(&self) -> u32 { @@ -213,22 +210,13 @@ impl JubjubBls12 { fixed_base_circuit_generators: vec![], }; - fn find_group_hash( - m: &[u8], - personalization: &[u8; 8], - params: &E::Params - ) -> edwards::Point - { + fn find_group_hash(m: &[u8], personalization: &[u8; 8], params: &E::Params) -> edwards::Point { let mut tag = m.to_vec(); let i = tag.len(); tag.push(0u8); loop { - let gh = group_hash( - &tag, - personalization, - params - ); + let gh = group_hash(&tag, personalization, params); // We don't want to overflow and start reusing generators assert!(tag[i] != u8::max_value()); @@ -245,18 +233,12 @@ impl JubjubBls12 { let mut pedersen_hash_generators = vec![]; for m in 0..5 { - use byteorder::{WriteBytesExt, LittleEndian}; + use byteorder::{LittleEndian, WriteBytesExt}; let mut segment_number = [0u8; 4]; (&mut segment_number[0..4]).write_u32::(m).unwrap(); - pedersen_hash_generators.push( - find_group_hash( - &segment_number, - constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, - &tmp_params - ) - ); + pedersen_hash_generators.push(find_group_hash(&segment_number, constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params)); } // Check for duplicates, far worse than spec inconsistencies! @@ -265,7 +247,7 @@ impl JubjubBls12 { panic!("Neutral element!"); } - for p2 in pedersen_hash_generators.iter().skip(i+1) { + for p2 in pedersen_hash_generators.iter().skip(i + 1) { if p1 == p2 { panic!("Duplicate generator!"); } @@ -315,23 +297,17 @@ impl JubjubBls12 { { let mut fixed_base_generators = vec![edwards::Point::zero(); FixedGenerators::Max as usize]; - fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = - find_group_hash(&[], constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = find_group_hash(&[], constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] = - find_group_hash(b"r", constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] = find_group_hash(b"r", constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::NullifierPosition as usize] = - find_group_hash(&[], constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::NullifierPosition as usize] = find_group_hash(&[], constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = - find_group_hash(b"v", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = find_group_hash(b"v", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] = - find_group_hash(b"r", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] = find_group_hash(b"r", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); - fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = - find_group_hash(&[], constants::SPENDING_KEY_GENERATOR_PERSONALIZATION, &tmp_params); + fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = find_group_hash(&[], constants::SPENDING_KEY_GENERATOR_PERSONALIZATION, &tmp_params); // Check for duplicates, far worse than spec inconsistencies! for (i, p1) in fixed_base_generators.iter().enumerate() { @@ -339,7 +315,7 @@ impl JubjubBls12 { panic!("Neutral element!"); } - for p2 in fixed_base_generators.iter().skip(i+1) { + for p2 in fixed_base_generators.iter().skip(i + 1) { if p1 == p2 { panic!("Duplicate generator!"); } diff --git a/crates/franklin-crypto/src/jubjub/montgomery.rs b/crates/franklin-crypto/src/jubjub/montgomery.rs index 53ed1d8..5f09c82 100644 --- a/crates/franklin-crypto/src/jubjub/montgomery.rs +++ b/crates/franklin-crypto/src/jubjub/montgomery.rs @@ -1,22 +1,8 @@ -use bellman::pairing::ff::{ - Field, - SqrtField, - PrimeField, - PrimeFieldRepr, - BitIterator -}; - -use super::{ - JubjubEngine, - JubjubParams, - Unknown, - PrimeOrder, - edwards -}; - -use rand::{ - Rng -}; +use bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; + +use super::{edwards, JubjubEngine, JubjubParams, PrimeOrder, Unknown}; + +use rand::Rng; use std::marker::PhantomData; @@ -25,29 +11,25 @@ pub struct Point { x: E::Fr, y: E::Fr, infinity: bool, - _marker: PhantomData + _marker: PhantomData, } -fn convert_subgroup(from: &Point) -> Point -{ +fn convert_subgroup(from: &Point) -> Point { Point { x: from.x, y: from.y, infinity: from.infinity, - _marker: PhantomData + _marker: PhantomData, } } -impl From> for Point -{ - fn from(p: Point) -> Point - { +impl From> for Point { + fn from(p: Point) -> Point { convert_subgroup(&p) } } -impl Clone for Point -{ +impl Clone for Point { fn clone(&self) -> Self { convert_subgroup(self) } @@ -58,16 +40,13 @@ impl PartialEq for Point { match (self.infinity, other.infinity) { (true, true) => true, (true, false) | (false, true) => false, - (false, false) => { - self.x == other.x && self.y == other.y - } + (false, false) => self.x == other.x && self.y == other.y, } } } impl Point { - pub fn get_for_x(x: E::Fr, sign: bool, params: &E::Params) -> Option - { + pub fn get_for_x(x: E::Fr, sign: bool, params: &E::Params) -> Option { // Given an x on the curve, y = sqrt(x^3 + A*x^2 + x) let mut x2 = x; @@ -89,33 +68,27 @@ impl Point { x: x, y: y, infinity: false, - _marker: PhantomData - }) - }, - None => None + _marker: PhantomData, + }); + } + None => None, } } /// This guarantees the point is in the prime order subgroup #[must_use] - pub fn mul_by_cofactor(&self, params: &E::Params) -> Point - { - let tmp = self.double(params) - .double(params) - .double(params); + pub fn mul_by_cofactor(&self, params: &E::Params) -> Point { + let tmp = self.double(params).double(params).double(params); convert_subgroup(&tmp) } - pub fn rand(rng: &mut R, params: &E::Params) -> Self - { + pub fn rand(rng: &mut R, params: &E::Params) -> Self { loop { let x: E::Fr = rng.gen(); match Self::get_for_x(x, rng.gen(), params) { - Some(p) => { - return p - }, + Some(p) => return p, None => {} } } @@ -124,11 +97,7 @@ impl Point { impl Point { /// Convert from an Edwards point - pub fn from_edwards( - e: &edwards::Point, - params: &E::Params - ) -> Self - { + pub fn from_edwards(e: &edwards::Point, params: &E::Params) -> Self { let (x, y) = e.into_xy(); if y == E::Fr::one() { @@ -156,7 +125,7 @@ impl Point { x: E::Fr::zero(), y: E::Fr::zero(), infinity: false, - _marker: PhantomData + _marker: PhantomData, } } else { // The mapping is defined as above. @@ -183,7 +152,7 @@ impl Point { x: u, y: v, infinity: false, - _marker: PhantomData + _marker: PhantomData, } } } @@ -204,12 +173,11 @@ impl Point { x: E::Fr::zero(), y: E::Fr::zero(), infinity: true, - _marker: PhantomData + _marker: PhantomData, } } - pub fn into_xy(&self) -> Option<(E::Fr, E::Fr)> - { + pub fn into_xy(&self) -> Option<(E::Fr, E::Fr)> { if self.infinity { None } else { @@ -279,13 +247,12 @@ impl Point { x: x3, y: y3, infinity: false, - _marker: PhantomData + _marker: PhantomData, } } #[must_use] - pub fn add(&self, other: &Self, params: &E::Params) -> Self - { + pub fn add(&self, other: &Self, params: &E::Params) -> Self { // This is a standard affine point addition formula // See 4.3.2 The group law for Weierstrass curves // Montgomery curves and the Montgomery Ladder @@ -327,7 +294,7 @@ impl Point { x: x3, y: y3, infinity: false, - _marker: PhantomData + _marker: PhantomData, } } } @@ -335,12 +302,7 @@ impl Point { } #[must_use] - pub fn mul::Repr>>( - &self, - scalar: S, - params: &E::Params - ) -> Self - { + pub fn mul::Repr>>(&self, scalar: S, params: &E::Params) -> Self { // Standard double-and-add scalar multiplication let mut res = Self::zero(); diff --git a/crates/franklin-crypto/src/jubjub/tests.rs b/crates/franklin-crypto/src/jubjub/tests.rs index 77813b4..819ed5c 100644 --- a/crates/franklin-crypto/src/jubjub/tests.rs +++ b/crates/franklin-crypto/src/jubjub/tests.rs @@ -1,20 +1,8 @@ -use super::{ - JubjubEngine, - JubjubParams, - PrimeOrder, - montgomery, - edwards -}; - -use bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - SqrtField, - LegendreSymbol -}; - -use rand::{XorShiftRng, SeedableRng, Rand}; +use super::{edwards, montgomery, JubjubEngine, JubjubParams, PrimeOrder}; + +use bellman::pairing::ff::{Field, LegendreSymbol, PrimeField, PrimeFieldRepr, SqrtField}; + +use rand::{Rand, SeedableRng, XorShiftRng}; pub fn test_suite(params: &E::Params) { test_back_and_forth::(params); @@ -29,12 +17,7 @@ pub fn test_suite(params: &E::Params) { test_read_write::(params); } -fn is_on_mont_curve>( - x: E::Fr, - y: E::Fr, - params: &P -) -> bool -{ +fn is_on_mont_curve>(x: E::Fr, y: E::Fr, params: &P) -> bool { let mut lhs = y; lhs.square(); @@ -52,12 +35,7 @@ fn is_on_mont_curve>( lhs == rhs } -fn is_on_twisted_edwards_curve>( - x: E::Fr, - y: E::Fr, - params: &P -) -> bool -{ +fn is_on_twisted_edwards_curve>(x: E::Fr, y: E::Fr, params: &P) -> bool { let mut x2 = x; x2.square(); @@ -237,11 +215,7 @@ fn test_get_for(params: &E::Params) { if let Some(mut p) = edwards::Point::::get_for_y(y, sign, params) { assert!(p.into_xy().0.into_repr().is_odd() == sign); p = p.negate(); - assert!( - edwards::Point::::get_for_y(y, !sign, params).unwrap() - == - p - ); + assert!(edwards::Point::::get_for_y(y, !sign, params).unwrap() == p); } } } @@ -293,13 +267,9 @@ fn test_back_and_forth(params: &E::Params) { let mont = mont_p1.add(&mont_p2, params).mul(s, params); let edwards = edwards_p1.add(&edwards_p2, params).mul(s, params); - assert!( - montgomery::Point::from_edwards(&edwards, params) == mont - ); + assert!(montgomery::Point::from_edwards(&edwards, params) == mont); - assert!( - edwards::Point::from_montgomery(&mont, params) == edwards - ); + assert!(edwards::Point::from_montgomery(&mont, params) == edwards); } } @@ -383,8 +353,7 @@ fn test_jubjub_params(params: &E::Params) { let mut pacc = E::Fs::zero().into_repr(); let mut nacc = E::Fs::char(); - for _ in 0..params.pedersen_hash_chunks_per_generator() - { + for _ in 0..params.pedersen_hash_chunks_per_generator() { // tmp = cur * 4 let mut tmp = cur; tmp.mul2(); diff --git a/crates/franklin-crypto/src/lib.rs b/crates/franklin-crypto/src/lib.rs index 28545ea..ff38ba8 100644 --- a/crates/franklin-crypto/src/lib.rs +++ b/crates/franklin-crypto/src/lib.rs @@ -2,63 +2,60 @@ #![allow(macro_expanded_macro_exports_accessed_by_absolute_paths)] #![warn(unused_assignments)] - pub extern crate bellman; -pub extern crate boojum; +extern crate blake2; extern crate blake2_rfc_bellman_edition as blake2_rfc; +pub extern crate boojum; +extern crate byteorder; +extern crate derivative; extern crate digest; +extern crate indexmap; +extern crate itertools; +extern crate num_bigint; +extern crate num_derive; +extern crate num_integer; +extern crate num_traits; extern crate rand; -extern crate byteorder; -extern crate tiny_keccak; +extern crate serde; extern crate sha2; extern crate sha3; -extern crate num_bigint; -extern crate num_traits; -extern crate num_integer; -extern crate itertools; extern crate splitmut; -extern crate blake2; -extern crate serde; -extern crate num_derive; -extern crate indexmap; -extern crate derivative; +extern crate tiny_keccak; use bellman::pairing; use bellman::pairing::ff; - #[macro_use] extern crate lazy_static; #[macro_use] extern crate arr_macro; - #[cfg(test)] extern crate hex; -pub mod jubjub; pub mod alt_babyjubjub; +pub mod as_waksman; +pub mod constants; +pub mod generic_twisted_edwards; pub mod group_hash; +pub mod interpolation; +pub mod jubjub; pub mod pedersen_hash; +pub mod plonk; pub mod primitives; -pub mod constants; pub mod redjubjub; -pub mod util; -pub mod interpolation; -pub mod as_waksman; pub mod rescue; -pub mod generic_twisted_edwards; -pub mod plonk; +pub mod util; pub fn log2_floor(num: usize) -> u32 { assert!(num > 0); let mut pow = 0; - while (1 << (pow+1)) <= num { + while (1 << (pow + 1)) <= num { pow += 1; } pow -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/pedersen_hash.rs b/crates/franklin-crypto/src/pedersen_hash.rs index f5d02fa..c4102a8 100644 --- a/crates/franklin-crypto/src/pedersen_hash.rs +++ b/crates/franklin-crypto/src/pedersen_hash.rs @@ -1,17 +1,16 @@ -use jubjub::*; use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; +use jubjub::*; #[derive(Copy, Clone)] pub enum Personalization { NoteCommitment, - MerkleTree(usize) + MerkleTree(usize), } impl Personalization { pub fn get_bits(&self) -> Vec { match *self { - Personalization::NoteCommitment => - vec![true, true, true, true, true, true], + Personalization::NoteCommitment => vec![true, true, true, true, true, true], Personalization::MerkleTree(num) => { assert!(num < 63); @@ -21,13 +20,10 @@ impl Personalization { } } -pub fn pedersen_hash( - personalization: Personalization, - bits: I, - params: &E::Params -) -> edwards::Point - where I: IntoIterator, - E: JubjubEngine +pub fn pedersen_hash(personalization: Personalization, bits: I, params: &E::Params) -> edwards::Point +where + I: IntoIterator, + E: JubjubEngine, { let mut bits = personalization.get_bits().into_iter().chain(bits.into_iter()); @@ -84,7 +80,7 @@ pub fn pedersen_hash( let window_mask = (1 << window) - 1; let mut acc = acc.into_repr(); - + let mut tmp = edwards::Point::zero(); while !acc.is_zero() { @@ -102,15 +98,12 @@ pub fn pedersen_hash( result } -use alt_babyjubjub::{AltJubjubBn256}; +use alt_babyjubjub::AltJubjubBn256; -pub fn baby_pedersen_hash( - personalization: Personalization, - bits: I, - params: &E::Params -) -> edwards::Point - where I: IntoIterator, - E: JubjubEngine +pub fn baby_pedersen_hash(personalization: Personalization, bits: I, params: &E::Params) -> edwards::Point +where + I: IntoIterator, + E: JubjubEngine, { let mut bits = personalization.get_bits().into_iter().chain(bits.into_iter()); @@ -167,7 +160,7 @@ pub fn baby_pedersen_hash( let window_mask = (1 << window) - 1; let mut acc = acc.into_repr(); - + let mut tmp = edwards::Point::zero(); while !acc.is_zero() { diff --git a/crates/franklin-crypto/src/plonk/circuit/allocated_num.rs b/crates/franklin-crypto/src/plonk/circuit/allocated_num.rs index de0698f..ee21a94 100644 --- a/crates/franklin-crypto/src/plonk/circuit/allocated_num.rs +++ b/crates/franklin-crypto/src/plonk/circuit/allocated_num.rs @@ -1,27 +1,12 @@ use std::unimplemented; -use crate::bellman::pairing::{ - Engine, -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; - -use crate::bellman::{ - SynthesisError, -}; - -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - MainGate, -}; +use crate::bellman::pairing::Engine; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; + +use crate::bellman::SynthesisError; + +use crate::bellman::plonk::better_better_cs::cs::{ArithmeticTerm, ConstraintSystem, MainGate, MainGateTerm, Variable}; use super::utils::is_selector_specialized_gate; @@ -30,7 +15,7 @@ use super::linear_combination::*; use crate::plonk::circuit::Assignment; -pub const STATE_WIDTH : usize = 4; +pub const STATE_WIDTH: usize = 4; pub mod stats { use std::sync::atomic::*; @@ -57,14 +42,14 @@ pub mod stats { #[derive(Debug)] pub enum Num { Variable(AllocatedNum), - Constant(E::Fr) + Constant(E::Fr), } impl Clone for Num { fn clone(&self) -> Self { match &self { Num::Variable(ref var) => Num::Variable(*var), - Num::Constant(ref constant) => Num::Constant(*constant) + Num::Constant(ref constant) => Num::Constant(*constant), } } } @@ -83,7 +68,7 @@ impl std::fmt::Display for Num { match self { Num::Variable(v) => { write!(f, "Variable({:?})", v.get_variable())?; - }, + } Num::Constant(c) => { write!(f, "Constant({}), ", c)?; } @@ -101,21 +86,16 @@ impl Num { Num::Constant(E::Fr::one()) } - pub fn alloc>( - cs: &mut CS, - witness: Option - ) -> Result { - let new = Num::Variable( - AllocatedNum::alloc(cs, || Ok(*witness.get()?))? - ); + pub fn alloc>(cs: &mut CS, witness: Option) -> Result { + let new = Num::Variable(AllocatedNum::alloc(cs, || Ok(*witness.get()?))?); Ok(new) } - + pub fn get_value(&self) -> Option { match self { Num::Variable(v) => v.get_value(), - Num::Constant(c) => Some(*c) + Num::Constant(c) => Some(*c), } } @@ -131,7 +111,7 @@ impl Num { pub fn is_constant(&self) -> bool { match self { Num::Variable(..) => false, - Num::Constant(..) => true + Num::Constant(..) => true, } } @@ -139,7 +119,7 @@ impl Num { pub fn get_constant_value(&self) -> E::Fr { match self { Num::Variable(..) => panic!("this Num is not a constant"), - Num::Constant(c) => *c + Num::Constant(c) => *c, } } @@ -148,10 +128,8 @@ impl Num { match self { Num::Constant(..) => { panic!("this Num is not a variable") - }, - Num::Variable(v) => { - v.clone() } + Num::Variable(v) => v.clone(), } } @@ -161,14 +139,14 @@ impl Num { let allocated_num = AllocatedNum::from_boolean_is(boolean); Num::Variable(allocated_num) - }, + } Boolean::Constant(constant_value) => { if constant_value { Num::Constant(E::Fr::one()) } else { Num::Constant(E::Fr::zero()) } - }, + } _ => { panic!("Can not boolean NOT") } @@ -176,19 +154,10 @@ impl Num { } #[track_caller] - pub fn enforce_equal>( - &self, - cs: &mut CS, - b: &Self - ) -> Result<(), SynthesisError> { + pub fn enforce_equal>(&self, cs: &mut CS, b: &Self) -> Result<(), SynthesisError> { match (self, b) { - (Num::Variable(ref a), Num::Variable(ref b)) => { - a.enforce_equal(cs, b) - }, - (Num::Variable(ref var), Num::Constant(constant)) | - (Num::Constant(constant), Num::Variable(ref var)) => { - var.assert_equal_to_constant(cs, *constant) - }, + (Num::Variable(ref a), Num::Variable(ref b)) => a.enforce_equal(cs, b), + (Num::Variable(ref var), Num::Constant(constant)) | (Num::Constant(constant), Num::Variable(ref var)) => var.assert_equal_to_constant(cs, *constant), (Num::Constant(a), Num::Constant(b)) => { assert_eq!(a, b); @@ -199,14 +168,15 @@ impl Num { #[track_caller] pub fn conditionally_enforce_equal(cs: &mut CS, cond: &Boolean, a: &Self, b: &Self) -> Result<(), SynthesisError> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { match (cond.get_value(), a.get_value(), b.get_value()) { (Some(cond), Some(a), Some(b)) => { if cond { assert_eq!(a, b); } - }, + } _ => {} } let masked_a = Num::mask(cs, &a, &cond)?; @@ -217,21 +187,17 @@ impl Num { /// Takes two allocated numbers (a, b) and returns /// (b, a) if the condition is true, and (a, b) /// otherwise. - pub fn conditionally_reverse( - cs: &mut CS, - a: &Self, - b: &Self, - condition: &Boolean - ) -> Result<(Self, Self), SynthesisError> - where CS: ConstraintSystem + pub fn conditionally_reverse(cs: &mut CS, a: &Self, b: &Self, condition: &Boolean) -> Result<(Self, Self), SynthesisError> + where + CS: ConstraintSystem, { if condition.is_constant() { let swap = condition.get_value().expect("must get a value of the constant"); if swap { - return Ok((b.clone(), a.clone())) + return Ok((b.clone(), a.clone())); } else { - return Ok((a.clone(), b.clone())) + return Ok((a.clone(), b.clone())); } } @@ -246,47 +212,29 @@ impl Num { (Num::Variable(a), Num::Variable(b)) => { let (c, d) = AllocatedNum::conditionally_reverse(cs, a, b, condition)?; return Ok((Num::Variable(c), Num::Variable(d))); - }, - _ =>{} + } + _ => {} } - let c = AllocatedNum::alloc( - cs, - || { - if *condition.get_value().get()? { - Ok(*b.get_value().get()?) - } else { - Ok(*a.get_value().get()?) - } - } - )?; + let c = AllocatedNum::alloc(cs, || if *condition.get_value().get()? { Ok(*b.get_value().get()?) } else { Ok(*a.get_value().get()?) })?; - let d = AllocatedNum::alloc( - cs, - || { - if *condition.get_value().get()? { - Ok(*a.get_value().get()?) - } else { - Ok(*b.get_value().get()?) - } - } - )?; + let d = AllocatedNum::alloc(cs, || if *condition.get_value().get()? { Ok(*a.get_value().get()?) } else { Ok(*b.get_value().get()?) })?; let c = Num::Variable(c); let d = Num::Variable(d); // (a - b) * condition = a - c - // (b - a) * condition = b - d + // (b - a) * condition = b - d // if condition == 0, then a == c, b == d // if condition == 1, then b == c, a == d match (condition, a, b) { (Boolean::Constant(..), _, _) => { unreachable!("constant is already handles") - }, + } (Boolean::Is(condition_var), Num::Constant(a), Num::Constant(b)) => { // (a - b) * condition = a - c - // (b - a) * condition = b - d + // (b - a) * condition = b - d // if condition == 0, then a == c, b == d // if condition == 1, then b == c, a == d @@ -315,10 +263,10 @@ impl Num { bd_term.add_assign(d_term); cs.allocate_main_gate(bd_term)?; - }, + } (Boolean::Is(condition_var), Num::Variable(..), Num::Constant(b_const)) => { // (a - b) * condition = a - c - // (b - a) * condition = b - d + // (b - a) * condition = b - d // if condition == 0, then a == c, b == d // if condition == 1, then b == c, a == d @@ -345,10 +293,10 @@ impl Num { bd_term.add_assign(d_term); cs.allocate_main_gate(bd_term)?; - }, + } (Boolean::Is(condition_var), Num::Constant(a_const), Num::Variable(..)) => { // (a - b) * condition = a - c - // (b - a) * condition = b - d + // (b - a) * condition = b - d // if condition == 0, then a == c, b == d // if condition == 1, then b == c, a == d @@ -375,7 +323,7 @@ impl Num { bd_term.add_assign(d_term); cs.allocate_main_gate(bd_term)?; - }, + } _ => { unimplemented!() } @@ -384,21 +332,14 @@ impl Num { Ok((c, d)) } - pub fn equals>( - cs: &mut CS, - a: &Self, - b: &Self - ) -> Result { + pub fn equals>(cs: &mut CS, a: &Self, b: &Self) -> Result { match (a, b) { - (Num::Variable(ref a), Num::Variable(ref b)) => { - AllocatedNum::equals(cs, a, b) - }, - (Num::Variable(ref var), Num::Constant(constant)) | - (Num::Constant(constant), Num::Variable(ref var)) => { + (Num::Variable(ref a), Num::Variable(ref b)) => AllocatedNum::equals(cs, a, b), + (Num::Variable(ref var), Num::Constant(constant)) | (Num::Constant(constant), Num::Variable(ref var)) => { let delta = var.sub_constant(cs, *constant)?; delta.is_zero(cs) - }, + } (Num::Constant(a), Num::Constant(b)) => { let is_equal = a == b; Ok(Boolean::Constant(is_equal)) @@ -406,23 +347,18 @@ impl Num { } } - pub fn add>( - &self, - cs: &mut CS, - other: &Self, - ) -> Result { + pub fn add>(&self, cs: &mut CS, other: &Self) -> Result { match (self, other) { (Num::Variable(ref a), Num::Variable(ref b)) => { let new = a.add(cs, b)?; Ok(Num::Variable(new)) - }, - (Num::Variable(ref var), Num::Constant(constant)) | - (Num::Constant(constant), Num::Variable(ref var)) => { + } + (Num::Variable(ref var), Num::Constant(constant)) | (Num::Constant(constant), Num::Variable(ref var)) => { let new = var.add_constant(cs, *constant)?; Ok(Num::Variable(new)) - }, + } (Num::Constant(a), Num::Constant(b)) => { let mut result = *a; result.add_assign(&b); @@ -432,22 +368,18 @@ impl Num { } } - pub fn sub>( - &self, - cs: &mut CS, - other: &Self, - ) -> Result { + pub fn sub>(&self, cs: &mut CS, other: &Self) -> Result { match (self, other) { (Num::Variable(ref a), Num::Variable(ref b)) => { let new = a.sub(cs, b)?; Ok(Num::Variable(new)) - }, + } (Num::Variable(ref var), Num::Constant(constant)) => { let new = var.sub_constant(cs, *constant)?; Ok(Num::Variable(new)) - }, + } (Num::Constant(constant), Num::Variable(ref var)) => { use crate::plonk::circuit::simple_term::Term; let mut term = Term::::from_allocated_num(var.clone()); @@ -457,7 +389,7 @@ impl Num { let new = term.collapse_into_num(cs)?; Ok(new) - }, + } (Num::Constant(a), Num::Constant(b)) => { let mut result = *a; result.sub_assign(&b); @@ -467,35 +399,29 @@ impl Num { } } - pub fn mask_by_boolean_into_accumulator>(&self, cs: &mut CS, boolean: &Boolean, accumulator: &Self) -> Result - { + pub fn mask_by_boolean_into_accumulator>(&self, cs: &mut CS, boolean: &Boolean, accumulator: &Self) -> Result { match (self, accumulator, boolean) { (Num::Variable(self_var), Num::Variable(accumulator_var), _) => { let accumulated = self_var.mask_by_boolean_into_accumulator(cs, boolean, accumulator_var)?; Ok(Num::Variable(accumulated)) - }, + } (Num::Constant(self_value), Num::Constant(accumulator_value), _) => { let mut lc = LinearCombination::zero(); lc.add_assign_constant(*accumulator_value); lc.add_assign_boolean_with_coeff(boolean, *self_value); lc.into_num(cs) - }, + } (Num::Constant(self_value), accumulator @ Num::Variable(..), _) => { let mut lc = LinearCombination::zero(); lc.add_assign_number_with_coeff(accumulator, E::Fr::one()); lc.add_assign_boolean_with_coeff(boolean, *self_value); lc.into_num(cs) - }, + } (self_value @ Num::Variable(..), accumulator @ Num::Constant(..), Boolean::Constant(flag)) => { - let res = if *flag { - accumulator.add(cs, &self_value)? - } - else { - accumulator.clone() - }; + let res = if *flag { accumulator.add(cs, &self_value)? } else { accumulator.clone() }; Ok(res) } (Num::Variable(self_value), Num::Constant(accumulator), Boolean::Is(bit)) => { @@ -508,26 +434,21 @@ impl Num { } tmp.add_assign(accumulator); - value = Some(tmp); + value = Some(tmp); Ok(tmp) })?; - let allocated_res = AllocatedNum { - value: value, - variable: result - }; + let allocated_res = AllocatedNum { value: value, variable: result }; - let self_term = ArithmeticTerm::from_variable( - self_value.get_variable()).mul_by_variable(bit.get_variable() - ); + let self_term = ArithmeticTerm::from_variable(self_value.get_variable()).mul_by_variable(bit.get_variable()); let other_term = ArithmeticTerm::constant(accumulator.clone()); let result_term = ArithmeticTerm::from_variable(result); - + let mut term = MainGateTerm::new(); term.add_assign(self_term); term.add_assign(other_term); term.sub_assign(result_term); - + cs.allocate_main_gate(term)?; Ok(Num::Variable(allocated_res)) @@ -543,28 +464,23 @@ impl Num { } tmp.add_assign(accumulator); - value = Some(tmp); + value = Some(tmp); Ok(tmp) })?; - let allocated_res = AllocatedNum { - value: value, - variable: result - }; + let allocated_res = AllocatedNum { value: value, variable: result }; let self_term = ArithmeticTerm::from_variable(self_value.get_variable()); - let mul_term = ArithmeticTerm::from_variable( - self_value.get_variable()).mul_by_variable(bit.get_variable() - ); + let mul_term = ArithmeticTerm::from_variable(self_value.get_variable()).mul_by_variable(bit.get_variable()); let other_term = ArithmeticTerm::constant(accumulator.clone()); let result_term = ArithmeticTerm::from_variable(result); - + let mut term = MainGateTerm::new(); term.add_assign(self_term); term.add_assign(other_term); term.sub_assign(result_term); term.sub_assign(mul_term); - + cs.allocate_main_gate(term)?; Ok(Num::Variable(allocated_res)) @@ -572,18 +488,17 @@ impl Num { } } - pub fn add_two>(&self, cs: &mut CS, first: &Self, second: &Self) -> Result - { + pub fn add_two>(&self, cs: &mut CS, first: &Self, second: &Self) -> Result { let res = match (self, first, second) { (Num::Constant(x), Num::Constant(y), Num::Constant(z)) => { let mut temp = *x; temp.add_assign(y); temp.add_assign(z); Num::Constant(temp) - }, - (Num::Variable(var), Num::Constant(cnst1), Num::Constant(cnst2)) | - (Num::Constant(cnst1), Num::Variable(var), Num::Constant(cnst2)) | - (Num::Constant(cnst1), Num::Constant(cnst2), Num::Variable(var)) => { + } + (Num::Variable(var), Num::Constant(cnst1), Num::Constant(cnst2)) + | (Num::Constant(cnst1), Num::Variable(var), Num::Constant(cnst2)) + | (Num::Constant(cnst1), Num::Constant(cnst2), Num::Variable(var)) => { let mut value = None; let addition_result = cs.alloc(|| { @@ -608,12 +523,12 @@ impl Num { Num::Variable(AllocatedNum { value: value, - variable: addition_result + variable: addition_result, }) - }, - (Num::Variable(var1), Num::Variable(var2), Num::Constant(constant)) | - (Num::Variable(var1), Num::Constant(constant), Num::Variable(var2)) | - (Num::Constant(constant), Num::Variable(var1), Num::Variable(var2)) => { + } + (Num::Variable(var1), Num::Variable(var2), Num::Constant(constant)) + | (Num::Variable(var1), Num::Constant(constant), Num::Variable(var2)) + | (Num::Constant(constant), Num::Variable(var1), Num::Variable(var2)) => { let mut value = None; let addition_result = cs.alloc(|| { @@ -639,9 +554,9 @@ impl Num { Num::Variable(AllocatedNum { value: value, - variable: addition_result + variable: addition_result, }) - }, + } (Num::Variable(var1), Num::Variable(var2), Num::Variable(var3)) => { let mut value = None; @@ -669,38 +584,30 @@ impl Num { Num::Variable(AllocatedNum { value: value, - variable: addition_result + variable: addition_result, }) - }, + } }; Ok(res) } - pub fn negate>( - &self, - cs: &mut CS - ) -> Result { + pub fn negate>(&self, cs: &mut CS) -> Result { Num::Constant(E::Fr::zero()).sub(cs, self) } - pub fn mul>( - &self, - cs: &mut CS, - other: &Self, - ) -> Result { + pub fn mul>(&self, cs: &mut CS, other: &Self) -> Result { match (self, other) { (Num::Variable(ref a), Num::Variable(ref b)) => { let new = a.mul(cs, b)?; Ok(Num::Variable(new)) - }, - (Num::Variable(ref var), Num::Constant(constant)) | - (Num::Constant(constant), Num::Variable(ref var)) => { + } + (Num::Variable(ref var), Num::Constant(constant)) | (Num::Constant(constant), Num::Variable(ref var)) => { let new = var.mul_constant(cs, *constant)?; Ok(Num::Variable(new)) - }, + } (Num::Constant(a), Num::Constant(b)) => { let mut result = *a; result.mul_assign(&b); @@ -711,32 +618,29 @@ impl Num { } // compute coeff_ab * A * B + coeff_c * C - pub fn fma_with_coefficients>( - cs: &mut CS, a: &Self, b: &Self, c: &Self, ab_coeff: E::Fr, c_coeff: E::Fr - ) -> Result - { + pub fn fma_with_coefficients>(cs: &mut CS, a: &Self, b: &Self, c: &Self, ab_coeff: E::Fr, c_coeff: E::Fr) -> Result { let result_val = { let a_val = a.get_value().grab()?; let b_val = b.get_value().grab()?; let c_val = c.get_value().grab()?; - let mut tmp : E::Fr = a_val; + let mut tmp: E::Fr = a_val; tmp.mul_assign(&ab_coeff); tmp.mul_assign(&b_val); let mut tmp2 = c_val; tmp2.mul_assign(&c_coeff); - + tmp.add_assign(&tmp2); Ok(tmp) }; - + // if all of the variables are constant: // return constant if [a, b, c].iter().all(|x| x.is_constant()) { - return Ok(Num::Constant(result_val.unwrap())) + return Ok(Num::Constant(result_val.unwrap())); } - + let result = AllocatedNum::alloc(cs, || result_val)?; let mut gate = MainGateTerm::new(); let mut cnst = E::Fr::zero(); @@ -748,17 +652,15 @@ impl Num { tmp.mul_assign(&b_fr); tmp.mul_assign(&ab_coeff); cnst = tmp; - }, + } (Num::Constant(fr), Num::Variable(var)) | (Num::Variable(var), Num::Constant(fr)) => { let mut tmp = fr.clone(); tmp.mul_assign(&ab_coeff); let term = ArithmeticTerm::from_variable_and_coeff(var.get_variable(), tmp); gate.add_assign(term); - }, + } (Num::Variable(a_var), Num::Variable(b_var)) => { - let term = ArithmeticTerm::from_variable_and_coeff( - a_var.get_variable(), ab_coeff - ).mul_by_variable(b_var.get_variable()); + let term = ArithmeticTerm::from_variable_and_coeff(a_var.get_variable(), ab_coeff).mul_by_variable(b_var.get_variable()); gate.add_assign(term); } }; @@ -768,7 +670,7 @@ impl Num { Num::Variable(var) => { let term = ArithmeticTerm::from_variable(var.get_variable()); gate.add_assign(term); - }, + } }; let term = ArithmeticTerm::constant(cnst); @@ -776,20 +678,18 @@ impl Num { let term = ArithmeticTerm::from_variable(result.get_variable()); gate.sub_assign(term); cs.allocate_main_gate(gate)?; - + Ok(Num::Variable(result)) } - pub fn assert_not_zero( - &self, - cs: &mut CS, - ) -> Result<(), SynthesisError> - where CS: ConstraintSystem + pub fn assert_not_zero(&self, cs: &mut CS) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { match self { Num::Constant(c) => { assert!(!c.is_zero()); - }, + } Num::Variable(var) => { var.assert_not_zero(cs)?; } @@ -798,16 +698,14 @@ impl Num { Ok(()) } - pub fn assert_is_zero( - &self, - cs: &mut CS, - ) -> Result<(), SynthesisError> - where CS: ConstraintSystem + pub fn assert_is_zero(&self, cs: &mut CS) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { match self { Num::Constant(c) => { assert!(c.is_zero()); - }, + } Num::Variable(var) => { var.assert_is_zero(cs)?; } @@ -816,15 +714,12 @@ impl Num { Ok(()) } - pub fn inverse>( - &self, - cs: &mut CS - ) -> Result { + pub fn inverse>(&self, cs: &mut CS) -> Result { match self { Num::Constant(c) => { assert!(!c.is_zero()); Ok(Num::Constant(c.inverse().expect("inverse must exist"))) - }, + } Num::Variable(var) => { let result = var.inverse(cs)?; @@ -833,12 +728,9 @@ impl Num { } } - pub fn div( - &self, - cs: &mut CS, - other: &Self - ) -> Result - where CS: ConstraintSystem + pub fn div(&self, cs: &mut CS, other: &Self) -> Result + where + CS: ConstraintSystem, { match (self, other) { (Num::Constant(a), Num::Constant(b)) => { @@ -848,18 +740,18 @@ impl Num { result.mul_assign(&b_inv); Ok(Num::Constant(result)) - }, + } (Num::Variable(a), Num::Variable(b)) => { - let result = a.div(cs, b)?; + let result = a.div(cs, b)?; Ok(Num::Variable(result)) - }, + } (Num::Variable(a), Num::Constant(b)) => { let b_inv = b.inverse().expect("inverse must exist"); let result = Num::Variable(*a).mul(cs, &Num::Constant(b_inv))?; Ok(result) - }, + } (Num::Constant(a), Num::Variable(b)) => { let b_inv = b.inverse(cs)?; let result = Num::Variable(b_inv).mul(cs, &Num::Constant(*a))?; @@ -870,11 +762,7 @@ impl Num { } /// returns 0 if condition == `false` and `a` if condition == `true` - pub fn mask>( - cs: &mut CS, - a: &Self, - condition: &Boolean - ) -> Result { + pub fn mask>(cs: &mut CS, a: &Self, condition: &Boolean) -> Result { match (a, condition) { (Num::Constant(a), Boolean::Constant(flag)) => { if *flag { @@ -882,32 +770,19 @@ impl Num { } else { return Ok(Num::Constant(E::Fr::zero())); } - }, + } (Num::Variable(var), Boolean::Constant(flag)) => { if *flag { return Ok(Num::Variable(*var)); } else { return Ok(Num::Constant(E::Fr::zero())); } - }, - (Num::Variable(var), cond @ Boolean::Is(..)) => { - return Ok(Num::Variable(AllocatedNum::mask(cs, var, cond)?)) - }, - (Num::Variable(var), cond @ Boolean::Not(..)) => { - return Ok(Num::Variable(AllocatedNum::mask(cs, var, cond)?)) - }, + } + (Num::Variable(var), cond @ Boolean::Is(..)) => return Ok(Num::Variable(AllocatedNum::mask(cs, var, cond)?)), + (Num::Variable(var), cond @ Boolean::Not(..)) => return Ok(Num::Variable(AllocatedNum::mask(cs, var, cond)?)), (Num::Constant(a), Boolean::Is(flag)) => { let a = *a; - let c = AllocatedNum::alloc( - cs, - || { - if *flag.get_value().get()? { - Ok(a) - } else { - Ok(E::Fr::zero()) - } - } - )?; + let c = AllocatedNum::alloc(cs, || if *flag.get_value().get()? { Ok(a) } else { Ok(E::Fr::zero()) })?; let mut main_term = MainGateTerm::::new(); let term = ArithmeticTerm::from_variable_and_coeff(flag.get_variable(), a); @@ -917,19 +792,10 @@ impl Num { cs.allocate_main_gate(main_term)?; return Ok(Num::Variable(c)); - }, + } (Num::Constant(a), Boolean::Not(flag)) => { let a = *a; - let c = AllocatedNum::alloc( - cs, - || { - if *flag.get_value().get()? { - Ok(E::Fr::zero()) - } else { - Ok(a) - } - } - )?; + let c = AllocatedNum::alloc(cs, || if *flag.get_value().get()? { Ok(E::Fr::zero()) } else { Ok(a) })?; // a - flag*a - c = 0 @@ -942,47 +808,39 @@ impl Num { cs.allocate_main_gate(main_term)?; return Ok(Num::Variable(c)); - }, + } } } - pub fn conditionally_select>( - cs: &mut CS, - condition_flag: &Boolean, - a: &Self, - b: &Self - ) -> Result { + pub fn conditionally_select>(cs: &mut CS, condition_flag: &Boolean, a: &Self, b: &Self) -> Result { match (a, b) { (Num::Variable(ref a), Num::Variable(ref b)) => { let num = AllocatedNum::conditionally_select(cs, a, b, condition_flag)?; Ok(Num::Variable(num)) - }, + } (Num::Variable(ref var), Num::Constant(constant)) => { match condition_flag { Boolean::Constant(flag) => { - if *flag { + if *flag { Ok(Num::Variable(var.clone())) - } else { + } else { Ok(Num::Constant(*constant)) } - }, + } Boolean::Is(cond) => { // var * flag + constant * (1 - flag) - result = 0 - let c = AllocatedNum::alloc( - cs, - || { - let a_value = *var.get_value().get()?; - let b_value = *constant; - if *cond.get_value().get()? { - Ok(a_value) - } else { - Ok(b_value) - } + let c = AllocatedNum::alloc(cs, || { + let a_value = *var.get_value().get()?; + let b_value = *constant; + if *cond.get_value().get()? { + Ok(a_value) + } else { + Ok(b_value) } - )?; - + })?; + let mut main_term = MainGateTerm::::new(); let term = ArithmeticTerm::from_variable(cond.get_variable()).mul_by_variable(var.get_variable()); main_term.add_assign(term); @@ -991,26 +849,23 @@ impl Num { main_term.add_assign(ArithmeticTerm::constant(*constant)); cs.allocate_main_gate(main_term)?; - + Ok(Num::Variable(c)) - }, - + } + Boolean::Not(cond) => { // var * (1-cond) + constant * cond - result = 0 - let c = AllocatedNum::alloc( - cs, - || { - let a_value = *var.get_value().get()?; - let b_value = *constant; - if *cond.get_value().get()? { - Ok(b_value) - } else { - Ok(a_value) - } + let c = AllocatedNum::alloc(cs, || { + let a_value = *var.get_value().get()?; + let b_value = *constant; + if *cond.get_value().get()? { + Ok(b_value) + } else { + Ok(a_value) } - )?; - + })?; + let mut main_term = MainGateTerm::::new(); let term = ArithmeticTerm::from_variable(cond.get_variable()).mul_by_variable(var.get_variable()); main_term.sub_assign(term); @@ -1019,47 +874,32 @@ impl Num { main_term.add_assign(ArithmeticTerm::from_variable(var.get_variable())); cs.allocate_main_gate(main_term)?; - + Ok(Num::Variable(c)) } } - }, + } - (Num::Constant(..), Num::Variable(..)) => { - Self::conditionally_select(cs, &condition_flag.not(), b, a) - }, + (Num::Constant(..), Num::Variable(..)) => Self::conditionally_select(cs, &condition_flag.not(), b, a), (&Num::Constant(a), &Num::Constant(b)) => { if a == b { return Ok(Num::Constant(a)); } match condition_flag { Boolean::Constant(flag) => { - let result_value = if *flag { - a - } else { - b - }; + let result_value = if *flag { a } else { b }; Ok(Num::Constant(result_value)) - }, + } Boolean::Is(cond) => { - let c = AllocatedNum::alloc( - cs, - || { - if *cond.get_value().get()? { - Ok(a) - } else { - Ok(b) - } - } - )?; - + let c = AllocatedNum::alloc(cs, || if *cond.get_value().get()? { Ok(a) } else { Ok(b) })?; + // a * condition + b*(1-condition) = c -> // (a - b) *condition - c + b = 0 - + let mut a_minus_b = a; a_minus_b.sub_assign(&b); - + let mut main_term = MainGateTerm::::new(); let term = ArithmeticTerm::from_variable_and_coeff(cond.get_variable(), a_minus_b); main_term.add_assign(term); @@ -1067,37 +907,28 @@ impl Num { main_term.sub_assign(ArithmeticTerm::from_variable(c.get_variable())); cs.allocate_main_gate(main_term)?; - + Ok(Num::Variable(c)) - }, - + } + Boolean::Not(cond) => { - let c = AllocatedNum::alloc( - cs, - || { - if *cond.get_value().get()? { - Ok(b) - } else { - Ok(a) - } - } - )?; - + let c = AllocatedNum::alloc(cs, || if *cond.get_value().get()? { Ok(b) } else { Ok(a) })?; + // b * condition + a*(1-condition) = c -> // (b - a) * condition - c + a = 0 - + let mut b_minus_a = b; b_minus_a.sub_assign(&a); - + let mut main_term = MainGateTerm::::new(); let term = ArithmeticTerm::from_variable_and_coeff(cond.get_variable(), b_minus_a); main_term.add_assign(term); - + main_term.sub_assign(ArithmeticTerm::from_variable(c.get_variable())); main_term.add_assign(ArithmeticTerm::constant(a)); cs.allocate_main_gate(main_term)?; - + Ok(Num::Variable(c)) } } @@ -1105,37 +936,30 @@ impl Num { } } - pub fn alloc_multiple, const N: usize>( - cs: &mut CS, - witness: Option<[E::Fr; N]> - ) -> Result<[Self; N], SynthesisError> { + pub fn alloc_multiple, const N: usize>(cs: &mut CS, witness: Option<[E::Fr; N]>) -> Result<[Self; N], SynthesisError> { let mut result = [Num::Constant(E::Fr::zero()); N]; for (idx, r) in result.iter_mut().enumerate() { let witness = witness.map(|el| el[idx]); *r = Num::alloc(cs, witness)?; } - + Ok(result) } - pub fn get_value_multiple( - els: &[Self; N] - ) -> Option<[E::Fr; N]> { + pub fn get_value_multiple(els: &[Self; N]) -> Option<[E::Fr; N]> { let mut result = [E::Fr::zero(); N]; for (r, el) in result.iter_mut().zip(els.iter()) { if let Some(value) = el.get_value() { *r = value; } else { - return None + return None; } } - + Some(result) } - pub fn get_value_for_slice( - els: &[Self] - ) -> Option> { + pub fn get_value_for_slice(els: &[Self]) -> Option> { let mut result = Vec::with_capacity(els.len()); for el in els.iter() { if let Some(value) = el.get_value() { @@ -1144,15 +968,11 @@ impl Num { return None; } } - + Some(result) } - pub fn into_bits_le( - &self, - cs: &mut CS, - bit_length: Option, - ) -> Result, SynthesisError> + pub fn into_bits_le(&self, cs: &mut CS, bit_length: Option) -> Result, SynthesisError> where CS: ConstraintSystem, { @@ -1161,9 +981,7 @@ impl Num { } match self { - Num::Variable(ref var) => { - var.into_bits_le(cs, bit_length) - }, + Num::Variable(ref var) => var.into_bits_le(cs, bit_length), Num::Constant(c) => { use crate::plonk::circuit::utils::fe_to_lsb_first_bits; if let Some(bit_length) = bit_length { @@ -1187,12 +1005,7 @@ impl Num { } } - pub fn conditionally_select_multiple, const N: usize>( - cs: &mut CS, - flag: &Boolean, - a: &[Self; N], - b: &[Self; N] - ) -> Result<[Self; N], SynthesisError> { + pub fn conditionally_select_multiple, const N: usize>(cs: &mut CS, flag: &Boolean, a: &[Self; N], b: &[Self; N]) -> Result<[Self; N], SynthesisError> { let mut result = [Num::zero(); N]; for ((a, b), r) in (a.iter().zip(b.iter())).zip(result.iter_mut()) { @@ -1203,37 +1016,38 @@ impl Num { } } -impl From for Num { +impl From for Num { fn from(b: Boolean) -> Num { match b { Boolean::Constant(cnst_flag) => { - let value = if cnst_flag {E::Fr::one()} else {E::Fr::zero()}; + let value = if cnst_flag { E::Fr::one() } else { E::Fr::zero() }; Num::Constant(value) - }, + } Boolean::Is(is) => { let var = AllocatedNum { - value : is.get_value_as_field_element::(), - variable : is.get_variable(), + value: is.get_value_as_field_element::(), + variable: is.get_variable(), }; Num::Variable(var) - }, - Boolean::Not(_) => unimplemented!("convertion from Boolean::Not into Num is not supported yet"), + } + Boolean::Not(_) => { + unimplemented!("convertion from Boolean::Not into Num is not supported yet") + } } } } - #[derive(Debug)] pub struct AllocatedNum { pub(crate) value: Option, - pub(crate) variable: Variable + pub(crate) variable: Variable, } impl Clone for AllocatedNum { fn clone(&self) -> Self { AllocatedNum { value: self.value, - variable: self.variable + variable: self.variable, } } } @@ -1248,62 +1062,46 @@ impl AllocatedNum { pub fn get_value(&self) -> Option { self.value } - - pub fn alloc( - cs: &mut CS, - value: F, - ) -> Result - where CS: ConstraintSystem, - F: FnOnce() -> Result + + pub fn alloc(cs: &mut CS, value: F) -> Result + where + CS: ConstraintSystem, + F: FnOnce() -> Result, { let mut new_value = None; - let var = cs.alloc( - || { - let tmp = value()?; + let var = cs.alloc(|| { + let tmp = value()?; - new_value = Some(tmp); + new_value = Some(tmp); - Ok(tmp) - } - )?; + Ok(tmp) + })?; - Ok(AllocatedNum { - value: new_value, - variable: var - }) + Ok(AllocatedNum { value: new_value, variable: var }) } - pub fn alloc_input( - cs: &mut CS, - value: F, - ) -> Result - where CS: ConstraintSystem, - F: FnOnce() -> Result + pub fn alloc_input(cs: &mut CS, value: F) -> Result + where + CS: ConstraintSystem, + F: FnOnce() -> Result, { let mut new_value = None; - let var = cs.alloc_input( - || { - let tmp = value()?; + let var = cs.alloc_input(|| { + let tmp = value()?; - new_value = Some(tmp); + new_value = Some(tmp); - Ok(tmp) - } - )?; + Ok(tmp) + })?; - Ok(AllocatedNum { - value: new_value, - variable: var - }) + Ok(AllocatedNum { value: new_value, variable: var }) } pub fn from_boolean_is(boolean: Boolean) -> Self { match boolean { - Boolean::Is(var) => { - AllocatedNum { - value: var.get_value_as_field_element::(), - variable: var.get_variable() - } + Boolean::Is(var) => AllocatedNum { + value: var.get_value_as_field_element::(), + variable: var.get_variable(), }, _ => { panic!("Can not boolean NOT") @@ -1311,12 +1109,11 @@ impl AllocatedNum { } } - pub fn alloc_cnst( - cs: &mut CS, fr: E::Fr, - ) -> Result - where CS: ConstraintSystem + pub fn alloc_cnst(cs: &mut CS, fr: E::Fr) -> Result + where + CS: ConstraintSystem, { - let var = cs.alloc(|| { Ok(fr.clone()) })?; + let var = cs.alloc(|| Ok(fr.clone()))?; let self_term = ArithmeticTerm::::from_variable(var); let other_term = ArithmeticTerm::constant(fr.clone()); @@ -1326,19 +1123,11 @@ impl AllocatedNum { cs.allocate_main_gate(term)?; - Ok(AllocatedNum { - value: Some(fr), - variable: var - }) + Ok(AllocatedNum { value: Some(fr), variable: var }) } pub fn inputize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let input = Self::alloc_input( - cs, - || { - Ok(*self.get_value().get()?) - } - )?; + let input = Self::alloc_input(cs, || Ok(*self.get_value().get()?))?; self.enforce_equal(cs, &input)?; @@ -1362,20 +1151,17 @@ impl AllocatedNum { } #[track_caller] - pub fn enforce_equal( - &self, - cs: &mut CS, - other: &Self - ) -> Result<(), SynthesisError> - where CS: ConstraintSystem + pub fn enforce_equal(&self, cs: &mut CS, other: &Self) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { if self.get_variable() == other.get_variable() { - return Ok(()) + return Ok(()); } match (self.get_value(), other.get_value()) { (Some(a), Some(b)) => { assert_eq!(a, b); - }, + } _ => {} } let self_term = ArithmeticTerm::from_variable(self.variable); @@ -1389,10 +1175,7 @@ impl AllocatedNum { Ok(()) } - pub fn inverse>( - &self, - cs: &mut CS - ) -> Result { + pub fn inverse>(&self, cs: &mut CS) -> Result { let new_value = if let Some(value) = self.get_value() { let t = value.inverse(); if let Some(inv) = t { @@ -1407,12 +1190,7 @@ impl AllocatedNum { None }; - let new_allocated = Self::alloc( - cs, - || { - Ok(*new_value.get()?) - } - )?; + let new_allocated = Self::alloc(cs, || Ok(*new_value.get()?))?; let self_by_inv = ArithmeticTerm::from_variable(self.variable).mul_by_variable(new_allocated.variable); let constant_term = ArithmeticTerm::constant(E::Fr::one()); @@ -1425,22 +1203,18 @@ impl AllocatedNum { Ok(new_allocated) } - pub fn assert_not_zero( - &self, - cs: &mut CS, - ) -> Result<(), SynthesisError> - where CS: ConstraintSystem + pub fn assert_not_zero(&self, cs: &mut CS) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { let _ = self.inverse(cs)?; Ok(()) } - pub fn assert_is_zero( - &self, - cs: &mut CS, - ) -> Result<(), SynthesisError> - where CS: ConstraintSystem + pub fn assert_is_zero(&self, cs: &mut CS) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { self.assert_equal_to_constant(cs, E::Fr::zero())?; @@ -1448,12 +1222,9 @@ impl AllocatedNum { } #[track_caller] - pub fn assert_equal_to_constant( - &self, - cs: &mut CS, - constant: E::Fr - ) -> Result<(), SynthesisError> - where CS: ConstraintSystem + pub fn assert_equal_to_constant(&self, cs: &mut CS, constant: E::Fr) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { if let Some(v) = self.get_value() { assert_eq!(v, constant); @@ -1469,11 +1240,9 @@ impl AllocatedNum { Ok(()) } - pub fn is_zero( - &self, - cs: &mut CS, - ) -> Result - where CS: ConstraintSystem + pub fn is_zero(&self, cs: &mut CS) -> Result + where + CS: ConstraintSystem, { // two constraints @@ -1489,22 +1258,16 @@ impl AllocatedNum { // flag * X = 0 let flag_value = self.get_value().map(|x| x.is_zero()); - let flag_value_as_field_element = flag_value.map(|el| { - if el { - E::Fr::one() - } else { - E::Fr::zero() - } - }); + let flag_value_as_field_element = flag_value.map(|el| if el { E::Fr::one() } else { E::Fr::zero() }); let raw_flag = AllocatedNum::alloc(cs, || flag_value_as_field_element.grab())?; let flag = AllocatedBit { variable: raw_flag.get_variable(), - value: flag_value + value: flag_value, }; let inv_value = if let Some(value) = self.get_value() { let inv = value.inverse(); - + if inv.is_some() { inv } else { @@ -1514,12 +1277,7 @@ impl AllocatedNum { None }; - let inv = Self::alloc( - cs, - || { - Ok(*inv_value.get()?) - } - )?; + let inv = Self::alloc(cs, || Ok(*inv_value.get()?))?; // inv * X = (1 - flag) => inv * X + flag - 1 = 0 // flag * X = 0 @@ -1534,7 +1292,6 @@ impl AllocatedNum { // | a = 0 | inv != 0 | flag = 1 | - invalid assignment, but not satisfiable // | a = 0 | inv != 0 | flag = 0 | - invalid assignment, but not satisfiable - let a_term = ArithmeticTerm::from_variable(self.variable).mul_by_variable(inv.variable); let b_term = ArithmeticTerm::from_variable(flag.get_variable()); let c_term = ArithmeticTerm::constant(E::Fr::one()); @@ -1557,21 +1314,17 @@ impl AllocatedNum { /// Takes two allocated numbers (a, b) and returns /// (b, a) if the condition is true, and (a, b) /// otherwise. - pub fn conditionally_reverse( - cs: &mut CS, - a: &Self, - b: &Self, - condition: &Boolean - ) -> Result<(Self, Self), SynthesisError> - where CS: ConstraintSystem + pub fn conditionally_reverse(cs: &mut CS, a: &Self, b: &Self, condition: &Boolean) -> Result<(Self, Self), SynthesisError> + where + CS: ConstraintSystem, { if condition.is_constant() { let swap = condition.get_value().expect("must get a value of the constant"); if swap { - return Ok((b.clone(), a.clone())) + return Ok((b.clone(), a.clone())); } else { - return Ok((a.clone(), b.clone())) + return Ok((a.clone(), b.clone())); } } @@ -1582,43 +1335,25 @@ impl AllocatedNum { return Ok((c, d)); } - let c = Self::alloc( - cs, - || { - if *condition.get_value().get()? { - Ok(*b.value.get()?) - } else { - Ok(*a.value.get()?) - } - } - )?; + let c = Self::alloc(cs, || if *condition.get_value().get()? { Ok(*b.value.get()?) } else { Ok(*a.value.get()?) })?; - let d = Self::alloc( - cs, - || { - if *condition.get_value().get()? { - Ok(*a.value.get()?) - } else { - Ok(*b.value.get()?) - } - } - )?; + let d = Self::alloc(cs, || if *condition.get_value().get()? { Ok(*a.value.get()?) } else { Ok(*b.value.get()?) })?; let a_minus_b = a.sub(cs, &b)?; // (a - b) * condition = a - c - // (b - a) * condition = b - d + // (b - a) * condition = b - d // if condition == 0, then a == c, b == d // if condition == 1, then b == c, a == d match condition { Boolean::Constant(..) => { unreachable!("constant is already handled") - }, + } Boolean::Is(condition_var) => { // no modifications // (a - b) * condition = a - c - // (b - a) * condition = b - d + // (b - a) * condition = b - d // if condition == 0, then a == c, b == d // if condition == 1, then b == c, a == d @@ -1644,12 +1379,12 @@ impl AllocatedNum { bd_term.add_assign(d_term); cs.allocate_main_gate(bd_term)?; - }, + } Boolean::Not(condition_var) => { // modifications // (a - b) * (1 - condition) = a - c - // (b - a) * (1 - condition) = b - d + // (b - a) * (1 - condition) = b - d // -(a-b) * condition - b + c = 0 // (a-b) * condition - a + d = 0 @@ -1679,22 +1414,15 @@ impl AllocatedNum { } // returns a==b - pub fn equals>( - cs: &mut CS, - a: &Self, - b: &Self, - ) -> Result { + pub fn equals>(cs: &mut CS, a: &Self, b: &Self) -> Result { let delta = a.sub(cs, b)?; delta.is_zero(cs) } - pub fn add( - &self, - cs: &mut CS, - other: &Self - ) -> Result - where CS: ConstraintSystem + pub fn add(&self, cs: &mut CS, other: &Self) -> Result + where + CS: ConstraintSystem, { let mut value = None; @@ -1719,16 +1447,13 @@ impl AllocatedNum { Ok(AllocatedNum { value: value, - variable: addition_result + variable: addition_result, }) } - pub fn sub( - &self, - cs: &mut CS, - other: &Self - ) -> Result - where CS: ConstraintSystem + pub fn sub(&self, cs: &mut CS, other: &Self) -> Result + where + CS: ConstraintSystem, { let mut value = None; @@ -1753,16 +1478,13 @@ impl AllocatedNum { Ok(AllocatedNum { value: value, - variable: subtraction_result + variable: subtraction_result, }) } - pub fn add_constant( - &self, - cs: &mut CS, - constant: E::Fr - ) -> Result - where CS: ConstraintSystem + pub fn add_constant(&self, cs: &mut CS, constant: E::Fr) -> Result + where + CS: ConstraintSystem, { let mut value = None; @@ -1787,16 +1509,13 @@ impl AllocatedNum { Ok(AllocatedNum { value: value, - variable: addition_result + variable: addition_result, }) } - pub fn sub_constant( - &self, - cs: &mut CS, - constant: E::Fr - ) -> Result - where CS: ConstraintSystem + pub fn sub_constant(&self, cs: &mut CS, constant: E::Fr) -> Result + where + CS: ConstraintSystem, { let mut c = constant; c.negate(); @@ -1804,8 +1523,7 @@ impl AllocatedNum { self.add_constant(cs, c) } - pub fn fma>(&self, cs: &mut CS, b: Self, c: Self) -> Result - { + pub fn fma>(&self, cs: &mut CS, b: Self, c: Self) -> Result { let mut value = None; let result = cs.alloc(|| { @@ -1828,15 +1546,11 @@ impl AllocatedNum { cs.allocate_main_gate(term)?; - Ok(AllocatedNum { - value: value, - variable: result - }) + Ok(AllocatedNum { value: value, variable: result }) } // compute coeff_ab * A * B + coeff_c * C - pub fn fma_with_coefficients>(&self, cs: &mut CS, b: (E::Fr, Self), c: (E::Fr, Self)) -> Result - { + pub fn fma_with_coefficients>(&self, cs: &mut CS, b: (E::Fr, Self), c: (E::Fr, Self)) -> Result { let mut value = None; let (ab_coeff, b) = b; @@ -1865,14 +1579,10 @@ impl AllocatedNum { cs.allocate_main_gate(term)?; - Ok(AllocatedNum { - value: value, - variable: result - }) + Ok(AllocatedNum { value: value, variable: result }) } - pub fn mask_by_boolean_into_accumulator>(&self, cs: &mut CS, boolean: &Boolean, accumulator: &Self) -> Result - { + pub fn mask_by_boolean_into_accumulator>(&self, cs: &mut CS, boolean: &Boolean, accumulator: &Self) -> Result { match boolean { Boolean::Constant(flag) => { if *flag { @@ -1880,11 +1590,11 @@ impl AllocatedNum { } else { return Ok(accumulator.clone()); } - }, + } Boolean::Is(bit) => { let mut value = None; let bit_value = bit.get_value(); - + let result = cs.alloc(|| { let mut tmp = *self.value.get()?; let bit_value = bit_value.get()?; @@ -1894,10 +1604,10 @@ impl AllocatedNum { } tmp.add_assign(&acc_value); value = Some(tmp); - + Ok(tmp) })?; - + let self_term = ArithmeticTerm::from_variable(self.get_variable()).mul_by_variable(bit.get_variable()); let other_term = ArithmeticTerm::from_variable(accumulator.variable); let result_term = ArithmeticTerm::from_variable(result); @@ -1905,18 +1615,15 @@ impl AllocatedNum { term.add_assign(self_term); term.add_assign(other_term); term.sub_assign(result_term); - + cs.allocate_main_gate(term)?; - - Ok(AllocatedNum { - value: value, - variable: result - }) - }, + + Ok(AllocatedNum { value: value, variable: result }) + } Boolean::Not(not_bit) => { let mut value = None; let not_bit_value = not_bit.get_value(); - + let result = cs.alloc(|| { let mut tmp = *self.value.get()?; let not_bit_value = not_bit_value.get()?; @@ -1926,7 +1633,7 @@ impl AllocatedNum { } tmp.add_assign(&acc_value); value = Some(tmp); - + Ok(tmp) })?; @@ -1934,7 +1641,7 @@ impl AllocatedNum { let mut minus_one = E::Fr::one(); minus_one.negate(); - + let self_term = ArithmeticTerm::from_variable_and_coeff(self.get_variable(), minus_one).mul_by_variable(not_bit.get_variable()); let a_term = ArithmeticTerm::from_variable(self.get_variable()); let other_term = ArithmeticTerm::from_variable(accumulator.variable); @@ -1944,19 +1651,15 @@ impl AllocatedNum { term.add_assign(a_term); term.add_assign(other_term); term.sub_assign(result_term); - + cs.allocate_main_gate(term)?; - - Ok(AllocatedNum { - value: value, - variable: result - }) + + Ok(AllocatedNum { value: value, variable: result }) } - } + } } - pub fn add_two>(&self, cs: &mut CS, x: Self, y: Self) -> Result - { + pub fn add_two>(&self, cs: &mut CS, x: Self, y: Self) -> Result { let mut value = None; let addition_result = cs.alloc(|| { @@ -1983,16 +1686,13 @@ impl AllocatedNum { Ok(AllocatedNum { value: value, - variable: addition_result + variable: addition_result, }) } - pub fn mul_constant( - &self, - cs: &mut CS, - constant: E::Fr - ) -> Result - where CS: ConstraintSystem + pub fn mul_constant(&self, cs: &mut CS, constant: E::Fr) -> Result + where + CS: ConstraintSystem, { let mut value = None; @@ -2013,18 +1713,12 @@ impl AllocatedNum { cs.allocate_main_gate(term)?; - Ok(AllocatedNum { - value: value, - variable: result - }) + Ok(AllocatedNum { value: value, variable: result }) } - pub fn mul( - &self, - cs: &mut CS, - other: &Self - ) -> Result - where CS: ConstraintSystem + pub fn mul(&self, cs: &mut CS, other: &Self) -> Result + where + CS: ConstraintSystem, { let mut value = None; @@ -2045,33 +1739,23 @@ impl AllocatedNum { cs.allocate_main_gate(term)?; - Ok(AllocatedNum { - value: value, - variable: product - }) + Ok(AllocatedNum { value: value, variable: product }) } - pub fn square( - &self, - cs: &mut CS, - ) -> Result - where CS: ConstraintSystem + pub fn square(&self, cs: &mut CS) -> Result + where + CS: ConstraintSystem, { self.mul(cs, &self) } - /// Takes two allocated numbers (a, b) and returns /// a if the condition is true, and b /// otherwise. /// Most often to be used with b = 0 - pub fn conditionally_select( - cs: &mut CS, - a: &Self, - b: &Self, - condition: &Boolean - ) -> Result - where CS: ConstraintSystem + pub fn conditionally_select(cs: &mut CS, a: &Self, b: &Self, condition: &Boolean) -> Result + where + CS: ConstraintSystem, { // we quickly work on a special case if we actually do not select anything if a.get_variable() == b.get_variable() { @@ -2084,19 +1768,16 @@ impl AllocatedNum { // code below is valid if a variable != b variable let res = match condition { - Boolean::Constant(flag) => if *flag { a.clone() } else { b.clone() }, - + Boolean::Constant(flag) => { + if *flag { + a.clone() + } else { + b.clone() + } + } + Boolean::Is(cond) => { - let c = Self::alloc( - cs, - || { - if *cond.get_value().get()? { - Ok(*a.value.get()?) - } else { - Ok(*b.value.get()?) - } - } - )?; + let c = Self::alloc(cs, || if *cond.get_value().get()? { Ok(*a.value.get()?) } else { Ok(*b.value.get()?) })?; // a * condition + b*(1-condition) = c -> // (a - b) *condition - c + b = 0 @@ -2114,19 +1795,10 @@ impl AllocatedNum { self::stats::increment_counter(); c - }, + } Boolean::Not(cond) => { - let c = Self::alloc( - cs, - || { - if *cond.get_value().get()? { - Ok(*b.value.get()?) - } else { - Ok(*a.value.get()?) - } - } - )?; + let c = Self::alloc(cs, || if *cond.get_value().get()? { Ok(*b.value.get()?) } else { Ok(*a.value.get()?) })?; // b * condition + a*(1-condition) = c -> // ( b - a) * condition - c + a = 0 @@ -2146,16 +1818,11 @@ impl AllocatedNum { c } }; - + Ok(res) } - fn conditionally_select_for_special_main_gate>( - cs: &mut CS, - a: &Self, - b: &Self, - condition: &Boolean - ) -> Result { + fn conditionally_select_for_special_main_gate>(cs: &mut CS, a: &Self, b: &Self, condition: &Boolean) -> Result { use bellman::plonk::better_better_cs::cs::GateInternal; use bellman::plonk::better_better_cs::gates::selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext; @@ -2167,25 +1834,21 @@ impl AllocatedNum { // code below is valid if a variable != b variable let res = match condition { - Boolean::Constant(flag) => if *flag { a.clone() } else { b.clone() }, - - Boolean::Is(cond) => { + Boolean::Constant(flag) => { + if *flag { + a.clone() + } else { + b.clone() + } + } - let c = Self::alloc( - cs, - || { - if *cond.get_value().get()? { - Ok(*a.value.get()?) - } else { - Ok(*b.value.get()?) - } - } - )?; + Boolean::Is(cond) => { + let c = Self::alloc(cs, || if *cond.get_value().get()? { Ok(*a.value.get()?) } else { Ok(*b.value.get()?) })?; // a * condition + b*(1-condition) = c -> // (a - b) *condition - c + b = 0 - // that has to be formatted as + // that has to be formatted as // A (var) = condition // B = a // C = b @@ -2215,32 +1878,18 @@ impl AllocatedNum { vars[2] = b.get_variable(); vars[3] = c.get_variable(); - cs.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - )?; + cs.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[])?; c - }, + } Boolean::Not(cond) => { - let c = Self::alloc( - cs, - || { - if *cond.get_value().get()? { - Ok(*b.value.get()?) - } else { - Ok(*a.value.get()?) - } - } - )?; + let c = Self::alloc(cs, || if *cond.get_value().get()? { Ok(*b.value.get()?) } else { Ok(*a.value.get()?) })?; // b * condition + a*(1-condition) = c -> // (b - a) * condition - c + a = 0 - // that has to be formatted as + // that has to be formatted as // A (var) = condition // B = a // C = b @@ -2267,43 +1916,32 @@ impl AllocatedNum { vars[2] = b.get_variable(); vars[3] = c.get_variable(); - cs.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - )?; + cs.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[])?; c } }; - + Ok(res) } /// Masks a value with a Boolean - pub fn mask( - cs: &mut CS, - a: &Self, - condition: &Boolean - ) -> Result - where CS: ConstraintSystem + pub fn mask(cs: &mut CS, a: &Self, condition: &Boolean) -> Result + where + CS: ConstraintSystem, { // code below is valid if a variable != b variable let res = match condition { - Boolean::Constant(flag) => if *flag { a.clone() } else { AllocatedNum::zero(cs) }, - + Boolean::Constant(flag) => { + if *flag { + a.clone() + } else { + AllocatedNum::zero(cs) + } + } + Boolean::Is(cond) => { - let c = Self::alloc( - cs, - || { - if *cond.get_value().get()? { - Ok(*a.value.get()?) - } else { - Ok(E::Fr::zero()) - } - } - )?; + let c = Self::alloc(cs, || if *cond.get_value().get()? { Ok(*a.value.get()?) } else { Ok(E::Fr::zero()) })?; // c = a * condition // a * condition - c = 0 @@ -2316,19 +1954,10 @@ impl AllocatedNum { cs.allocate_main_gate(main_term)?; c - }, + } Boolean::Not(cond) => { - let c = Self::alloc( - cs, - || { - if *cond.get_value().get()? { - Ok(E::Fr::zero()) - } else { - Ok(*a.value.get()?) - } - } - )?; + let c = Self::alloc(cs, || if *cond.get_value().get()? { Ok(E::Fr::zero()) } else { Ok(*a.value.get()?) })?; // a * (1 - condition) = c // a * (1-condition) - c = 0 @@ -2346,23 +1975,20 @@ impl AllocatedNum { c } }; - + Ok(res) } - pub fn div( - &self, - cs: &mut CS, - other: &Self - ) -> Result - where CS: ConstraintSystem + pub fn div(&self, cs: &mut CS, other: &Self) -> Result + where + CS: ConstraintSystem, { let mut value = None; - let quotient= cs.alloc(|| { + let quotient = cs.alloc(|| { let mut tmp = *other.value.get()?; tmp = *tmp.inverse().get()?; - + tmp.mul_assign(self.value.get()?); value = Some(tmp); @@ -2378,15 +2004,14 @@ impl AllocatedNum { cs.allocate_main_gate(term)?; - Ok(AllocatedNum { - value: value, - variable: quotient - }) + Ok(AllocatedNum { value: value, variable: quotient }) } // Montgomery double and add algorithm - pub fn pow(cs: &mut CS, base: &Self, d: F) -> Result - where CS: ConstraintSystem, F: AsRef<[Boolean]> + pub fn pow(cs: &mut CS, base: &Self, d: F) -> Result + where + CS: ConstraintSystem, + F: AsRef<[Boolean]>, { let mut r0 = Self::one(cs); let mut r1 = base.clone(); @@ -2397,20 +2022,10 @@ impl AllocatedNum { let r0_squared = r0.square(cs)?; let r1_squared = r1.square(cs)?; let r0_times_r1 = r0.mul(cs, &r1)?; - - r0 = AllocatedNum::conditionally_select( - cs, - &r0_times_r1, - &r0_squared, - b, - )?; - - r1 = AllocatedNum::conditionally_select( - cs, - &r1_squared, - &r0_times_r1, - b, - )?; + + r0 = AllocatedNum::conditionally_select(cs, &r0_times_r1, &r0_squared, b)?; + + r1 = AllocatedNum::conditionally_select(cs, &r1_squared, &r0_times_r1, b)?; } Ok(r0) @@ -2418,18 +2033,14 @@ impl AllocatedNum { /// Return (fixed) amount of bits of the allocated number. /// Can be used when there is a priori knowledge of bit length of the number - pub fn into_bits_le( - &self, - cs: &mut CS, - bit_length: Option, - ) -> Result, SynthesisError> + pub fn into_bits_le(&self, cs: &mut CS, bit_length: Option) -> Result, SynthesisError> where CS: ConstraintSystem, { if let Some(bit_length) = bit_length { assert!(bit_length <= E::Fr::NUM_BITS as usize); } - + let bits = boolean::field_into_allocated_bits_le_fixed(cs, self.value, bit_length)?; let mut minus_one = E::Fr::one(); @@ -2452,20 +2063,15 @@ impl AllocatedNum { } } - #[cfg(test)] mod test { use super::*; - use rand::{SeedableRng, Rng, XorShiftRng}; use super::*; + use crate::bellman::plonk::better_better_cs::cs::{PlonkCsWidth4WithNextStepParams, TrivialAssembly, Width4MainGateWithDNext}; + use crate::rescue; use bellman::pairing::bn256::{Bn256, Fr}; use bellman::pairing::ff::PrimeField; - use crate::rescue; - use crate::bellman::plonk::better_better_cs::cs::{ - TrivialAssembly, - PlonkCsWidth4WithNextStepParams, - Width4MainGateWithDNext - }; + use rand::{Rng, SeedableRng, XorShiftRng}; #[test] fn test_multiplication() { @@ -2477,18 +2083,11 @@ mod test { out.mul_assign(&in_1); { - let mut cs = TrivialAssembly::::new(); + let mut cs = TrivialAssembly::::new(); - let this = AllocatedNum::alloc(&mut cs, - || Ok(in_0) - ).unwrap(); + let this = AllocatedNum::alloc(&mut cs, || Ok(in_0)).unwrap(); - let other = AllocatedNum::alloc(&mut cs, - || Ok(in_1) - ).unwrap(); + let other = AllocatedNum::alloc(&mut cs, || Ok(in_1)).unwrap(); let result = this.mul(&mut cs, &other).unwrap(); @@ -2509,11 +2108,7 @@ mod test { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Self::MainGate::default().into_internal(), - ] - ) + Ok(vec![Self::MainGate::default().into_internal()]) } fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { let z = AllocatedNum::zero(cs); @@ -2540,16 +2135,10 @@ mod test { let setup = assembly.create_setup::(&worker).unwrap(); use crate::bellman::kate_commitment::*; - use crate::bellman::plonk::commitments::transcript::{*, keccak_transcript::RollingKeccakTranscript}; + use crate::bellman::plonk::commitments::transcript::{keccak_transcript::RollingKeccakTranscript, *}; - let crs_mons = - Crs::::crs_42(setup.permutation_monomials[0].size(), &worker); + let crs_mons = Crs::::crs_42(setup.permutation_monomials[0].size(), &worker); - let _proof = assembly.create_proof::<_, RollingKeccakTranscript>( - &worker, - &setup, - &crs_mons, - None - ).unwrap(); + let _proof = assembly.create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs_mons, None).unwrap(); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/assignment.rs b/crates/franklin-crypto/src/plonk/circuit/assignment.rs index 10b7af2..be07c3d 100644 --- a/crates/franklin-crypto/src/plonk/circuit/assignment.rs +++ b/crates/franklin-crypto/src/plonk/circuit/assignment.rs @@ -1,6 +1,4 @@ -use crate::bellman::{ - SynthesisError -}; +use crate::bellman::SynthesisError; pub trait Assignment { fn get(&self) -> Result<&T, SynthesisError>; @@ -11,14 +9,14 @@ impl Assignment for Option { fn get(&self) -> Result<&T, SynthesisError> { match self { Some(v) => Ok(v), - None => Err(SynthesisError::AssignmentMissing) + None => Err(SynthesisError::AssignmentMissing), } } fn grab(self) -> Result { match self { Some(v) => Ok(v), - None => Err(SynthesisError::AssignmentMissing) + None => Err(SynthesisError::AssignmentMissing), } } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint/bigint.rs b/crates/franklin-crypto/src/plonk/circuit/bigint/bigint.rs index a0a7954..69338db 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint/bigint.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint/bigint.rs @@ -1,33 +1,12 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PolynomialInConstraint, + PolynomialMultiplicativeTerm, TimeDilation, Variable, Width4MainGateWithDNext, }; use num_bigint::BigUint; @@ -51,7 +30,7 @@ pub struct LimbedRepresentationParameters { pub shift_left_by_limb_constant: E::Fr, pub shift_right_by_limb_constant: E::Fr, pub mul_two_constant: E::Fr, - pub div_two_constant: E::Fr + pub div_two_constant: E::Fr, } impl LimbedRepresentationParameters { @@ -108,37 +87,24 @@ pub(crate) fn get_num_bits(el: &F) -> usize { } impl Limb { - pub fn new( - term: Term, - max_value: BigUint, - ) -> Self { - Self { - term, - max_value, - } + pub fn new(term: Term, max_value: BigUint) -> Self { + Self { term, max_value } } - pub fn new_constant( - value: BigUint - ) -> Self { + pub fn new_constant(value: BigUint) -> Self { let v = biguint_to_fe(value.clone()); let term = Term::::from_constant(v); - Self { - term, - max_value: value - } + Self { term, max_value: value } } - pub fn new_constant_from_field_value( - value: E::Fr - ) -> Self { + pub fn new_constant_from_field_value(value: E::Fr) -> Self { let term = Term::::from_constant(value); Self { term, - max_value: fe_to_biguint(&value) + max_value: fe_to_biguint(&value), } } @@ -188,10 +154,7 @@ impl Limb { self.term.get_constant_value() } - pub fn collapse_into_num>( - &self, - cs: &mut CS - ) -> Result, SynthesisError> { + pub fn collapse_into_num>(&self, cs: &mut CS) -> Result, SynthesisError> { self.term.collapse_into_num(cs) } @@ -217,8 +180,8 @@ pub fn repr_to_biguint(repr: &F::Repr) -> BigUint { #[track_caller] pub fn mod_inverse(el: &BigUint, modulus: &BigUint) -> BigUint { use crate::num_bigint::BigInt; - use crate::num_integer::{Integer, ExtendedGcd}; - use crate::num_traits::{ToPrimitive, Zero, One}; + use crate::num_integer::{ExtendedGcd, Integer}; + use crate::num_traits::{One, ToPrimitive, Zero}; if el.is_zero() { panic!("division by zero"); @@ -227,7 +190,7 @@ pub fn mod_inverse(el: &BigUint, modulus: &BigUint) -> BigUint { let el_signed = BigInt::from(el.clone()); let modulus_signed = BigInt::from(modulus.clone()); - let ExtendedGcd{ gcd, x: _, y, .. } = modulus_signed.extended_gcd(&el_signed); + let ExtendedGcd { gcd, x: _, y, .. } = modulus_signed.extended_gcd(&el_signed); assert!(gcd.is_one()); let y = if y < BigInt::zero() { let mut y = y; @@ -269,8 +232,8 @@ pub fn some_biguint_to_fe(value: &Option) -> Option { let n = F::from_str(&value.to_str_radix(10)).unwrap(); Some(n) - }, - None => None + } + None => None, } } @@ -288,8 +251,8 @@ pub fn some_fe_to_biguint(el: &Option) -> Option { let ret = repr_to_biguint::(&repr); Some(ret) - }, - None => None + } + None => None, } } @@ -419,4 +382,4 @@ pub(crate) fn make_multiple(mut value: usize, multiple_of: usize) -> usize { } value -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint/field.rs b/crates/franklin-crypto/src/plonk/circuit/bigint/field.rs index c4b39cc..116917a 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint/field.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint/field.rs @@ -1,43 +1,22 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PolynomialInConstraint, + PolynomialMultiplicativeTerm, TimeDilation, Variable, Width4MainGateWithDNext, }; use super::super::allocated_num::{AllocatedNum, Num}; +use super::super::boolean::{AllocatedBit, Boolean}; use super::super::linear_combination::LinearCombination; use super::super::simple_term::Term; -use super::super::boolean::{Boolean, AllocatedBit}; use crate::plonk::circuit::SomeArithmetizable; -use super::*; use super::bigint::*; +use super::*; use num_bigint::BigUint; use num_integer::Integer; use num_traits::Zero; @@ -45,7 +24,7 @@ use num_traits::Zero; // Parameters of the representation #[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[serde(bound = "")] -pub struct RnsParameters{ +pub struct RnsParameters { // this is kind-of normal UintX limbs pub binary_limbs_params: LimbedRepresentationParameters, pub num_binary_limbs: usize, @@ -81,10 +60,10 @@ pub struct RnsParameters{ #[serde(skip_serializing, default)] #[serde(bound(serialize = ""))] #[serde(bound(deserialize = ""))] - pub (crate) _marker: std::marker::PhantomData + pub(crate) _marker: std::marker::PhantomData, } -impl<'a, E: Engine, F: PrimeField> RnsParameters{ +impl<'a, E: Engine, F: PrimeField> RnsParameters { pub fn max_representable_value(&self) -> BigUint { let mut tmp = self.base_field_modulus.clone() * &self.binary_representation_max_value; tmp = tmp.sqrt(); @@ -96,25 +75,19 @@ impl<'a, E: Engine, F: PrimeField> RnsParameters{ self.base_field_modulus.clone() * &self.binary_representation_max_value } - pub fn new_for_field(limb_size: usize, intermediate_limb_capacity: usize, num_binary_limbs:usize) -> Self { + pub fn new_for_field(limb_size: usize, intermediate_limb_capacity: usize, num_binary_limbs: usize) -> Self { let default_strategy = RangeConstraintInfo { minimal_multiple: 2, optimal_multiple: 8, multiples_per_gate: 4, linear_terms_used: 4, - strategy: RangeConstraintStrategy::CustomTwoBitGate + strategy: RangeConstraintStrategy::CustomTwoBitGate, }; Self::new_for_field_with_strategy(limb_size, intermediate_limb_capacity, num_binary_limbs, default_strategy, false) } - pub fn new_for_field_with_strategy( - limb_size: usize, - intermediate_limb_capacity: usize, - num_binary_limbs:usize, - strategy: RangeConstraintInfo, - prefer_single_limb_allocation: bool - ) -> Self { + pub fn new_for_field_with_strategy(limb_size: usize, intermediate_limb_capacity: usize, num_binary_limbs: usize, strategy: RangeConstraintInfo, prefer_single_limb_allocation: bool) -> Self { let binary_limbs_params = LimbedRepresentationParameters::new(limb_size, intermediate_limb_capacity); let minimal_multiple = strategy.minimal_multiple; @@ -212,7 +185,7 @@ impl<'a, E: Engine, F: PrimeField> RnsParameters{ represented_field_modulus, binary_limbs_bit_widths: binary_limbs_max_bits_if_in_field.clone(), binary_limbs_max_values: binary_limbs_max_values_if_in_field.clone(), - represented_field_modulus_negated_limbs_biguints : negated_modulus_chunks, + represented_field_modulus_negated_limbs_biguints: negated_modulus_chunks, represented_field_modulus_limbs: modulus_limbs, represented_field_modulus_negated_limbs, represented_field_modulus_negated_in_base_field: repr_modulus_negated, @@ -221,17 +194,22 @@ impl<'a, E: Engine, F: PrimeField> RnsParameters{ prefer_single_limb_carry_propagation: false, represented_field_modulus_in_base_field: represented_modulo_base, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; if freshly_allocated_max_value >= new.max_representable_value() { - panic!("Newly allocated value will have limit of {} ({} bits) that is larger than max intermediate value {} ({} bits) before forced reduction", - &freshly_allocated_max_value, freshly_allocated_max_value.bits(), new.max_representable_value(), new.max_representable_value().bits()); + panic!( + "Newly allocated value will have limit of {} ({} bits) that is larger than max intermediate value {} ({} bits) before forced reduction", + &freshly_allocated_max_value, + freshly_allocated_max_value.bits(), + new.max_representable_value(), + new.max_representable_value().bits() + ); } assert!( - &new.max_representable_value() >= &new.represented_field_modulus, - "not sufficient capacity to represent modulus: RNS max value < p^2", + &new.max_representable_value() >= &new.represented_field_modulus, + "not sufficient capacity to represent modulus: RNS max value < p^2", ); if new.can_allocate_from_double_limb_witness() { @@ -267,7 +245,7 @@ impl<'a, E: Engine, F: PrimeField> RnsParameters{ } #[derive(Clone, Debug)] -pub struct FieldElement<'a, E: Engine, F: PrimeField>{ +pub struct FieldElement<'a, E: Engine, F: PrimeField> { // this is kind-of normal UintX limbs pub binary_limbs: Vec>, // we can not multiply by power of modulus of our base field E, @@ -289,23 +267,23 @@ impl<'a, E: Engine, F: PrimeField> std::fmt::Display for FieldElement<'a, E, F> write!(f, "Value from binary limbs = None, ")?; } for (i, l) in self.binary_limbs.iter().enumerate() { - write!(f, "Limb {}: value = {:?}, max_value = {}, bits = {}, ", i, l.term.get_value(), l.max_value.to_str_radix(16), l.max_value.bits())?; + write!( + f, + "Limb {}: value = {:?}, max_value = {}, bits = {}, ", + i, + l.term.get_value(), + l.max_value.to_str_radix(16), + l.max_value.bits() + )?; } write!(f, "Base field limb value = {:?} ", self.base_field_limb.get_value())?; writeln!(f, "}}") } } -pub fn split_into_limbs( - value: F, - params: &RnsParameters -) -> (Vec, E::Fr) { +pub fn split_into_limbs(value: F, params: &RnsParameters) -> (Vec, E::Fr) { let value_as_bigint = fe_to_biguint(&value); - let binary_limb_values = split_into_fixed_number_of_limbs( - value_as_bigint, - params.binary_limbs_params.limb_size_bits, - params.num_binary_limbs - ); + let binary_limb_values = split_into_fixed_number_of_limbs(value_as_bigint, params.binary_limbs_params.limb_size_bits, params.num_binary_limbs); assert_eq!(binary_limb_values.len(), params.num_binary_limbs); let base_limb = fe_to_biguint(&value) % ¶ms.base_field_modulus; @@ -317,10 +295,7 @@ pub fn split_into_limbs( return (binary_limbs, base_limb); } -pub fn value_to_limbs( - value: Option, - params: &RnsParameters -) -> (Vec>, Option) { +pub fn value_to_limbs(value: Option, params: &RnsParameters) -> (Vec>, Option) { let num_limbs = params.num_binary_limbs; match value { @@ -330,7 +305,7 @@ pub fn value_to_limbs( assert_eq!(binary_limbs.len(), params.num_binary_limbs); return (binary_limbs, Some(base_limb)); - }, + } None => { return (vec![None; num_limbs], None); } @@ -348,24 +323,16 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { result } - pub fn new_allocated>( - cs: &mut CS, - value: Option, - params: &'a RnsParameters - ) -> Result { + pub fn new_allocated>(cs: &mut CS, value: Option, params: &'a RnsParameters) -> Result { let (binary_limbs, _) = value_to_limbs(value, params); let mut witnesses = Vec::with_capacity(params.num_binary_limbs); - for (l, &width) in binary_limbs.into_iter() - .zip(params.binary_limbs_bit_widths.iter()) - { + for (l, &width) in binary_limbs.into_iter().zip(params.binary_limbs_bit_widths.iter()) { if width == 0 { witnesses.push(Num::Constant(E::Fr::zero())); } else { - let a = AllocatedNum::alloc(cs, || { - Ok(*l.get()?) - })?; + let a = AllocatedNum::alloc(cs, || Ok(*l.get()?))?; let n = Num::Variable(a); @@ -376,24 +343,16 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { Self::coarsely_allocate_from_single_limb_witnesses(cs, &witnesses, false, params) } - pub fn new_allocated_in_field>( - cs: &mut CS, - value: Option, - params: &'a RnsParameters - ) -> Result { + pub fn new_allocated_in_field>(cs: &mut CS, value: Option, params: &'a RnsParameters) -> Result { let (binary_limbs, _) = value_to_limbs(value, params); let mut witnesses = Vec::with_capacity(params.num_binary_limbs); - for (l, &width) in binary_limbs.into_iter() - .zip(params.binary_limbs_bit_widths.iter()) - { + for (l, &width) in binary_limbs.into_iter().zip(params.binary_limbs_bit_widths.iter()) { if width == 0 { witnesses.push(Num::Constant(E::Fr::zero())); } else { - let a = AllocatedNum::alloc(cs, || { - Ok(*l.get()?) - })?; + let a = AllocatedNum::alloc(cs, || Ok(*l.get()?))?; let n = Num::Variable(a); @@ -409,14 +368,12 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { /// larger than for an element that is in a field. Number of limbs is limited, /// so that number of binary limbs is strictly enough to represent value in-field #[track_caller] - pub fn allocate_from_single_limb_witnesses_in_field>( - cs: &mut CS, - witnesses: &[Num], - params: &'a RnsParameters - ) -> Result { + pub fn allocate_from_single_limb_witnesses_in_field>(cs: &mut CS, witnesses: &[Num], params: &'a RnsParameters) -> Result { assert_eq!(params.num_limbs_for_in_field_representation, witnesses.len()); - assert!(params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, - "limb size must be divisible by range constraint strategy granularity"); + assert!( + params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, + "limb size must be divisible by range constraint strategy granularity" + ); let mut binary_limbs_allocated = Vec::with_capacity(params.num_binary_limbs); @@ -432,25 +389,22 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match w { Num::Constant(value) => { let v = fe_to_biguint(value); - this_value += v.clone() << (witness_idx*params.binary_limbs_params.limb_size_bits); + this_value += v.clone() << (witness_idx * params.binary_limbs_params.limb_size_bits); - let (expected_width, expected_max_value) = - (params.binary_limbs_bit_widths[witness_idx], params.binary_limbs_max_values[witness_idx].clone()); + let (expected_width, expected_max_value) = (params.binary_limbs_bit_widths[witness_idx], params.binary_limbs_max_values[witness_idx].clone()); assert!(expected_width > 0); assert!(v.bits() as usize <= expected_width); assert!(v <= expected_max_value); - let limb = Limb::::new_constant( - v - ); + let limb = Limb::::new_constant(v); binary_limbs_allocated.push(limb); - }, + } Num::Variable(var) => { let limb_value = if let Some(v) = var.get_value() { let v = fe_to_biguint(&v); - this_value += v.clone() << (witness_idx*params.binary_limbs_params.limb_size_bits); + this_value += v.clone() << (witness_idx * params.binary_limbs_params.limb_size_bits); Some(v) } else { @@ -459,8 +413,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { None }; - let (expected_width, expected_max_value) = - (params.binary_limbs_bit_widths[witness_idx], params.binary_limbs_max_values[witness_idx].clone()); + let (expected_width, expected_max_value) = (params.binary_limbs_bit_widths[witness_idx], params.binary_limbs_max_values[witness_idx].clone()); assert!(expected_width > 0); if let Some(v) = limb_value.as_ref() { @@ -472,22 +425,21 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match params.range_check_info.strategy { RangeConstraintStrategy::MultiTable => { self::range_constraint_functions::coarsely_enforce_using_multitable(cs, var, expected_width)?; - }, + } RangeConstraintStrategy::SingleTableInvocation => { self::single_table_range_constraint::enforce_using_single_column_table(cs, var, expected_width)?; - }, + } RangeConstraintStrategy::CustomTwoBitGate => { let _ = create_range_constraint_chain(cs, var, expected_width)?; } - _ => {unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled")} + _ => { + unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled") + } } let term = Term::::from_allocated_num(var.clone()); - let limb = Limb::::new( - term, - expected_max_value, - ); + let limb = Limb::::new(term, expected_max_value); binary_limbs_allocated.push(limb); } @@ -505,11 +457,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let base_field_term = Term::::from_num(base_field_limb_num); - let this_value = if value_is_none { - None - } else { - Some(this_value) - }; + let this_value = if value_is_none { None } else { Some(this_value) }; let this_value = some_biguint_to_fe::(&this_value); @@ -528,14 +476,12 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { /// Use limb witnesses from some other source to cast them into field element. /// Caller must ensure that witnesses are properly range constrainted #[track_caller] - pub fn from_single_limb_witnesses_unchecked>( - cs: &mut CS, - witnesses: &[Num], - params: &'a RnsParameters - ) -> Result { + pub fn from_single_limb_witnesses_unchecked>(cs: &mut CS, witnesses: &[Num], params: &'a RnsParameters) -> Result { assert_eq!(params.num_limbs_for_in_field_representation, witnesses.len()); - assert!(params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, - "limb size must be divisible by range constraint strategy granularity"); + assert!( + params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, + "limb size must be divisible by range constraint strategy granularity" + ); let mut binary_limbs_allocated = Vec::with_capacity(params.num_binary_limbs); @@ -551,25 +497,22 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match w { Num::Constant(value) => { let v = fe_to_biguint(value); - this_value += v.clone() << (witness_idx*params.binary_limbs_params.limb_size_bits); + this_value += v.clone() << (witness_idx * params.binary_limbs_params.limb_size_bits); - let (expected_width, expected_max_value) = - (params.binary_limbs_bit_widths[witness_idx], params.binary_limbs_max_values[witness_idx].clone()); + let (expected_width, expected_max_value) = (params.binary_limbs_bit_widths[witness_idx], params.binary_limbs_max_values[witness_idx].clone()); assert!(expected_width > 0); assert!(v.bits() as usize <= expected_width); assert!(v <= expected_max_value); - let limb = Limb::::new_constant( - v - ); + let limb = Limb::::new_constant(v); binary_limbs_allocated.push(limb); - }, + } Num::Variable(var) => { let limb_value = if let Some(v) = var.get_value() { let v = fe_to_biguint(&v); - this_value += v.clone() << (witness_idx*params.binary_limbs_params.limb_size_bits); + this_value += v.clone() << (witness_idx * params.binary_limbs_params.limb_size_bits); Some(v) } else { @@ -578,8 +521,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { None }; - let (expected_width, expected_max_value) = - (params.binary_limbs_bit_widths[witness_idx], params.binary_limbs_max_values[witness_idx].clone()); + let (expected_width, expected_max_value) = (params.binary_limbs_bit_widths[witness_idx], params.binary_limbs_max_values[witness_idx].clone()); assert!(expected_width > 0); if let Some(v) = limb_value.as_ref() { @@ -588,10 +530,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let term = Term::::from_allocated_num(var.clone()); - let limb = Limb::::new( - term, - expected_max_value, - ); + let limb = Limb::::new(term, expected_max_value); binary_limbs_allocated.push(limb); } @@ -609,11 +548,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let base_field_term = Term::::from_num(base_field_limb_num); - let this_value = if value_is_none { - None - } else { - Some(this_value) - }; + let this_value = if value_is_none { None } else { Some(this_value) }; let this_value = some_biguint_to_fe::(&this_value); @@ -638,11 +573,13 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { cs: &mut CS, witnesses: &[Num], may_overflow: bool, - params: &'a RnsParameters + params: &'a RnsParameters, ) -> Result { assert!(params.num_binary_limbs == witnesses.len()); - assert!(params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, - "limb size must be divisible by range constraint strategy granularity"); + assert!( + params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, + "limb size must be divisible by range constraint strategy granularity" + ); let mut binary_limbs_allocated = Vec::with_capacity(params.num_binary_limbs); @@ -658,8 +595,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match w { Num::Constant(value) => { let v = fe_to_biguint(value); - this_value += v.clone() << (witness_idx*params.binary_limbs_params.limb_size_bits); - + this_value += v.clone() << (witness_idx * params.binary_limbs_params.limb_size_bits); // if the element must fit into the field than pad with zeroes if may_overflow == false && witness_idx >= params.num_limbs_for_in_field_representation { @@ -678,16 +614,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { assert!(v.bits() as usize <= expected_width); assert!(v <= expected_max_value); - let limb = Limb::::new_constant( - v - ); + let limb = Limb::::new_constant(v); binary_limbs_allocated.push(limb); - }, + } Num::Variable(var) => { let limb_value = if let Some(v) = var.get_value() { let v = fe_to_biguint(&v); - this_value += v.clone() << (witness_idx*params.binary_limbs_params.limb_size_bits); + this_value += v.clone() << (witness_idx * params.binary_limbs_params.limb_size_bits); Some(v) } else { @@ -717,30 +651,31 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { assert!(v <= &expected_max_value); } - assert!(expected_width % params.range_check_info.minimal_multiple == 0, - "limb size must be divisible by range constraint strategy granularity"); + assert!( + expected_width % params.range_check_info.minimal_multiple == 0, + "limb size must be divisible by range constraint strategy granularity" + ); // match over strategy match params.range_check_info.strategy { RangeConstraintStrategy::MultiTable => { self::range_constraint_functions::coarsely_enforce_using_multitable(cs, var, expected_width)?; - }, + } RangeConstraintStrategy::SingleTableInvocation => { self::single_table_range_constraint::enforce_using_single_column_table(cs, var, expected_width)?; - }, + } RangeConstraintStrategy::CustomTwoBitGate => { let _ = create_range_constraint_chain(cs, var, expected_width)?; } - _ => {unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled")} + _ => { + unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled") + } } let term = Term::::from_allocated_num(var.clone()); - let limb = Limb::::new( - term, - expected_max_value, - ); + let limb = Limb::::new(term, expected_max_value); binary_limbs_allocated.push(limb); } @@ -755,11 +690,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let base_field_term = Term::::from_num(base_field_limb_num); - let this_value = if value_is_none { - None - } else { - Some(this_value) - }; + let this_value = if value_is_none { None } else { Some(this_value) }; let this_value = some_biguint_to_fe::(&this_value); @@ -781,15 +712,12 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { /// such that highest limb may be a little (up to range constraint granularity) /// larger than for an element that is in a field. #[track_caller] - pub fn coarsely_allocate_for_known_bit_width>( - cs: &mut CS, - value: Option, - width: usize, - params: &'a RnsParameters - ) -> Result { + pub fn coarsely_allocate_for_known_bit_width>(cs: &mut CS, value: Option, width: usize, params: &'a RnsParameters) -> Result { assert!(width > 0); - assert!(params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, - "limb size must be divisible by range constraint strategy granularity"); + assert!( + params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, + "limb size must be divisible by range constraint strategy granularity" + ); if let Some(v) = value.as_ref() { assert!(v.bits() as usize <= width); @@ -810,12 +738,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { for (idx, (value, mut size)) in limb_values.into_iter().zip(limb_sizes.into_iter()).enumerate() { let value_as_fe = some_biguint_to_fe::(&value); - let a = AllocatedNum::alloc( - cs, - || { - Ok(*value_as_fe.get()?) - } - )?; + let a = AllocatedNum::alloc(cs, || Ok(*value_as_fe.get()?))?; let remainder = size % params.range_check_info.minimal_multiple; @@ -832,22 +755,21 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match params.range_check_info.strategy { RangeConstraintStrategy::MultiTable => { self::range_constraint_functions::coarsely_enforce_using_multitable(cs, &a, size)?; - }, + } RangeConstraintStrategy::SingleTableInvocation => { self::single_table_range_constraint::enforce_using_single_column_table(cs, &a, size)?; - }, + } RangeConstraintStrategy::CustomTwoBitGate => { let _ = create_range_constraint_chain(cs, &a, size)?; } - _ => {unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled")} + _ => { + unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled") + } } let term = Term::::from_allocated_num(a.clone()); - let limb = Limb::::new( - term, - max_value, - ); + let limb = Limb::::new(term, max_value); binary_limbs_allocated.push(limb); @@ -856,7 +778,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } binary_limbs_allocated.resize(params.num_binary_limbs, Self::zero_limb()); - + let base_field_limb_num = base_field_lc.into_num(cs)?; let base_field_term = Term::::from_num(base_field_limb_num); @@ -871,18 +793,16 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { Ok(new) } - pub fn coarsely_allocate_for_unknown_width>( - cs: &mut CS, - value: Option, - params: &'a RnsParameters - ) -> Result { + pub fn coarsely_allocate_for_unknown_width>(cs: &mut CS, value: Option, params: &'a RnsParameters) -> Result { if params.can_allocate_from_double_limb_witness() == true { let slices = Self::slice_into_double_limb_witnesses(value, cs, params, true)?; Self::from_double_size_limb_witnesses(cs, &slices, true, params) } else { - assert!(params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, - "limb size must be divisible by range constraint strategy granularity"); + assert!( + params.binary_limbs_params.limb_size_bits % params.range_check_info.minimal_multiple == 0, + "limb size must be divisible by range constraint strategy granularity" + ); let slices = Self::slice_into_limb_witnesses(value, cs, params)?; @@ -890,15 +810,10 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } } - pub fn from_double_size_limb_witnesses>( - cs: &mut CS, - witnesses: &[Num], - top_limb_may_overflow: bool, - params: &'a RnsParameters - ) -> Result { + pub fn from_double_size_limb_witnesses>(cs: &mut CS, witnesses: &[Num], top_limb_may_overflow: bool, params: &'a RnsParameters) -> Result { assert!(params.num_binary_limbs == 2 * witnesses.len()); // until we make better handling of a case that top limb should be zero - // we make sure that + // we make sure that assert!(params.num_limbs_for_in_field_representation & 1 == 0); let mut binary_limbs_allocated = Vec::with_capacity(params.num_binary_limbs); @@ -917,18 +832,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match w { Num::Constant(value) => { let v = fe_to_biguint(value); - this_value += v.clone() << (witness_idx*2*params.binary_limbs_params.limb_size_bits); + this_value += v.clone() << (witness_idx * 2 * params.binary_limbs_params.limb_size_bits); - let limb_values = split_into_fixed_number_of_limbs( - v, - params.binary_limbs_params.limb_size_bits, - 2 - ); + let limb_values = split_into_fixed_number_of_limbs(v, params.binary_limbs_params.limb_size_bits, 2); assert!(limb_values.len() == 2); - let low_idx = witness_idx*2; - let high_idx = witness_idx*2+1; + let low_idx = witness_idx * 2; + let high_idx = witness_idx * 2 + 1; // there are two cases: // - can not overflow and indexes are in range for in-range field element @@ -942,10 +853,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } // if the element must fit into the field than pad with zeroes - if top_limb_may_overflow == false && - low_idx >= params.num_limbs_for_in_field_representation && - high_idx >= params.num_limbs_for_in_field_representation { - + if top_limb_may_overflow == false && low_idx >= params.num_limbs_for_in_field_representation && high_idx >= params.num_limbs_for_in_field_representation { assert!(limb_values[0].is_zero()); assert!(limb_values[1].is_zero()); @@ -974,23 +882,17 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { assert!(limb_values[1].bits() as usize <= expected_high_width); for v in limb_values.into_iter() { - let limb = Limb::::new_constant( - v - ); + let limb = Limb::::new_constant(v); binary_limbs_allocated.push(limb); } - }, + } Num::Variable(var) => { let _limb_values = if let Some(v) = var.get_value() { let v = fe_to_biguint(&v); - this_value += v.clone() << (witness_idx*2*params.binary_limbs_params.limb_size_bits); + this_value += v.clone() << (witness_idx * 2 * params.binary_limbs_params.limb_size_bits); - let limb_values = split_some_into_fixed_number_of_limbs( - Some(v), - params.binary_limbs_params.limb_size_bits, - 2 - ); + let limb_values = split_some_into_fixed_number_of_limbs(Some(v), params.binary_limbs_params.limb_size_bits, 2); limb_values } else { @@ -999,8 +901,8 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { vec![None; 2] }; - let low_idx = witness_idx*2; - let high_idx = witness_idx*2+1; + let low_idx = witness_idx * 2; + let high_idx = witness_idx * 2 + 1; // there are two cases: // - can not overflow and indexes are in range for in-range field element @@ -1014,10 +916,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } // if the element must fit into the field than pad with zeroes - if top_limb_may_overflow == false && - low_idx >= params.num_limbs_for_in_field_representation && - high_idx >= params.num_limbs_for_in_field_representation { - + if top_limb_may_overflow == false && low_idx >= params.num_limbs_for_in_field_representation && high_idx >= params.num_limbs_for_in_field_representation { unreachable!("should not try to allocate a value in a field with non-constant high limbs"); } @@ -1066,17 +965,11 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let low_term = full_term.add(cs, &high_part_shifted_and_negated)?; - let low_limb = Limb::::new( - low_term.clone(), - params.binary_limbs_params.limb_max_value.clone(), - ); + let low_limb = Limb::::new(low_term.clone(), params.binary_limbs_params.limb_max_value.clone()); binary_limbs_allocated.push(low_limb); - let high_limb = Limb::::new( - high_term, - expected_high_max_value - ); + let high_limb = Limb::::new(high_term, expected_high_max_value); binary_limbs_allocated.push(high_limb); } @@ -1091,11 +984,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let base_field_term = Term::::from_num(base_field_limb_num); - let this_value = if value_is_none { - None - } else { - Some(this_value) - }; + let this_value = if value_is_none { None } else { Some(this_value) }; let this_value = some_biguint_to_fe::(&this_value); @@ -1109,29 +998,18 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { Ok(new) } - pub fn new_constant( - v: F, - params: &'a RnsParameters - ) -> Self { + pub fn new_constant(v: F, params: &'a RnsParameters) -> Self { let value = fe_to_biguint(&v); - let binary_limb_values = split_into_fixed_number_of_limbs( - value.clone(), - params.binary_limbs_params.limb_size_bits, - params.num_binary_limbs - ); + let binary_limb_values = split_into_fixed_number_of_limbs(value.clone(), params.binary_limbs_params.limb_size_bits, params.num_binary_limbs); let base_limb_value = value.clone() % ¶ms.base_field_modulus; let base_limb = biguint_to_fe::(base_limb_value.clone()); let mut binary_limbs_allocated = Vec::with_capacity(binary_limb_values.len()); - for l in binary_limb_values.into_iter() - { + for l in binary_limb_values.into_iter() { let f = biguint_to_fe(l.clone()); let term = Term::::from_constant(f); - let limb = Limb::::new( - term, - l - ); + let limb = Limb::::new(term, l); binary_limbs_allocated.push(limb); } @@ -1151,10 +1029,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { fn zero_limb() -> Limb { let term = Term::::from_constant(E::Fr::zero()); - let limb = Limb::::new( - term, - BigUint::from(0u64) - ); + let limb = Limb::::new(term, BigUint::from(0u64)); limb } @@ -1162,21 +1037,16 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { fn one_limb() -> Limb { let term = Term::::from_constant(E::Fr::one()); - let limb = Limb::::new( - term, - BigUint::from(1u64) - ); + let limb = Limb::::new(term, BigUint::from(1u64)); limb } - pub fn zero( - params: &'a RnsParameters - ) -> Self { + pub fn zero(params: &'a RnsParameters) -> Self { let zero_limb = Self::zero_limb(); let binary_limbs = vec![zero_limb.clone(); params.num_binary_limbs]; - + Self { binary_limbs: binary_limbs, base_field_limb: Term::::from_constant(E::Fr::zero()), @@ -1185,16 +1055,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } } - pub fn one( - params: &'a RnsParameters - ) -> Self { + pub fn one(params: &'a RnsParameters) -> Self { let one_limb = Self::one_limb(); let zero_limb = Self::zero_limb(); let mut binary_limbs = Vec::with_capacity(params.num_binary_limbs); binary_limbs.push(one_limb); binary_limbs.resize(params.num_binary_limbs, zero_limb.clone()); - + Self { binary_limbs: binary_limbs, base_field_limb: Term::::from_constant(E::Fr::one()), @@ -1249,20 +1117,16 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { self.base_field_limb.is_constant() } - pub fn is_zero>( - self, - cs: &mut CS, - ) -> Result<(Boolean, Self), SynthesisError> - { + pub fn is_zero>(self, cs: &mut CS) -> Result<(Boolean, Self), SynthesisError> { let x = self; let x = x.reduce_if_necessary(cs)?; let mut lc = LinearCombination::zero(); - + let num = x.base_field_limb.collapse_into_num(cs)?; let not_zero = num.is_zero(cs)?.not(); lc.add_assign_boolean_with_coeff(¬_zero, E::Fr::one()); - + for limb in x.binary_limbs.iter() { let num = limb.term.collapse_into_num(cs)?; let not_zero = num.is_zero(cs)?.not(); @@ -1272,26 +1136,22 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let num = lc.into_num(cs)?; // if any of the limbs !=0 then lc != 0 let is_zero = num.is_zero(cs)?; - + Ok((is_zero, x)) } - fn is_modulus>( - self, - cs: &mut CS, - ) -> Result<(Boolean, Self), SynthesisError> - { + fn is_modulus>(self, cs: &mut CS) -> Result<(Boolean, Self), SynthesisError> { let x = self; let x = x.reduce_if_necessary(cs)?; let params = x.representation_params; let mut lc = LinearCombination::zero(); - + let num = x.base_field_limb.collapse_into_num(cs)?; let base_limb_of_modulus = Num::Constant(params.represented_field_modulus_in_base_field); let not_modulus = Num::equals(cs, &num, &base_limb_of_modulus)?.not(); lc.add_assign_boolean_with_coeff(¬_modulus, E::Fr::one()); - + for (limb, modulus_limb) in x.binary_limbs.iter().zip(params.represented_field_modulus_limbs.iter()) { let num = limb.term.collapse_into_num(cs)?; let limb = Num::::Constant(*modulus_limb); @@ -1302,22 +1162,17 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let num = lc.into_num(cs)?; // if any of the limbs !=0 then lc != 0 let is_modulus = num.is_zero(cs)?; - + Ok((is_modulus, x)) } - pub fn negated>( - self, - cs: &mut CS - ) -> Result<(Self, Self), SynthesisError> { + pub fn negated>(self, cs: &mut CS) -> Result<(Self, Self), SynthesisError> { let (new, (_, this)) = Self::zero(&self.representation_params).sub(cs, self)?; Ok((new, this)) } - pub fn is_within_2_in_modulus_len( - &self - ) -> bool { + pub fn is_within_2_in_modulus_len(&self) -> bool { if self.is_constant() { return true; } @@ -1328,9 +1183,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { max_value < ceil } - pub fn needs_reduction( - &self - ) -> bool { + pub fn needs_reduction(&self) -> bool { if self.is_constant() { return false; } @@ -1347,10 +1200,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn reduce_if_necessary>( - self, - cs: &mut CS - ) -> Result { + pub fn reduce_if_necessary>(self, cs: &mut CS) -> Result { if self.is_constant() { return Ok(self); } @@ -1363,18 +1213,12 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn force_reduce_into_field>( - self, - cs: &mut CS - ) -> Result { + pub fn force_reduce_into_field>(self, cs: &mut CS) -> Result { self.reduction_impl(cs) } #[track_caller] - pub(crate) fn reduction_impl>( - self, - cs: &mut CS - ) -> Result { + pub(crate) fn reduction_impl>(self, cs: &mut CS) -> Result { if self.is_constant() { return Ok(self); } @@ -1389,30 +1233,21 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } else { (None, None) }; - + let max_q_bits = (self.get_max_value() / ¶ms.represented_field_modulus).bits() as usize; assert!(max_q_bits <= E::Fr::CAPACITY as usize, "for no quotient size can overflow capacity"); let q_as_field_repr = if max_q_bits == 0 { Self::zero(¶ms) - } else { - let q_as_field_repr = Self::coarsely_allocate_for_known_bit_width( - cs, - q, - max_q_bits, - ¶ms - )?; + } else { + let q_as_field_repr = Self::coarsely_allocate_for_known_bit_width(cs, q, max_q_bits, ¶ms)?; q_as_field_repr }; let r_fe = some_biguint_to_fe::(&rem); - let r_elem = Self::new_allocated( - cs, - r_fe, - params - )?; + let r_elem = Self::new_allocated(cs, r_fe, params)?; assert!(r_elem.needs_reduction() == false); @@ -1421,23 +1256,13 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let one = Self::one(self.representation_params); - Self::constraint_fma_with_multiple_additions( - cs, - &self, - &one, - &[], - &q_as_field_repr, - &[r_elem.clone()], - )?; + Self::constraint_fma_with_multiple_additions(cs, &self, &one, &[], &q_as_field_repr, &[r_elem.clone()])?; Ok(r_elem) } #[track_caller] - pub(crate) fn strict_reduction_impl>( - self, - cs: &mut CS - ) -> Result { + pub(crate) fn strict_reduction_impl>(self, cs: &mut CS) -> Result { if self.is_constant() { return Ok(self); } @@ -1452,30 +1277,21 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } else { (None, None) }; - + let max_q_bits = (self.get_max_value() / ¶ms.represented_field_modulus).bits() as usize; assert!(max_q_bits <= E::Fr::CAPACITY as usize, "for no quotient size can overflow capacity"); let q_as_field_repr = if max_q_bits == 0 { Self::zero(¶ms) - } else { - let q_as_field_repr = Self::coarsely_allocate_for_known_bit_width( - cs, - q, - max_q_bits, - ¶ms - )?; + } else { + let q_as_field_repr = Self::coarsely_allocate_for_known_bit_width(cs, q, max_q_bits, ¶ms)?; q_as_field_repr }; let r_fe = some_biguint_to_fe::(&rem); - let r_elem = Self::new_allocated_in_field( - cs, - r_fe, - params - )?; + let r_elem = Self::new_allocated_in_field(cs, r_fe, params)?; assert!(r_elem.needs_reduction() == false); @@ -1484,41 +1300,22 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let one = Self::one(self.representation_params); - Self::constraint_fma_with_multiple_additions( - cs, - &self, - &one, - &[], - &q_as_field_repr, - &[r_elem.clone()], - )?; + Self::constraint_fma_with_multiple_additions(cs, &self, &one, &[], &q_as_field_repr, &[r_elem.clone()])?; Ok(r_elem) } - fn slice_into_double_limb_witnesses>( - value: Option, - cs: &mut CS, - params: &RnsParameters, - can_overflow: bool - ) -> Result>, SynthesisError> { + fn slice_into_double_limb_witnesses>(value: Option, cs: &mut CS, params: &RnsParameters, can_overflow: bool) -> Result>, SynthesisError> { assert!(params.num_binary_limbs % 2 == 0); if can_overflow { let num_witness = params.num_binary_limbs / 2; - let witness_limbs = split_some_into_fixed_number_of_limbs( - value, - params.binary_limbs_params.limb_size_bits * 2, - num_witness - ); + let witness_limbs = split_some_into_fixed_number_of_limbs(value, params.binary_limbs_params.limb_size_bits * 2, num_witness); let mut witnesses = vec![]; for l in witness_limbs.into_iter() { let v = some_biguint_to_fe::(&l); - let w = AllocatedNum::alloc(cs, - || { - Ok(*v.get()?) - })?; + let w = AllocatedNum::alloc(cs, || Ok(*v.get()?))?; witnesses.push(Num::Variable(w)); } @@ -1530,50 +1327,29 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { num_witness += 1; } - let witness_limbs = split_some_into_fixed_number_of_limbs( - value, - params.binary_limbs_params.limb_size_bits * 2, - num_witness - ); + let witness_limbs = split_some_into_fixed_number_of_limbs(value, params.binary_limbs_params.limb_size_bits * 2, num_witness); let mut witnesses = vec![]; for l in witness_limbs.into_iter() { let v = some_biguint_to_fe::(&l); - let w = AllocatedNum::alloc(cs, - || { - Ok(*v.get()?) - })?; + let w = AllocatedNum::alloc(cs, || Ok(*v.get()?))?; witnesses.push(Num::Variable(w)); } - witnesses.resize( - params.num_binary_limbs / 2, - Num::Constant(E::Fr::zero()) - ); + witnesses.resize(params.num_binary_limbs / 2, Num::Constant(E::Fr::zero())); Ok(witnesses) } } - fn slice_into_limb_witnesses>( - value: Option, - cs: &mut CS, - params: &RnsParameters, - ) -> Result>, SynthesisError> { - let witness_limbs = split_some_into_fixed_number_of_limbs( - value, - params.binary_limbs_params.limb_size_bits, - params.num_binary_limbs - ); + fn slice_into_limb_witnesses>(value: Option, cs: &mut CS, params: &RnsParameters) -> Result>, SynthesisError> { + let witness_limbs = split_some_into_fixed_number_of_limbs(value, params.binary_limbs_params.limb_size_bits, params.num_binary_limbs); let mut witnesses = vec![]; for l in witness_limbs.into_iter() { let v = some_biguint_to_fe::(&l); - let w = AllocatedNum::alloc(cs, - || { - Ok(*v.get()?) - })?; + let w = AllocatedNum::alloc(cs, || Ok(*v.get()?))?; witnesses.push(Num::Variable(w)); } @@ -1581,11 +1357,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { Ok(witnesses) } - pub fn add>( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn add>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { let params = self.representation_params; let this = self.reduce_if_necessary(cs)?; @@ -1595,9 +1367,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut new_binary_limbs = vec![]; - for (l, r) in this.binary_limbs.iter() - .zip(other.binary_limbs.iter()) - { + for (l, r) in this.binary_limbs.iter().zip(other.binary_limbs.iter()) { let new_term = l.term.add(cs, &r.term)?; let new_max_value = l.max_value.clone() + &r.max_value; @@ -1613,16 +1383,13 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { binary_limbs: new_binary_limbs, base_field_limb: new_base_limb, value: new_value, - representation_params: params + representation_params: params, }; Ok((new, (this, other))) } - pub fn double>( - self, - cs: &mut CS, - ) -> Result<(Self, Self), SynthesisError> { + pub fn double>(self, cs: &mut CS) -> Result<(Self, Self), SynthesisError> { let params = self.representation_params; let this = self.reduce_if_necessary(cs)?; @@ -1634,8 +1401,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut new_binary_limbs = vec![]; - for l in this.binary_limbs.iter() - { + for l in this.binary_limbs.iter() { let mut new_term = l.term.clone(); new_term.scale(&two); let new_max_value = l.max_value.clone() * BigUint::from(2u64); @@ -1653,17 +1419,13 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { binary_limbs: new_binary_limbs, base_field_limb: new_base_limb, value: new_value, - representation_params: params + representation_params: params, }; Ok((new, this)) } - pub fn sub>( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn sub>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { let params = self.representation_params; // subtraction is a little more involved @@ -1717,7 +1479,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { previous = Some(borrow_bits); } - // now we can determine how many moduluses of the represented field + // now we can determine how many moduluses of the represented field // we have to add to never underflow let shift = params.binary_limbs_params.limb_size_bits * (params.num_binary_limbs - 1); @@ -1733,11 +1495,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let start = params.binary_limbs_params.limb_size_bits * (params.num_binary_limbs - 1); let end = start + params.binary_limbs_params.limb_size_bits; - let slice = get_bit_slice( - multiples.clone(), - start, - end - ); + let slice = get_bit_slice(multiples.clone(), start, end); if &slice < borrow_max_values.last().unwrap() { multiples += ¶ms.represented_field_modulus; @@ -1750,11 +1508,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } } - let multiple_slices = split_into_fixed_number_of_limbs( - multiples.clone(), - params.binary_limbs_params.limb_size_bits, - params.num_binary_limbs - ); + let multiple_slices = split_into_fixed_number_of_limbs(multiples.clone(), params.binary_limbs_params.limb_size_bits, params.num_binary_limbs); // create new limbs @@ -1766,11 +1520,13 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut new_multiple = BigUint::from(0u64); - for (idx, (((l, r), &bits), multiple)) in this.binary_limbs.iter() - .zip(other.binary_limbs.iter()) - .zip(borrow_bit_widths.iter()) - .zip(multiple_slices.iter()) - .enumerate() + for (idx, (((l, r), &bits), multiple)) in this + .binary_limbs + .iter() + .zip(other.binary_limbs.iter()) + .zip(borrow_bit_widths.iter()) + .zip(multiple_slices.iter()) + .enumerate() { let mut tmp = BigUint::from(1u64) << bits; if let Some(previous_bits) = previous.take() { @@ -1780,11 +1536,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { tmp = BigUint::from(1u64) << (previous_bits - params.binary_limbs_params.limb_size_bits); } } - let constant = if idx != last_idx { - tmp + multiple - } else { - multiple.clone() - tmp - }; + let constant = if idx != last_idx { tmp + multiple } else { multiple.clone() - tmp }; new_multiple += constant.clone() << (params.binary_limbs_params.limb_size_bits * idx); @@ -1800,10 +1552,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let new_max_value = l.max_value() + constant; - let limb = Limb::::new( - r, - new_max_value - ); + let limb = Limb::::new(r, new_max_value); new_binary_limbs.push(limb); @@ -1828,18 +1577,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { binary_limbs: new_binary_limbs, base_field_limb: new_base_limb, value: new_value, - representation_params: params + representation_params: params, }; Ok((new, (this, other))) } #[track_caller] - pub fn mul>( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn mul>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { let params = self.representation_params; let this = self.reduce_if_necessary(cs)?; @@ -1859,7 +1604,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { (Some(q), Some(r)) } - _ => (None, None) + _ => (None, None), }; // estimate q bit width @@ -1869,31 +1614,17 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // let q_elem = Self::coarsely_allocate_for_unknown_width(cs, q, params)?; - let r_elem = Self::new_allocated( - cs, - some_biguint_to_fe(&r), - params - )?; + let r_elem = Self::new_allocated(cs, some_biguint_to_fe(&r), params)?; // we constraint a * b = q*p + rem - Self::constraint_fma_with_multiple_additions( - cs, - &this, - &other, - &[], - &q_elem, - &[r_elem.clone()], - )?; + Self::constraint_fma_with_multiple_additions(cs, &this, &other, &[], &q_elem, &[r_elem.clone()])?; Ok((r_elem, (this, other))) } #[track_caller] - pub fn square>( - self, - cs: &mut CS, - ) -> Result<(Self, Self), SynthesisError> { + pub fn square>(self, cs: &mut CS) -> Result<(Self, Self), SynthesisError> { let params = self.representation_params; let this = self.reduce_if_necessary(cs)?; @@ -1912,14 +1643,10 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { (Some(q), Some(r)) } - _ => (None, None) + _ => (None, None), }; - let r_elem = Self::new_allocated( - cs, - some_biguint_to_fe(&r), - params - )?; + let r_elem = Self::new_allocated(cs, some_biguint_to_fe(&r), params)?; // we constraint a * a = q*p + rem @@ -1930,23 +1657,12 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // let q_elem = Self::coarsely_allocate_for_unknown_width(cs, q, params)?; - Self::constraint_square_with_multiple_additions( - cs, - &this, - &[], - &q_elem, - &[r_elem.clone()], - )?; + Self::constraint_square_with_multiple_additions(cs, &this, &[], &q_elem, &[r_elem.clone()])?; Ok((r_elem, this)) } - pub fn fma_with_addition_chain>( - self, - cs: &mut CS, - to_mul: Self, - to_add: Vec - ) -> Result<(Self, (Self, Self, Vec)), SynthesisError> { + pub fn fma_with_addition_chain>(self, cs: &mut CS, to_mul: Self, to_add: Vec) -> Result<(Self, (Self, Self, Vec)), SynthesisError> { let params = self.representation_params; let mut final_value = self.get_field_value(); @@ -1963,12 +1679,12 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match (this.get_value(), to_mul.get_value()) { (Some(t), Some(m)) => { value += t * m; - }, + } _ => { value_is_none = true; } } - + let mut all_constants = this.is_constant() && to_mul.is_constant(); for a in to_add.iter() { if let Some(v) = a.get_value() { @@ -1977,7 +1693,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { value_is_none = true; } all_constants = all_constants & a.is_constant(); - } + } let (q, r) = value.div_rem(¶ms.represented_field_modulus); if all_constants { @@ -1986,11 +1702,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { return Ok((new, (this, to_mul, to_add))); } - let (q, r) = if value_is_none { - (None, None) - } else { - (Some(q), Some(r)) - }; + let (q, r) = if value_is_none { (None, None) } else { (Some(q), Some(r)) }; // so we constraint self * to_mul + [to_add] = q * p + r // we we estimate q width @@ -2005,29 +1717,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // let q_elem = Self::coarsely_allocate_for_unknown_width(cs, q, params)?; - let r_elem = Self::new_allocated( - cs, - some_biguint_to_fe(&r), - params - )?; - - Self::constraint_fma_with_multiple_additions( - cs, - &this, - &to_mul, - &to_add, - &q_elem, - &[r_elem.clone()], - )?; + let r_elem = Self::new_allocated(cs, some_biguint_to_fe(&r), params)?; + + Self::constraint_fma_with_multiple_additions(cs, &this, &to_mul, &to_add, &q_elem, &[r_elem.clone()])?; return Ok((r_elem, (this, to_mul, to_add))); } - pub fn square_with_addition_chain>( - self, - cs: &mut CS, - to_add: Vec - ) -> Result<(Self, (Self, Vec)), SynthesisError> { + pub fn square_with_addition_chain>(self, cs: &mut CS, to_add: Vec) -> Result<(Self, (Self, Vec)), SynthesisError> { let params = self.representation_params; let mut final_value = self.get_field_value(); @@ -2043,7 +1740,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match this.get_value() { Some(t) => { value += t.clone() * &t; - }, + } _ => { value_is_none = true; } @@ -2056,7 +1753,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { value_is_none = true; } all_constants = all_constants & a.is_constant(); - } + } let (q, r) = value.div_rem(¶ms.represented_field_modulus); if all_constants { @@ -2065,17 +1762,9 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { return Ok((new, (this, to_add))); } - let (q, r) = if value_is_none { - (None, None) - } else { - (Some(q), Some(r)) - }; + let (q, r) = if value_is_none { (None, None) } else { (Some(q), Some(r)) }; - let r_elem = Self::new_allocated( - cs, - some_biguint_to_fe(&r), - params - )?; + let r_elem = Self::new_allocated(cs, some_biguint_to_fe(&r), params)?; // estimate q bit width let q_max_value = this.get_max_value() * this.get_max_value() / ¶ms.represented_field_modulus; @@ -2084,23 +1773,13 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // let q_elem = Self::coarsely_allocate_for_unknown_width(cs, q, params)?; - Self::constraint_square_with_multiple_additions( - cs, - &this, - &to_add, - &q_elem, - &[r_elem.clone()], - )?; + Self::constraint_square_with_multiple_additions(cs, &this, &to_add, &q_elem, &[r_elem.clone()])?; return Ok((r_elem, (this, to_add))); } #[track_caller] - pub fn div>( - self, - cs: &mut CS, - den: Self, - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn div>(self, cs: &mut CS, den: Self) -> Result<(Self, (Self, Self)), SynthesisError> { let params = self.representation_params; // we do self/den = result mod p // so we constraint result * den = q * p + self @@ -2137,17 +1816,11 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { assert!(rem.is_zero(), "remainder = {}", rem.to_str_radix(16)); (Some(inv), Some(result), Some(q), Some(rem)) - }, - _ => { - (None, None, None, None) } + _ => (None, None, None, None), }; - let inv_wit = Self::new_allocated( - cs, - some_biguint_to_fe::(&result), - params - )?; + let inv_wit = Self::new_allocated(cs, some_biguint_to_fe::(&result), params)?; // estimate q bit width // result * den = q * p + self, so we say that self min value == 0 (as it goes into LHS with - sign) and worst case for q is @@ -2158,24 +1831,13 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // let q_elem = Self::coarsely_allocate_for_unknown_width(cs, q, params)?; - Self::constraint_fma_with_multiple_additions( - cs, - &den, - &inv_wit, - &[], - &q_elem, - &[this.clone()], - )?; + Self::constraint_fma_with_multiple_additions(cs, &den, &inv_wit, &[], &q_elem, &[this.clone()])?; Ok((inv_wit, (this, den))) } #[track_caller] - pub(crate) fn div_from_addition_chain>( - cs: &mut CS, - nums: Vec, - den: Self - ) -> Result<(Self, (Vec, Self)), SynthesisError> { + pub(crate) fn div_from_addition_chain>(cs: &mut CS, nums: Vec, den: Self) -> Result<(Self, (Vec, Self)), SynthesisError> { let params = den.representation_params; // we do (a1 + a2 + ... + an) /den = result mod p @@ -2213,11 +1875,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { all_constant = all_constant & n.is_constant(); reduced_nums.push(n); } - let num_value = if value_is_none { - None - } else { - Some(num_value) - }; + let num_value = if value_is_none { None } else { Some(num_value) }; let (result, q, _rem) = match (num_value, den.get_value(), inv.clone()) { (Some(num_value), Some(den), Some(inv)) => { @@ -2229,21 +1887,19 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { rhs += result.clone() * &den; let value = den * &result - num_value; - + let (q, rem) = value.div_rem(¶ms.represented_field_modulus); lhs += q.clone() * ¶ms.represented_field_modulus; assert_eq!(lhs, rhs); - + use crate::num_traits::Zero; assert!(rem.is_zero(), "remainder = {}", rem.to_str_radix(16)); (Some(result), Some(q), Some(rem)) - }, - _ => { - (None, None, None) } + _ => (None, None, None), }; if all_constant { @@ -2252,11 +1908,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { return Ok((new, (reduced_nums, den))); } - let result_wit = Self::new_allocated( - cs, - some_biguint_to_fe::(&result), - params - )?; + let result_wit = Self::new_allocated(cs, some_biguint_to_fe::(&result), params)?; // result*den = q*p + (a1 + a2 + ... + an), but since we have to subtract (a1 + a2 + ... + an) we do not use them // in this estimation @@ -2266,25 +1918,13 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // let q_elem = Self::coarsely_allocate_for_unknown_width(cs, q, params)?; - Self::constraint_fma_with_multiple_additions( - cs, - &den, - &result_wit, - &[], - &q_elem, - &reduced_nums, - )?; + Self::constraint_fma_with_multiple_additions(cs, &den, &result_wit, &[], &q_elem, &reduced_nums)?; Ok((result_wit, (reduced_nums, den))) } // returns first if true and second if false - pub fn select>( - cs: &mut CS, - flag: &Boolean, - first: Self, - second: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn select>(cs: &mut CS, flag: &Boolean, first: Self, second: Self) -> Result<(Self, (Self, Self)), SynthesisError> { match flag { Boolean::Constant(c) => { if *c { @@ -2292,7 +1932,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } else { return Ok((second.clone(), (first, second))); } - }, + } _ => {} } @@ -2305,9 +1945,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut new_binary_limbs = vec![]; - for (l, r) in first.binary_limbs.iter() - .zip(second.binary_limbs.iter()) - { + for (l, r) in first.binary_limbs.iter().zip(second.binary_limbs.iter()) { let mut minus_b = r.term.clone(); minus_b.negate(); let a_minus_b = l.term.add(cs, &minus_b)?; @@ -2316,10 +1954,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let new_max = std::cmp::max(l.max_value(), r.max_value()); - let new_limb = Limb::new( - n, - new_max - ); + let new_limb = Limb::new(n, new_max); new_binary_limbs.push(new_limb); } @@ -2344,18 +1979,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { binary_limbs: new_binary_limbs, base_field_limb: new_base_limb, value: new_value, - representation_params: first.representation_params + representation_params: first.representation_params, }; Ok((new, (first, second))) } // negates if true - pub fn conditional_negation>( - cs: &mut CS, - flag: &Boolean, - this: Self, - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn conditional_negation>(cs: &mut CS, flag: &Boolean, this: Self) -> Result<(Self, (Self, Self)), SynthesisError> { let (negated, this) = this.negated(cs)?; let (selected, (negated, this)) = Self::select(cs, flag, negated, this)?; @@ -2372,7 +2003,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { result_quotient: &Self, result_remainder_decomposition: &[Self], ) -> Result<(), SynthesisError> { - // we perform an exhaustive check here: + // we perform an exhaustive check here: // a * b + [addition_elements] < RNS modulus // result_quotient * p + [result_remainder_decomposition] < RNS modulus @@ -2404,7 +2035,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // = // 0 high(a1*b1) high(a0*b0) + low(b0*a1) low(a0*b0) // + - // .... + // .... // = // so we want to take 0th binary limb of mul_a and multiply it by 0th binary limb of b @@ -2441,7 +2072,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut pairs = vec![]; for i in 0..params.num_binary_limbs { for j in 0..params.num_binary_limbs { - if i + j == target { + if i + j == target { pairs.push((i, j)); } } @@ -2476,21 +2107,9 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let params = mul_a.representation_params; if params.propagate_carries_using_double_limbs() { - Self::propagate_carries_using_double_limb_approach( - cs, - (result_limbs, collapsed_max_values), - &addition_elements, - result_remainder_decomposition, - params - )?; + Self::propagate_carries_using_double_limb_approach(cs, (result_limbs, collapsed_max_values), &addition_elements, result_remainder_decomposition, params)?; } else { - Self::propagate_carries_using_single_limb_approach( - cs, - (result_limbs, collapsed_max_values), - &addition_elements, - result_remainder_decomposition, - params - )?; + Self::propagate_carries_using_single_limb_approach(cs, (result_limbs, collapsed_max_values), &addition_elements, result_remainder_decomposition, params)?; } // now much more trivial part - multiply base field basis @@ -2517,7 +2136,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match must_be_zero { Num::Constant(c) => { assert!(c.is_zero()); - }, + } Num::Variable(var) => { var.assert_equal_to_constant(cs, E::Fr::zero())?; } @@ -2568,7 +2187,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut factors = vec![]; for i in 0..params.num_binary_limbs { for j in 0..params.num_binary_limbs { - if i + j == target { + if i + j == target { if let Some(idx) = pairs.iter().position(|el| el == &(j, i)) { if i != j { factors[idx] += 1; @@ -2615,7 +2234,6 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { max_value += params.represented_field_modulus_negated_limbs_biguints[j].clone() << params.binary_limbs_params.limb_size_bits; expected_binary_max_values[target].push(max_value); - } else { let mut q_limb = result_quotient.binary_limbs[j].term.clone(); q_limb.scale(¶ms.represented_field_modulus_negated_limbs[i]); @@ -2632,8 +2250,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut collapsed_max_values = vec![]; - for max_values_components in expected_binary_max_values.into_iter() - { + for max_values_components in expected_binary_max_values.into_iter() { let mut max_value = BigUint::from(0u64); for c in max_values_components.into_iter() { max_value += c; @@ -2645,21 +2262,9 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let params = this.representation_params; if params.propagate_carries_using_double_limbs() { - Self::propagate_carries_using_double_limb_approach( - cs, - (result_limbs, collapsed_max_values), - addition_elements, - result_remainder_decomposition, - params - )?; + Self::propagate_carries_using_double_limb_approach(cs, (result_limbs, collapsed_max_values), addition_elements, result_remainder_decomposition, params)?; } else { - Self::propagate_carries_using_single_limb_approach( - cs, - (result_limbs, collapsed_max_values), - addition_elements, - result_remainder_decomposition, - params - )?; + Self::propagate_carries_using_single_limb_approach(cs, (result_limbs, collapsed_max_values), addition_elements, result_remainder_decomposition, params)?; } // now much more trivial part - multiply base field basis @@ -2686,7 +2291,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match must_be_zero { Num::Constant(c) => { assert!(c.is_zero()); - }, + } Num::Variable(var) => { var.assert_equal_to_constant(cs, E::Fr::zero())?; } @@ -2700,7 +2305,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { bases: (Vec>>, Vec), add: &[Self], sub: &[Self], - params: &RnsParameters + params: &RnsParameters, ) -> Result<(), SynthesisError> { // keep track of the max values after additions @@ -2714,18 +2319,18 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { for i in (0..target_limbs).step_by(2) { let mut max_value = BigUint::from(0u64); max_value += &collapsed_max_values[i]; - max_value += &collapsed_max_values[i+1] << params.binary_limbs_params.limb_size_bits; + max_value += &collapsed_max_values[i + 1] << params.binary_limbs_params.limb_size_bits; for a in add.iter() { max_value += a.binary_limbs[i].max_value(); - max_value += a.binary_limbs[i+1].max_value() << params.binary_limbs_params.limb_size_bits; + max_value += a.binary_limbs[i + 1].max_value() << params.binary_limbs_params.limb_size_bits; } let max_bits = max_value.bits() as usize; - assert!(max_bits >= 2*params.binary_limbs_params.limb_size_bits); + assert!(max_bits >= 2 * params.binary_limbs_params.limb_size_bits); assert!(max_bits <= E::Fr::CAPACITY as usize, "max width is higher than unique representation in double limb carry propagation"); - let carry_max_bits = max_bits - 2*params.binary_limbs_params.limb_size_bits; + let carry_max_bits = max_bits - 2 * params.binary_limbs_params.limb_size_bits; double_limb_max_bits.push(carry_max_bits); } @@ -2775,7 +2380,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { contributions.push(c.clone()); } - for c in result_limbs[i+1].iter() { + for c in result_limbs[i + 1].iter() { let mut tmp = c.clone(); tmp.scale(&shift_left_one_limb_constant); contributions.push(tmp); @@ -2785,8 +2390,8 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut tmp = result_remainder.binary_limbs[i].term.clone(); tmp.negate(); contributions.push(tmp); - - let mut tmp = result_remainder.binary_limbs[i+1].term.clone(); + + let mut tmp = result_remainder.binary_limbs[i + 1].term.clone(); tmp.scale(&shift_left_one_limb_constant); tmp.negate(); contributions.push(tmp); @@ -2796,7 +2401,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let tmp = addition_element.binary_limbs[i].term.clone(); contributions.push(tmp); - let mut tmp = addition_element.binary_limbs[i+1].term.clone(); + let mut tmp = addition_element.binary_limbs[i + 1].term.clone(); tmp.scale(&shift_left_one_limb_constant); contributions.push(tmp); } @@ -2811,7 +2416,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { r.scale(&shift_right_two_limb_constant); - if i+1 == last_idx && last_single_limb_max_bits.is_none() { + if i + 1 == last_idx && last_single_limb_max_bits.is_none() { // we don't need to propagate any further } else { chunk_of_previous_carry = Some(r.clone()); @@ -2863,14 +2468,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match params.range_check_info.strategy { RangeConstraintStrategy::MultiTable => { super::range_constraint_functions::adaptively_coarsely_constraint_multiple_with_multitable(cs, &double_limb_carries, &double_limb_max_bits)?; - }, + } RangeConstraintStrategy::SingleTableInvocation => { super::single_table_range_constraint::adaptively_constraint_multiple_with_single_table(cs, &double_limb_carries, &double_limb_max_bits)?; - }, + } RangeConstraintStrategy::CustomTwoBitGate => { super::range_constraint_functions::adaptively_coarsely_constraint_multiple_with_two_bit_decomposition(cs, &double_limb_carries, &double_limb_max_bits)?; - }, - _ => unimplemented!("other forms of range constraining are not implemented") + } + _ => unimplemented!("other forms of range constraining are not implemented"), } Ok(()) @@ -2881,7 +2486,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { bases: (Vec>>, Vec), add: &[Self], sub: &[Self], - params: &RnsParameters + params: &RnsParameters, ) -> Result<(), SynthesisError> { let num_limbs = params.num_binary_limbs; @@ -2949,7 +2554,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { r.scale(&shift_right_one_limb_constant); - if i+1 == num_limbs { + if i + 1 == num_limbs { // we don't need to propagate any further } else { chunk_of_previous_carry = Some(r.clone()); @@ -2967,14 +2572,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match params.range_check_info.strategy { RangeConstraintStrategy::MultiTable => { super::range_constraint_functions::adaptively_coarsely_constraint_multiple_with_multitable(cs, &carries, &limb_max_bits)?; - }, + } RangeConstraintStrategy::SingleTableInvocation => { super::single_table_range_constraint::adaptively_constraint_multiple_with_single_table(cs, &carries, &limb_max_bits)?; - }, + } RangeConstraintStrategy::CustomTwoBitGate => { super::range_constraint_functions::adaptively_coarsely_constraint_multiple_with_two_bit_decomposition(cs, &carries, &limb_max_bits)?; - }, - _ => unimplemented!("other forms of range constraining are not implemented") + } + _ => unimplemented!("other forms of range constraining are not implemented"), } Ok(()) @@ -3014,10 +2619,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { /// check that element is in a field and is strictly less /// than modulus - pub fn enforce_is_normalized>( - self, - cs: &mut CS, - ) -> Result { + pub fn enforce_is_normalized>(self, cs: &mut CS) -> Result { if self.is_constant() { return Ok(self); } @@ -3026,18 +2628,10 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let this = self.reduce_if_necessary(cs)?; - let modulus_limbs = split_into_fixed_number_of_limbs( - params.represented_field_modulus.clone(), - params.binary_limbs_params.limb_size_bits, - params.num_binary_limbs - ); + let modulus_limbs = split_into_fixed_number_of_limbs(params.represented_field_modulus.clone(), params.binary_limbs_params.limb_size_bits, params.num_binary_limbs); let borrow_witnesses = if let Some(v) = this.get_value() { - let value_limbs = split_into_fixed_number_of_limbs( - v, - params.binary_limbs_params.limb_size_bits, - params.num_binary_limbs - ); + let value_limbs = split_into_fixed_number_of_limbs(v, params.binary_limbs_params.limb_size_bits, params.num_binary_limbs); let mut wit = Vec::with_capacity(params.num_binary_limbs - 1); let mut previous = None; @@ -3071,10 +2665,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut borrow_bits = vec![]; for w in borrow_witnesses.into_iter() { - let b = Boolean::from(AllocatedBit::alloc( - cs, - w - )?); + let b = Boolean::from(AllocatedBit::alloc(cs, w)?); borrow_bits.push(b) } @@ -3082,10 +2673,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut results = Vec::with_capacity(params.num_binary_limbs); - for ((l, b), m) in this.binary_limbs.iter() - .zip(borrow_bits.into_iter()) - .zip(modulus_limbs_as_fe.iter()) - { + for ((l, b), m) in this.binary_limbs.iter().zip(borrow_bits.into_iter()).zip(modulus_limbs_as_fe.iter()) { let mut tmp = l.term.clone(); tmp.negate(); tmp.add_constant(m); @@ -3127,14 +2715,16 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { match params.range_check_info.strategy { RangeConstraintStrategy::MultiTable => { self::range_constraint_functions::coarsely_enforce_using_multitable(cs, &el, expected_width)?; - }, + } RangeConstraintStrategy::SingleTableInvocation => { self::single_table_range_constraint::enforce_using_single_column_table(cs, &el, expected_width)?; - }, + } RangeConstraintStrategy::CustomTwoBitGate => { let _ = create_range_constraint_chain(cs, &el, expected_width)?; } - _ => {unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled")} + _ => { + unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled") + } } } @@ -3142,22 +2732,16 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn enforce_equal>( - cs: &mut CS, - this: Self, - other: Self - ) -> Result<(), SynthesisError> { + pub fn enforce_equal>(cs: &mut CS, this: Self, other: Self) -> Result<(), SynthesisError> { match (this.is_constant(), other.is_constant()) { (true, true) => { let a = this.get_field_value().unwrap(); let b = other.get_field_value().unwrap(); assert!(a == b); - return Ok(()) - }, - _ => { - + return Ok(()); } + _ => {} }; let before = cs.get_current_step_number(); @@ -3182,15 +2766,11 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn special_case_enforce_not_equal>( - cs: &mut CS, - first: Self, - second: Self - ) -> Result<(Self, Self), SynthesisError> { + pub fn special_case_enforce_not_equal>(cs: &mut CS, first: Self, second: Self) -> Result<(Self, Self), SynthesisError> { match (first.get_field_value(), second.get_field_value()) { (Some(f), Some(s)) => { assert!(f != s, "values are actually equal"); - }, + } _ => {} } @@ -3201,12 +2781,8 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { assert!(second.is_within_2_in_modulus_len()); let swap_witness = match (first.get_value(), second.get_value()) { - (Some(first), Some(second)) => { - Some(second > first) - }, - _ => { - None - } + (Some(first), Some(second)) => Some(second > first), + _ => None, }; let swap = Boolean::from(AllocatedBit::alloc(cs, swap_witness)?); @@ -3230,11 +2806,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { Ok((first, second)) } - fn sub_noborrow>( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + fn sub_noborrow>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { let params = self.representation_params; // subtraction is a little more involved @@ -3275,22 +2847,20 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut shift = 0; - for (_idx, (((l, r), &limb_width), max_value)) in this.binary_limbs.iter() - .zip(other.binary_limbs.iter()) - .zip(params.binary_limbs_bit_widths.iter()) - .zip(params.binary_limbs_max_values.iter()) - .enumerate() + for (_idx, (((l, r), &limb_width), max_value)) in this + .binary_limbs + .iter() + .zip(other.binary_limbs.iter()) + .zip(params.binary_limbs_bit_widths.iter()) + .zip(params.binary_limbs_max_values.iter()) + .enumerate() { let borrow_shift = biguint_to_fe(BigUint::from(1u64) << limb_width); assert_eq!(&l.max_value, max_value); assert_eq!(&r.max_value, max_value); let borrow_bit_witness = match (l.term.get_value(), r.term.get_value()) { - (Some(l), Some(r)) => { - Some(l.into_repr() < r.into_repr()) - }, - _ => { - None - } + (Some(l), Some(r)) => Some(l.into_repr() < r.into_repr()), + _ => None, }; let new_borrow = Boolean::from(AllocatedBit::alloc(cs, borrow_bit_witness)?); @@ -3304,7 +2874,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { if let Some(borrow) = borrow.take() { sub_result.add_assign_boolean_with_coeff(&borrow, minus_one); } - + let sub_result = sub_result.into_num(cs)?; constraint_num_bits(cs, &sub_result, limb_width)?; @@ -3313,7 +2883,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let term = Term::from_num(sub_result); let limb = Limb { max_value: max_value.clone(), - term: term + term: term, }; new_binary_limbs.push(limb); @@ -3332,7 +2902,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { binary_limbs: new_binary_limbs, base_field_limb: Term::from_num(new_base_limb), value: new_value, - representation_params: params + representation_params: params, }; assert_eq!(new.get_field_value().unwrap(), biguint_to_fe(new.get_value().unwrap())); @@ -3387,35 +2957,26 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // } #[track_caller] - pub fn force_reduce_close_to_modulus>( - self, - cs: &mut CS - ) -> Result { + pub fn force_reduce_close_to_modulus>(self, cs: &mut CS) -> Result { if !self.is_within_2_in_modulus_len() { let reduced = self.strict_reduction_impl(cs)?; - return Ok(reduced) + return Ok(reduced); } Ok(self) } - + #[track_caller] - pub fn equals>( - cs: &mut CS, - this: Self, - other: Self - ) -> Result<(Boolean, (Self, Self)), SynthesisError> { + pub fn equals>(cs: &mut CS, this: Self, other: Self) -> Result<(Boolean, (Self, Self)), SynthesisError> { match (this.is_constant(), other.is_constant()) { (true, true) => { let a = this.get_field_value().unwrap(); let b = other.get_field_value().unwrap(); return Ok((Boolean::constant(a == b), (this, other))); - }, - _ => { - } + _ => {} }; let before = cs.get_current_step_number(); @@ -3431,21 +2992,15 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn equals_assuming_reduced>( - cs: &mut CS, - first: Self, - second: Self - ) -> Result { + pub fn equals_assuming_reduced>(cs: &mut CS, first: Self, second: Self) -> Result { match (first.is_constant(), second.is_constant()) { (true, true) => { let a = first.get_field_value().unwrap(); let b = second.get_field_value().unwrap(); return Ok(Boolean::constant(a == b)); - }, - _ => { - } + _ => {} }; let mut lc = LinearCombination::zero(); @@ -3485,11 +3040,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // } #[track_caller] - pub fn enforce_not_equal>( - cs: &mut CS, - this: Self, - other: Self - ) -> Result<(Self, Self), SynthesisError> { + pub fn enforce_not_equal>(cs: &mut CS, this: Self, other: Self) -> Result<(Self, Self), SynthesisError> { let this = this.force_reduce_close_to_modulus(cs)?; let other = other.force_reduce_close_to_modulus(cs)?; let equal = Self::equals_assuming_reduced(cs, this.clone(), other.clone())?; @@ -3506,7 +3057,7 @@ mod test { #[test] fn test_bn_254() { - use crate::bellman::pairing::bn256::{Fq, Bn256, Fr}; + use crate::bellman::pairing::bn256::{Bn256, Fq, Fr}; let params = RnsParameters::::new_for_field(68, 110, 4); @@ -3534,9 +3085,9 @@ mod test { #[test] fn test_bn_254_with_multitable() { - use crate::bellman::pairing::bn256::{Fq, Bn256, Fr}; + use crate::bellman::pairing::bn256::{Bn256, Fq, Fr}; - use rand::{XorShiftRng, SeedableRng, Rng}; + use rand::{Rng, SeedableRng, XorShiftRng}; let _rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); use crate::bellman::plonk::better_better_cs::cs::*; @@ -3551,31 +3102,23 @@ mod test { let strats = get_range_constraint_info(&cs); - let params = RnsParameters::::new_for_field_with_strategy( - 80, - 110, - 4, - strats[0], - true - ); + let params = RnsParameters::::new_for_field_with_strategy(80, 110, 4, strats[0], true); let init_function = move || { cs.clone() // let mut cs = TrivialAssembly::::new(); - + // let over = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; // let table = MultiTableApplication::::new_range_table_of_width_3(16, over).unwrap(); - + // cs.add_multitable(table).unwrap(); - + // cs }; (params, init_function) }; - - test_allocation_on_random_witnesses(¶ms, &init_function); test_add_on_random_witnesses(¶ms, &init_function); test_sub_on_random_witnesses(¶ms, &init_function); @@ -3592,15 +3135,18 @@ mod test { test_inv_mul_on_random_witnesses(¶ms, &init_function); } - #[test] fn test_bls_12_381() { - use crate::bellman::pairing::bls12_381::{Bls12, Fr, Fq}; + use crate::bellman::pairing::bls12_381::{Bls12, Fq, Fr}; let params = RnsParameters::::new_for_field(64, 110, 8); // let params = RnsParameters::::new_for_field(88, 120, 6); - println!("Max representable = {}, with {} bits", params.max_representable_value().to_str_radix(16), params.max_representable_value().bits()); + println!( + "Max representable = {}, with {} bits", + params.max_representable_value().to_str_radix(16), + params.max_representable_value().bits() + ); let init_function = move || { let cs = TrivialAssembly::::new(); @@ -3624,12 +3170,8 @@ mod test { test_inv_mul_on_random_witnesses(¶ms, &init_function); } - - fn test_mul_on_random_witnesses, I: Fn() -> TrivialAssembly::>( - params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_mul_on_random_witnesses, I: Fn() -> TrivialAssembly>(params: &RnsParameters, init: &I) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for i in 0..100 { @@ -3637,24 +3179,16 @@ mod test { let a_f: F = rng.gen(); let b_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); let a_base = biguint_to_fe::(fe_to_biguint(&a_f) % repr_to_biguint::(&E::Fr::char())); assert_eq!(a_base, a.base_field_limb.get_value().unwrap()); - let b = FieldElement::new_allocated( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); + let b = FieldElement::new_allocated(&mut cs, Some(b_f), ¶ms).unwrap(); let b_base = biguint_to_fe::(fe_to_biguint(&b_f) % repr_to_biguint::(&E::Fr::char())); assert_eq!(b_base, b.base_field_limb.get_value().unwrap()); - + let (result, (a, b)) = a.mul(&mut cs, b).unwrap(); assert!(cs.is_satisfied()); @@ -3680,27 +3214,20 @@ mod test { } } - fn test_allocation_on_random_witnesses, I: Fn() -> TrivialAssembly::>( + fn test_allocation_on_random_witnesses, I: Fn() -> TrivialAssembly>( params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + init: &I, + ) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..100 { let mut cs = init(); let a_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let a_const = FieldElement::new_constant( - a_f, - ¶ms - ); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); + + let a_const = FieldElement::new_constant(a_f, ¶ms); let a_base = biguint_to_fe::(fe_to_biguint(&a_f) % repr_to_biguint::(&E::Fr::char())); assert_eq!(a_base, a.base_field_limb.get_value().unwrap()); @@ -3713,33 +3240,22 @@ mod test { } } - fn test_equality_on_random_witnesses, I: Fn() -> TrivialAssembly::>( + fn test_equality_on_random_witnesses, I: Fn() -> TrivialAssembly>( params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + init: &I, + ) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..100 { let mut cs = init(); let a_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let a_const = FieldElement::new_constant( - a_f, - ¶ms - ); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); + + let a_const = FieldElement::new_constant(a_f, ¶ms); - let b = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let b = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); let _ = FieldElement::enforce_equal(&mut cs, a.clone(), b.clone()).unwrap(); let _ = FieldElement::enforce_equal(&mut cs, a.clone(), a_const.clone()).unwrap(); @@ -3748,11 +3264,11 @@ mod test { } } - fn test_non_equality_on_random_witnesses, I: Fn() -> TrivialAssembly::>( + fn test_non_equality_on_random_witnesses, I: Fn() -> TrivialAssembly>( params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + init: &I, + ) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..100 { @@ -3761,27 +3277,13 @@ mod test { let a_f: F = rng.gen(); let b_f: F = rng.gen(); - let _a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let _a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); - let _a_const = FieldElement::new_constant( - a_f, - ¶ms - ); + let _a_const = FieldElement::new_constant(a_f, ¶ms); - let _b = FieldElement::new_allocated( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); + let _b = FieldElement::new_allocated(&mut cs, Some(b_f), ¶ms).unwrap(); - let _b_const = FieldElement::new_constant( - b_f, - ¶ms - ); + let _b_const = FieldElement::new_constant(b_f, ¶ms); //TODO @@ -3793,22 +3295,18 @@ mod test { } } - fn test_negation_on_random_witnesses, I: Fn() -> TrivialAssembly::>( + fn test_negation_on_random_witnesses, I: Fn() -> TrivialAssembly>( params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + init: &I, + ) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..100 { let mut cs = init(); let a_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); let mut neg = a_f; neg.negate(); @@ -3830,11 +3328,8 @@ mod test { } } - fn test_square_on_random_witnesses, I: Fn() -> TrivialAssembly::>( - params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_square_on_random_witnesses, I: Fn() -> TrivialAssembly>(params: &RnsParameters, init: &I) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for i in 0..100 { @@ -3842,15 +3337,11 @@ mod test { let a_f: F = rng.gen(); let _b_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); let a_base = biguint_to_fe::(fe_to_biguint(&a_f) % repr_to_biguint::(&E::Fr::char())); assert_eq!(a_base, a.base_field_limb.get_value().unwrap()); - + // let (result, (a, _)) = a.square_with_addition_chain(&mut cs, vec![]).unwrap(); let (result, a) = a.square(&mut cs).unwrap(); @@ -3882,11 +3373,8 @@ mod test { } } - fn test_add_on_random_witnesses, I: Fn() -> TrivialAssembly::>( - params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_add_on_random_witnesses, I: Fn() -> TrivialAssembly>(params: &RnsParameters, init: &I) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for i in 0..100 { @@ -3894,24 +3382,16 @@ mod test { let a_f: F = rng.gen(); let b_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let b = FieldElement::new_allocated( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); + + let b = FieldElement::new_allocated(&mut cs, Some(b_f), ¶ms).unwrap(); let a_base = biguint_to_fe::(fe_to_biguint(&a_f) % repr_to_biguint::(&E::Fr::char())); let b_base = biguint_to_fe::(fe_to_biguint(&b_f) % repr_to_biguint::(&E::Fr::char())); assert_eq!(a_base, a.base_field_limb.get_value().unwrap()); assert_eq!(b_base, b.base_field_limb.get_value().unwrap()); - + let (result, (a, _b)) = a.add(&mut cs, b).unwrap(); assert!(cs.is_satisfied()); @@ -3941,12 +3421,11 @@ mod test { } } - - fn test_long_addition_chain_on_random_witnesses, I: Fn() -> TrivialAssembly::>( + fn test_long_addition_chain_on_random_witnesses, I: Fn() -> TrivialAssembly>( params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + init: &I, + ) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..10 { @@ -3954,11 +3433,7 @@ mod test { let a_f: F = rng.gen(); let _b_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); let mut t = a; @@ -3967,11 +3442,7 @@ mod test { t = tt; } - let another = FieldElement::new_allocated( - &mut cs, - t.get_field_value(), - ¶ms - ).unwrap(); + let another = FieldElement::new_allocated(&mut cs, t.get_field_value(), ¶ms).unwrap(); let _ = FieldElement::enforce_equal(&mut cs, another, t).unwrap(); @@ -3979,11 +3450,11 @@ mod test { } } - fn test_long_subtraction_chain_on_random_witnesses, I: Fn() -> TrivialAssembly::>( + fn test_long_subtraction_chain_on_random_witnesses, I: Fn() -> TrivialAssembly>( params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + init: &I, + ) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..10 { @@ -3991,11 +3462,7 @@ mod test { let a_f: F = rng.gen(); let _b_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); let mut t = a; @@ -4004,11 +3471,7 @@ mod test { t = tt; } - let another = FieldElement::new_allocated( - &mut cs, - t.get_field_value(), - ¶ms - ).unwrap(); + let another = FieldElement::new_allocated(&mut cs, t.get_field_value(), ¶ms).unwrap(); let _ = FieldElement::enforce_equal(&mut cs, another, t).unwrap(); @@ -4016,11 +3479,11 @@ mod test { } } - fn test_long_negation_chain_on_random_witnesses, I: Fn() -> TrivialAssembly::>( + fn test_long_negation_chain_on_random_witnesses, I: Fn() -> TrivialAssembly>( params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + init: &I, + ) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..10 { @@ -4028,11 +3491,7 @@ mod test { let a_f: F = rng.gen(); let _b_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); let mut t = a; @@ -4041,11 +3500,7 @@ mod test { t = tt; } - let another = FieldElement::new_allocated( - &mut cs, - t.get_field_value(), - ¶ms - ).unwrap(); + let another = FieldElement::new_allocated(&mut cs, t.get_field_value(), ¶ms).unwrap(); let _ = FieldElement::enforce_equal(&mut cs, another, t).unwrap(); @@ -4053,11 +3508,8 @@ mod test { } } - fn test_sub_on_random_witnesses, I: Fn() -> TrivialAssembly::>( - params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_sub_on_random_witnesses, I: Fn() -> TrivialAssembly>(params: &RnsParameters, init: &I) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for i in 0..100 { @@ -4065,24 +3517,16 @@ mod test { let a_f: F = rng.gen(); let b_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let b = FieldElement::new_allocated( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); + + let b = FieldElement::new_allocated(&mut cs, Some(b_f), ¶ms).unwrap(); let a_base = biguint_to_fe::(fe_to_biguint(&a_f) % repr_to_biguint::(&E::Fr::char())); let b_base = biguint_to_fe::(fe_to_biguint(&b_f) % repr_to_biguint::(&E::Fr::char())); assert_eq!(a_base, a.base_field_limb.get_value().unwrap()); assert_eq!(b_base, b.base_field_limb.get_value().unwrap()); - + let (result, (a, b)) = a.sub(&mut cs, b).unwrap(); assert!(cs.is_satisfied()); @@ -4115,11 +3559,8 @@ mod test { } } - fn test_select_on_random_witnesses, I: Fn() -> TrivialAssembly::>( - params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_select_on_random_witnesses, I: Fn() -> TrivialAssembly>(params: &RnsParameters, init: &I) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for i in 0..100 { @@ -4129,43 +3570,28 @@ mod test { use crate::plonk::circuit::boolean::AllocatedBit; - let bit = AllocatedBit::alloc( - &mut cs, - Some(flag) - ).unwrap(); + let bit = AllocatedBit::alloc(&mut cs, Some(flag)).unwrap(); let bit = Boolean::Not(bit); // let bit = Boolean::Is(bit); let a_f: F = rng.gen(); let b_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let b = FieldElement::new_allocated( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); + + let b = FieldElement::new_allocated(&mut cs, Some(b_f), ¶ms).unwrap(); let a_base = biguint_to_fe::(fe_to_biguint(&a_f) % repr_to_biguint::(&E::Fr::char())); let b_base = biguint_to_fe::(fe_to_biguint(&b_f) % repr_to_biguint::(&E::Fr::char())); assert_eq!(a_base, a.base_field_limb.get_value().unwrap()); assert_eq!(b_base, b.base_field_limb.get_value().unwrap()); - + let (result, (a, _)) = FieldElement::select(&mut cs, &bit, a, b).unwrap(); assert!(cs.is_satisfied()); - let m = if !flag { - a_f - } else { - b_f - }; + let m = if !flag { a_f } else { b_f }; let res = result.get_value().unwrap() % repr_to_biguint::(&F::char()); assert_eq!(res, fe_to_biguint(&m)); @@ -4182,11 +3608,11 @@ mod test { } } - fn test_conditional_negation_on_random_witnesses, I: Fn() -> TrivialAssembly::>( + fn test_conditional_negation_on_random_witnesses, I: Fn() -> TrivialAssembly>( params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + init: &I, + ) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for i in 0..100 { @@ -4196,20 +3622,13 @@ mod test { use crate::plonk::circuit::boolean::AllocatedBit; - let bit = AllocatedBit::alloc( - &mut cs, - Some(flag) - ).unwrap(); + let bit = AllocatedBit::alloc(&mut cs, Some(flag)).unwrap(); let bit = Boolean::Not(bit); // let bit = Boolean::Is(bit); let a_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); let a_base = biguint_to_fe::(fe_to_biguint(&a_f) % repr_to_biguint::(&E::Fr::char())); @@ -4228,11 +3647,7 @@ mod test { assert!(cs.is_satisfied()); - let m = if flag { - a_f - } else { - minus_a_f - }; + let m = if flag { a_f } else { minus_a_f }; let res = result.get_value().unwrap() % repr_to_biguint::(&F::char()); assert_eq!(res, fe_to_biguint(&m)); @@ -4248,11 +3663,11 @@ mod test { } } - fn test_inv_mul_on_random_witnesses, I: Fn() -> TrivialAssembly::>( + fn test_inv_mul_on_random_witnesses, I: Fn() -> TrivialAssembly>( params: &RnsParameters, - init: &I - ){ - use rand::{XorShiftRng, SeedableRng, Rng}; + init: &I, + ) { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..100 { @@ -4260,24 +3675,16 @@ mod test { let a_f: F = rng.gen(); let b_f: F = rng.gen(); - let a = FieldElement::new_allocated( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = FieldElement::new_allocated(&mut cs, Some(a_f), ¶ms).unwrap(); let a_base = biguint_to_fe::(fe_to_biguint(&a_f) % repr_to_biguint::(&E::Fr::char())); assert_eq!(a_base, a.base_field_limb.get_value().unwrap()); - let b = FieldElement::new_allocated( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); + let b = FieldElement::new_allocated(&mut cs, Some(b_f), ¶ms).unwrap(); let b_base = biguint_to_fe::(fe_to_biguint(&b_f) % repr_to_biguint::(&E::Fr::char())); assert_eq!(b_base, b.base_field_limb.get_value().unwrap()); - + let (result, _) = a.div(&mut cs, b).unwrap(); assert!(cs.is_satisfied()); @@ -4325,15 +3732,13 @@ mod test { let strategies = get_range_constraint_info(&cs); - let params = RnsParameters::::new_for_field_with_strategy( - 96, - 110, - 3, - strategies[0], - false - ); + let params = RnsParameters::::new_for_field_with_strategy(96, 110, 3, strategies[0], false); - println!("Max representable = {}, with {} bits", params.max_representable_value().to_str_radix(16), params.max_representable_value().bits()); + println!( + "Max representable = {}, with {} bits", + params.max_representable_value().to_str_radix(16), + params.max_representable_value().bits() + ); } #[test] @@ -4354,13 +3759,7 @@ mod test { let strategies = get_range_constraint_info(&cs); - let _params = RnsParameters::::new_for_field_with_strategy( - 68, - 110, - 4, - strategies[0], - false - ); + let _params = RnsParameters::::new_for_field_with_strategy(68, 110, 4, strategies[0], false); } //#[test] @@ -4383,5 +3782,5 @@ mod test { // let a_f: Fq = rng.gen(); // let b_f: Fq = rng.gen(); - // } -} \ No newline at end of file + // } +} diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint/mod.rs b/crates/franklin-crypto/src/plonk/circuit/bigint/mod.rs index ff84adc..7dbbb2d 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint/mod.rs @@ -1,46 +1,23 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - PlonkCsWidth4WithNextStepParams, - TrivialAssembly + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; -use crate::plonk::circuit::Assignment; use crate::plonk::circuit::utils::u64_to_fe; +use crate::plonk::circuit::Assignment; use super::allocated_num::*; pub mod bigint; pub mod field; -pub mod range_constraint_gate; pub mod range_constraint_functions; +pub mod range_constraint_gate; pub mod range_constraint_with_two_bit_gate; pub mod single_table_range_constraint; @@ -57,7 +34,7 @@ pub fn constraint_num_bits>(cs: &mut CS, el: Num::Constant(c) => { let bits = c.into_repr().num_bits() as usize; assert!(bits <= num_bits); - }, + } Num::Variable(el) => { if let Some(value) = el.get_value() { let bits = value.into_repr().num_bits() as usize; @@ -67,33 +44,36 @@ pub fn constraint_num_bits>(cs: &mut CS, el: match infos[0].strategy { RangeConstraintStrategy::MultiTable => { self::range_constraint_functions::coarsely_enforce_using_multitable(cs, &el, num_bits)?; - }, + } RangeConstraintStrategy::SingleTableInvocation => { self::single_table_range_constraint::enforce_using_single_column_table(cs, &el, num_bits)?; - }, + } RangeConstraintStrategy::CustomTwoBitGate => { unreachable!(); let _ = create_range_constraint_chain(cs, &el, num_bits)?; } - _ => {unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled")} + _ => { + unimplemented!("range constraint strategies other than multitable, single table or custom gate are not yet handled") + } } } } - + Ok(()) } // splits an element into slices of fixed bit widths in LE order #[track_caller] -pub fn split_into_slices( - el: &F, - slice_width: usize, - num_slices: usize -) -> Vec { +pub fn split_into_slices(el: &F, slice_width: usize, num_slices: usize) -> Vec { let mut repr = el.into_repr(); - assert!(repr.num_bits() as usize <= slice_width * num_slices, "limit is {} bits, got {}", slice_width * num_slices, repr.num_bits()); + assert!( + repr.num_bits() as usize <= slice_width * num_slices, + "limit is {} bits, got {}", + slice_width * num_slices, + repr.num_bits() + ); let mut slices = Vec::with_capacity(num_slices); - if slice_width < 64 { + if slice_width < 64 { let mask = (1u64 << slice_width) - 1u64; for _ in 0..num_slices { let slice = repr.as_ref()[0] & mask; @@ -106,8 +86,7 @@ pub fn split_into_slices( repr.shr(slice_width as u32); } - } - else { + } else { let it = repr.as_ref().iter().map(|x| u64_to_fe::(*x)).take(num_slices); slices.extend(it); }; @@ -116,11 +95,7 @@ pub fn split_into_slices( } #[track_caller] -pub fn split_some_into_slices( - el: Option, - slice_width: usize, - num_slices: usize -) -> Vec> { +pub fn split_some_into_slices(el: Option, slice_width: usize, num_slices: usize) -> Vec> { if let Some(v) = el.as_ref() { split_into_slices(v, slice_width, num_slices).into_iter().map(|el| Some(el)).collect() } else { @@ -128,11 +103,7 @@ pub fn split_some_into_slices( } } -fn split_into_accululating_slices( - el: &F, - slice_width: usize, - num_slices: usize -) -> Vec { +fn split_into_accululating_slices(el: &F, slice_width: usize, num_slices: usize) -> Vec { let bases = split_into_slices(el, slice_width, num_slices); let mut slices = Vec::with_capacity(num_slices); let mut accum = F::zero(); @@ -153,11 +124,7 @@ fn split_into_accululating_slices( slices } -fn split_into_bit_constraint_slices( - el: &F, - slice_width: usize, - num_slices: usize -) -> Vec { +fn split_into_bit_constraint_slices(el: &F, slice_width: usize, num_slices: usize) -> Vec { // gate accumulates values a bit differently: each time it shift previous slice by X bits // and adds a new chunk into lowest bits, and then constraints the difference let bases = split_into_slices(el, slice_width, num_slices); @@ -184,17 +151,19 @@ pub(crate) static RANGE_GATES_COUNTER: AtomicUsize = AtomicUsize::new(0); // This is a case for no lookup tables that constraints 8 bits per gate #[track_caller] -pub fn create_range_constraint_chain>( - cs: &mut CS, - to_constraint: &AllocatedNum, - num_bits: usize -) -> Result>, SynthesisError> { +pub fn create_range_constraint_chain>(cs: &mut CS, to_constraint: &AllocatedNum, num_bits: usize) -> Result>, SynthesisError> { assert!(num_bits > 0); assert!(num_bits & 1 == 0); assert_eq!(CS::Params::STATE_WIDTH, 4, "this only works for a state of width 4 for now"); if let Some(v) = to_constraint.get_value() { let t = self::bigint::fe_to_biguint(&v); - assert!(t.bits() as usize <= num_bits, "value is {} that is {} bits, while expected {} bits", t.to_str_radix(16), t.bits(), num_bits); + assert!( + t.bits() as usize <= num_bits, + "value is {} that is {} bits, while expected {} bits", + t.to_str_radix(16), + t.bits(), + num_bits + ); } let num_elements = num_bits / 2; let mut slices: Vec> = if let Some(v) = to_constraint.get_value() { @@ -209,15 +178,10 @@ pub fn create_range_constraint_chain>( assert_eq!(last_val, v); } } - + let mut result = vec![]; for v in slices.into_iter() { - let a = AllocatedNum::alloc( - cs, - || { - Ok(*v.get()?) - } - )?; + let a = AllocatedNum::alloc(cs, || Ok(*v.get()?))?; result.push(a); } @@ -254,11 +218,7 @@ pub fn create_range_constraint_chain>( for _ in 0..to_add { let new_value = previous_value.mul(&four); - let padding = cs.alloc( - || { - Ok(*new_value.get()?) - } - )?; + let padding = cs.alloc(|| Ok(*new_value.get()?))?; raw_variables.push(padding); @@ -275,12 +235,7 @@ pub fn create_range_constraint_chain>( for row in &mut rows { let mut row = row.to_vec(); row.reverse(); - cs.new_single_gate_for_trace_step( - &gate, - &[], - &row, - &[] - )?; + cs.new_single_gate_for_trace_step(&gate, &[], &row, &[])?; } let last = rows.remainder(); @@ -295,14 +250,9 @@ pub fn create_range_constraint_chain>( let (mut variables, coeffs) = CS::MainGate::format_term(MainGateTerm::new(), dummy)?; *variables.last_mut().unwrap() = last; - cs.new_single_gate_for_trace_step( - &CS::MainGate::default(), - &coeffs, - &variables, - &[] - )?; + cs.new_single_gate_for_trace_step(&CS::MainGate::default(), &coeffs, &variables, &[])?; - RANGE_GATES_COUNTER.fetch_add(num_gates+1, Ordering::SeqCst); + RANGE_GATES_COUNTER.fetch_add(num_gates + 1, Ordering::SeqCst); Ok(result) } @@ -312,7 +262,7 @@ pub enum RangeConstraintStrategy { MultiTable, SingleTableInvocation, CustomTwoBitGate, - NaiveSingleBit + NaiveSingleBit, } impl RangeConstraintStrategy { @@ -356,7 +306,7 @@ pub fn get_range_constraint_info>(cs: &CS) -> optimal_multiple: (width as usize) * multiples, multiples_per_gate: multiples, linear_terms_used: table_width_over_polys, - strategy: RangeConstraintStrategy::MultiTable + strategy: RangeConstraintStrategy::MultiTable, }; strategies.push(strategy); @@ -373,9 +323,9 @@ pub fn get_range_constraint_info>(cs: &CS) -> optimal_multiple: width as usize, multiples_per_gate: 1, linear_terms_used: table_width_over_polys, - strategy: RangeConstraintStrategy::SingleTableInvocation + strategy: RangeConstraintStrategy::SingleTableInvocation, }; - + strategies.push(strategy); } @@ -385,7 +335,7 @@ pub fn get_range_constraint_info>(cs: &CS) -> optimal_multiple: 8, multiples_per_gate: 4, linear_terms_used: 0, - strategy: RangeConstraintStrategy::CustomTwoBitGate + strategy: RangeConstraintStrategy::CustomTwoBitGate, }; strategies.push(strategy); @@ -396,7 +346,7 @@ pub fn get_range_constraint_info>(cs: &CS) -> optimal_multiple: 1, multiples_per_gate: 1, linear_terms_used: 0, - strategy: RangeConstraintStrategy::NaiveSingleBit + strategy: RangeConstraintStrategy::NaiveSingleBit, }; strategies.push(strategy); @@ -412,9 +362,9 @@ mod test { fn check_two_bit_gate() { use crate::bellman::pairing::bn256::{Bn256, Fr}; use crate::bellman::plonk::better_better_cs::cs::*; + use crate::plonk::circuit::allocated_num::*; use crate::plonk::circuit::bigint::*; use crate::plonk::circuit::linear_combination::*; - use crate::plonk::circuit::allocated_num::*; struct Tester; @@ -422,21 +372,11 @@ mod test { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Self::MainGate::default().into_internal(), - TwoBitDecompositionRangecheckCustomGate::default().into_internal(), - ] - ) + Ok(vec![Self::MainGate::default().into_internal(), TwoBitDecompositionRangecheckCustomGate::default().into_internal()]) } fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let variables: Vec<_> = (0..5).map(|_| AllocatedNum::alloc( - cs, - || { - Ok(Fr::one()) - } - ).unwrap()).collect(); - + let variables: Vec<_> = (0..5).map(|_| AllocatedNum::alloc(cs, || Ok(Fr::one())).unwrap()).collect(); + let mut lc = LinearCombination::::zero(); lc.add_assign_constant(Fr::one()); let mut current = Fr::one(); @@ -444,16 +384,11 @@ mod test { lc.add_assign_variable_with_coeff(v, current); current.double(); } - + let _result = lc.into_allocated_num(cs).unwrap(); - - let num = AllocatedNum::alloc( - cs, - || { - Ok(Fr::from_str("40000").unwrap()) - } - ).unwrap(); - + + let num = AllocatedNum::alloc(cs, || Ok(Fr::from_str("40000").unwrap())).unwrap(); + let _ = create_range_constraint_chain(cs, &num, 18)?; Ok(()) @@ -478,16 +413,10 @@ mod test { let setup = assembly.create_setup::(&worker).unwrap(); use crate::bellman::kate_commitment::*; - use crate::bellman::plonk::commitments::transcript::{*, keccak_transcript::RollingKeccakTranscript}; + use crate::bellman::plonk::commitments::transcript::{keccak_transcript::RollingKeccakTranscript, *}; - let crs_mons = - Crs::::crs_42(setup.gate_selectors_monomials[0].size(), &worker); + let crs_mons = Crs::::crs_42(setup.gate_selectors_monomials[0].size(), &worker); - let _proof = assembly.create_proof::<_, RollingKeccakTranscript>( - &worker, - &setup, - &crs_mons, - None - ).unwrap(); + let _proof = assembly.create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs_mons, None).unwrap(); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint/range_constraint_functions.rs b/crates/franklin-crypto/src/plonk/circuit/bigint/range_constraint_functions.rs index f4eab8a..6778f5b 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint/range_constraint_functions.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint/range_constraint_functions.rs @@ -1,52 +1,25 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - PlonkCsWidth4WithNextStepParams, - TrivialAssembly + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; -use crate::plonk::circuit::Assignment; -use super::*; use super::bigint::*; +use super::*; +use crate::plonk::circuit::Assignment; use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; -use crate::plonk::circuit::simple_term::{Term}; use crate::plonk::circuit::linear_combination::LinearCombination; +use crate::plonk::circuit::simple_term::Term; -// enforces that this value is either `num_bits` long or a little longer +// enforces that this value is either `num_bits` long or a little longer // up to a single range constraint width from the table -pub fn coarsely_enforce_using_multitable>( - cs: &mut CS, - to_constraint: &AllocatedNum, - num_bits: usize -) -> Result<(), SynthesisError> { +pub fn coarsely_enforce_using_multitable>(cs: &mut CS, to_constraint: &AllocatedNum, num_bits: usize) -> Result<(), SynthesisError> { let strategies = get_range_constraint_info(&*cs); assert_eq!(CS::Params::STATE_WIDTH, 4); assert!(strategies.len() > 0); @@ -59,11 +32,7 @@ pub fn coarsely_enforce_using_multitable>( assert_eq!(linear_terms_used, 3); if num_bits <= width_per_gate { - return coarsely_enforce_using_multitable_into_single_gate( - cs, - to_constraint, - num_bits - ); + return coarsely_enforce_using_multitable_into_single_gate(cs, to_constraint, num_bits); } // we do two things simultaneously: @@ -120,9 +89,7 @@ pub fn coarsely_enforce_using_multitable>( let mut term = MainGateTerm::::new(); for _ in 0..3 { let value = (&mut it).next().unwrap(); - let allocated = AllocatedNum::alloc(cs, || { - Ok(*value.get()?) - })?; + let allocated = AllocatedNum::alloc(cs, || Ok(*value.get()?))?; let scaled = value.mul(&Some(current_term_coeff)); next_step_value = next_step_value.add(&scaled); @@ -145,9 +112,7 @@ pub fn coarsely_enforce_using_multitable>( let is_last_gate = (full_gate_idx == num_full_gates - 1) && num_terms_in_partial_gate == 0; if is_last_gate == false { - let next_var = AllocatedNum::alloc(cs, || { - Ok(*next_step_value.get()?) - })?; + let next_var = AllocatedNum::alloc(cs, || Ok(*next_step_value.get()?))?; next_step_variable_from_previous_gate = Some(next_var); } else { next_step_variable_from_previous_gate = Some(to_constraint.clone()); @@ -155,12 +120,7 @@ pub fn coarsely_enforce_using_multitable>( cs.begin_gates_batch_for_step()?; - cs.new_gate_in_batch( - &CS::MainGate::default(), - &coeffs, - &variables, - &[] - )?; + cs.new_gate_in_batch(&CS::MainGate::default(), &coeffs, &variables, &[])?; cs.apply_multi_lookup_gate(&variables[0..linear_terms_used], Arc::clone(&table))?; @@ -171,9 +131,7 @@ pub fn coarsely_enforce_using_multitable>( if num_terms_in_partial_gate != 0 { let mut term = MainGateTerm::::new(); for value in it { - let allocated = AllocatedNum::alloc(cs, || { - Ok(*value.get()?) - })?; + let allocated = AllocatedNum::alloc(cs, || Ok(*value.get()?))?; let scaled = value.mul(&Some(current_term_coeff)); next_step_value = next_step_value.add(&scaled); @@ -195,17 +153,12 @@ pub fn coarsely_enforce_using_multitable>( let (variables, mut coeffs) = CS::MainGate::format_linear_term_with_duplicates(term, dummy_var)?; coeffs[next_step_coeff_idx] = minus_one; - + next_step_variable_from_previous_gate = Some(to_constraint.clone()); cs.begin_gates_batch_for_step()?; - cs.new_gate_in_batch( - &CS::MainGate::default(), - &coeffs, - &variables, - &[] - )?; + cs.new_gate_in_batch(&CS::MainGate::default(), &coeffs, &variables, &[])?; cs.apply_multi_lookup_gate(&variables[0..linear_terms_used], Arc::clone(&table))?; @@ -218,24 +171,14 @@ pub fn coarsely_enforce_using_multitable>( *vars.last_mut().unwrap() = final_val.get_variable(); - cs.new_single_gate_for_trace_step( - &CS::MainGate::default(), - &coeffs, - &vars, - &[] - )?; - + cs.new_single_gate_for_trace_step(&CS::MainGate::default(), &coeffs, &vars, &[])?; + Ok(()) } - -// enforces that this value is either `num_bits` long or a little longer +// enforces that this value is either `num_bits` long or a little longer // up to a single range constraint width from the table -pub fn coarsely_enforce_using_multitable_into_single_gate>( - cs: &mut CS, - to_constraint: &AllocatedNum, - num_bits: usize -) -> Result<(), SynthesisError> { +pub fn coarsely_enforce_using_multitable_into_single_gate>(cs: &mut CS, to_constraint: &AllocatedNum, num_bits: usize) -> Result<(), SynthesisError> { let strategies = get_range_constraint_info(&*cs); assert_eq!(CS::Params::STATE_WIDTH, 4); assert!(strategies.len() > 0); @@ -275,9 +218,7 @@ pub fn coarsely_enforce_using_multitable_into_single_gate::new(); for value in slices.into_iter() { - let allocated = AllocatedNum::alloc(cs, || { - Ok(*value.get()?) - })?; + let allocated = AllocatedNum::alloc(cs, || Ok(*value.get()?))?; // let scaled = value.mul(&Some(current_term_coeff)); @@ -296,27 +237,18 @@ pub fn coarsely_enforce_using_multitable_into_single_gate>( - cs: &mut CS, - terms: &[Term], - widths: &[usize] -) -> Result<(), SynthesisError> { +pub fn adaptively_coarsely_constraint_multiple_with_multitable>(cs: &mut CS, terms: &[Term], widths: &[usize]) -> Result<(), SynthesisError> { let strategies = get_range_constraint_info(&*cs); assert_eq!(CS::Params::STATE_WIDTH, 4); assert!(strategies.len() > 0); @@ -400,11 +332,7 @@ pub fn adaptively_coarsely_constraint_multiple_with_multitable>( - cs: &mut CS, - terms: &[Term], - widths: &[usize] -) -> Result<(), SynthesisError> { +pub fn adaptively_coarsely_constraint_multiple_with_two_bit_decomposition>(cs: &mut CS, terms: &[Term], widths: &[usize]) -> Result<(), SynthesisError> { let strategies = get_range_constraint_info(&*cs); assert_eq!(CS::Params::STATE_WIDTH, 4); assert!(strategies.len() > 0); @@ -422,7 +350,7 @@ pub fn adaptively_coarsely_constraint_multiple_with_two_bit_decomposition GateInternal for TwoBitDecompositionRangecheckCustomGate { &[] } - fn needs_opened_for_linearization(&self) ->&'static [PolynomialInConstraint] { + fn needs_opened_for_linearization(&self) -> &'static [PolynomialInConstraint] { &[] } @@ -83,7 +76,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { let b_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(1), row); let c_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(2), row); let d_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row); - let d_next_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row+1); + let d_next_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row + 1); let one = E::Fr::one(); let mut two = one; @@ -93,12 +86,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { let mut four = two; four.double(); - for (high, high_and_low) in [ - (d_value, c_value), - (c_value, b_value), - (b_value, a_value), - (a_value, d_next_value), - ].iter() { + for (high, high_and_low) in [(d_value, c_value), (c_value, b_value), (b_value, a_value), (a_value, d_next_value)].iter() { let mut shifted_high = *high; shifted_high.mul_assign(&four); @@ -106,7 +94,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { low.sub_assign(&shifted_high); let mut total = low; - + let mut tmp = low; tmp.sub_assign(&one); total.mul_assign(&tmp); @@ -128,14 +116,14 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { } fn contribute_into_quotient( - &self, + &self, domain_size: usize, poly_storage: &mut AssembledPolynomialStorage, - monomials_storage: & AssembledPolynomialStorageForMonomialForms, + monomials_storage: &AssembledPolynomialStorageForMonomialForms, challenges: &[E::Fr], omegas_bitreversed: &BitReversedOmegas, _omegas_inv_bitreversed: &OmegasInvBitreversed, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { assert!(domain_size.is_power_of_two()); assert_eq!(challenges.len(), >::num_quotient_terms(&self)); @@ -146,53 +134,27 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { assert!(poly_storage.is_bitreversed); let coset_factor = E::Fr::multiplicative_generator(); - + for &p in >::all_queried_polynomials(&self).into_iter() { - ensure_in_map_or_create(&worker, - p, - domain_size, - omegas_bitreversed, - lde_factor, - coset_factor, - monomials_storage, - poly_storage - )?; + ensure_in_map_or_create(&worker, p, domain_size, omegas_bitreversed, lde_factor, coset_factor, monomials_storage, poly_storage)?; } let ldes_storage = &*poly_storage; - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); let mut tmp = a_ref.clone(); // just allocate, we don't actually use it drop(a_ref); - let a_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ).as_ref(); + let a_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage).as_ref(); - let b_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), - ldes_storage - ).as_ref(); + let b_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), ldes_storage).as_ref(); - let c_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), - ldes_storage - ).as_ref(); + let c_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), ldes_storage).as_ref(); - let d_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), - ldes_storage - ).as_ref(); + let d_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), ldes_storage).as_ref(); - let d_next_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), - ldes_storage - ).as_ref(); + let d_next_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), ldes_storage).as_ref(); let one = E::Fr::one(); let mut two = one; @@ -207,50 +169,43 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { // a - 4b \in [0, 4) // d_next - 4a \in [0, 4) - tmp.map_indexed(&worker, - |i, el| { - let a_value = a_raw_ref[i]; - let b_value = b_raw_ref[i]; - let c_value = c_raw_ref[i]; - let d_value = d_raw_ref[i]; - let d_next_value = d_next_raw_ref[i]; + tmp.map_indexed(&worker, |i, el| { + let a_value = a_raw_ref[i]; + let b_value = b_raw_ref[i]; + let c_value = c_raw_ref[i]; + let d_value = d_raw_ref[i]; + let d_next_value = d_next_raw_ref[i]; - let mut result = E::Fr::zero(); + let mut result = E::Fr::zero(); - for (contribution_idx, (high, high_and_low)) in [ - (d_value, c_value), - (c_value, b_value), - (b_value, a_value), - (a_value, d_next_value), - ].iter().enumerate() { - let mut shifted_high = *high; - shifted_high.mul_assign(&four); + for (contribution_idx, (high, high_and_low)) in [(d_value, c_value), (c_value, b_value), (b_value, a_value), (a_value, d_next_value)].iter().enumerate() { + let mut shifted_high = *high; + shifted_high.mul_assign(&four); - let mut low = *high_and_low; - low.sub_assign(&shifted_high); + let mut low = *high_and_low; + low.sub_assign(&shifted_high); - let mut total = low; - - let mut tmp = low; - tmp.sub_assign(&one); - total.mul_assign(&tmp); + let mut total = low; - let mut tmp = low; - tmp.sub_assign(&two); - total.mul_assign(&tmp); + let mut tmp = low; + tmp.sub_assign(&one); + total.mul_assign(&tmp); - let mut tmp = low; - tmp.sub_assign(&three); - total.mul_assign(&tmp); + let mut tmp = low; + tmp.sub_assign(&two); + total.mul_assign(&tmp); - total.mul_assign(&challenges[contribution_idx]); + let mut tmp = low; + tmp.sub_assign(&three); + total.mul_assign(&tmp); - result.add_assign(&total); - } + total.mul_assign(&challenges[contribution_idx]); - *el = result; - }, - ); + result.add_assign(&total); + } + + *el = result; + }); // { // let mut t = tmp.clone(); @@ -262,25 +217,25 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { // dbg!(values.as_ref()[i]); // } // } - + // } Ok(tmp) } fn contribute_into_linearization( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, - _monomials_storage: & AssembledPolynomialStorageForMonomialForms, + _monomials_storage: &AssembledPolynomialStorageForMonomialForms, _challenges: &[E::Fr], - _worker: &Worker + _worker: &Worker, ) -> Result, SynthesisError> { unreachable!("this gate does not contribute into linearization"); } fn contribute_into_verification_equation( - &self, + &self, _domain_size: usize, _at: E::Fr, queried_values: &std::collections::HashMap, @@ -288,17 +243,22 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { ) -> Result { assert_eq!(challenges.len(), >::num_quotient_terms(&self)); - let a_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) + let a_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) .ok_or(SynthesisError::AssignmentMissing)?; - let b_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) + let b_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) .ok_or(SynthesisError::AssignmentMissing)?; - let c_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) + let c_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) .ok_or(SynthesisError::AssignmentMissing)?; - let d_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) + let d_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) .ok_or(SynthesisError::AssignmentMissing)?; - let d_next_value = *queried_values.get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) + let d_next_value = *queried_values + .get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) .ok_or(SynthesisError::AssignmentMissing)?; - + let mut result = E::Fr::zero(); let one = E::Fr::one(); @@ -309,12 +269,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { let mut four = two; four.double(); - for (contribution_idx, (high, high_and_low)) in [ - (d_value, c_value), - (c_value, b_value), - (b_value, a_value), - (a_value, d_next_value), - ].iter().enumerate() { + for (contribution_idx, (high, high_and_low)) in [(d_value, c_value), (c_value, b_value), (b_value, a_value), (a_value, d_next_value)].iter().enumerate() { let mut shifted_high = *high; shifted_high.mul_assign(&four); @@ -322,7 +277,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { low.sub_assign(&shifted_high); let mut total = low; - + let mut tmp = low; tmp.sub_assign(&one); total.mul_assign(&tmp); @@ -348,7 +303,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { } fn contribute_into_linearization_commitment( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint/range_constraint_with_two_bit_gate.rs b/crates/franklin-crypto/src/plonk/circuit/bigint/range_constraint_with_two_bit_gate.rs index e69de29..8b13789 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint/range_constraint_with_two_bit_gate.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint/range_constraint_with_two_bit_gate.rs @@ -0,0 +1 @@ + diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint/single_table_range_constraint.rs b/crates/franklin-crypto/src/plonk/circuit/bigint/single_table_range_constraint.rs index 4ff1ce3..5e28c02 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint/single_table_range_constraint.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint/single_table_range_constraint.rs @@ -1,44 +1,21 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - PlonkCsWidth4WithNextStepParams, - TrivialAssembly + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; -use crate::plonk::circuit::Assignment; -use super::*; use super::bigint::*; +use super::*; +use crate::plonk::circuit::Assignment; use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; -use crate::plonk::circuit::simple_term::{Term}; use crate::plonk::circuit::linear_combination::LinearCombination; +use crate::plonk::circuit::simple_term::Term; use std::sync::Arc; @@ -48,7 +25,6 @@ pub static NUM_RANGE_CHECK_INVOCATIONS: AtomicUsize = AtomicUsize::new(0); pub static NUM_SHORT_RANGE_CHECK_INVOCATIONS: AtomicUsize = AtomicUsize::new(0); pub static NUM_GATES_SPENT_ON_RANGE_CHECKS: AtomicUsize = AtomicUsize::new(0); - pub fn reset_stats() { NUM_RANGE_CHECK_INVOCATIONS.store(0, Ordering::Relaxed); NUM_SHORT_RANGE_CHECK_INVOCATIONS.store(0, Ordering::Relaxed); @@ -72,17 +48,19 @@ pub fn print_stats() { let short_checks = NUM_SHORT_RANGE_CHECK_INVOCATIONS.load(Ordering::Relaxed); let total_gates = NUM_GATES_SPENT_ON_RANGE_CHECKS.load(Ordering::Relaxed); - println!("Has made in total of {} range checks, with {} being short (singe gate) and {} gates in total", total_checks, short_checks, total_gates); + println!( + "Has made in total of {} range checks, with {} being short (singe gate) and {} gates in total", + total_checks, short_checks, total_gates + ); } - -// enforces that this value is either `num_bits` long or a little longer +// enforces that this value is either `num_bits` long or a little longer // up to a single range constraint width from the table pub fn enforce_using_single_column_table_for_shifted_variable>( - cs: &mut CS, - to_constraint: &AllocatedNum, + cs: &mut CS, + to_constraint: &AllocatedNum, shift: E::Fr, - num_bits: usize + num_bits: usize, ) -> Result>, SynthesisError> { // we ensure that var * shift <= N bits let strategies = get_range_constraint_info(&*cs); @@ -98,14 +76,9 @@ pub fn enforce_using_single_column_table_for_shifted_variable>( - cs: &mut CS, - to_constraint: &AllocatedNum, + cs: &mut CS, + to_constraint: &AllocatedNum, shift: E::Fr, - num_bits: usize + num_bits: usize, ) -> Result>, SynthesisError> { // we ensure that var * shift <= N bits let strategies = get_range_constraint_info(&*cs); @@ -227,12 +190,7 @@ pub fn enforce_using_single_column_table_for_shifted_variable_optimized::new(); let value = it.next().unwrap(); - let chunk_allocated = AllocatedNum::alloc(cs, || { - Ok(*value.get()?) - })?; + let chunk_allocated = AllocatedNum::alloc(cs, || Ok(*value.get()?))?; chunks.push(Num::Variable(chunk_allocated)); last_allocated_var = Some(chunk_allocated.clone()); let scaled = value.mul(&Some(current_term_coeff)); next_step_value = next_step_value.add(&scaled); - let next_step_allocated = AllocatedNum::alloc(cs, || { - Ok(*next_step_value.get()?) - })?; + let next_step_allocated = AllocatedNum::alloc(cs, || Ok(*next_step_value.get()?))?; // a * 2^k term.add_assign(ArithmeticTerm::from_variable_and_coeff(chunk_allocated.get_variable(), current_term_coeff)); @@ -334,12 +288,10 @@ pub fn enforce_using_single_column_table_for_shifted_variable_optimized>( - cs: &mut CS, - to_constraint: &AllocatedNum, + cs: &mut CS, + to_constraint: &AllocatedNum, shift: E::Fr, - num_bits: usize + num_bits: usize, ) -> Result>, SynthesisError> { // we ensure that var * shift <= N bits let strategies = get_range_constraint_info(&*cs); @@ -470,16 +412,12 @@ pub fn enforce_using_single_column_table_for_shifted_variable_optimized_for_mult let mut term = MainGateTerm::::new(); let value = it.next().unwrap(); - let chunk_allocated = AllocatedNum::alloc(cs, || { - Ok(*value.get()?) - })?; + let chunk_allocated = AllocatedNum::alloc(cs, || Ok(*value.get()?))?; chunks.push(Num::Variable(chunk_allocated)); let scaled = value.mul(&Some(current_term_coeff)); next_step_value = next_step_value.add(&scaled); - let next_step_allocated = AllocatedNum::alloc(cs, || { - Ok(*next_step_value.get()?) - })?; + let next_step_allocated = AllocatedNum::alloc(cs, || Ok(*next_step_value.get()?))?; // a * 2^k term.add_assign(ArithmeticTerm::from_variable_and_coeff(chunk_allocated.get_variable(), current_term_coeff)); @@ -510,12 +448,7 @@ pub fn enforce_using_single_column_table_for_shifted_variable_optimized_for_mult cs.begin_gates_batch_for_step()?; - cs.new_gate_in_batch( - &CS::MainGate::default(), - &coeffs, - &variables, - &[] - )?; + cs.new_gate_in_batch(&CS::MainGate::default(), &coeffs, &variables, &[])?; cs.apply_single_lookup_gate(&variables[0..linear_terms_used], Arc::clone(&table))?; @@ -523,47 +456,28 @@ pub fn enforce_using_single_column_table_for_shifted_variable_optimized_for_mult } increment_total_gates_count(num_gates_for_coarse_constraint + (remainder_bits != 0) as usize); - + Ok(chunks) } -// enforces that this value is either `num_bits` long or a little longer +// enforces that this value is either `num_bits` long or a little longer // up to a single range constraint width from the table -pub fn enforce_using_single_column_table>( - cs: &mut CS, - to_constraint: &AllocatedNum, - num_bits: usize -) -> Result>, SynthesisError> { - enforce_using_single_column_table_for_shifted_variable( - cs, - to_constraint, - E::Fr::one(), - num_bits - ) +pub fn enforce_using_single_column_table>(cs: &mut CS, to_constraint: &AllocatedNum, num_bits: usize) -> Result>, SynthesisError> { + enforce_using_single_column_table_for_shifted_variable(cs, to_constraint, E::Fr::one(), num_bits) } -// enforces that this value is either `num_bits` long or a little longer +// enforces that this value is either `num_bits` long or a little longer // up to a single range constraint width from the table -pub fn enforce_using_single_column_table_optimized>( - cs: &mut CS, - to_constraint: &AllocatedNum, - num_bits: usize -) -> Result>, SynthesisError> { - enforce_using_single_column_table_for_shifted_variable_optimized( - cs, - to_constraint, - E::Fr::one(), - num_bits - ) +pub fn enforce_using_single_column_table_optimized>(cs: &mut CS, to_constraint: &AllocatedNum, num_bits: usize) -> Result>, SynthesisError> { + enforce_using_single_column_table_for_shifted_variable_optimized(cs, to_constraint, E::Fr::one(), num_bits) } - // enforces that this value * shift is exactly `num_bits` long fn enforce_shorter_range_into_single_gate_for_shifted_variable>( - cs: &mut CS, - to_constraint: &AllocatedNum, + cs: &mut CS, + to_constraint: &AllocatedNum, shift: E::Fr, - num_bits: usize + num_bits: usize, ) -> Result, SynthesisError> { // var * shift <= num bits increment_invocation_count(); @@ -586,7 +500,7 @@ fn enforce_shorter_range_into_single_gate_for_shifted_variable::new(); let value = to_constraint.get_value().mul(&Some(shift)); - let allocated = AllocatedNum::alloc(cs, || { - Ok(*value.get()?) - })?; + let allocated = AllocatedNum::alloc(cs, || Ok(*value.get()?))?; term.add_assign(ArithmeticTerm::from_variable(allocated.get_variable())); @@ -612,45 +524,29 @@ fn enforce_shorter_range_into_single_gate_for_shifted_variable>( - cs: &mut CS, - to_constraint: &AllocatedNum, - num_bits: usize -) -> Result, SynthesisError> { - enforce_shorter_range_into_single_gate_for_shifted_variable( - cs, - to_constraint, - E::Fr::one(), - num_bits - ) +fn enforce_shorter_range_into_single_gate>(cs: &mut CS, to_constraint: &AllocatedNum, num_bits: usize) -> Result, SynthesisError> { + enforce_shorter_range_into_single_gate_for_shifted_variable(cs, to_constraint, E::Fr::one(), num_bits) } - -// enforces that this value * shift is either `num_bits` long or a little longer +// enforces that this value * shift is either `num_bits` long or a little longer // up to a single range constraint width from the table fn enforce_range_into_single_gate_for_shifted_variable>( - cs: &mut CS, - to_constraint: &AllocatedNum, + cs: &mut CS, + to_constraint: &AllocatedNum, shift: E::Fr, - num_bits: usize + num_bits: usize, ) -> Result, SynthesisError> { let strategies = get_range_constraint_info(&*cs); assert_eq!(CS::Params::STATE_WIDTH, 4); @@ -663,21 +559,12 @@ fn enforce_range_into_single_gate_for_shifted_variable>( - cs: &mut CS, - to_constraint: &AllocatedNum, - num_bits: usize -) -> Result<(), SynthesisError> { +fn enforce_range_into_single_gate>(cs: &mut CS, to_constraint: &AllocatedNum, num_bits: usize) -> Result<(), SynthesisError> { increment_invocation_count(); increment_short_checks_count(); increment_total_gates_count(1); @@ -709,26 +596,16 @@ fn enforce_range_into_single_gate>( cs.begin_gates_batch_for_step()?; - cs.new_gate_in_batch( - &CS::MainGate::default(), - &coeffs, - &variables, - &[] - )?; + cs.new_gate_in_batch(&CS::MainGate::default(), &coeffs, &variables, &[])?; cs.apply_single_lookup_gate(&variables[0..linear_terms_used], Arc::clone(&table))?; cs.end_gates_batch_for_step()?; - + Ok(()) } - -pub fn adaptively_constraint_multiple_with_single_table>( - cs: &mut CS, - terms: &[Term], - widths: &[usize] -) -> Result<(), SynthesisError> { +pub fn adaptively_constraint_multiple_with_single_table>(cs: &mut CS, terms: &[Term], widths: &[usize]) -> Result<(), SynthesisError> { let strategies = get_range_constraint_info(&*cs); assert_eq!(CS::Params::STATE_WIDTH, 4); assert!(strategies.len() > 0); @@ -765,4 +642,4 @@ pub fn adaptively_constraint_multiple_with_single_table { - a: Variable, b: Variable, c: Variable, d: Variable, - a_mul_b_coef: E::Fr, a_mul_c_coef: E::Fr, - a_linear_coef: E::Fr, b_linear_coef: E::Fr, c_linear_coef: E::Fr, d_linear_coef: E::Fr, - cnst: E::Fr, free_vars_start_idx: usize, free_vars_end_idx: usize, is_final: bool + a: Variable, + b: Variable, + c: Variable, + d: Variable, + a_mul_b_coef: E::Fr, + a_mul_c_coef: E::Fr, + a_linear_coef: E::Fr, + b_linear_coef: E::Fr, + c_linear_coef: E::Fr, + d_linear_coef: E::Fr, + cnst: E::Fr, + free_vars_start_idx: usize, + free_vars_end_idx: usize, + is_final: bool, } impl GateConstructorHelper { pub fn new>(cs: &mut CS) -> Self { let dummy = AllocatedNum::zero(cs).get_variable(); GateConstructorHelper:: { - a: dummy, b: dummy, c: dummy, d: dummy, a_mul_b_coef: E::Fr::zero(), a_mul_c_coef: E::Fr::zero(), - a_linear_coef: E::Fr::zero(), b_linear_coef: E::Fr::zero(), c_linear_coef: E::Fr::zero(), - d_linear_coef: E::Fr::zero(), cnst: E::Fr::zero(), - free_vars_start_idx: 0, free_vars_end_idx: REQUIRED_STATE_WIDTH, is_final: false + a: dummy, + b: dummy, + c: dummy, + d: dummy, + a_mul_b_coef: E::Fr::zero(), + a_mul_c_coef: E::Fr::zero(), + a_linear_coef: E::Fr::zero(), + b_linear_coef: E::Fr::zero(), + c_linear_coef: E::Fr::zero(), + d_linear_coef: E::Fr::zero(), + cnst: E::Fr::zero(), + free_vars_start_idx: 0, + free_vars_end_idx: REQUIRED_STATE_WIDTH, + is_final: false, } } pub fn new_for_mul>(cs: &mut CS, vars: OrderedVariablePair, coef: E::Fr) -> Self { let dummy = AllocatedNum::zero(cs).get_variable(); GateConstructorHelper:: { - a: vars.first, b: vars.second, c: dummy, d: dummy, a_mul_b_coef: coef, a_mul_c_coef: E::Fr::zero(), - a_linear_coef: E::Fr::zero(), b_linear_coef: E::Fr::zero(), c_linear_coef: E::Fr::zero(), - d_linear_coef: E::Fr::zero(), cnst: E::Fr::zero(), - free_vars_start_idx: 2, free_vars_end_idx: REQUIRED_STATE_WIDTH, is_final: false + a: vars.first, + b: vars.second, + c: dummy, + d: dummy, + a_mul_b_coef: coef, + a_mul_c_coef: E::Fr::zero(), + a_linear_coef: E::Fr::zero(), + b_linear_coef: E::Fr::zero(), + c_linear_coef: E::Fr::zero(), + d_linear_coef: E::Fr::zero(), + cnst: E::Fr::zero(), + free_vars_start_idx: 2, + free_vars_end_idx: REQUIRED_STATE_WIDTH, + is_final: false, } } - pub fn new_for_pair_of_muls>( - cs: &mut CS, a: Variable, b: Variable, c: Variable, a_mul_b_coef: E::Fr, a_mul_c_coef: E::Fr - ) -> Self { + pub fn new_for_pair_of_muls>(cs: &mut CS, a: Variable, b: Variable, c: Variable, a_mul_b_coef: E::Fr, a_mul_c_coef: E::Fr) -> Self { let dummy = AllocatedNum::zero(cs).get_variable(); let zero = E::Fr::zero(); GateConstructorHelper:: { - a, b, c, d: dummy, a_mul_b_coef, a_mul_c_coef, - a_linear_coef: zero, b_linear_coef: zero, c_linear_coef: zero, d_linear_coef: zero, - cnst: zero, free_vars_start_idx: 3, free_vars_end_idx: REQUIRED_STATE_WIDTH, is_final: false + a, + b, + c, + d: dummy, + a_mul_b_coef, + a_mul_c_coef, + a_linear_coef: zero, + b_linear_coef: zero, + c_linear_coef: zero, + d_linear_coef: zero, + cnst: zero, + free_vars_start_idx: 3, + free_vars_end_idx: REQUIRED_STATE_WIDTH, + is_final: false, } } @@ -67,23 +103,24 @@ impl GateConstructorHelper { pub fn add_linear_coefficients_for_bound_variables(&mut self, var_map: &mut IndexMap) { let iter = std::array::IntoIter::new([ - (self.a, &mut self.a_linear_coef), (self.b, &mut self.b_linear_coef), - (self.c, &mut self.c_linear_coef), (self.d, &mut self.d_linear_coef) - ]).take(self.free_vars_start_idx); + (self.a, &mut self.a_linear_coef), + (self.b, &mut self.b_linear_coef), + (self.c, &mut self.c_linear_coef), + (self.d, &mut self.d_linear_coef), + ]) + .take(self.free_vars_start_idx); for (var, pos) in iter { let fr = var_map.remove(&var).unwrap_or(E::Fr::zero()); *pos = fr; } } - pub fn add_linear_coefficients_for_free_variables( - &mut self, var_map: &mut IndexMap, free_vars_set: &mut IndexSet - ) { + pub fn add_linear_coefficients_for_free_variables(&mut self, var_map: &mut IndexMap, free_vars_set: &mut IndexSet) { // Rust is not an expressive language at all, that's why we unroll the loop manually // How much better it would look in C++.. Mmm... let mut vars = [self.a, self.b, self.c, self.d]; let mut coefs = [self.a_linear_coef, self.b_linear_coef, self.c_linear_coef, self.d_linear_coef]; - + let num_elems = self.free_vars_end_idx - self.free_vars_start_idx; for (var_ptr, coef_ptr) in vars.iter_mut().zip(coefs.iter_mut()).skip(self.free_vars_start_idx).take(num_elems) { if free_vars_set.is_empty() { @@ -114,7 +151,7 @@ impl GateConstructorHelper { let range_of_multiplicative_terms = CS::MainGate::range_of_multiplicative_term(); let range_of_linear_terms = CS::MainGate::range_of_linear_terms(); let index_for_constant_term = CS::MainGate::index_for_constant_term(); - let range_of_next_step_linear_terms = CS::MainGate::range_of_next_step_linear_terms(); + let range_of_next_step_linear_terms = CS::MainGate::range_of_next_step_linear_terms(); let dummy = AllocatedNum::zero(cs).get_variable(); let gate_term = MainGateTerm::new(); @@ -122,12 +159,12 @@ impl GateConstructorHelper { let vars = [self.a, self.b, self.c, self.d]; for (pos, fr) in range_of_multiplicative_terms.zip(&[self.a_mul_b_coef, self.a_mul_c_coef]) { - coefs[pos] = *fr; + coefs[pos] = *fr; } let linear_coefs = [self.a_linear_coef, self.b_linear_coef, self.c_linear_coef, self.d_linear_coef]; for (pos, fr) in range_of_linear_terms.zip(&linear_coefs[..]) { - coefs[pos] = *fr; + coefs[pos] = *fr; } coefs[index_for_constant_term] = self.cnst; @@ -140,18 +177,21 @@ impl GateConstructorHelper { let mg = CS::MainGate::default(); cs.new_single_gate_for_trace_step(&mg, &coefs, &vars, &[]) } - + pub fn evaluate_next_trace_step_value>(&self, cs: &mut CS) -> Result { let a_val = cs.get_value(self.a)?; let b_val = cs.get_value(self.b)?; let c_val = cs.get_value(self.c)?; let d_val = cs.get_value(self.d)?; - + let mut result = self.cnst; let products = [ - &[a_val, b_val, self.a_mul_b_coef][..], &[a_val, c_val, self.a_mul_c_coef][..], - &[a_val, self.a_linear_coef][..], &[b_val, self.b_linear_coef][..], - &[c_val, self.c_linear_coef][..], &[d_val, self.d_linear_coef][..] + &[a_val, b_val, self.a_mul_b_coef][..], + &[a_val, c_val, self.a_mul_c_coef][..], + &[a_val, self.a_linear_coef][..], + &[b_val, self.b_linear_coef][..], + &[c_val, self.c_linear_coef][..], + &[d_val, self.d_linear_coef][..], ]; for chunk in std::array::IntoIter::new(products) { let mut tmp = chunk[0].clone(); @@ -165,11 +205,10 @@ impl GateConstructorHelper { } } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] struct OrderedVariablePair { first: Variable, - second: Variable + second: Variable, } impl OrderedVariablePair { @@ -193,7 +232,6 @@ impl OrderedVariablePair { } } - // module containing amplified version of linear combination that supports both linear and multiplicative terms pub struct AmplifiedLinearCombination { value: Option, @@ -220,7 +258,7 @@ impl From> for AmplifiedLinearCombination { value: num.value, linear_terms: IndexMap::from([(num.variable, E::Fr::one())]), quadratic_terms: IndexMap::new(), - constant: E::Fr::zero() + constant: E::Fr::zero(), } } } @@ -228,17 +266,13 @@ impl From> for AmplifiedLinearCombination { impl From> for AmplifiedLinearCombination { fn from(num: Num) -> AmplifiedLinearCombination { match num { - Num::Variable(allocated) => { - Self::from(allocated) + Num::Variable(allocated) => Self::from(allocated), + Num::Constant(constant) => Self { + value: Some(constant), + linear_terms: IndexMap::new(), + quadratic_terms: IndexMap::new(), + constant: constant, }, - Num::Constant(constant) => { - Self { - value: Some(constant), - linear_terms: IndexMap::new(), - quadratic_terms: IndexMap::new(), - constant: constant - } - } } } } @@ -303,12 +337,12 @@ impl AmplifiedLinearCombination { match number { Num::Variable(ref allocated_number) => { self.add_assign_variable_with_coeff(allocated_number, coeff); - }, + } Num::Constant(constant) => { let mut res = coeff; res.mul_assign(&constant); self.add_assign_constant(res); - } + } } } @@ -325,16 +359,15 @@ impl AmplifiedLinearCombination { curval.add_assign(&tmp); Some(curval) - }, - _ => None + } + _ => None, }; self.value = newval; self.linear_terms.entry(variable.get_variable()).and_modify(|fr| fr.add_assign(&coeff)).or_insert(coeff); } - pub fn add_assign_term(&mut self, term: &Term) - { + pub fn add_assign_term(&mut self, term: &Term) { if term.is_constant() { self.add_assign_constant(term.get_constant_value()); return; @@ -345,29 +378,26 @@ impl AmplifiedLinearCombination { self.add_assign_number_with_coeff(&term.num, term.coeff); } - pub fn sub_assign_term(&mut self, term: &Term) - { + pub fn sub_assign_term(&mut self, term: &Term) { let mut negated_term = term.clone(); negated_term.negate(); self.add_assign_term(&negated_term); } - pub fn add_assign_term_with_coeff(&mut self, term: &Term, coeff: E::Fr) - { + pub fn add_assign_term_with_coeff(&mut self, term: &Term, coeff: E::Fr) { let mut scaled_term = term.clone(); scaled_term.scale(&coeff); self.add_assign_term(&scaled_term) } - pub fn sub_assign_term_with_coeff(&mut self, term: &Term, coeff: E::Fr) - { + pub fn sub_assign_term_with_coeff(&mut self, term: &Term, coeff: E::Fr) { let mut scaled_term = term.clone(); scaled_term.scale(&coeff); scaled_term.negate(); self.add_assign_term(&scaled_term) } - - pub fn add_assign_constant(&mut self, coeff: E::Fr){ + + pub fn add_assign_constant(&mut self, coeff: E::Fr) { if coeff.is_zero() { return; } @@ -377,10 +407,8 @@ impl AmplifiedLinearCombination { curval.add_assign(&coeff); Some(curval) - }, - None => { - None } + None => None, }; self.value = newval; @@ -408,7 +436,7 @@ impl AmplifiedLinearCombination { a_scaled.scale(&coeff); if let Some(fr) = a_scaled.try_into_constant_value() { - self.add_assign_term_with_coeff(b, fr); + self.add_assign_term_with_coeff(b, fr); } else if let Some(fr) = b.try_into_constant_value() { self.add_assign_term_with_coeff(&a_scaled, fr); } else { @@ -418,36 +446,36 @@ impl AmplifiedLinearCombination { tmp.mul_assign(&b_val); tmp.add_assign(&lc_val); Some(tmp) - }, + } _ => None, }; // let a = p_1 * x + c_1, b = p_2 * y + c_2, then: - // a * b = (p_1 * x + c_1) * (p_2 * y + c_2) = + // a * b = (p_1 * x + c_1) * (p_2 * y + c_2) = // = p_1 * p_2 * x * y + p_1 * c_2 * x + p_2 * c_1 * y + c_1 * c_2 - let (x, p_1, c_1) = a_scaled.unpack(); + let (x, p_1, c_1) = a_scaled.unpack(); let (y, p_2, c_2) = b.unpack(); - + // add p_1 * p_2 * x * y let var_pair = OrderedVariablePair::new(x, y); let mut coeff = p_1.clone(); - coeff.mul_assign(&p_2); + coeff.mul_assign(&p_2); self.quadratic_terms.entry(var_pair).and_modify(|fr| fr.add_assign(&coeff)).or_insert(coeff); // add p_1 * c_2 * x let mut coeff = p_1.clone(); - coeff.mul_assign(&c_2); + coeff.mul_assign(&c_2); self.linear_terms.entry(x).and_modify(|fr| fr.add_assign(&coeff)).or_insert(coeff); // add p_2 * c_1 * y let mut coeff = c_1.clone(); - coeff.mul_assign(&p_2); + coeff.mul_assign(&p_2); self.linear_terms.entry(y).and_modify(|fr| fr.add_assign(&coeff)).or_insert(coeff); // add c_1 * c_2 let mut coeff = c_1.clone(); coeff.mul_assign(&c_2); - self.constant.add_assign(&coeff); + self.constant.add_assign(&coeff); } } @@ -462,7 +490,7 @@ impl AmplifiedLinearCombination { quad.insert(var_pair.first); quad.insert(var_pair.second); } - + let mut lin = IndexSet::new(); for var in self.linear_terms.keys() { lin.insert(var.clone()); @@ -480,14 +508,16 @@ impl AmplifiedLinearCombination { assert!(CS::Params::STATE_WIDTH == REQUIRED_STATE_WIDTH); assert!(is_selector_specialized_gate::()); self.normalize(); - if self.len() == 0 { return Ok(0); } - + if self.len() == 0 { + return Ok(0); + } + let mut linear_terms_only_vars = self.get_linear_terms_only_variables(); - let flattened_quad_releations : Vec<(OrderedVariablePair, E::Fr)> = self.quadratic_terms.into_iter().collect(); + let flattened_quad_releations: Vec<(OrderedVariablePair, E::Fr)> = self.quadratic_terms.into_iter().collect(); let flattened_arr_len = flattened_quad_releations.len(); - let mut arr_indexer : IndexMap = IndexMap::new(); - let mut gate_templates : Vec> = vec![]; - let mut num_gates_allocated : usize = 0; + let mut arr_indexer: IndexMap = IndexMap::new(); + let mut gate_templates: Vec> = vec![]; + let mut num_gates_allocated: usize = 0; for i in 0..flattened_arr_len { let (var_pair_i, fr_i) = flattened_quad_releations[i].clone(); @@ -495,7 +525,7 @@ impl AmplifiedLinearCombination { for var in [var_pair_i.first, var_pair_i.second].iter() { if let Some(j) = arr_indexer.get(var) { let (var_pair_j, fr_j) = flattened_quad_releations[*j].clone(); - + // construct gate from two multiplications: let a = *var; let b = var_pair_i.get_associate(a); @@ -514,7 +544,7 @@ impl AmplifiedLinearCombination { } } } - + let unconsumed_idxes = IndexSet::::from_iter(arr_indexer.into_values()); for i in unconsumed_idxes { let (var_pair, fr) = flattened_quad_releations[i]; @@ -531,31 +561,27 @@ impl AmplifiedLinearCombination { if is_first { gate_template.add_constant_term(self.constant); is_first = false; - } - else { + } else { gate_template.add_next_trace_step_term(next_trace_step_var); } gate_template.add_linear_coefficients_for_bound_variables(&mut self.linear_terms); - gate_template.add_linear_coefficients_for_free_variables( - &mut self.linear_terms, &mut linear_terms_only_vars - ); + gate_template.add_linear_coefficients_for_free_variables(&mut self.linear_terms, &mut linear_terms_only_vars); let is_final = (idx >= gate_templates.len()) && (linear_terms_only_vars.is_empty()); if is_final { gate_template.set_finality_flag(); - } - else { + } else { // we manually allocate the new variable let may_be_new_intermediate_value = gate_template.evaluate_next_trace_step_value(cs); - next_trace_step_var = cs.alloc(|| { may_be_new_intermediate_value })?; + next_trace_step_var = cs.alloc(|| may_be_new_intermediate_value)?; } gate_template.materialize(cs)?; num_gates_allocated += 1; if is_final { - break + break; } - } + } Ok(num_gates_allocated) } @@ -578,7 +604,7 @@ impl AmplifiedLinearCombination { minus_one.negate(); self.add_assign_number_with_coeff(&num, minus_one); let num_gates = self.enforce_zero(cs)?; - + Ok((num, num_gates)) } } diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint_new/bigint.rs b/crates/franklin-crypto/src/plonk/circuit/bigint_new/bigint.rs index 4b9f327..74eb027 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint_new/bigint.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint_new/bigint.rs @@ -1,12 +1,11 @@ -use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr, BitIterator}; -use crate::bellman::SynthesisError; -use crate::bellman::plonk::better_better_cs::cs::ConstraintSystem; -use num_bigint::BigUint; use super::super::allocated_num::{AllocatedNum, Num}; use super::super::linear_combination::LinearCombination; use super::super::simple_term::Term; - +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; +use crate::bellman::pairing::Engine; +use crate::bellman::plonk::better_better_cs::cs::ConstraintSystem; +use crate::bellman::SynthesisError; +use num_bigint::BigUint; pub fn repr_to_biguint(repr: &F::Repr) -> BigUint { let mut b = BigUint::from(0u64); @@ -20,8 +19,8 @@ pub fn repr_to_biguint(repr: &F::Repr) -> BigUint { #[track_caller] pub fn mod_inverse(el: &BigUint, modulus: &BigUint) -> BigUint { use crate::num_bigint::BigInt; - use crate::num_integer::{Integer, ExtendedGcd}; - use crate::num_traits::{ToPrimitive, Zero, One}; + use crate::num_integer::{ExtendedGcd, Integer}; + use crate::num_traits::{One, ToPrimitive, Zero}; if el.is_zero() { panic!("division by zero"); @@ -30,7 +29,7 @@ pub fn mod_inverse(el: &BigUint, modulus: &BigUint) -> BigUint { let el_signed = BigInt::from(el.clone()); let modulus_signed = BigInt::from(modulus.clone()); - let ExtendedGcd{ gcd, x: _, y, .. } = modulus_signed.extended_gcd(&el_signed); + let ExtendedGcd { gcd, x: _, y, .. } = modulus_signed.extended_gcd(&el_signed); assert!(gcd.is_one()); let y = if y < BigInt::zero() { let mut y = y; @@ -72,8 +71,8 @@ pub fn some_biguint_to_fe(value: &Option) -> Option { let n = F::from_str(&value.to_str_radix(10)).unwrap(); Some(n) - }, - None => None + } + None => None, } } @@ -91,8 +90,8 @@ pub fn some_fe_to_biguint(el: &Option) -> Option { let ret = repr_to_biguint::(&repr); Some(ret) - }, - None => None + } + None => None, } } @@ -127,10 +126,7 @@ pub fn split_into_fixed_width_limbs(mut fe: BigUint, bits_per_limb: usize) -> Ve } #[track_caller] -pub fn split_some_into_fixed_number_of_limbs( - fe: Option, bits_per_limb: usize, num_limbs: usize -) -> Vec> -{ +pub fn split_some_into_fixed_number_of_limbs(fe: Option, bits_per_limb: usize, num_limbs: usize) -> Vec> { if let Some(fe) = fe { let mut fe = fe; assert!(fe.bits() as usize <= bits_per_limb * num_limbs); @@ -170,12 +166,7 @@ pub fn split_some_into_limbs_of_variable_width(fe: Option, bits_per_lim if let Some(fe) = fe { let mut fe = fe; let full_width = bits_per_limb.iter().sum(); - assert!( - fe.bits() as usize <= full_width, - "can fit {} bits maximum, but got {}", - full_width, - fe.bits() - ); + assert!(fe.bits() as usize <= full_width, "can fit {} bits maximum, but got {}", full_width, fe.bits()); let mut limbs = Vec::with_capacity(bits_per_limb.len()); for &width in bits_per_limb.iter() { diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint_new/field.rs b/crates/franklin-crypto/src/plonk/circuit/bigint_new/field.rs index 12e5fc8..4720463 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint_new/field.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint_new/field.rs @@ -1,28 +1,26 @@ -use super::*; use super::bigint::*; +use super::*; use bellman::CurveProjective; -use num_traits::{Zero, One}; +use num_derive::FromPrimitive; use num_integer::Integer; -use num_derive::FromPrimitive; use num_traits::FromPrimitive; +use num_traits::{One, Zero}; use std::ops::ControlFlow; use std::os::raw; -use num_bigint::BigUint; use super::super::allocated_num::{AllocatedNum, Num}; use super::super::linear_combination::LinearCombination; use super::super::simple_term::Term; use crate::plonk::circuit::hashes_with_tables::utils::IdentifyFirstLast; use crate::plonk::circuit::SomeArithmetizable; - +use num_bigint::BigUint; // TODO and NB: the code here is very tight and dense. Every line should be carefully reviewed and double checked - -// this variable is used in fma implementation: it is set to the maximal numver of bits on which +// this variable is used in fma implementation: it is set to the maximal numver of bits on which // new_of * shift + /sum_{i+j = k} a[i] * b[j] + \sum addition_elements[k] may overflow the limb width border // NB: this value is chosen more or less randomly - may be it is better to add some heuristics here -const MAX_INTERMIDIATE_OVERFLOW_WIDTH : usize = 8; +const MAX_INTERMIDIATE_OVERFLOW_WIDTH: usize = 8; // TODO: coarsely is completely unnecessary - get rid of it everywhere! // There is no problem to pay for one addtional constraint on exact allocation @@ -35,17 +33,14 @@ fn get_max_possible_value_for_bit_width(bitwidth: usize) -> BigUint { // constructs a term t which attests equality of x and y: t is equal to zero if x == y and (x-y)^{-1} otherwise // required for enforce_zero and equals family of functions // if flag is set then certificate witness will be zero independent of values of x and y -fn construct_equality_certificate>( - cs: &mut CS, x: &Term, y: &Term, flag: bool -) -> Result, SynthesisError> -{ +fn construct_equality_certificate>(cs: &mut CS, x: &Term, y: &Term, flag: bool) -> Result, SynthesisError> { let cert_wit = match (x.get_value(), y.get_value()) { (Some(x_wit), Some(y_wit)) => { let mut tmp = x_wit.clone(); tmp.sub_assign(&y_wit); let res = tmp.inverse().unwrap_or(E::Fr::zero()); Some(res) - }, + } _ => None, }; let cert_wit = if flag { Some(E::Fr::zero()) } else { cert_wit }; @@ -56,24 +51,23 @@ fn construct_equality_certificate>( Ok(cert) } - // Parameters of the RNS representation of extrinsic (non-native field element) // Every FieldElement is (by CRT) uniquely represented as a tuple of two residues x_0, x_1 such that // x = x_0 (mod T = 2^t), x = x_1 (mod E::Fr) // binary limb representation is of the form: -// most significat limb is of the form: [cap_bits | msl_bits] +// most significat limb is of the form: [cap_bits | msl_bits] // other num_binary_lims - 1 (regular) limbs are of the form: [cap_bits | limb_bits] // where all of msl_width, capacity_width and limb_width are multiples of range check granularity // ordinary limb may occupy up to cap_bits + limb_width // let max_binary_bitlen = (n - 1) * limb_bits + msl_bits + cap_bits // we chose t to be large enough, so that: 2^(2 * max_binary_bitlen) < native_modulus * 2^t -// this is mostly expolited internally by fma function to prevent overflow modulo T * native_modulus +// this is mostly expolited internally by fma function to prevent overflow modulo T * native_modulus // overflow bug is described in: https://hackmd.io/@kilic/S1wze9Ert -// NB: -// it seems that we may have better control by introducing msl_capacity_width -// which can be different from reg_capacity_width +// NB: +// it seems that we may have better control by introducing msl_capacity_width +// which can be different from reg_capacity_width #[derive(Clone, Debug, PartialEq, Eq)] -pub struct RnsParameters{ +pub struct RnsParameters { allow_individual_limb_overflow: bool, allow_coarse_allocation_for_temp_values: bool, @@ -89,13 +83,13 @@ pub struct RnsParameters{ represented_field_modulus: BigUint, represented_field_modulus_bitlength: usize, shift_left_by_limb_constant: E::Fr, // is equal to (1 << binary_limb_width) - + // these fields are required only for "if_zero" method - f_char_mod_fr_char: E::Fr, // represented_module % Fr + f_char_mod_fr_char: E::Fr, // represented_module % Fr f_char_mod_binary_shift: E::Fr, // represented_module % (1 << binary_limb_width) - + // just some random very large value that raw binary value would never overflow - // we let infty to be 2^t = binary_RNS_module, where t = modulus_bitlen * 2 + // we let infty to be 2^t = binary_RNS_module, where t = modulus_bitlen * 2 infty: BigUint, max_ordinary_limb_val_on_alloc: BigUint, @@ -103,12 +97,11 @@ pub struct RnsParameters{ max_msl_val_on_alloc_strict: BigUint, _marker_engine: std::marker::PhantomData, - _marker_fr: std::marker::PhantomData + _marker_fr: std::marker::PhantomData, } -impl<'a, E: Engine, F: PrimeField> RnsParameters{ - pub fn new_optimal>(cs: &mut CS, limb_size: usize) -> Self - { +impl<'a, E: Engine, F: PrimeField> RnsParameters { + pub fn new_optimal>(cs: &mut CS, limb_size: usize) -> Self { let allow_individual_limb_overflow = true; let allow_coarse_allocation_for_temp_values = true; @@ -120,14 +113,14 @@ impl<'a, E: Engine, F: PrimeField> RnsParameters{ let native_field_modulus_bitlength = native_field_modulus.bits() as usize; let represented_field_modulus = repr_to_biguint::(&F::char()); let represented_field_modulus_bitlength = represented_field_modulus.bits() as usize; - let num_binary_limbs = (represented_field_modulus_bitlength + limb_size - 1) / limb_size; - + let num_binary_limbs = (represented_field_modulus_bitlength + limb_size - 1) / limb_size; + let rem = represented_field_modulus_bitlength % limb_size; let msl_width = if rem == 0 { limb_size } else { rem }; let shift = BigUint::one() << limb_size; let shift_left_by_limb_constant = biguint_to_fe::(shift.clone()); - + // (verifying that k * Fr::modulus != 0 (mod 2^{limb_width}) for all positive values of k, such that: // bitlength(k * Fr::modulus) <= represented_field_modulus_bitlength bits // for the testimony of the necessity of this check look the comments in "iz_zero" function @@ -136,11 +129,11 @@ impl<'a, E: Engine, F: PrimeField> RnsParameters{ if (multiple_of_fr_char.clone() % shift.clone()).is_zero() { panic!("k * Fr::modulus == 0 (mod 2^limb_width)"); } - multiple_of_fr_char += native_field_modulus.clone(); + multiple_of_fr_char += native_field_modulus.clone(); } let f_char_mod_fr_char = biguint_to_fe::(represented_field_modulus.clone()); let f_char_mod_binary_shift = biguint_to_fe::(represented_field_modulus.clone() % shift); - + // we chose t to be large enough, so that: 2^(2 * max_binary_bitlen) < native_field_modulus * 2^t let t = represented_field_modulus_bitlength * 2usize; let infty = BigUint::one() << t; @@ -148,7 +141,7 @@ impl<'a, E: Engine, F: PrimeField> RnsParameters{ let max_ordinary_limb_val_on_alloc = get_max_possible_value_for_bit_width(limb_size); let max_msl_val_on_alloc_coarsely = get_max_possible_value_for_bit_width(msl_width); let max_msl_val_on_alloc_strict = represented_field_modulus.clone() >> ((num_binary_limbs - 1) * limb_size); - + // check by 4 * p < native_field_modulus * 2^{limb_width} : // this is required by enforce_zero family of functions let lhs = represented_field_modulus.clone() * 4u64; @@ -175,17 +168,16 @@ impl<'a, E: Engine, F: PrimeField> RnsParameters{ max_msl_val_on_alloc_coarsely, max_msl_val_on_alloc_strict, _marker_engine: std::marker::PhantomData::, - _marker_fr: std::marker::PhantomData:: + _marker_fr: std::marker::PhantomData::, } } } - // Simple term and bit counter/max value counter that we can update #[derive(Clone, Debug)] pub struct Limb { pub term: Term, - pub max_value: BigUint + pub max_value: BigUint, } impl Limb { @@ -203,12 +195,16 @@ impl Limb { let term = Term::::from_constant(value); Self { term, - max_value: fe_to_biguint(&value) + max_value: fe_to_biguint(&value), } } pub fn max_value(&self) -> BigUint { - if self.is_constant() { self.get_value_as_biguint().unwrap() } else { self.max_value.clone() } + if self.is_constant() { + self.get_value_as_biguint().unwrap() + } else { + self.max_value.clone() + } } pub fn get_value_as_biguint(&self) -> Option { @@ -222,14 +218,14 @@ impl Limb { pub fn zero() -> Self { Limb:: { term: Term::::zero(), - max_value: BigUint::zero() + max_value: BigUint::zero(), } } pub fn one() -> Self { Limb:: { term: Term::::from_constant(E::Fr::one()), - max_value: BigUint::one() + max_value: BigUint::one(), } } @@ -246,58 +242,49 @@ impl Limb { } } - -fn get_limbs_in_diapason<'a, E: Engine>( - x: &'a Vec>, start: usize, end: usize -) -> impl Iterator)> + 'a { - let iter = x.iter().enumerate().filter(move |(i, _x)| { *i >= start && *i < end}); +fn get_limbs_in_diapason<'a, E: Engine>(x: &'a Vec>, start: usize, end: usize) -> impl Iterator)> + 'a { + let iter = x.iter().enumerate().filter(move |(i, _x)| *i >= start && *i < end); iter } -fn get_limbs_product_in_diapason<'a, E: Engine>( - x: &'a Vec>, y: &'a Vec>, start: usize, end: usize -) -> impl Iterator, &'a Limb)> + 'a { +fn get_limbs_product_in_diapason<'a, E: Engine>(x: &'a Vec>, y: &'a Vec>, start: usize, end: usize) -> impl Iterator, &'a Limb)> + 'a { let iter = itertools::iproduct!(x.iter().enumerate(), y.iter().enumerate()).filter_map(move |x| { let ((i, x_limb), (j, y_limb)) = x; if i + j >= start && i + j < end { Some((i + j, x_limb, y_limb)) - } - else { + } else { None } }); - + iter } - #[repr(u8)] -#[derive(Clone, Debug, PartialEq)] -#[derive(FromPrimitive)] +#[derive(Clone, Debug, PartialEq, FromPrimitive)] pub enum ReductionStatus { // we say that FieldElement x is normalized if there are no overflowed chunks and 0 <= x < F::chat // the only way to make nonconstant x normalized is to explicitely call normalize function on it // NB: even freshly allocated elements are not normalized! (except for unsafe unchecked allocation) - // all constants are always in normalized form + // all constants are always in normalized form Normalized, // FieldElement x is in Loose reduction status if there are no oberflowed chunks and 0 <= x < ceil[log_2(F::char)] // in other words x may be greater than F::Char but doesn't have more bits in representation // freshly allocated FieldElements are loosely reduced, results of mul, div, inverse, and fma are also in this form Loose, // results of addition, subtraction and negation are in this form - Unreduced + Unreduced, } impl Copy for ReductionStatus {} - #[derive(Clone, Debug)] -pub struct FieldElement<'a, E: Engine, F: PrimeField>{ +pub struct FieldElement<'a, E: Engine, F: PrimeField> { binary_limbs: Vec>, base_field_limb: Term, pub(crate) representation_params: &'a RnsParameters, value: Option, - reduction_status: ReductionStatus + reduction_status: ReductionStatus, } impl<'a, E: Engine, F: PrimeField> std::fmt::Display for FieldElement<'a, E, F> { @@ -312,8 +299,12 @@ impl<'a, E: Engine, F: PrimeField> std::fmt::Display for FieldElement<'a, E, F> } for (i, l) in self.binary_limbs.iter().enumerate() { write!( - f, "Limb {}: value = {:?}, max_value = {}, bits = {}, ", - i, l.term.get_value(), l.max_value.to_str_radix(16), l.max_value.bits() + f, + "Limb {}: value = {:?}, max_value = {}, bits = {}, ", + i, + l.term.get_value(), + l.max_value.to_str_radix(16), + l.max_value.bits() )?; } write!(f, "Base field limb value = {:?} ", self.base_field_limb.get_value())?; @@ -321,24 +312,23 @@ impl<'a, E: Engine, F: PrimeField> std::fmt::Display for FieldElement<'a, E, F> } } - pub struct FieldElementsChain<'a, E: Engine, F: PrimeField> { pub elems_to_add: Vec>, - pub elems_to_sub: Vec> + pub elems_to_sub: Vec>, } impl<'a, E: Engine, F: PrimeField> FieldElementsChain<'a, E, F> { pub fn new() -> Self { FieldElementsChain:: { elems_to_add: vec![], - elems_to_sub: vec![] + elems_to_sub: vec![], } } - + pub fn add_pos_term(&mut self, elem: &FieldElement<'a, E, F>) -> &mut Self { self.elems_to_add.push(elem.clone()); self - } + } pub fn add_neg_term(&mut self, elem: &FieldElement<'a, E, F>) -> &mut Self { self.elems_to_sub.push(elem.clone()); @@ -357,7 +347,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElementsChain<'a, E, F> { pub fn get_maximal_positive_stored_value(&self) -> BigUint { self.elems_to_add.iter().fold(BigUint::zero(), |acc, x| acc + x.get_maximal_possible_stored_value()) - } + } pub fn get_maximal_negative_stored_value(&self) -> BigUint { self.elems_to_sub.iter().fold(BigUint::zero(), |acc, x| acc + x.get_maximal_possible_stored_value()) @@ -367,45 +357,44 @@ impl<'a, E: Engine, F: PrimeField> FieldElementsChain<'a, E, F> { let FieldElementsChain { elems_to_add, elems_to_sub } = self; FieldElementsChain { elems_to_add: elems_to_sub, - elems_to_sub: elems_to_add + elems_to_sub: elems_to_add, } - } + } fn add_raw_value_to_accumulator(&self, init_acc_val: Option) -> Option { if init_acc_val.is_none() { return None; } - let final_acc_value = self.elems_to_add.iter().map(|x| (x, true)).chain( - self.elems_to_sub.iter().map(|x| (x, false)) - ) .try_fold(init_acc_val.unwrap(), |prev, (x, is_pos_term)| { - if let Some(val) = x.get_raw_value() { - let next = match is_pos_term { - true => prev + val, - false => { - assert!(prev >= val); - prev - val - }, - }; - ControlFlow::Continue(next) - } else { - ControlFlow::Break(prev) - } - }); + let final_acc_value = self + .elems_to_add + .iter() + .map(|x| (x, true)) + .chain(self.elems_to_sub.iter().map(|x| (x, false))) + .try_fold(init_acc_val.unwrap(), |prev, (x, is_pos_term)| { + if let Some(val) = x.get_raw_value() { + let next = match is_pos_term { + true => prev + val, + false => { + assert!(prev >= val); + prev - val + } + }; + ControlFlow::Continue(next) + } else { + ControlFlow::Break(prev) + } + }); match final_acc_value { ControlFlow::Break(_) => None, - ControlFlow::Continue(x) => Some(x) + ControlFlow::Continue(x) => Some(x), } - } + } } - -pub fn split_into_limbs(value: F, params: &RnsParameters) -> (Vec, E::Fr) -{ +pub fn split_into_limbs(value: F, params: &RnsParameters) -> (Vec, E::Fr) { let value_as_bigint = fe_to_biguint(&value); - let binary_limb_values = split_into_fixed_number_of_limbs( - value_as_bigint, params.binary_limb_width, params.num_binary_limbs - ); + let binary_limb_values = split_into_fixed_number_of_limbs(value_as_bigint, params.binary_limb_width, params.num_binary_limbs); assert_eq!(binary_limb_values.len(), params.num_binary_limbs); let base_limb = fe_to_biguint(&value) % ¶ms.native_field_modulus; @@ -417,8 +406,10 @@ pub fn split_into_limbs(value: F, params: &RnsParamete return (binary_limbs, base_limb); } -pub fn value_to_limbs(value: Option, params: &RnsParameters) -> (Vec>, Option) -where E: Engine, F: PrimeField +pub fn value_to_limbs(value: Option, params: &RnsParameters) -> (Vec>, Option) +where + E: Engine, + F: PrimeField, { let num_limbs = params.num_binary_limbs; @@ -428,7 +419,7 @@ where E: Engine, F: PrimeField let binary_limbs: Vec> = binary_limbs.into_iter().map(|el| Some(el)).collect(); assert_eq!(binary_limbs.len(), params.num_binary_limbs); return (binary_limbs, Some(base_limb)); - }, + } None => { return (vec![None; num_limbs], None); } @@ -436,15 +427,12 @@ where E: Engine, F: PrimeField } #[track_caller] -pub fn slice_some_into_limbs_non_exact( - value: Option, max_width: usize, limb_width: usize -) -> (Vec>, usize) -{ +pub fn slice_some_into_limbs_non_exact(value: Option, max_width: usize, limb_width: usize) -> (Vec>, usize) { let rem = max_width % limb_width; let msl_bit_width = if rem == 0 { limb_width } else { rem }; let num_limbs = (max_width + limb_width - 1) / limb_width; let limbs = split_some_into_fixed_number_of_limbs(value, limb_width, num_limbs); - + (limbs, msl_bit_width) } @@ -452,10 +440,9 @@ pub fn slice_some_into_limbs_non_exact( pub fn slice_into_limbs_non_exact(value: BigUint, total_width: usize, limb_width: usize) -> (Vec, usize) { // here msl stands for Most Significant Limb let (chunks, msl_width) = slice_some_into_limbs_non_exact(Some(value), total_width, limb_width); - let chunks : Vec = chunks.into_iter().map(|x| x.unwrap()).collect(); - (chunks, msl_width) -} - + let chunks: Vec = chunks.into_iter().map(|x| x.unwrap()).collect(); + (chunks, msl_width) +} impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // check that self and other are actuall the same circuit variables! @@ -468,13 +455,11 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { is_circuit_eq } - // we do not do the range check for the limbs: + // we do not do the range check for the limbs: // this function assumes that every limb is at most params.binary_limb_bitwidth bits long // and the maximal_stored_value < F::char #[track_caller] - pub unsafe fn alloc_from_limbs_unchecked>( - cs: &mut CS, raw_limbs: &[Num], params: &'a RnsParameters, is_normalized: bool - ) -> Result { + pub unsafe fn alloc_from_limbs_unchecked>(cs: &mut CS, raw_limbs: &[Num], params: &'a RnsParameters, is_normalized: bool) -> Result { let mut binary_limbs_allocated = Vec::with_capacity(params.num_binary_limbs); let msl_max_val = ¶ms.max_msl_val_on_alloc_strict; let ord_max_val = ¶ms.max_ordinary_limb_val_on_alloc; @@ -499,65 +484,66 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { current_constant.mul_assign(&shift_constant); } binary_limbs_allocated.resize(params.num_binary_limbs, Limb::zero()); - + let base_field_limb_num = base_field_lc.into_num(cs)?; let base_field_term = Term::::from_num(base_field_limb_num); - let total_value = raw_limbs.iter().rev().fold(Some(BigUint::zero()), |acc, &x| { - match (acc, x.get_value()) { + let total_value = raw_limbs + .iter() + .rev() + .fold(Some(BigUint::zero()), |acc, &x| match (acc, x.get_value()) { (Some(mut acc), Some(fr)) => { acc <<= params.binary_limb_width; acc += fe_to_biguint(&fr); Some(acc) - }, + } (_, _) => None, - } - }).map(|x| biguint_to_fe::(x)); - + }) + .map(|x| biguint_to_fe::(x)); + let reduction_status = if is_normalized { ReductionStatus::Normalized } else { ReductionStatus::Unreduced }; let new = Self { binary_limbs: binary_limbs_allocated, base_field_limb: base_field_term, representation_params: params, value: total_value, - reduction_status + reduction_status, }; - + Ok(new) } #[track_caller] fn alloc_impl>( - cs: &mut CS, value: Option, bit_width: usize, params: &'a RnsParameters, coarsely: bool + cs: &mut CS, + value: Option, + bit_width: usize, + params: &'a RnsParameters, + coarsely: bool, ) -> Result<(Self, RangeCheckDecomposition), SynthesisError> { assert!(bit_width > 0); if let Some(v) = value.as_ref() { assert!(v.bits() as usize <= bit_width); } - let mut decompositions : Vec> = vec![]; + let mut decompositions: Vec> = vec![]; let mut binary_limbs_allocated = Vec::with_capacity(params.num_binary_limbs); let mut base_field_lc = LinearCombination::::zero(); let shift_constant = params.shift_left_by_limb_constant; let mut current_constant = E::Fr::one(); - let (limb_values, msl_width) = slice_some_into_limbs_non_exact( - value.clone(), bit_width, params.binary_limb_width - ); + let (limb_values, msl_width) = slice_some_into_limbs_non_exact(value.clone(), bit_width, params.binary_limb_width); let msl_width_padded = if coarsely { round_up(msl_width, params.range_check_granularity) } else { msl_width }; let msl_max_val = get_max_possible_value_for_bit_width(msl_width_padded); - for (_is_first, is_last, value) in limb_values.into_iter().identify_first_last() - { + for (_is_first, is_last, value) in limb_values.into_iter().identify_first_last() { let value_as_fe = some_biguint_to_fe::(&value); let a = AllocatedNum::alloc(cs, || Ok(*value_as_fe.get()?))?; let max_value = if is_last { msl_max_val.clone() } else { params.max_ordinary_limb_val_on_alloc.clone() }; let bitlength = if is_last { msl_width } else { params.binary_limb_width }; - let decomposition = constraint_bit_length_ext_with_strategy( - cs, &a, bitlength, params.range_check_strategy, coarsely - )?; + let decomposition = constraint_bit_length_ext_with_strategy(cs, &a, bitlength, params.range_check_strategy, coarsely)?; decompositions.push(decomposition); let term = Term::::from_allocated_num(a.clone()); @@ -571,37 +557,32 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { if binary_limbs_allocated.len() < params.num_binary_limbs { binary_limbs_allocated.resize(params.num_binary_limbs, Limb::zero()); } - + let base_field_limb_num = base_field_lc.into_num(cs)?; let base_field_term = Term::::from_num(base_field_limb_num); let field_value = value.map(|x| biguint_to_fe::(x)); - + let new = Self { binary_limbs: binary_limbs_allocated, base_field_limb: base_field_term, representation_params: params, value: field_value, - reduction_status: ReductionStatus::Loose + reduction_status: ReductionStatus::Loose, }; let total_decomposition = RangeCheckDecomposition::combine(&decompositions); - + Ok((new, total_decomposition)) } // NB: we do not check for normalization on allocation #[track_caller] - pub fn alloc>( - cs: &mut CS, value: Option, params: &'a RnsParameters - ) -> Result { + pub fn alloc>(cs: &mut CS, value: Option, params: &'a RnsParameters) -> Result { let (new, _decomposition) = Self::alloc_ext(cs, value, params)?; Ok(new) } #[track_caller] - pub fn alloc_ext>( - cs: &mut CS, value: Option, params: &'a RnsParameters - ) -> Result<(Self, RangeCheckDecomposition), SynthesisError> - { + pub fn alloc_ext>(cs: &mut CS, value: Option, params: &'a RnsParameters) -> Result<(Self, RangeCheckDecomposition), SynthesisError> { let bit_width = params.represented_field_modulus_bitlength; let value_as_biguint = value.map(|x| fe_to_biguint(&x)); Self::alloc_impl(cs, value_as_biguint, bit_width, params, false) @@ -609,19 +590,20 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { #[track_caller] pub(crate) fn alloc_for_known_bitwidth>( - cs: &mut CS, value: Option, bit_width: usize, params: &'a RnsParameters, coarsely: bool + cs: &mut CS, + value: Option, + bit_width: usize, + params: &'a RnsParameters, + coarsely: bool, ) -> Result { let (val, _decomposition) = Self::alloc_impl(cs, value, bit_width, params, coarsely)?; Ok(val) } pub(crate) fn split_const_into_limbs(value: BigUint, params: &'a RnsParameters) -> Vec> { - let binary_limb_values = split_into_fixed_number_of_limbs( - value, params.binary_limb_width, params.num_binary_limbs - ); + let binary_limb_values = split_into_fixed_number_of_limbs(value, params.binary_limb_width, params.num_binary_limbs); let mut binary_limbs = Vec::with_capacity(binary_limb_values.len()); - for l in binary_limb_values.into_iter() - { + for l in binary_limb_values.into_iter() { let f = biguint_to_fe(l.clone()); let term = Term::::from_constant(f); let limb = Limb::::new(term, l); @@ -643,41 +625,37 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { base_field_limb: base_limb, representation_params: params, value: Some(v), - reduction_status: ReductionStatus::Normalized + reduction_status: ReductionStatus::Normalized, } } - pub fn zero( - params: &'a RnsParameters - ) -> Self { + pub fn zero(params: &'a RnsParameters) -> Self { let zero_limb = Limb::zero(); let binary_limbs = vec![zero_limb.clone(); params.num_binary_limbs]; - + Self { binary_limbs: binary_limbs, base_field_limb: Term::::from_constant(E::Fr::zero()), representation_params: params, value: Some(F::zero()), - reduction_status: ReductionStatus::Normalized + reduction_status: ReductionStatus::Normalized, } } - pub fn one( - params: &'a RnsParameters - ) -> Self { + pub fn one(params: &'a RnsParameters) -> Self { let one_limb = Limb::one(); let zero_limb = Limb::zero(); let mut binary_limbs = Vec::with_capacity(params.num_binary_limbs); binary_limbs.push(one_limb); binary_limbs.resize(params.num_binary_limbs, zero_limb.clone()); - + Self { binary_limbs: binary_limbs, base_field_limb: Term::::from_constant(E::Fr::one()), representation_params: params, value: Some(F::one()), - reduction_status: ReductionStatus::Normalized + reduction_status: ReductionStatus::Normalized, } } @@ -739,21 +717,20 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // this method requires x to be either loosely refuced or normalized, if it is in fact not - we do // normalization ourselves, and that's why referece is mutable - pub fn is_zero>(&mut self, cs: &mut CS) -> Result - { + pub fn is_zero>(&mut self, cs: &mut CS) -> Result { let params = self.representation_params; self.reduce_if_necessary(cs, ReductionStatus::Loose)?; - + // after reduction the value of x is in interval [0; 2*F) and all limbs occupy exactly limb_width bits // (i.e. capacity bits are not involved) // so, to test if x is zero we need to consider two cases: x == 0 and x == F - // x == 0 <=> field_limb == 0 and least_significant_binary_limb == 0 + // x == 0 <=> field_limb == 0 and least_significant_binary_limb == 0 // (but we should additionaly check that k * Fr::modulus % 2^{limb_width} != 0 for small positive k) // x == F <=> field_limb == F (mod Fr) and least_significal_binary_llimb == F (mod 2^{limb_width}) // (again, as long as k * Fr::modulus != 0 (mod 2^{limb_width}) for small positive k) // the exact range of k to test is determined by the maximal multiple of Fr::modulus which fits into // params.represented_field_modulus_bitlength bits - + let least_significant_binary_limb = self.binary_limbs[0].term.collapse_into_num(cs)?; let base_field_limb = self.base_field_limb.collapse_into_num(cs)?; @@ -771,34 +748,38 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { self.binary_limbs[0].term = Term::from_num(least_significant_binary_limb); self.base_field_limb = Term::from_num(base_field_limb); - + let is_zero = if self.reduction_status == ReductionStatus::Loose { Boolean::or(cs, &x_is_raw_zero, &x_is_raw_modulus)? } else { x_is_raw_zero }; - + Ok(is_zero) } #[track_caller] - pub fn conditionally_select(cs: &mut CS, flag: &Boolean, first: &Self, second: &Self) -> Result - where CS: ConstraintSystem + pub fn conditionally_select(cs: &mut CS, flag: &Boolean, first: &Self, second: &Self) -> Result + where + CS: ConstraintSystem, { assert!(Self::check_params_equivalence(first, second)); match flag { Boolean::Constant(c) => { - if *c { return Ok(first.clone()) } else { return Ok(second.clone()) }; - }, - _ => {}, + if *c { + return Ok(first.clone()); + } else { + return Ok(second.clone()); + }; + } + _ => {} }; // flag * a + (1-flag) * b = flag * (a-b) + b let flag_as_term = Term::::from_boolean(flag); let mut new_binary_limbs = vec![]; - for (l, r) in first.binary_limbs.iter().zip(second.binary_limbs.iter()) - { + for (l, r) in first.binary_limbs.iter().zip(second.binary_limbs.iter()) { let mut minus_b = r.term.clone(); minus_b.negate(); let a_minus_b = l.term.add(cs, &minus_b)?; @@ -815,7 +796,11 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let new_base_limb = Term::::fma(cs, &flag_as_term, &a_minus_b, &second.base_field_limb)?; let new_value = if let Some(f) = flag.get_value() { - if f { first.get_field_value() } else { second.get_field_value() } + if f { + first.get_field_value() + } else { + second.get_field_value() + } } else { None }; @@ -823,7 +808,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let final_reduction_status = match (first.reduction_status, second.reduction_status) { (ReductionStatus::Unreduced, _) | (_, ReductionStatus::Unreduced) => ReductionStatus::Unreduced, (ReductionStatus::Loose, _) | (_, ReductionStatus::Loose) => ReductionStatus::Loose, - (ReductionStatus::Normalized, ReductionStatus::Normalized) => ReductionStatus::Normalized + (ReductionStatus::Normalized, ReductionStatus::Normalized) => ReductionStatus::Normalized, }; let new = Self { @@ -831,7 +816,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { base_field_limb: new_base_limb, value: new_value, representation_params: first.representation_params, - reduction_status: final_reduction_status + reduction_status: final_reduction_status, }; Ok(new) } @@ -843,23 +828,28 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { #[track_caller] // negates if true // TODO: we could create optimized conditional negation by p +/ sign_bit * x - pub fn conditionally_negate(&self, cs: &mut CS, flag: &Boolean) -> Result - where CS: ConstraintSystem + pub fn conditionally_negate(&self, cs: &mut CS, flag: &Boolean) -> Result + where + CS: ConstraintSystem, { if let Some(f) = flag.get_value() { - if f { return self.negate(cs) } else { return Ok(self.clone()) } + if f { + return self.negate(cs); + } else { + return Ok(self.clone()); + } }; let negated = self.negate(cs)?; Self::conditionally_select(cs, flag, &negated, self) } - // we call value to be reduced if all binary limbs do not overflow: i.e there are no capacity bits occupied + // we call value to be reduced if all binary limbs do not overflow: i.e there are no capacity bits occupied fn needs_reduction(&self, mode: ReductionStatus) -> bool { // if the element is already reduced do nothing: if self.reduction_status as u8 <= mode as u8 { return false; } - + let params = &self.representation_params; let upper_bound = match mode { ReductionStatus::Loose => BigUint::one() << params.represented_field_modulus.bits(), @@ -871,7 +861,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { if mode == ReductionStatus::Unreduced { return false; } - + for (_is_first, is_last, binary_limb) in self.binary_limbs.iter().identify_first_last() { let max_width = if is_last { params.msl_width } else { params.binary_limb_width }; needs_reduction = needs_reduction || (binary_limb.max_value().bits() as usize > max_width); @@ -881,21 +871,22 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - fn reduce_if_necessary(&mut self, cs: &mut CS, mode: ReductionStatus) -> Result<(), SynthesisError> - where CS: ConstraintSystem + fn reduce_if_necessary(&mut self, cs: &mut CS, mode: ReductionStatus) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { if self.is_constant() { self.reduction_status = ReductionStatus::Normalized; return Ok(()); } - + let old_reduction_status = self.reduction_status; if self.needs_reduction(mode) { return self.reduction_impl(cs); } // if new reduction status is better - replace self.reduction_status = FromPrimitive::from_u8(std::cmp::min(old_reduction_status as u8, mode as u8)).unwrap(); - + Ok(()) } @@ -903,36 +894,35 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // if already normalized no nothing - we do not want to normalize twice in a row if self.reduction_status == ReductionStatus::Normalized { return Ok(()); - } - self.reduce_if_necessary(cs, ReductionStatus::Normalized)?; + } + self.reduce_if_necessary(cs, ReductionStatus::Normalized)?; self.enforce_if_normalized(cs) } pub fn reduce_loose>(&mut self, cs: &mut CS) -> Result<(), SynthesisError> { - self.reduce_if_necessary(cs, ReductionStatus::Loose) + self.reduce_if_necessary(cs, ReductionStatus::Loose) } #[track_caller] fn reduction_impl>(&mut self, cs: &mut CS) -> Result<(), SynthesisError> { let one = Self::one(self.representation_params); let reduced = self.mul(cs, &one)?; - + *self = reduced; Ok(()) } #[track_caller] pub fn enforce_if_normalized>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - if self.is_constant() { return Ok(()) } + if self.is_constant() { + return Ok(()); + } let params = self.representation_params; let mut minus_one = E::Fr::one(); minus_one.negate(); // msl here stands for Most Significant Limb - let (modulus_limbs, msl_width) = slice_into_limbs_non_exact( - params.represented_field_modulus.clone(), - params.represented_field_modulus_bitlength, params.binary_limb_width - ); + let (modulus_limbs, msl_width) = slice_into_limbs_non_exact(params.represented_field_modulus.clone(), params.represented_field_modulus_bitlength, params.binary_limb_width); let ordinary_shift = params.shift_left_by_limb_constant; let msl_shift = biguint_to_fe::(BigUint::one() << msl_width); @@ -940,7 +930,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut borrow = Limb::zero(); let mut is_const_term = true; let iter = self.binary_limbs.iter().zip(modulus_limbs.iter()).identify_first_last(); - for (_is_first, is_last, (l, m)) in iter { + for (_is_first, is_last, (l, m)) in iter { // l - borrow - m + new_borrow * shift = r // check if l >= borrow + m to fing the value of new_borrow let width = if is_last { msl_width } else { params.binary_limb_width }; @@ -952,10 +942,10 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { (Some(true), Some((BigUint::one() << width) + l - borrow - m)) } } - (_, _) => (None, None) - }; - is_const_term &= l.is_constant(); - + (_, _) => (None, None), + }; + is_const_term &= l.is_constant(); + let b = if is_last { Boolean::constant(true) } else if is_const_term { @@ -970,7 +960,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } else { let var = AllocatedNum::alloc(cs, || r_wit.map(|x| biguint_to_fe::(x)).grab())?; constraint_bit_length_with_strategy(cs, &var, width, params.range_check_strategy)?; - Num::Variable(var) + Num::Variable(var) }; let r_term = Term::::from_num(r); @@ -983,7 +973,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { lc.add_assign_term_with_coeff(&new_borrow, shift); lc.add_assign_term_with_coeff(&r_term, minus_one.clone()); lc.enforce_zero(cs)?; - + borrow = Limb::new(new_borrow, BigUint::one()); } @@ -995,9 +985,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // such that k - x is nonzero // the function returns k - x and chunk division of k - x #[track_caller] - fn subtraction_helper( - max_val: BigUint, limbs_max_vals: Vec, params: &RnsParameters - ) -> (BigUint, Vec) { + fn subtraction_helper(max_val: BigUint, limbs_max_vals: Vec, params: &RnsParameters) -> (BigUint, Vec) { let mut multiples_to_add_at_least = params.represented_field_modulus.clone(); while multiples_to_add_at_least < max_val { multiples_to_add_at_least += params.represented_field_modulus.clone(); @@ -1007,7 +995,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut tmp = multiples_to_add_at_least.clone(); for (_is_first, is_last, limb) in limbs_max_vals.into_iter().identify_first_last() { - if !is_last { + if !is_last { let bitlen = limb.bits(); let modulus = BigUint::one() << bitlen; let rem = tmp.clone() % modulus.clone(); @@ -1022,7 +1010,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { tmp <<= bitlen as usize - params.binary_limb_width; tmp -= 1u64 << (bitlen as usize - params.binary_limb_width); } - } else { + } else { const_constituent_chunks.push(tmp.clone()); }; } @@ -1031,9 +1019,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn add_with_reduction>( - &self, cs: &mut CS, other: &Self, mode: ReductionStatus - ) -> Result { + pub fn add_with_reduction>(&self, cs: &mut CS, other: &Self, mode: ReductionStatus) -> Result { let params = self.representation_params; assert!(Self::check_params_equivalence(self, other)); @@ -1042,11 +1028,10 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let new = Self::constant(tmp.unwrap(), params); return Ok(new); } - + // perform addition without reduction, so it will eventually be reduced later on let mut new_binary_limbs = vec![]; - for (l, r) in self.binary_limbs.iter().zip(other.binary_limbs.iter()) - { + for (l, r) in self.binary_limbs.iter().zip(other.binary_limbs.iter()) { let new_term = l.term.add(cs, &r.term)?; let new_max_value = l.max_value.clone() + &r.max_value; let limb = Limb::::new(new_term, new_max_value); @@ -1060,7 +1045,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { base_field_limb: new_base_limb, value: new_value, representation_params: params, - reduction_status: ReductionStatus::Unreduced + reduction_status: ReductionStatus::Unreduced, }; if cfg!(debug_assertions) { @@ -1080,8 +1065,9 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { self.add_with_reduction(cs, other, mode) } - pub fn double_with_reduction(&self, cs: &mut CS, mode: ReductionStatus) -> Result - where CS: ConstraintSystem + pub fn double_with_reduction(&self, cs: &mut CS, mode: ReductionStatus) -> Result + where + CS: ConstraintSystem, { let params = self.representation_params; let mut two = E::Fr::one(); @@ -1094,8 +1080,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } let mut new_binary_limbs = vec![]; - for l in self.binary_limbs.iter() - { + for l in self.binary_limbs.iter() { let mut new_term = l.term.clone(); new_term.scale(&two); let new_max_value = l.max_value.clone() * BigUint::from(2u64); @@ -1112,9 +1097,9 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { base_field_limb: new_base_limb, value: new_value, representation_params: params, - reduction_status: ReductionStatus::Unreduced + reduction_status: ReductionStatus::Unreduced, }; - + new.reduce_if_necessary(cs, mode)?; Ok(new) } @@ -1128,10 +1113,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { self.double_with_reduction(cs, mode) } - pub fn sub_with_reduction>( - &self, cs: &mut CS, other: &Self, mode: ReductionStatus - ) -> Result - { + pub fn sub_with_reduction>(&self, cs: &mut CS, other: &Self, mode: ReductionStatus) -> Result { let params = self.representation_params; assert!(Self::check_params_equivalence(self, other)); @@ -1152,14 +1134,13 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let max_val = other.get_maximal_possible_stored_value(); let limbs_max_vals = other.binary_limbs.iter().map(|x| x.max_value()).collect::>(); let (multiples_to_add_at_least, const_constituent_chunks) = Self::subtraction_helper(max_val, limbs_max_vals, params); - + // create new limbs let mut new_binary_limbs = vec![]; let iter = itertools::multizip((&self.binary_limbs, &other.binary_limbs, const_constituent_chunks)); - for (left, right, cnst) in iter - { + for (left, right, cnst) in iter { let constant_as_fe = biguint_to_fe::(cnst.clone()); - + let mut tmp = left.term.clone(); tmp.add_constant(&constant_as_fe); let res = tmp.sub(cs, &right.term)?; @@ -1182,7 +1163,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { base_field_limb: new_field_limb, value: new_value, representation_params: params, - reduction_status: ReductionStatus::Unreduced + reduction_status: ReductionStatus::Unreduced, }; if cfg!(debug_assertions) { @@ -1210,8 +1191,9 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { Self::mul_with_chain(cs, &self, &self, FieldElementsChain::new()) } - pub fn square_with_chain(&self, cs: &mut CS, chain: FieldElementsChain<'a, E, F>) -> Result - where CS: ConstraintSystem + pub fn square_with_chain(&self, cs: &mut CS, chain: FieldElementsChain<'a, E, F>) -> Result + where + CS: ConstraintSystem, { Self::mul_with_chain(cs, &self, &self, chain) } @@ -1229,8 +1211,9 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn div_with_chain(cs: &mut CS, chain: FieldElementsChain<'a, E, F>, den: &Self) -> Result - where CS: ConstraintSystem + pub fn div_with_chain(cs: &mut CS, chain: FieldElementsChain<'a, E, F>, den: &Self) -> Result + where + CS: ConstraintSystem, { let sample_elem = chain.elems_to_add.get(0).unwrap_or_else(|| chain.elems_to_sub.get(0).expect("Chain is empty")); let params = &sample_elem.representation_params; @@ -1241,12 +1224,11 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let den_inverse_value = den.get_field_value().map(|x| x.inverse().expect("denominator is zero")); let final_value = numerator_value.mul(&den_inverse_value); let all_constants = den.is_constant() && chain.is_constant(); - + if all_constants { let res = Self::constant(final_value.unwrap(), params); Ok(res) - } - else { + } else { let res = Self::alloc(cs, final_value, params)?; let chain = chain.negate(); Self::constraint_fma(cs, &res, &den, chain)?; @@ -1255,20 +1237,17 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn mul_with_chain>( - cs: &mut CS, a: &Self, b: &Self, mut chain: FieldElementsChain<'a, E, F>, - ) -> Result { + pub fn mul_with_chain>(cs: &mut CS, a: &Self, b: &Self, mut chain: FieldElementsChain<'a, E, F>) -> Result { let params = &a.representation_params; let mut final_value = a.get_field_value(); final_value = final_value.mul(&b.get_field_value()); final_value = final_value.add(&chain.get_field_value()); let all_constants = a.is_constant() && b.is_constant() && chain.is_constant(); - + if all_constants { let r = Self::constant(final_value.unwrap(), params); Ok(r) - } - else { + } else { let r = Self::alloc(cs, final_value, params)?; chain.add_neg_term(&r); Self::constraint_fma(cs, &a, &b, chain)?; @@ -1277,34 +1256,32 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn enforce_equal(cs: &mut CS, this: &mut Self, other: &mut Self) -> Result<(), SynthesisError> - where CS: ConstraintSystem + pub fn enforce_equal(cs: &mut CS, this: &mut Self, other: &mut Self) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { assert!(Self::check_params_equivalence(&this, &other)); if this.is_constant() && other.is_constant() { let a = this.get_field_value().unwrap(); let b = other.get_field_value().unwrap(); assert!(a == b); - return Ok(()) + return Ok(()); } - + this.reduce_if_necessary(cs, ReductionStatus::Loose)?; other.reduce_if_necessary(cs, ReductionStatus::Loose)?; // now we know that both this and other are < 2 * F::char, hence to enforce that they are equal // However, in all user scenarious we may assume that reduction is complete, i.e: // both values are in range [0; F::char) - // it is enough to chech equality only mod native field and mod limb_width + // it is enough to chech equality only mod native field and mod limb_width // which is justified by 2 * p < native_field_modulus * 2^{limb_width} this.binary_limbs[0].term.enforce_equal(cs, &other.binary_limbs[0].term)?; this.base_field_limb.enforce_equal(cs, &other.base_field_limb)?; // if field_elements are equal than they are normalized or not simultaneously! // hence if we somehow know that one of values is normalized than we may lay the other to be normalized - let any_is_normalized = { - this.reduction_status == ReductionStatus::Normalized || - other.reduction_status == ReductionStatus::Normalized - }; + let any_is_normalized = { this.reduction_status == ReductionStatus::Normalized || other.reduction_status == ReductionStatus::Normalized }; if any_is_normalized { this.reduction_status = ReductionStatus::Normalized; other.reduction_status = ReductionStatus::Normalized; @@ -1314,15 +1291,16 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - pub fn enforce_not_equal(cs: &mut CS, this: &mut Self, other: &mut Self) -> Result<(), SynthesisError> - where CS: ConstraintSystem + pub fn enforce_not_equal(cs: &mut CS, this: &mut Self, other: &mut Self) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { - assert!(Self::check_params_equivalence(&this, &other)); + assert!(Self::check_params_equivalence(&this, &other)); if this.is_constant() && other.is_constant() { let a = this.get_field_value().unwrap(); let b = other.get_field_value().unwrap(); assert!(a != b); - return Ok(()) + return Ok(()); } this.normalize(cs)?; @@ -1335,12 +1313,10 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // a * this.field_modulus - a * other.field_modulus - 1 = tmp // 2) [b, this.limb_modulus, other.limb_modulus, tmp]: // b * this.limb_modulus - b * other.limb_modulus + tmp = 0 - let a = construct_equality_certificate( - cs, &this.binary_limbs[0].term, &other.binary_limbs[0].term, false - )?; + let a = construct_equality_certificate(cs, &this.binary_limbs[0].term, &other.binary_limbs[0].term, false)?; let flag = !a.get_value().unwrap_or(E::Fr::zero()).is_zero(); let b = construct_equality_certificate(cs, &this.base_field_limb, &other.base_field_limb, flag)?; - + // construct first_gate: let mut lc = AmplifiedLinearCombination::zero(); lc.add_assign_product_of_terms(&a, &this.binary_limbs[0].term); @@ -1355,8 +1331,8 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { lc.add_assign_number_with_coeff(&tmp, E::Fr::one()); let num_gates = lc.enforce_zero(cs)?; assert_eq!(num_gates, 1); - - return Ok(()) + + return Ok(()); } // TODO: usage by reference here is much more better @@ -1374,10 +1350,10 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let mut out_0 = Boolean::zero(); let mut out_1 = Boolean::zero(); - + let arr = vec![ - (&this.binary_limbs[0].term, &other.binary_limbs[0].term, &mut out_0), - (&this.base_field_limb, &other.base_field_limb, &mut out_1) + (&this.binary_limbs[0].term, &other.binary_limbs[0].term, &mut out_0), + (&this.base_field_limb, &other.base_field_limb, &mut out_1), ]; for (a, b, out) in arr.into_iter() { let a = a.collapse_into_num(cs)?; @@ -1391,9 +1367,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } #[track_caller] - fn constraint_fma>( - cs: &mut CS, a: &Self, b: &Self, chain: FieldElementsChain<'a, E, F> - ) -> Result<(), SynthesisError> { + fn constraint_fma>(cs: &mut CS, a: &Self, b: &Self, chain: FieldElementsChain<'a, E, F>) -> Result<(), SynthesisError> { assert!(Self::check_params_equivalence(a, b)); assert!(chain.elems_to_add.iter().all(|x| Self::check_params_equivalence(a, x))); assert!(chain.elems_to_sub.iter().all(|x| Self::check_params_equivalence(a, x))); @@ -1405,14 +1379,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // and no positive elements // one of possible solutions would be to transform (*) into equaivalent representation: // a * b + /sum positive_chain_elements = /sum negative_chain_elements = sign_bit * q * p - // but this approach is expensive in terms of constrains as there will be additional multiplications - // of q by the sign (which would be an allocated bit) and we would pay additional multiplication gate for + // but this approach is expensive in terms of constrains as there will be additional multiplications + // of q by the sign (which would be an allocated bit) and we would pay additional multiplication gate for // EVERY limb of q - // we take another way, borrowing the approach taken in sub function: instead of simply subtracting + // we take another way, borrowing the approach taken in sub function: instead of simply subtracting // /sum negative_chain_elements = x we instead add (k * p - x) (**), where k - is constant, taken in such a way - // that the difference (**) is positive is for every value of x (that's one of the reasons, + // that the difference (**) is positive is for every value of x (that's one of the reasons, // we are tracking the maximal possible of FieldElement) - // this apporach reduces the problem of handling negative chain elements to ONE constant addition + // this apporach reduces the problem of handling negative chain elements to ONE constant addition // in constaint system. Nobody could deny that this price is neglectable! let mut raw_value = a.get_raw_value().zip(b.get_raw_value()).map(|(x, y)| x * y); @@ -1428,9 +1402,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } Self::subtraction_helper(max_val, limbs_max_vals, params) }; - let const_limbs : Vec<_> = const_delta_chunks.into_iter().map(|x| { - Limb::::constant_from_biguint(x) - }).collect(); + let const_limbs: Vec<_> = const_delta_chunks.into_iter().map(|x| Limb::::constant_from_biguint(x)).collect(); raw_value.as_mut().map(|x| *x += const_delta_value.clone()); raw_value = chain.add_raw_value_to_accumulator(raw_value); @@ -1439,11 +1411,11 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { assert!(r.is_zero()); q }); - - // so we constraint a * b + [chain_elems_to_add] = q * p + [chain_elems_to_sub] + + // so we constraint a * b + [chain_elems_to_add] = q * p + [chain_elems_to_sub] // we start ny estimating q width let mut lhs_max_value = a.get_maximal_possible_stored_value() * b.get_maximal_possible_stored_value(); - lhs_max_value += chain.get_maximal_positive_stored_value(); + lhs_max_value += chain.get_maximal_positive_stored_value(); lhs_max_value += const_delta_value.clone(); let q_max_value = lhs_max_value.clone() / ¶ms.represented_field_modulus; let q_max_bits = q_max_value.bits(); @@ -1451,25 +1423,23 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { // println!("alloc quotient with bitlen: {}", q_max_bits); let quotient = Self::alloc_for_known_bitwidth(cs, q, q_max_bits as usize, params, coarsely)?; - // next with finding the RNS binary modulus - we perform an exhaustive check here: + // next with finding the RNS binary modulus - we perform an exhaustive check here: // a * b + [chain_elems_to_add] < RNS composite_modulus = RNS_binary_modulus * RNS_native_modulus // q * p + [chain_elems_to_sub] < RNS composite_modulus let mut rhs_max_value = quotient.get_maximal_possible_stored_value() * ¶ms.represented_field_modulus; - rhs_max_value += chain.get_maximal_negative_stored_value(); + rhs_max_value += chain.get_maximal_negative_stored_value(); let max_value = BigUint::max(lhs_max_value, rhs_max_value); // now we need to select t - multiple of range check granularity to be large enough, so that: // max_value < 2^t * native_field_modulus let granularity = params.range_check_granularity; let mut rns_binary_modulus_width = round_up(params.represented_field_modulus_bitlength, granularity); - let mut dynamic_binary_modulus = BigUint::one() << rns_binary_modulus_width; + let mut dynamic_binary_modulus = BigUint::one() << rns_binary_modulus_width; while max_value >= dynamic_binary_modulus.clone() * params.native_field_modulus.clone() { rns_binary_modulus_width += granularity; - dynamic_binary_modulus <<= granularity; + dynamic_binary_modulus <<= granularity; } - let rns_binary_modulus_width_in_limbs = { - (rns_binary_modulus_width + params.binary_limb_width - 1) / params.binary_limb_width - }; + let rns_binary_modulus_width_in_limbs = { (rns_binary_modulus_width + params.binary_limb_width - 1) / params.binary_limb_width }; // find how many limbs we could process during single lc processing let limbs_per_cycle = { let max_btilen = params.native_field_modulus_bitlength; @@ -1490,14 +1460,14 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { two.double(); // final goal is to prove that a*b + \sum addition_elements = q * p + r - // we transform it into the following form for each limb : + // we transform it into the following form for each limb : // new_of * shift + /sum_{i+j = k} a[i] * b[j] + \sum addition_elements[k] - q[k] * p[k] - r[k] + old_shift // NB that all p[i] are constants, so in principle we have less multiplications - let mut left_border : usize = 0; + let mut left_border: usize = 0; let mut input_carry = Term::zero(); let p_limbs = Self::split_const_into_limbs(params.represented_field_modulus.clone(), params); let carry_width = params.binary_limb_width + MAX_INTERMIDIATE_OVERFLOW_WIDTH; - + while left_border < rns_binary_modulus_width_in_limbs { let mut lc = AmplifiedLinearCombination::zero(); lc.add_assign_term(&input_carry); @@ -1506,7 +1476,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { if cfg!(debug_assertions) { // we optimistically assume that all intermidiate overflows do not exceed special // apriori chosen constant - MAX_INTERMIDIATE_OVERFLOW_WIDTH - // however, we are a "validium" solution, so we are going to check that + // however, we are a "validium" solution, so we are going to check that // all overflows are indeed small enough let mut dbg_lhs_max_value = BigUint::zero(); let mut dbg_rhs_max_value = BigUint::zero(); @@ -1529,7 +1499,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { for (i, limb) in get_limbs_in_diapason(&const_limbs, left_border, right_border) { dbg_lhs_max_value += limb.max_value() * fe_to_biguint(&shifts[i - left_border]); } - + // add limbs of elements that are added: for elem in chain.elems_to_add.iter() { for (i, limb) in get_limbs_in_diapason(&elem.binary_limbs, left_border, right_border) { @@ -1556,7 +1526,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let allowed_bitlen = num_limbs * params.binary_limb_width + carry_width; assert!(dbg_max_value.bits() as usize <= allowed_bitlen); } - + // add terms like a[i] * b[j], where i+j /in [left_border, right_border) let iter = get_limbs_product_in_diapason(&a.binary_limbs, &b.binary_limbs, left_border, right_border); for (idx, a_limb, b_limb) in iter { @@ -1569,7 +1539,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let shift = shifts[i - left_border]; lc.add_assign_term_with_coeff(&limb.term, shift); } - + // add limbs of elements that are added: for elem in chain.elems_to_add.iter() { for (i, limb) in get_limbs_in_diapason(&elem.binary_limbs, left_border, right_border) { @@ -1601,7 +1571,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { lc.scale(&scale_coef); input_carry = Term::from_num(lc.into_num(cs)?); - // carry could be both positive and negative but in any case the bitwidth of it absolute value is + // carry could be both positive and negative but in any case the bitwidth of it absolute value is // [0, chunk_bitlen + MAX_INTERMIDIATE_OVERFLOW_WIDTH] // input_carry = +/- abs_carry * shift; let (abs_flag_wit, abs_wit) = match input_carry.get_value() { @@ -1614,15 +1584,15 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { tmp.negate(); (Some(false), Some(tmp)) } - }, - None => (None, None) + } + None => (None, None), }; - - let abs_flag = Term::from_boolean(&Boolean::Is(AllocatedBit::alloc(cs, abs_flag_wit)?)); + + let abs_flag = Term::from_boolean(&Boolean::Is(AllocatedBit::alloc(cs, abs_flag_wit)?)); let abs_carry = AllocatedNum::alloc(cs, || abs_wit.grab())?; constraint_bit_length_ext_with_strategy(cs, &abs_carry, carry_width, params.range_check_strategy, true)?; - let abs_carry = Term::from_num(Num::Variable(abs_carry)); - + let abs_carry = Term::from_num(Num::Variable(abs_carry)); + // we need to constraint: carry == (2 * abs_flag - 1) * abs_carry // 2 * abs_flag * abs_carry - carry - abs_carry == 0 let mut lc = AmplifiedLinearCombination::zero(); @@ -1633,7 +1603,7 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { left_border = right_border; } - + // now much more trivial part - multiply elements modulo base field // a * b + \sum positive_chain_terms - /sum negative_chain_terms - q * p == 0 (mod base_field) let residue_to_add = const_delta_value % ¶ms.native_field_modulus; @@ -1652,16 +1622,20 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { lc.enforce_zero(cs)?; Ok(()) - } + } - pub fn get_raw_limbs_representation(&self, cs: &mut CS) -> Result>, SynthesisError> - where CS: ConstraintSystem { + pub fn get_raw_limbs_representation(&self, cs: &mut CS) -> Result>, SynthesisError> + where + CS: ConstraintSystem, + { self.binary_limbs.iter().map(|x| x.term.collapse_into_num(cs)).collect::, SynthesisError>>() } #[track_caller] - pub fn decompose_into_binary_representation(&mut self, cs: &mut CS)-> Result, SynthesisError> - where CS: ConstraintSystem { + pub fn decompose_into_binary_representation(&mut self, cs: &mut CS) -> Result, SynthesisError> + where + CS: ConstraintSystem, + { let params = self.representation_params; self.reduce_loose(cs)?; @@ -1675,13 +1649,10 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { Ok(binary_decomposition) } - + // this fucction is used in elliptic curve by scalar multiplication #[track_caller] - pub fn decompose_into_skewed_representation>( - &mut self, cs: &mut CS - ) -> Result, SynthesisError> - { + pub fn decompose_into_skewed_representation>(&mut self, cs: &mut CS) -> Result, SynthesisError> { let params = self.representation_params; self.reduce_loose(cs)?; @@ -1689,19 +1660,17 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let reg_chunk_bitlen = params.binary_limb_width; let msl_chunk_bitlen = params.msl_width; let total_bitlen = params.represented_field_modulus_bitlength; - + let bit_values = compute_skewed_naf_representation(&self.get_raw_value(), total_bitlen); let mut bits = Vec::::with_capacity(bit_values.len()); let mut alloc_cnst_bit = false; for (idx, bit) in bit_values.into_iter().enumerate() { if idx % reg_chunk_bitlen == 0 { - alloc_cnst_bit = self.binary_limbs.get(idx / reg_chunk_bitlen).map(|chunk| { - chunk.is_constant() - }).unwrap_or(true); + alloc_cnst_bit = self.binary_limbs.get(idx / reg_chunk_bitlen).map(|chunk| chunk.is_constant()).unwrap_or(true); } - let elem = if alloc_cnst_bit { - Boolean::Constant(bit.unwrap()) + let elem = if alloc_cnst_bit { + Boolean::Constant(bit.unwrap()) } else { Boolean::from(AllocatedBit::alloc(cs, bit)?) }; @@ -1713,16 +1682,16 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let two = shifts[1].clone(); let mut minus_one = E::Fr::one(); minus_one.negate(); - let mut limb_shift_negated = shifts[reg_chunk_bitlen]; + let mut limb_shift_negated = shifts[reg_chunk_bitlen]; limb_shift_negated.negate(); - for (chunk_idx, chunk) in self.binary_limbs.iter().enumerate() { + for (chunk_idx, chunk) in self.binary_limbs.iter().enumerate() { let is_first = chunk_idx == 0; let is_last = chunk_idx == num_of_chunks - 1; let chunk_bitlen = if is_last { msl_chunk_bitlen } else { reg_chunk_bitlen }; let mut start_offset = chunk_idx * reg_chunk_bitlen; - let mut end_offset = (chunk_idx + 1) * chunk_bitlen; + let mut end_offset = (chunk_idx + 1) * chunk_bitlen; let mut reconstructed = Term::::zero(); if is_first { @@ -1761,11 +1730,11 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { let contribution = construct_skewed_bit_term::(&last, &two); reconstructed = reconstructed.add(cs, &contribution)?; } - + // y_ch_0 = x_ch_0 - 2^l // for every intermidiate chunk: y_ch_i = x_ch_i - 2^l + 1 // y_ch_l = x_ch_k + 1 - // this is equal to the following: + // this is equal to the following: // if not first_limb: y_ch += 1, if not last limb: y_ch -= 2^l if !is_first { let contribution = Term::from_constant(E::Fr::one()); @@ -1782,35 +1751,34 @@ impl<'a, E: Engine, F: PrimeField> FieldElement<'a, E, F> { } } - // if x = [x_0, x_1, ..., x_n] = /sum x_i 2^i - binary representation of x: x_i /in {0, 1} // then x = [y_-1, y_0, y_1, ..., y_n] - skewed naf representation: where y_i /in {0, 1} // x = -y_-1 + /sum_{i >= 1} (1 - 2* y_i) 2^i -// algorithm for construction of skewed representation: +// algorithm for construction of skewed representation: // for -1 <= y < n: y_i = ~x_{i+1} = 1 - x_{i+1} and y_n = 0 (always) // indeed: -// y = -y_-1 + /sum (1 - 2* y_i) 2^i = x_0 - 1 + /sum (2* x_{i+1} - 1) 2^i +2^n = +// y = -y_-1 + /sum (1 - 2* y_i) 2^i = x_0 - 1 + /sum (2* x_{i+1} - 1) 2^i +2^n = // = x - 1 - \sum_{i=0}^{n-1} 2^i + 2^n = x - 1 - (2^n - 1) + 2^n = x // if x is simultaneously split into chunks: x = [x_ch_0, x_ch_1, ..., x_ch_k] of length l -// then we split y = [y_-1, y_0, y_1, ..., y_n] into chunks of l bits length +// then we split y = [y_-1, y_0, y_1, ..., y_n] into chunks of l bits length // and we would have the following relations between corresponding chunks of x and y: // y_ch_0 = x_ch_0 - 2^l // for every intermidiate chunk (every chunk between least significant and most sigificant chunks): // y_ch_i = x_ch_i - 2^l + 1 // y_ch_l = x_ch_k + 1 -// in terms of cost in constraints computing skewed_wnaf is the same as computing traditional +// in terms of cost in constraints computing skewed_wnaf is the same as computing traditional // binary representation #[track_caller] fn compute_skewed_naf_representation(value: &Option, bit_limit: usize) -> Vec> { assert!(bit_limit > 0); if value.is_none() { - return vec![None; bit_limit+1]; + return vec![None; bit_limit + 1]; } let value = value.as_ref().unwrap(); - let mut bits = Vec::with_capacity(bit_limit+1); + let mut bits = Vec::with_capacity(bit_limit + 1); for i in 0..bit_limit as u64 { let b = value.bit(i); bits.push(Some(!b)); @@ -1829,20 +1797,19 @@ fn construct_skewed_bit_term(c: &Boolean, two: &E::Fr) -> Term { contribution } - #[cfg(test)] mod test { use super::*; - use crate::bellman::pairing::bn256::{Fq, Bn256, Fr}; - use plonk::circuit::Width4WithCustomGates; - use bellman::plonk::better_better_cs::gates::{selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext, self}; - use rand::{XorShiftRng, SeedableRng, Rng}; + use crate::bellman::pairing::bn256::{Bn256, Fq, Fr}; use bellman::plonk::better_better_cs::cs::*; + use bellman::plonk::better_better_cs::gates::{self, selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext}; + use plonk::circuit::Width4WithCustomGates; + use rand::{Rng, SeedableRng, XorShiftRng}; // the reason for this test is twofold: // first we would like to measure the efficiency of RNS-approach (in terms of number of resulting constraints), // and to do this we would compare the number of gates in RNS-mul against number of gates in naive approach - // second - implemeting modulus multiplication and reduction via schoolbook limbwise approach is a cool and + // second - implemeting modulus multiplication and reduction via schoolbook limbwise approach is a cool and // simple way to test our AmplifiedLinearCombination on a rather maningful example #[test] fn test_naive_modulus_multiplication() { @@ -1855,11 +1822,11 @@ mod test { let b_f: Fq = rng.gen(); let mut result_f = a_f; result_f.mul_assign(&b_f); - + let a = FieldElement::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); let b = FieldElement::alloc(&mut cs, Some(b_f), ¶ms).unwrap(); let mut actual_result = FieldElement::alloc(&mut cs, Some(result_f), ¶ms).unwrap(); - + let naive_mul_start = cs.get_current_step_number(); let total_bitlen = params.binary_limb_width * params.num_binary_limbs * 2; let carry_bitlen = params.binary_limb_width + params.range_check_granularity; @@ -1899,11 +1866,11 @@ mod test { let carry_shift_inverse = shifts[limbs_per_window].inverse().unwrap(); let mut input_carry = Term::zero(); - let mut left_border : usize = 0; + let mut left_border: usize = 0; let total_num_of_limbs = params.num_binary_limbs * 2; let mut two = Fr::one(); two.double(); - + while left_border < total_num_of_limbs { let mut lc = AmplifiedLinearCombination::zero(); lc.add_assign_term(&input_carry); @@ -1915,7 +1882,7 @@ mod test { let shift = shifts[idx - left_border]; lc.add_assign_product_of_terms_with_coeff(&a_limb.term, &b_limb.term, shift); } - + // sub limbs for q * p let iter = get_limbs_product_in_diapason(q_raw, &p_raw, left_border, right_border); for (idx, q_limb, p_limb) in iter { @@ -1938,7 +1905,7 @@ mod test { lc.scale(&carry_shift_inverse); input_carry = Term::from_num(lc.into_num(&mut cs).unwrap()); - // carry could be both positive and negative but in any case the bitwidth of it absolute value is + // carry could be both positive and negative but in any case the bitwidth of it absolute value is // [0, chunk_bitlen + MAX_INTERMIDIATE_OVERFLOW_WIDTH] // input_carry = +/- abs_carry * shift; let mut x = input_carry.get_value().unwrap(); @@ -1951,14 +1918,12 @@ mod test { (Some(false), Some(x)) } }; - - let abs_flag = Term::from_boolean(&Boolean::Is(AllocatedBit::alloc(&mut cs, abs_flag_wit).unwrap())); + + let abs_flag = Term::from_boolean(&Boolean::Is(AllocatedBit::alloc(&mut cs, abs_flag_wit).unwrap())); let abs_carry = AllocatedNum::alloc(&mut cs, || abs_wit.grab()).unwrap(); - constraint_bit_length_ext_with_strategy( - &mut cs, &abs_carry, carry_bitlen, params.range_check_strategy, true - ).unwrap(); - let abs_carry = Term::from_num(Num::Variable(abs_carry)); - + constraint_bit_length_ext_with_strategy(&mut cs, &abs_carry, carry_bitlen, params.range_check_strategy, true).unwrap(); + let abs_carry = Term::from_num(Num::Variable(abs_carry)); + // we need to constraint: carry == (2 * abs_flag - 1) * abs_carry // 2 * abs_flag * abs_carry - carry - abs_carry == 0 let mut lc = AmplifiedLinearCombination::zero(); @@ -1975,29 +1940,27 @@ mod test { let rns_mul_start = cs.get_current_step_number(); let mut result = a.mul(&mut cs, &b).unwrap(); let rns_mul_end = cs.get_current_step_number(); - + // check the correctness of rns multiplication FieldElement::enforce_equal(&mut cs, &mut actual_result, &mut result).unwrap(); - + assert!(cs.is_satisfied()); println!("number of constraints for naive approach: {}", naive_mul_end - naive_mul_start); println!("number of constraints for rns approach: {}", rns_mul_end - rns_mul_start); - } + } #[test] fn testing_remaining_stuff() { - struct TestCircuit{ - _marker: std::marker::PhantomData + struct TestCircuit { + _marker: std::marker::PhantomData, } - + impl Circuit for TestCircuit { type MainGate = SelectorOptimizedWidth4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ SelectorOptimizedWidth4MainGateWithDNext::default().into_internal() ] - ) + Ok(vec![SelectorOptimizedWidth4MainGateWithDNext::default().into_internal()]) } - + fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { let params = RnsParameters::::new_optimal(cs, 64usize); let mut rng = rand::thread_rng(); @@ -2009,8 +1972,8 @@ mod test { let elem_to_sub_0 = rng.gen(); let elem_to_sub_1 = rng.gen(); let mut actual_res = a; - actual_res.add_assign(&elem_to_add_0); - actual_res.add_assign(&elem_to_add_1); + actual_res.add_assign(&elem_to_add_0); + actual_res.add_assign(&elem_to_add_1); actual_res.sub_assign(&elem_to_sub_0); actual_res.sub_assign(&elem_to_sub_1); let b_inv = b.inverse().unwrap(); @@ -2034,29 +1997,29 @@ mod test { } use crate::bellman::kate_commitment::{Crs, CrsForMonomialForm}; - use crate::bellman::worker::Worker; - use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; use crate::bellman::plonk::better_better_cs::setup::VerificationKey; use crate::bellman::plonk::better_better_cs::verifier::verify; - + use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; + use crate::bellman::worker::Worker; + let mut cs = TrivialAssembly::::new(); inscribe_default_bitop_range_table(&mut cs).unwrap(); - let circuit = TestCircuit:: {_marker: std::marker::PhantomData}; + let circuit = TestCircuit:: { _marker: std::marker::PhantomData }; circuit.synthesize(&mut cs).expect("must work"); cs.finalize(); - assert!(cs.is_satisfied()); + assert!(cs.is_satisfied()); let worker = Worker::new(); let setup_size = cs.n().next_power_of_two(); let crs = Crs::::crs_42(setup_size, &worker); - let setup = cs.create_setup::>(&worker).unwrap(); + let setup = cs.create_setup::>(&worker).unwrap(); let vk = VerificationKey::from_setup(&setup, &worker, &crs).unwrap(); - + let mut cs = TrivialAssembly::::new(); inscribe_default_bitop_range_table(&mut cs).unwrap(); - let circuit = TestCircuit:: {_marker: std::marker::PhantomData}; + let circuit = TestCircuit:: { _marker: std::marker::PhantomData }; circuit.synthesize(&mut cs).expect("must work"); cs.finalize(); - assert!(cs.is_satisfied()); + assert!(cs.is_satisfied()); let proof = cs.create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs, None).unwrap(); let valid = verify::<_, _, RollingKeccakTranscript>(&vk, &proof, None).unwrap(); assert!(valid); @@ -2073,10 +2036,5 @@ mod test { let mut a = FieldElement::alloc(&mut cs, Some(a), ¶ms).unwrap(); a.normalize(&mut cs).unwrap(); assert!(cs.is_satisfied()); - } + } } - - - - - diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint_new/mod.rs b/crates/franklin-crypto/src/plonk/circuit/bigint_new/mod.rs index c1843f0..278b670 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint_new/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint_new/mod.rs @@ -1,48 +1,45 @@ use bellman::plonk::better_better_cs::cs::LookupTableApplication; +use super::allocated_num::*; +use super::boolean::*; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr, BitIterator}; -use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, ConstraintSystem, ArithmeticTerm, MainGateTerm, Width4MainGateWithDNext, MainGate, GateInternal, - Gate, LinearCombinationOfTerms, PolynomialMultiplicativeTerm, PolynomialInConstraint, TimeDilation, - Coefficient, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, TrivialAssembly + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; -use bellman::plonk::better_better_cs::data_structures::*; -use crate::plonk::circuit::Assignment; +use crate::bellman::SynthesisError; use crate::plonk::circuit::utils::u64_to_fe; -use super::allocated_num::*; -use super::boolean::*; +use crate::plonk::circuit::Assignment; +use bellman::plonk::better_better_cs::data_structures::*; use std::iter::FromIterator; use std::sync::Arc; pub mod bigint; pub mod range_check_custom_gate2; -pub mod range_checks; pub mod range_check_table2; +pub mod range_checks; pub use self::bigint::*; pub use self::range_check_custom_gate2::*; -pub use self::range_checks::*; pub use self::range_check_table2::*; +pub use self::range_checks::*; pub mod amplified_linear_combination; pub mod field; pub use self::amplified_linear_combination::*; pub use self::field::*; - pub const BITWISE_LOGICAL_OPS_TABLE_NAME: &'static str = "Table for bitwise logical ops"; pub const DEFAULT_RANGE_TABLE_GRANULARITY: usize = 8; - // splits an element into slices of fixed bit widths in LE order #[track_caller] pub fn split_into_slices(el: &F, slice_width: usize, num_slices: usize) -> Vec { let mut repr = el.into_repr(); assert!(repr.num_bits() as usize <= slice_width * num_slices); let mut slices = Vec::with_capacity(num_slices); - if slice_width < 64 { + if slice_width < 64 { let mask = (1u64 << slice_width) - 1u64; for _ in 0..num_slices { let slice = repr.as_ref()[0] & mask; @@ -55,8 +52,7 @@ pub fn split_into_slices(el: &F, slice_width: usize, num_slices: repr.shr(slice_width as u32); } - } - else { + } else { let it = repr.as_ref().iter().map(|x| u64_to_fe::(*x)).take(num_slices); slices.extend(it); }; @@ -65,11 +61,7 @@ pub fn split_into_slices(el: &F, slice_width: usize, num_slices: } #[track_caller] -pub fn split_some_into_slices( - el: Option, - slice_width: usize, - num_slices: usize -) -> Vec> { +pub fn split_some_into_slices(el: Option, slice_width: usize, num_slices: usize) -> Vec> { if let Some(v) = el.as_ref() { split_into_slices(v, slice_width, num_slices).into_iter().map(|el| Some(el)).collect() } else { @@ -77,12 +69,11 @@ pub fn split_some_into_slices( } } - #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum RangeConstraintStrategy { NaiveSingleBit, CustomTwoBitGate, - WithBitwiseOpTable(usize) // parameter here is the chunk width + WithBitwiseOpTable(usize), // parameter here is the chunk width } impl RangeConstraintStrategy { @@ -97,39 +88,35 @@ impl RangeConstraintStrategy { pub fn get_optimal_strategy>(cs: &CS) -> RangeConstraintStrategy { if let Ok(table) = cs.get_table(BITWISE_LOGICAL_OPS_TABLE_NAME) { - let width = crate::log2_floor(table.size())/2; + let width = crate::log2_floor(table.size()) / 2; return RangeConstraintStrategy::WithBitwiseOpTable(width as usize); - } + } if CS::Params::STATE_WIDTH == 4 && CS::Params::HAS_CUSTOM_GATES { - return RangeConstraintStrategy::CustomTwoBitGate + return RangeConstraintStrategy::CustomTwoBitGate; } RangeConstraintStrategy::NaiveSingleBit } -pub fn inscribe_default_bitop_range_table(cs: &mut CS) -> Result>, SynthesisError> -where E: Engine, CS: ConstraintSystem +pub fn inscribe_default_bitop_range_table(cs: &mut CS) -> Result>, SynthesisError> +where + E: Engine, + CS: ConstraintSystem, { use crate::plonk::circuit::hashes_with_tables::get_or_create_table; - let columns3 = vec![ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2) - ]; - - get_or_create_table( - cs, BITWISE_LOGICAL_OPS_TABLE_NAME, || { - LookupTableApplication::new( - BITWISE_LOGICAL_OPS_TABLE_NAME, CombinedBitwiseLogicRangeTable::new( - BITWISE_LOGICAL_OPS_TABLE_NAME, DEFAULT_RANGE_TABLE_GRANULARITY, - ), - columns3, None, true - ) - } - ) + let columns3 = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; + + get_or_create_table(cs, BITWISE_LOGICAL_OPS_TABLE_NAME, || { + LookupTableApplication::new( + BITWISE_LOGICAL_OPS_TABLE_NAME, + CombinedBitwiseLogicRangeTable::new(BITWISE_LOGICAL_OPS_TABLE_NAME, DEFAULT_RANGE_TABLE_GRANULARITY), + columns3, + None, + true, + ) + }) } - pub(crate) fn compute_shifts() -> Vec { let mut result = Vec::with_capacity(F::CAPACITY as usize); let mut el = F::one(); @@ -142,11 +129,8 @@ pub(crate) fn compute_shifts() -> Vec { result } - pub(crate) fn round_up(x: usize, granularity: usize) -> usize { let rem = x % granularity; let to_add = if rem == 0 { 0 } else { granularity - rem }; x + to_add } - - diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_check_custom_gate2.rs b/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_check_custom_gate2.rs index 590bb54..f34594f 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_check_custom_gate2.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_check_custom_gate2.rs @@ -1,19 +1,12 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::SynthesisError; -use crate::bellman::worker::Worker; use crate::bellman::plonk::better_better_cs::cs::*; -use crate::bellman::plonk::polynomials::*; use crate::bellman::plonk::fft::cooley_tukey_ntt::*; +use crate::bellman::plonk::polynomials::*; +use crate::bellman::worker::Worker; +use crate::bellman::SynthesisError; use crate::plonk::circuit::Assignment; @@ -37,7 +30,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { } fn all_queried_polynomials(&self) -> &'static [PolynomialInConstraint] { - const POLYS : [PolynomialInConstraint; 5] = [ + const POLYS: [PolynomialInConstraint; 5] = [ PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), @@ -53,7 +46,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { } fn variable_polynomials(&self) -> &'static [PolyIdentifier] { - const POLYS : [PolyIdentifier;4] = [ + const POLYS: [PolyIdentifier; 4] = [ PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2), @@ -85,7 +78,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { let b_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(1), row); let c_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(2), row); let d_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row); - let d_next_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row+1); + let d_next_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row + 1); let one = E::Fr::one(); let mut two = one; @@ -95,12 +88,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { let mut four = two; four.double(); - for (high, high_and_low) in [ - (d_value, c_value), - (c_value, b_value), - (b_value, a_value), - (a_value, d_next_value), - ].iter() { + for (high, high_and_low) in [(d_value, c_value), (c_value, b_value), (b_value, a_value), (a_value, d_next_value)].iter() { let mut shifted_high = *high; shifted_high.mul_assign(&four); @@ -108,7 +96,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { low.sub_assign(&shifted_high); let mut total = low; - + let mut tmp = low; tmp.sub_assign(&one); total.mul_assign(&tmp); @@ -130,14 +118,14 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { } fn contribute_into_quotient( - &self, + &self, domain_size: usize, poly_storage: &mut AssembledPolynomialStorage, - monomials_storage: & AssembledPolynomialStorageForMonomialForms, + monomials_storage: &AssembledPolynomialStorageForMonomialForms, challenges: &[E::Fr], omegas_bitreversed: &BitReversedOmegas, _omegas_inv_bitreversed: &OmegasInvBitreversed, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { assert!(domain_size.is_power_of_two()); assert_eq!(challenges.len(), >::num_quotient_terms(&self)); @@ -148,53 +136,27 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { assert!(poly_storage.is_bitreversed); let coset_factor = E::Fr::multiplicative_generator(); - + for &p in >::all_queried_polynomials(&self).into_iter() { - ensure_in_map_or_create(&worker, - p, - domain_size, - omegas_bitreversed, - lde_factor, - coset_factor, - monomials_storage, - poly_storage - )?; + ensure_in_map_or_create(&worker, p, domain_size, omegas_bitreversed, lde_factor, coset_factor, monomials_storage, poly_storage)?; } let ldes_storage = &*poly_storage; - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); let mut tmp = a_ref.clone(); // just allocate, we don't actually use it drop(a_ref); - let a_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ).as_ref(); + let a_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage).as_ref(); - let b_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), - ldes_storage - ).as_ref(); + let b_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), ldes_storage).as_ref(); - let c_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), - ldes_storage - ).as_ref(); + let c_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), ldes_storage).as_ref(); - let d_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), - ldes_storage - ).as_ref(); + let d_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), ldes_storage).as_ref(); - let d_next_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), - ldes_storage - ).as_ref(); + let d_next_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1), ldes_storage).as_ref(); let one = E::Fr::one(); let mut two = one; @@ -209,50 +171,43 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { // a - 4b \in [0, 4) // d_next - 4a \in [0, 4) - tmp.map_indexed(&worker, - |i, el| { - let a_value = a_raw_ref[i]; - let b_value = b_raw_ref[i]; - let c_value = c_raw_ref[i]; - let d_value = d_raw_ref[i]; - let d_next_value = d_next_raw_ref[i]; + tmp.map_indexed(&worker, |i, el| { + let a_value = a_raw_ref[i]; + let b_value = b_raw_ref[i]; + let c_value = c_raw_ref[i]; + let d_value = d_raw_ref[i]; + let d_next_value = d_next_raw_ref[i]; - let mut result = E::Fr::zero(); + let mut result = E::Fr::zero(); - for (contribution_idx, (high, high_and_low)) in [ - (d_value, c_value), - (c_value, b_value), - (b_value, a_value), - (a_value, d_next_value), - ].iter().enumerate() { - let mut shifted_high = *high; - shifted_high.mul_assign(&four); + for (contribution_idx, (high, high_and_low)) in [(d_value, c_value), (c_value, b_value), (b_value, a_value), (a_value, d_next_value)].iter().enumerate() { + let mut shifted_high = *high; + shifted_high.mul_assign(&four); - let mut low = *high_and_low; - low.sub_assign(&shifted_high); + let mut low = *high_and_low; + low.sub_assign(&shifted_high); - let mut total = low; - - let mut tmp = low; - tmp.sub_assign(&one); - total.mul_assign(&tmp); + let mut total = low; - let mut tmp = low; - tmp.sub_assign(&two); - total.mul_assign(&tmp); + let mut tmp = low; + tmp.sub_assign(&one); + total.mul_assign(&tmp); - let mut tmp = low; - tmp.sub_assign(&three); - total.mul_assign(&tmp); + let mut tmp = low; + tmp.sub_assign(&two); + total.mul_assign(&tmp); - total.mul_assign(&challenges[contribution_idx]); + let mut tmp = low; + tmp.sub_assign(&three); + total.mul_assign(&tmp); - result.add_assign(&total); - } + total.mul_assign(&challenges[contribution_idx]); - *el = result; - }, - ); + result.add_assign(&total); + } + + *el = result; + }); // { // let mut t = tmp.clone(); @@ -264,25 +219,25 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { // dbg!(values.as_ref()[i]); // } // } - + // } Ok(tmp) } fn contribute_into_linearization( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, - _monomials_storage: & AssembledPolynomialStorageForMonomialForms, + _monomials_storage: &AssembledPolynomialStorageForMonomialForms, _challenges: &[E::Fr], - _worker: &Worker + _worker: &Worker, ) -> Result, SynthesisError> { unreachable!("this gate does not contribute into linearization"); } fn contribute_into_verification_equation( - &self, + &self, _domain_size: usize, _at: E::Fr, queried_values: &std::collections::HashMap, @@ -290,17 +245,22 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { ) -> Result { assert_eq!(challenges.len(), >::num_quotient_terms(&self)); - let a_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) + let a_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) .ok_or(SynthesisError::AssignmentMissing)?; - let b_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) + let b_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) .ok_or(SynthesisError::AssignmentMissing)?; - let c_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) + let c_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) .ok_or(SynthesisError::AssignmentMissing)?; - let d_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) + let d_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) .ok_or(SynthesisError::AssignmentMissing)?; - let d_next_value = *queried_values.get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) + let d_next_value = *queried_values + .get(&PolynomialInConstraint::from_id_and_dilation(PolyIdentifier::VariablesPolynomial(3), 1)) .ok_or(SynthesisError::AssignmentMissing)?; - + let mut result = E::Fr::zero(); let one = E::Fr::one(); @@ -311,12 +271,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { let mut four = two; four.double(); - for (contribution_idx, (high, high_and_low)) in [ - (d_value, c_value), - (c_value, b_value), - (b_value, a_value), - (a_value, d_next_value), - ].iter().enumerate() { + for (contribution_idx, (high, high_and_low)) in [(d_value, c_value), (c_value, b_value), (b_value, a_value), (a_value, d_next_value)].iter().enumerate() { let mut shifted_high = *high; shifted_high.mul_assign(&four); @@ -324,7 +279,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { low.sub_assign(&shifted_high); let mut total = low; - + let mut tmp = low; tmp.sub_assign(&one); total.mul_assign(&tmp); @@ -350,7 +305,7 @@ impl GateInternal for TwoBitDecompositionRangecheckCustomGate { } fn contribute_into_linearization_commitment( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_check_table2.rs b/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_check_table2.rs index 065e20e..9d5834d 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_check_table2.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_check_table2.rs @@ -20,13 +20,12 @@ impl CombinedBitwiseLogicRangeTable { let mut values = Vec::with_capacity(table_len); let mut map = std::collections::HashMap::with_capacity(table_len); - for (x, y) in (0..var_range).cartesian_product(0..var_range) - { - let res_and = (x & y) as u64 ; + for (x, y) in (0..var_range).cartesian_product(0..var_range) { + let res_and = (x & y) as u64; let res_or = (x | y) as u64; let res_xor = (x ^ y) as u64; let z = res_and + (res_or << 16) + (res_xor << 32); - + let x = u64_to_fe(x as u64); let y = u64_to_fe(y as u64); let z = u64_to_fe(z as u64); @@ -48,9 +47,7 @@ impl CombinedBitwiseLogicRangeTable { impl std::fmt::Debug for CombinedBitwiseLogicRangeTable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("CombinedBitwiseLogicRangeTable") - .field("bits", &self.bits) - .finish() + f.debug_struct("CombinedBitwiseLogicRangeTable").field("bits", &self.bits).finish() } } @@ -101,7 +98,7 @@ impl LookupTableInternal for CombinedBitwiseLogicRangeTable { assert!(keys.len() == self.num_keys()); if let Some(entry) = self.table_lookup_map.get(&(keys[0], keys[1])) { - return Ok(vec![*entry]) + return Ok(vec![*entry]); } Err(SynthesisError::Unsatisfiable) diff --git a/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_checks.rs b/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_checks.rs index 99d28ec..c2cd2c9 100644 --- a/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_checks.rs +++ b/crates/franklin-crypto/src/plonk/circuit/bigint_new/range_checks.rs @@ -1,15 +1,14 @@ use super::*; -use std::iter; -use std::sync::Arc; -use std::sync::atomic::{AtomicUsize, Ordering}; -use crate::plonk::circuit::linear_combination::*; -use crate::plonk::circuit::SomeArithmetizable; +use crate::bellman::plonk::better_better_cs::lookup_tables::LookupTableApplication; use crate::plonk::circuit::assignment::Assignment; use crate::plonk::circuit::hashes_with_tables::utils::IdentifyFirstLast; -use crate::bellman::plonk::better_better_cs::lookup_tables::LookupTableApplication; +use crate::plonk::circuit::linear_combination::*; +use crate::plonk::circuit::SomeArithmetizable; use num_bigint::BigUint; use num_traits::Zero; - +use std::iter; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; pub static NUM_RANGE_CHECK_INVOCATIONS: AtomicUsize = AtomicUsize::new(0); // shorts range checks are range checks that occupy a single gate @@ -39,21 +38,19 @@ pub fn print_stats() { let short_checks = NUM_SHORT_RANGE_CHECK_INVOCATIONS.load(Ordering::Relaxed); let total_gates = NUM_GATES_SPENT_ON_RANGE_CHECKS.load(Ordering::Relaxed); println!( - "Has made in total of {} range checks, with {} being short (singe gate) and {} gates in total", + "Has made in total of {} range checks, with {} being short (singe gate) and {} gates in total", total_checks, short_checks, total_gates ); } - pub enum DecompositionType { BitDecomposition(Vec), ChunkDecomposition(Vec>), } -pub struct RangeCheckDecomposition -{ +pub struct RangeCheckDecomposition { chunks_bitlength: usize, - decomposition: DecompositionType + decomposition: DecompositionType, } impl RangeCheckDecomposition { @@ -64,34 +61,32 @@ impl RangeCheckDecomposition { pub fn get_num_chunks(&self) -> usize { match &self.decomposition { DecompositionType::BitDecomposition(x) => x.len(), - DecompositionType::ChunkDecomposition(x) => x.len() + DecompositionType::ChunkDecomposition(x) => x.len(), } } pub fn is_bit_decomposition(&self) -> bool { match &self.decomposition { DecompositionType::BitDecomposition(_) => true, - DecompositionType::ChunkDecomposition(_) => false + DecompositionType::ChunkDecomposition(_) => false, } } pub fn get_total_value(&self) -> Option { - let (values, chunk_size) : (Vec>, usize) = match &self.decomposition { + let (values, chunk_size): (Vec>, usize) = match &self.decomposition { DecompositionType::BitDecomposition(_) => { - let elems: Vec> = self.get_bits().iter().map(|x| { - x.get_value_as_field_element::() - }).collect(); + let elems: Vec> = self.get_bits().iter().map(|x| x.get_value_as_field_element::()).collect(); (elems, 1) - }, + } DecompositionType::ChunkDecomposition(_) => { - let elems: Vec> = self.get_vars().iter().map(|x| { x.get_value() }).collect(); + let elems: Vec> = self.get_vars().iter().map(|x| x.get_value()).collect(); (elems, self.chunks_bitlength) } }; if values.iter().any(|x| x.is_none()) { return None; }; - + let mut result = BigUint::zero(); for elem in values.into_iter().rev() { result <<= chunk_size; @@ -101,11 +96,19 @@ impl RangeCheckDecomposition { } pub fn get_bits(&self) -> &Vec { - if let DecompositionType::BitDecomposition(ref x) = self.decomposition { &x } else { unreachable!(); } + if let DecompositionType::BitDecomposition(ref x) = self.decomposition { + &x + } else { + unreachable!(); + } } pub fn get_vars(&self) -> &Vec> { - if let DecompositionType::ChunkDecomposition(ref x) = self.decomposition { &x } else { unreachable!(); } + if let DecompositionType::ChunkDecomposition(ref x) = self.decomposition { + &x + } else { + unreachable!(); + } } pub fn combine(separate_decompositions: &[Self]) -> Self { @@ -116,50 +119,56 @@ impl RangeCheckDecomposition { &DecompositionType::BitDecomposition(_) => { let all_bits = separate_decompositions.iter().map(|x| x.get_bits()).flatten().cloned().collect(); DecompositionType::BitDecomposition(all_bits) - }, + } &DecompositionType::ChunkDecomposition(_) => { let all_vars = separate_decompositions.iter().map(|x| x.get_vars()).flatten().cloned().collect(); DecompositionType::ChunkDecomposition(all_vars) } - }; + }; - RangeCheckDecomposition:: - { + RangeCheckDecomposition:: { chunks_bitlength: separate_decompositions[0].chunks_bitlength, - decomposition: total_decomposition + decomposition: total_decomposition, } } } - // if coarsely flag is set that we constraint bit length up to range check granularity pub fn constraint_bit_length_ext_with_strategy>( - cs: &mut CS, var: &AllocatedNum, num_bits: usize, strategy: RangeConstraintStrategy, coarsely: bool + cs: &mut CS, + var: &AllocatedNum, + num_bits: usize, + strategy: RangeConstraintStrategy, + coarsely: bool, ) -> Result, SynthesisError> { match strategy { - RangeConstraintStrategy::NaiveSingleBit => { - enforce_range_check_using_naive_approach(cs, var, num_bits) - }, + RangeConstraintStrategy::NaiveSingleBit => enforce_range_check_using_naive_approach(cs, var, num_bits), RangeConstraintStrategy::CustomTwoBitGate => { unreachable!(); enforce_range_check_using_custom_gate(cs, var, num_bits, coarsely) - }, - RangeConstraintStrategy::WithBitwiseOpTable(_table_width) => { - let table = cs.get_table(BITWISE_LOGICAL_OPS_TABLE_NAME).expect("should found a valid table"); + } + RangeConstraintStrategy::WithBitwiseOpTable(_table_width) => { + let table = cs.get_table(BITWISE_LOGICAL_OPS_TABLE_NAME).expect("should found a valid table"); enforce_range_check_using_bitop_table(cs, var, num_bits, table, coarsely) - } + } } } pub fn constraint_bit_length_with_strategy>( - cs: &mut CS, var: &AllocatedNum, num_bits: usize, range_check_strategy: RangeConstraintStrategy + cs: &mut CS, + var: &AllocatedNum, + num_bits: usize, + range_check_strategy: RangeConstraintStrategy, ) -> Result<(), SynthesisError> { let _decomposition = constraint_bit_length_ext_with_strategy(cs, var, num_bits, range_check_strategy, false)?; Ok(()) } pub fn coarsely_constraint_bit_length_with_strategy>( - cs: &mut CS, var: &AllocatedNum, num_bits: usize, range_check_strategy: RangeConstraintStrategy + cs: &mut CS, + var: &AllocatedNum, + num_bits: usize, + range_check_strategy: RangeConstraintStrategy, ) -> Result<(), SynthesisError> { let _decomposition = constraint_bit_length_ext_with_strategy(cs, var, num_bits, range_check_strategy, true)?; Ok(()) @@ -167,48 +176,38 @@ pub fn coarsely_constraint_bit_length_with_strategy>( - cs: &mut CS, var: &AllocatedNum, num_bits: usize -) -> Result, SynthesisError> { +pub fn constraint_bit_length_ext>(cs: &mut CS, var: &AllocatedNum, num_bits: usize) -> Result, SynthesisError> { let range_check_strategy = get_optimal_strategy(cs); constraint_bit_length_ext_with_strategy(cs, var, num_bits, range_check_strategy, false) } -pub fn constraint_bit_length>( - cs: &mut CS, var: &AllocatedNum, num_bits: usize -) -> Result<(), SynthesisError> { +pub fn constraint_bit_length>(cs: &mut CS, var: &AllocatedNum, num_bits: usize) -> Result<(), SynthesisError> { let _decomposition = constraint_bit_length_ext(cs, var, num_bits)?; Ok(()) } - -pub fn allocate_gate_with_linear_only_terms_in_reversed_order>( - cs: &mut CS, vars: &[Variable], coefs: &[E::Fr], d_next_coef: &E::Fr -) -> Result<(), SynthesisError> { +pub fn allocate_gate_with_linear_only_terms_in_reversed_order>(cs: &mut CS, vars: &[Variable], coefs: &[E::Fr], d_next_coef: &E::Fr) -> Result<(), SynthesisError> { let dummy = CS::get_dummy_variable(); let range_of_linear_terms = CS::MainGate::range_of_linear_terms(); let next_row_term_idx = CS::MainGate::range_of_next_step_linear_terms().last().unwrap(); - + let gate_term = MainGateTerm::new(); let (_, mut local_coeffs) = CS::MainGate::format_term(gate_term, dummy)?; for (pos, coef) in range_of_linear_terms.zip(coefs.iter().rev()) { local_coeffs[pos] = coef.clone(); - } + } local_coeffs[next_row_term_idx] = d_next_coef.clone(); let mg = CS::MainGate::default(); - let local_vars : Vec = vars.iter().rev().cloned().collect(); + let local_vars: Vec = vars.iter().rev().cloned().collect(); cs.new_single_gate_for_trace_step(&mg, &local_coeffs, &local_vars, &[]) } - // enforce that bitlength(var * shift) <= num_bits using naive approach which is the following: // we decompose var * shift into single bits [f0, f1, ..., fn], for each f_i we enforce that f_i is actually a bit // by f_i * (f_i - 1) == 0 // and then construct the long linear combination: var = \sum 2^i * f_i -pub fn enforce_range_check_using_naive_approach>( - cs: &mut CS, var: &AllocatedNum, num_bits: usize -) -> Result, SynthesisError> { +pub fn enforce_range_check_using_naive_approach>(cs: &mut CS, var: &AllocatedNum, num_bits: usize) -> Result, SynthesisError> { increment_invocation_count(); // count all constraints of the form f * (f - 1) == 0 increment_total_gates_count(num_bits); @@ -217,27 +216,30 @@ pub fn enforce_range_check_using_naive_approach 6, then the first gate will be of the form: // f0 + 2*f1 + 4*f2 + 8*f3 = d_next - and hence contain 4 variables - // the last gate will be of the form: + // the last gate will be of the form: // d_last + 2^(n-1)*f_(n-1) +2^n * f_n = var and hence containt 2 variables f_i - // all intermediate gates will be of the form: + // all intermediate gates will be of the form: // 2^i f_i + 2^(i+1) f_(i+1) + 2^(i+2) f_(i+2) + d_cur = d_next and hence containt 3 variables f_i // hence the total number of gates in linear combination will be: 2 + x, where x is the smallest integer, // such that 3 * x + 6 >= num_bits => x = ceil(num_bits / 3) - 2 - let lc_gates : usize = match num_bits { + let lc_gates: usize = match num_bits { 1..=3 => 1, 4..=6 => 2, - _ => (num_bits + 2) / 3 - 2, + _ => (num_bits + 2) / 3 - 2, }; increment_total_gates_count(lc_gates); let has_value = var.get_value().is_some(); let value = var.get_value().unwrap_or(E::Fr::zero()); - - let bits : Vec = BitIterator::new(value.into_repr()).take(num_bits).collect(); - let allocated_bits : Vec = bits.into_iter().map(|bit| { - let t = if has_value { Some(bit) } else { None }; - AllocatedBit::alloc(cs, t) - }).collect::, SynthesisError>>()?; + + let bits: Vec = BitIterator::new(value.into_repr()).take(num_bits).collect(); + let allocated_bits: Vec = bits + .into_iter() + .map(|bit| { + let t = if has_value { Some(bit) } else { None }; + AllocatedBit::alloc(cs, t) + }) + .collect::, SynthesisError>>()?; let mut minus_one = E::Fr::one(); minus_one.negate(); @@ -250,8 +252,7 @@ pub fn enforce_range_check_using_naive_approach = (0..slice_len+1).scan(coef.clone(), |st, _| { - let res = st.clone(); st.double(); Some(res) - }).collect(); + let mut coefs: Vec = (0..slice_len + 1) + .scan(coef.clone(), |st, _| { + let res = st.clone(); + st.double(); + Some(res) + }) + .collect(); coef = coefs.pop().unwrap(); - let (mut vars, mut vals): (Vec<_>, Vec>) = allocated_bits[idx..idx + slice_len].iter().map(|x| { - (x.get_variable(), x.get_value_as_field_element::()) - }).unzip(); + let (mut vars, mut vals): (Vec<_>, Vec>) = allocated_bits[idx..idx + slice_len].iter().map(|x| (x.get_variable(), x.get_value_as_field_element::())).unzip(); assert_eq!(coefs.len(), vars.len()); while coefs.len() <= CS::Params::STATE_WIDTH - 2 { if total_is_added { - coefs.push(E::Fr::zero()); - vars.push(CS::get_dummy_variable()); + coefs.push(E::Fr::zero()); + vars.push(CS::get_dummy_variable()); vals.push(Some(E::Fr::zero())); - } - else { + } else { total_is_added = true; coefs.push(minus_one.clone()); vars.push(var.get_variable()); @@ -292,11 +294,10 @@ pub fn enforce_range_check_using_naive_approach(el: &F, slice_width: usize, num_slices: usize) -> Vec { // gate accumulates values a bit differently: each time it shift previous slice by X bits // and adds a new chunk into lowest bits, and then constraints the difference @@ -347,13 +347,14 @@ fn split_into_bit_constraint_slices(el: &F, slice_width: usize, n slices } - // enforce bitlength(var * shift) <= num_bits via custom gate of the form: // { d_next - 4a /in [0, 3], a - 4b /in [0, 3], b - 4c /in [0, 3], c - 4d /in [0, 3] pub fn enforce_range_check_using_custom_gate>( - cs: &mut CS, var: &AllocatedNum, num_bits: usize, _coarsely: bool -) -> Result, SynthesisError> -{ + cs: &mut CS, + var: &AllocatedNum, + num_bits: usize, + _coarsely: bool, +) -> Result, SynthesisError> { assert!(num_bits > 0); // TODO: there should be additional logic for num_bits &1 != 0 // for now every such allocation is automatically coarse on 2 bit granularity @@ -365,8 +366,11 @@ pub fn enforce_range_check_using_custom_gate> if let Some(v) = var.get_value() { let t = self::bigint::fe_to_biguint(&v); assert!( - t.bits() as usize <= num_bits, "value is {} that is {} bits, while expected {} bits", - t.to_str_radix(16), t.bits(), num_bits + t.bits() as usize <= num_bits, + "value is {} that is {} bits, while expected {} bits", + t.to_str_radix(16), + t.bits(), + num_bits ); } let num_elements = num_bits / 2; @@ -382,13 +386,10 @@ pub fn enforce_range_check_using_custom_gate> assert_eq!(last_val, v); } } - + let mut result = vec![]; for v in slices.into_iter() { - let a = AllocatedNum::alloc(cs, || { - Ok(*v.get()?) - } - )?; + let a = AllocatedNum::alloc(cs, || Ok(*v.get()?))?; result.push(a); } // last element is actually an element we want to constraint @@ -415,7 +416,7 @@ pub fn enforce_range_check_using_custom_gate> previous_value = new_value; } assert_eq!(raw_variables.len() % CS::Params::STATE_WIDTH, 1, "variables len = {}", raw_variables.len()); - + let mut rows = raw_variables.chunks_exact(CS::Params::STATE_WIDTH); let gate = TwoBitDecompositionRangecheckCustomGate::default(); @@ -435,31 +436,36 @@ pub fn enforce_range_check_using_custom_gate> *variables.last_mut().unwrap() = last; cs.new_single_gate_for_trace_step(&CS::MainGate::default(), &coeffs, &variables, &[])?; - increment_total_gates_count(num_gates+1); + increment_total_gates_count(num_gates + 1); Ok(RangeCheckDecomposition { chunks_bitlength: 2, decomposition: DecompositionType::ChunkDecomposition(result), }) } - pub fn apply_range_table_gate>( - cs: &mut CS, a: &AllocatedNum, b: &AllocatedNum, acc: &AllocatedNum, - shift_a: &E::Fr, shift_b: &E::Fr, shift_acc: &E::Fr, shift_d_next: &E::Fr, - table: Arc>, is_final: bool -) -> Result, SynthesisError> -{ + cs: &mut CS, + a: &AllocatedNum, + b: &AllocatedNum, + acc: &AllocatedNum, + shift_a: &E::Fr, + shift_b: &E::Fr, + shift_acc: &E::Fr, + shift_d_next: &E::Fr, + table: Arc>, + is_final: bool, +) -> Result, SynthesisError> { let a_xor_b = match (a.get_value(), b.get_value()) { (Some(a_val), Some(b_val)) => { let res = table.query(&[a_val, b_val])?; AllocatedNum::alloc(cs, || Ok(res[0]))? - }, - (_, _) => AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))? + } + (_, _) => AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?, }; let new_acc = if !is_final { AllocatedNum::alloc(cs, || { - let mut res = acc.get_value().grab()?; + let mut res = acc.get_value().grab()?; let mut tmp = a.get_value().grab()?; tmp.mul_assign(&shift_a); res.sub_assign(&tmp); @@ -470,8 +476,7 @@ pub fn apply_range_table_gate>( res.mul_assign(&div_inv); Ok(res) })? - } - else { + } else { AllocatedNum::zero(cs) }; @@ -508,26 +513,28 @@ pub fn apply_range_table_gate>( Ok(new_acc) } - pub fn enforce_range_check_using_bitop_table>( - cs: &mut CS, var: &AllocatedNum, num_bits: usize, table: Arc>, coarsely: bool -) -> Result, SynthesisError> -{ + cs: &mut CS, + var: &AllocatedNum, + num_bits: usize, + table: Arc>, + coarsely: bool, +) -> Result, SynthesisError> { let chunk_width = (crate::log2_floor(table.size()) / 2) as usize; let num_chunks = (num_bits + chunk_width - 1) / chunk_width; let should_enforce_for_shifted_chunk = (num_bits % chunk_width) != 0 && !coarsely; increment_invocation_count(); - if (num_chunks == 1 && should_enforce_for_shifted_chunk) || (num_chunks <= 2 && !should_enforce_for_shifted_chunk) - { + if (num_chunks == 1 && should_enforce_for_shifted_chunk) || (num_chunks <= 2 && !should_enforce_for_shifted_chunk) { increment_short_checks_count(); } - increment_total_gates_count((num_chunks + 1 + should_enforce_for_shifted_chunk as usize)/2); - - let value = var.get_value().map(|x| { fe_to_biguint(&x) }); - let chunks = split_some_into_fixed_number_of_limbs(value, chunk_width, num_chunks).into_iter().map(|x| { - AllocatedNum::alloc(cs, || some_biguint_to_fe::(&x).grab()) - }).collect::>, SynthesisError>>()?; + increment_total_gates_count((num_chunks + 1 + should_enforce_for_shifted_chunk as usize) / 2); + + let value = var.get_value().map(|x| fe_to_biguint(&x)); + let chunks = split_some_into_fixed_number_of_limbs(value, chunk_width, num_chunks) + .into_iter() + .map(|x| AllocatedNum::alloc(cs, || some_biguint_to_fe::(&x).grab())) + .collect::>, SynthesisError>>()?; let dummy = AllocatedNum::zero(cs); let shifts = compute_shifts::(); @@ -541,12 +548,12 @@ pub fn enforce_range_check_using_bitop_table> let is_even_num_of_chunks = chunks.len() % 2 == 0; let last_chunk = chunks.last().unwrap().clone(); let iter = chunks.chunks_exact(2); - + for (_is_first, mut is_final, pair) in iter.identify_first_last() { // a + b * shift = acc - acc_next * shift^2; // a + b * shift - acc + acc_next * shift^2; let (a, b) = (&pair[0], &pair[1]); - is_final &= is_even_num_of_chunks; + is_final &= is_even_num_of_chunks; acc = apply_range_table_gate(cs, a, b, &acc, &shift_a, &shift_b, &minus_one.clone(), &shift_d_next, table.clone(), is_final)?; } @@ -562,15 +569,14 @@ pub fn enforce_range_check_using_bitop_table> res.mul_assign(&shift); Ok(res) })? - } - else { + } else { dummy.clone() }; - + let shift_a = if should_enforce_for_shifted_chunk { shift } else { E::Fr::zero() }; let shift_b = if should_enforce_for_shifted_chunk { minus_one.clone() } else { E::Fr::zero() }; apply_range_table_gate(cs, &a, &b, &a, &shift_a, &shift_b, &E::Fr::zero(), &E::Fr::zero(), table.clone(), true)?; - } + } Ok(RangeCheckDecomposition { chunks_bitlength: chunk_width, @@ -578,7 +584,6 @@ pub fn enforce_range_check_using_bitop_table> }) } - #[cfg(test)] mod test { use super::*; @@ -587,9 +592,9 @@ mod test { fn check_two_bit_gate() { use crate::bellman::pairing::bn256::{Bn256, Fr}; use crate::bellman::plonk::better_better_cs::cs::*; + use crate::plonk::circuit::allocated_num::*; use crate::plonk::circuit::bigint_new::*; use crate::plonk::circuit::linear_combination::*; - use crate::plonk::circuit::allocated_num::*; struct Tester; @@ -597,21 +602,11 @@ mod test { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Self::MainGate::default().into_internal(), - TwoBitDecompositionRangecheckCustomGate::default().into_internal(), - ] - ) + Ok(vec![Self::MainGate::default().into_internal(), TwoBitDecompositionRangecheckCustomGate::default().into_internal()]) } fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let variables: Vec<_> = (0..5).map(|_| AllocatedNum::alloc( - cs, - || { - Ok(Fr::one()) - } - ).unwrap()).collect(); - + let variables: Vec<_> = (0..5).map(|_| AllocatedNum::alloc(cs, || Ok(Fr::one())).unwrap()).collect(); + let mut lc = LinearCombination::::zero(); lc.add_assign_constant(Fr::one()); let mut current = Fr::one(); @@ -619,16 +614,11 @@ mod test { lc.add_assign_variable_with_coeff(v, current); current.double(); } - + let _result = lc.into_allocated_num(cs).unwrap(); - - let num = AllocatedNum::alloc( - cs, - || { - Ok(Fr::from_str("40000").unwrap()) - } - ).unwrap(); - + + let num = AllocatedNum::alloc(cs, || Ok(Fr::from_str("40000").unwrap())).unwrap(); + let _ = enforce_range_check_using_custom_gate(cs, &num, 18, false)?; Ok(()) @@ -653,33 +643,27 @@ mod test { let setup = assembly.create_setup::(&worker).unwrap(); use crate::bellman::kate_commitment::*; - use crate::bellman::plonk::commitments::transcript::{*, keccak_transcript::RollingKeccakTranscript}; + use crate::bellman::plonk::commitments::transcript::{keccak_transcript::RollingKeccakTranscript, *}; - let crs_mons = - Crs::::crs_42(setup.gate_selectors_monomials[0].size(), &worker); + let crs_mons = Crs::::crs_42(setup.gate_selectors_monomials[0].size(), &worker); - let _proof = assembly.create_proof::<_, RollingKeccakTranscript>( - &worker, - &setup, - &crs_mons, - None - ).unwrap(); + let _proof = assembly.create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs_mons, None).unwrap(); } #[cfg(test)] -mod test { - use super::*; - use crate::bellman::pairing::bn256::{Fq, Bn256, Fr}; - use plonk::circuit::Width4WithCustomGates; - - #[test] - fn test_unalligned_range_check_via_table() { - let mut cs = TrivialAssembly::::new(); - inscribe_default_bitop_range_table(&mut cs).unwrap(); - let var = AllocatedNum::alloc(&mut cs, || Ok(u64_to_fe::(0b1111111))).unwrap(); - constraint_bit_length(&mut cs, &var, 8).unwrap(); - - assert!(cs.is_satisfied()); + mod test { + use super::*; + use crate::bellman::pairing::bn256::{Bn256, Fq, Fr}; + use plonk::circuit::Width4WithCustomGates; + + #[test] + fn test_unalligned_range_check_via_table() { + let mut cs = TrivialAssembly::::new(); + inscribe_default_bitop_range_table(&mut cs).unwrap(); + let var = AllocatedNum::alloc(&mut cs, || Ok(u64_to_fe::(0b1111111))).unwrap(); + constraint_bit_length(&mut cs, &var, 8).unwrap(); + + assert!(cs.is_satisfied()); + } } } -} \ No newline at end of file diff --git a/crates/franklin-crypto/src/plonk/circuit/blake2s.rs b/crates/franklin-crypto/src/plonk/circuit/blake2s.rs index 58b04c9..e5297b9 100644 --- a/crates/franklin-crypto/src/plonk/circuit/blake2s.rs +++ b/crates/franklin-crypto/src/plonk/circuit/blake2s.rs @@ -1,49 +1,21 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, Variable, Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, }; - use crate::plonk::circuit::Assignment; -use super::allocated_num::{ - AllocatedNum -}; +use super::allocated_num::AllocatedNum; -use super::linear_combination::{ - LinearCombination -}; +use super::linear_combination::LinearCombination; -use super::boolean::{ - AllocatedBit, - Boolean -}; +use super::boolean::{AllocatedBit, Boolean}; use super::multieq::MultiEq; use super::uint32::UInt32; @@ -96,7 +68,7 @@ const SIGMA: [[usize; 16]; 10] = [ [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], - [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0] + [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], ]; /* @@ -121,17 +93,7 @@ const SIGMA: [[usize; 16]; 10] = [ END FUNCTION. */ -fn mixing_g>( - cs: &mut CS, - v: &mut [UInt32], - a: usize, - b: usize, - c: usize, - d: usize, - x: &UInt32, - y: &UInt32 -) -> Result<(), SynthesisError> -{ +fn mixing_g>(cs: &mut CS, v: &mut [UInt32], a: usize, b: usize, c: usize, d: usize, x: &UInt32, y: &UInt32) -> Result<(), SynthesisError> { v[a] = UInt32::addmany(cs, &[v[a].clone(), v[b].clone(), x.clone()])?; v[d] = v[d].xor(cs, &v[a])?.rotr(R1); v[c] = UInt32::addmany(cs, &[v[c].clone(), v[d].clone()])?; @@ -192,15 +154,7 @@ fn mixing_g>( END FUNCTION. */ - -fn blake2s_compression>( - cs: &mut CS, - h: &mut [UInt32], - m: &[UInt32], - t: u64, - f: bool -) -> Result<(), SynthesisError> -{ +fn blake2s_compression>(cs: &mut CS, h: &mut [UInt32], m: &[UInt32], t: u64, f: bool) -> Result<(), SynthesisError> { assert_eq!(h.len(), 8); assert_eq!(m.len(), 16); @@ -240,15 +194,15 @@ fn blake2s_compression>( let s = SIGMA[i % 10]; - mixing_g(cs, &mut v, 0, 4, 8, 12, &m[s[ 0]], &m[s[ 1]])?; - mixing_g(cs, &mut v, 1, 5, 9, 13, &m[s[ 2]], &m[s[ 3]])?; - mixing_g(cs, &mut v, 2, 6, 10, 14, &m[s[ 4]], &m[s[ 5]])?; - mixing_g(cs, &mut v, 3, 7, 11, 15, &m[s[ 6]], &m[s[ 7]])?; + mixing_g(cs, &mut v, 0, 4, 8, 12, &m[s[0]], &m[s[1]])?; + mixing_g(cs, &mut v, 1, 5, 9, 13, &m[s[2]], &m[s[3]])?; + mixing_g(cs, &mut v, 2, 6, 10, 14, &m[s[4]], &m[s[5]])?; + mixing_g(cs, &mut v, 3, 7, 11, 15, &m[s[6]], &m[s[7]])?; - mixing_g(cs, &mut v, 0, 5, 10, 15, &m[s[ 8]], &m[s[ 9]])?; + mixing_g(cs, &mut v, 0, 5, 10, 15, &m[s[8]], &m[s[9]])?; mixing_g(cs, &mut v, 1, 6, 11, 12, &m[s[10]], &m[s[11]])?; - mixing_g(cs, &mut v, 2, 7, 8, 13, &m[s[12]], &m[s[13]])?; - mixing_g(cs, &mut v, 3, 4, 9, 14, &m[s[14]], &m[s[15]])?; + mixing_g(cs, &mut v, 2, 7, 8, 13, &m[s[12]], &m[s[13]])?; + mixing_g(cs, &mut v, 3, 4, 9, 14, &m[s[14]], &m[s[15]])?; } } @@ -287,12 +241,7 @@ fn blake2s_compression>( END FUNCTION. */ -pub fn blake2s>( - cs: &mut CS, - input: &[Boolean], - personalization: &[u8] -) -> Result, SynthesisError> -{ +pub fn blake2s>(cs: &mut CS, input: &[Boolean], personalization: &[u8]) -> Result, SynthesisError> { use byteorder::{ByteOrder, LittleEndian}; assert_eq!(personalization.len(), 8); @@ -345,7 +294,7 @@ pub fn blake2s>( #[cfg(test)] mod test { use super::*; - use rand::{XorShiftRng, SeedableRng, Rng}; + use rand::{Rng, SeedableRng, XorShiftRng}; use bellman::pairing::bn256::{Bn256, Fr}; use bellman::pairing::ff::{Field, PrimeField}; @@ -394,10 +343,9 @@ mod test { let mut cs = TrivialAssembly::::new(); let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let input_bits: Vec<_> = (0..512) - .map(|_| Boolean::constant(rng.gen())) - .chain((0..512) - .map(|_i| AllocatedBit::alloc(&mut cs, Some(true)).unwrap().into())) - .collect(); + .map(|_| Boolean::constant(rng.gen())) + .chain((0..512).map(|_i| AllocatedBit::alloc(&mut cs, Some(true)).unwrap().into())) + .collect(); blake2s(&mut cs, &input_bits, b"12345678").unwrap(); assert!(cs.is_satisfied()); assert_eq!(cs.n(), 33348); @@ -416,8 +364,7 @@ mod test { fn test_blake2s() { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - for input_len in (0..32).chain((32..256).filter(|a| a % 8 == 0)) - { + for input_len in (0..32).chain((32..256).filter(|a| a % 8 == 0)) { let mut h = Blake2s::with_params(32, &[], &[], b"12345678"); let data: Vec = (0..input_len).map(|_| rng.gen()).collect(); @@ -440,17 +387,16 @@ mod test { assert!(cs.is_satisfied()); - let mut s = hash_result.as_ref().iter() - .flat_map(|&byte| (0..8).map(move |i| (byte >> i) & 1u8 == 1u8)); + let mut s = hash_result.as_ref().iter().flat_map(|&byte| (0..8).map(move |i| (byte >> i) & 1u8 == 1u8)); for b in r { match b { Boolean::Is(b) => { assert!(s.next().unwrap() == b.get_value().unwrap()); - }, + } Boolean::Not(b) => { assert!(s.next().unwrap() != b.get_value().unwrap()); - }, + } Boolean::Constant(b) => { assert!(input_len == 0); assert!(s.next().unwrap() == b); diff --git a/crates/franklin-crypto/src/plonk/circuit/boolean.rs b/crates/franklin-crypto/src/plonk/circuit/boolean.rs index 094d4e7..1a5a60a 100644 --- a/crates/franklin-crypto/src/plonk/circuit/boolean.rs +++ b/crates/franklin-crypto/src/plonk/circuit/boolean.rs @@ -1,51 +1,23 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, Variable, Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, }; use crate::plonk::circuit::Assignment; -use super::allocated_num::{ - AllocatedNum -}; +use super::allocated_num::AllocatedNum; -use super::linear_combination::{ - LinearCombination -}; +use super::linear_combination::LinearCombination; use super::utils::is_selector_specialized_gate; -pub fn field_into_allocated_bits_le_fixed, F: PrimeField>( - cs: &mut CS, - value: Option, - bit_length: Option, -) -> Result, SynthesisError> { +pub fn field_into_allocated_bits_le_fixed, F: PrimeField>(cs: &mut CS, value: Option, bit_length: Option) -> Result, SynthesisError> { let limit = if let Some(bit_length) = bit_length { assert!(bit_length <= F::NUM_BITS as usize); @@ -53,7 +25,7 @@ pub fn field_into_allocated_bits_le_fixed, F: } else { F::NUM_BITS as usize }; - + // Deconstruct in big-endian bit order let values = match value { Some(ref value) => { @@ -80,21 +52,12 @@ pub fn field_into_allocated_bits_le_fixed, F: }; // Allocate in little-endian order - let bits = values - .into_iter() - .rev() - .take(limit) - .map(|b| AllocatedBit::alloc(cs, b)) - .collect::, SynthesisError>>()?; + let bits = values.into_iter().rev().take(limit).map(|b| AllocatedBit::alloc(cs, b)).collect::, SynthesisError>>()?; Ok(bits) } -pub fn field_into_allocated_booleans_le_fixed, F: PrimeField>( - cs: &mut CS, - value: Option, - bit_length: Option, -) -> Result, SynthesisError> { +pub fn field_into_allocated_booleans_le_fixed, F: PrimeField>(cs: &mut CS, value: Option, bit_length: Option) -> Result, SynthesisError> { let bits = field_into_allocated_bits_le_fixed(cs, value, bit_length)?; let bools: Vec<_> = bits.into_iter().map(|el| Boolean::from(el)).collect(); @@ -106,7 +69,7 @@ pub fn field_into_allocated_booleans_le_fixed #[derive(Clone, Debug)] pub struct AllocatedBit { pub(crate) variable: Variable, - pub(crate) value: Option + pub(crate) value: Option, } impl Copy for AllocatedBit {} @@ -116,20 +79,20 @@ impl AllocatedBit { self.value } - pub fn get_value_as_field_element(&self) -> Option { - let value = self.get_value(); - match value{ - None => None, - Some(value) =>{ - if value{ - Some(E::Fr::one()) - }else{ - Some(E::Fr::zero()) - } - } - } + pub fn get_value_as_field_element(&self) -> Option { + let value = self.get_value(); + match value { + None => None, + Some(value) => { + if value { + Some(E::Fr::one()) + } else { + Some(E::Fr::zero()) + } + } + } } - + pub fn get_variable(&self) -> Variable { self.variable } @@ -137,13 +100,10 @@ impl AllocatedBit { /// Allocate a variable in the constraint system which can only be a /// boolean value. Further, constrain that the boolean is false /// unless the condition is false. - pub fn alloc_conditionally( - cs: &mut CS, - value: Option, - must_be_false: &AllocatedBit - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn alloc_conditionally(cs: &mut CS, value: Option, must_be_false: &AllocatedBit) -> Result + where + E: Engine, + CS: ConstraintSystem, { // In gated form it would be two separate logical gates // - a is boolean @@ -155,19 +115,17 @@ impl AllocatedBit { // b = a * (1 - must_be_false) // a*must_be_false - a + b = 0 - let b = cs.alloc(|| { - match (a.get_value().get(), must_be_false.get_value().get()) { - (Ok(a_value), Ok(must_be_false_value)) => { - let value = *a_value & (! *must_be_false_value); + let b = cs.alloc(|| match (a.get_value().get(), must_be_false.get_value().get()) { + (Ok(a_value), Ok(must_be_false_value)) => { + let value = *a_value & (!*must_be_false_value); - if value { - Ok(E::Fr::one()) - } else { - Ok(E::Fr::zero()) - } - }, - _ => return Err(SynthesisError::AssignmentMissing) + if value { + Ok(E::Fr::one()) + } else { + Ok(E::Fr::zero()) + } } + _ => return Err(SynthesisError::AssignmentMissing), })?; let mut gate_term = MainGateTerm::new(); @@ -180,28 +138,17 @@ impl AllocatedBit { cs.allocate_main_gate(gate_term)?; - Ok(AllocatedBit { - variable: b, - value: value - }) + Ok(AllocatedBit { variable: b, value: value }) } /// Allocate a variable in the constraint system which can only be a /// boolean value. - pub fn alloc( - cs: &mut CS, - value: Option, - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn alloc(cs: &mut CS, value: Option) -> Result + where + E: Engine, + CS: ConstraintSystem, { - let var = cs.alloc(|| { - if *value.get()? { - Ok(E::Fr::one()) - } else { - Ok(E::Fr::zero()) - } - })?; + let var = cs.alloc(|| if *value.get()? { Ok(E::Fr::one()) } else { Ok(E::Fr::zero()) })?; // Constrain: (1 - a) * a = 0 // This constrains a to be either 0 or 1. @@ -214,16 +161,11 @@ impl AllocatedBit { gate_term.sub_assign(ArithmeticTerm::from_variable(var)); cs.allocate_main_gate(gate_term)?; - - Ok(AllocatedBit { - variable: var, - value: value - }) + + Ok(AllocatedBit { variable: var, value: value }) } - pub fn from_allocated_num_unchecked( - num: AllocatedNum - ) -> Self { + pub fn from_allocated_num_unchecked(num: AllocatedNum) -> Self { AllocatedBit { variable: num.get_variable(), value: num.get_value().map(|el| { @@ -234,19 +176,16 @@ impl AllocatedBit { } else { unreachable!() } - }) + }), } } /// Performs an XOR operation over the two operands, returning /// an `AllocatedBit`. - pub fn xor( - cs: &mut CS, - a: &Self, - b: &Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn xor(cs: &mut CS, a: &Self, b: &Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { let mut result_value = None; @@ -297,19 +236,16 @@ impl AllocatedBit { Ok(AllocatedBit { variable: result_var, - value: result_value + value: result_value, }) } /// Performs an AND operation over the two operands, returning /// an `AllocatedBit`. - pub fn and( - cs: &mut CS, - a: &Self, - b: &Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn and(cs: &mut CS, a: &Self, b: &Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { let mut result_value = None; @@ -341,19 +277,16 @@ impl AllocatedBit { Ok(AllocatedBit { variable: result_var, - value: result_value + value: result_value, }) } /// Performs an OR operation over the two operands, returning /// an `AllocatedBit`. - pub fn or( - cs: &mut CS, - a: &Self, - b: &Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn or(cs: &mut CS, a: &Self, b: &Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { let mut result_value = None; @@ -373,7 +306,7 @@ impl AllocatedBit { // any of a, b are both 1. // (1-a)(1-b) = (1-c) => ab-a-b+1 = 1-c - // ab-a-b+c=0 + // ab-a-b+c=0 let mut gate_term = MainGateTerm::new(); @@ -388,18 +321,15 @@ impl AllocatedBit { Ok(AllocatedBit { variable: result_var, - value: result_value + value: result_value, }) } /// Calculates `a AND (NOT b)`. - pub fn and_not( - cs: &mut CS, - a: &Self, - b: &Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn and_not(cs: &mut CS, a: &Self, b: &Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { let mut result_value = None; @@ -420,7 +350,6 @@ impl AllocatedBit { // a*b - a + c = 0 - let mut gate_term = MainGateTerm::new(); let mut multiplicative_term = ArithmeticTerm::from_variable(a.get_variable()); @@ -433,18 +362,15 @@ impl AllocatedBit { Ok(AllocatedBit { variable: result_var, - value: result_value + value: result_value, }) } /// Calculates `(NOT a) AND (NOT b)`. - pub fn nor( - cs: &mut CS, - a: &Self, - b: &Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn nor(cs: &mut CS, a: &Self, b: &Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { let mut result_value = None; @@ -479,16 +405,12 @@ impl AllocatedBit { Ok(AllocatedBit { variable: result_var, - value: result_value + value: result_value, }) } } -pub fn u64_into_boolean_vec_le>( - cs: &mut CS, - value: Option -) -> Result, SynthesisError> -{ +pub fn u64_into_boolean_vec_le>(cs: &mut CS, value: Option) -> Result, SynthesisError> { let values = match value { Some(ref value) => { let mut tmp = Vec::with_capacity(64); @@ -498,18 +420,17 @@ pub fn u64_into_boolean_vec_le>( } tmp - }, + } None => { vec![None; 64] } }; - let bits = values.into_iter().enumerate().map(|(_i, b)| { - Ok(Boolean::from(AllocatedBit::alloc( - cs, - b - )?)) - }).collect::, SynthesisError>>()?; + let bits = values + .into_iter() + .enumerate() + .map(|(_i, b)| Ok(Boolean::from(AllocatedBit::alloc(cs, b)?))) + .collect::, SynthesisError>>()?; Ok(bits) } @@ -529,21 +450,13 @@ pub fn le_bits_into_le_bytes(bits: Vec) -> Vec { result } -pub fn field_into_boolean_vec_le, F: PrimeField>( - cs: &mut CS, - value: Option -) -> Result, SynthesisError> -{ +pub fn field_into_boolean_vec_le, F: PrimeField>(cs: &mut CS, value: Option) -> Result, SynthesisError> { let v = field_into_allocated_bits_le::(cs, value)?; Ok(v.into_iter().map(|e| Boolean::from(e)).collect()) } -pub fn field_into_allocated_bits_le, F: PrimeField>( - cs: &mut CS, - value: Option -) -> Result, SynthesisError> -{ +pub fn field_into_allocated_bits_le, F: PrimeField>(cs: &mut CS, value: Option) -> Result, SynthesisError> { field_into_allocated_bits_le_fixed(cs, value, None) } @@ -556,7 +469,7 @@ pub enum Boolean { /// Negated view of the boolean variable Not(AllocatedBit), /// Constant (not an allocated variable) - Constant(bool) + Constant(bool), } impl Default for Boolean { @@ -569,7 +482,7 @@ impl Boolean { pub fn is_constant(&self) -> bool { match *self { Boolean::Constant(_) => true, - _ => false + _ => false, } } @@ -581,34 +494,26 @@ impl Boolean { match *self { Boolean::Is(ref v) => Some(v), Boolean::Not(ref v) => Some(v), - Boolean::Constant(_) => None + Boolean::Constant(_) => None, } } - pub fn alloc>( - cs: &mut CS, - witness: Option - ) -> Result { - let new = Boolean::from( - AllocatedBit::alloc(cs, witness)? - ); + pub fn alloc>(cs: &mut CS, witness: Option) -> Result { + let new = Boolean::from(AllocatedBit::alloc(cs, witness)?); Ok(new) } #[track_caller] - pub fn enforce_equal( - cs: &mut CS, - a: &Self, - b: &Self - ) -> Result<(), SynthesisError> - where E: Engine, - CS: ConstraintSystem + pub fn enforce_equal(cs: &mut CS, a: &Self, b: &Self) -> Result<(), SynthesisError> + where + E: Engine, + CS: ConstraintSystem, { match (a.get_value(), b.get_value()) { (Some(a), Some(b)) => { assert_eq!(a, b, "unequal: a = {}, b = {}", a, b); - }, + } _ => {} }; match (a, b) { @@ -618,7 +523,7 @@ impl Boolean { } else { Err(SynthesisError::Unsatisfiable) } - }, + } (&Boolean::Constant(true), a) | (a, &Boolean::Constant(true)) => { let mut lc = a.lc(E::Fr::one()); let mut minus_one = E::Fr::one(); @@ -626,12 +531,12 @@ impl Boolean { lc.add_assign_constant(minus_one); lc.enforce_zero(cs) - }, + } (&Boolean::Constant(false), a) | (a, &Boolean::Constant(false)) => { let lc = a.lc(E::Fr::one()); lc.enforce_zero(cs) - }, + } (a, b) => { let mut lc = a.lc(E::Fr::one()); let mut minus_one = E::Fr::one(); @@ -645,9 +550,7 @@ impl Boolean { pub fn get_constant_value(&self) -> bool { match self { - &Boolean::Constant(c) => { - c - } + &Boolean::Constant(c) => c, _ => { panic!("value is not constant"); } @@ -658,29 +561,25 @@ impl Boolean { match self { &Boolean::Constant(c) => Some(c), &Boolean::Is(ref v) => v.get_value(), - &Boolean::Not(ref v) => v.get_value().map(|b| !b) + &Boolean::Not(ref v) => v.get_value().map(|b| !b), } } pub fn get_value_in_field(&self) -> Option { - let value = self.get_value(); - match value{ - None => None, - Some(value) =>{ - if value{ - Some(E::Fr::one()) - }else{ - Some(E::Fr::zero()) - } - } - } + let value = self.get_value(); + match value { + None => None, + Some(value) => { + if value { + Some(E::Fr::one()) + } else { + Some(E::Fr::zero()) + } + } + } } - pub fn lc( - &self, - coeff: E::Fr - ) -> LinearCombination - { + pub fn lc(&self, coeff: E::Fr) -> LinearCombination { match self { &Boolean::Constant(c) => { if c { @@ -691,13 +590,13 @@ impl Boolean { } else { LinearCombination::::zero() } - }, + } &Boolean::Is(ref v) => { let mut lc = LinearCombination::::zero(); lc.add_assign_bit_with_coeff(v, coeff); lc - }, + } &Boolean::Not(ref v) => { let mut lc = LinearCombination::::zero(); let mut coeff_negated = coeff; @@ -720,31 +619,21 @@ impl Boolean { match self { &Boolean::Constant(c) => Boolean::Constant(!c), &Boolean::Is(ref v) => Boolean::Not(v.clone()), - &Boolean::Not(ref v) => Boolean::Is(v.clone()) + &Boolean::Not(ref v) => Boolean::Is(v.clone()), } } - /// Perform XOR over two boolean operands - pub fn xor<'a, E, CS>( - cs: &mut CS, - a: &'a Self, - b: &'a Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn xor<'a, E, CS>(cs: &mut CS, a: &'a Self, b: &'a Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { match (a, b) { (&Boolean::Constant(false), x) | (x, &Boolean::Constant(false)) => Ok(x.clone()), (&Boolean::Constant(true), x) | (x, &Boolean::Constant(true)) => Ok(x.not()), // a XOR (NOT b) = NOT(a XOR b) - (is @ &Boolean::Is(_), not @ &Boolean::Not(_)) | (not @ &Boolean::Not(_), is @ &Boolean::Is(_)) => { - Ok(Boolean::xor( - cs, - is, - ¬.not() - )?.not()) - }, + (is @ &Boolean::Is(_), not @ &Boolean::Not(_)) | (not @ &Boolean::Not(_), is @ &Boolean::Is(_)) => Ok(Boolean::xor(cs, is, ¬.not())?.not()), // a XOR b = (NOT a) XOR (NOT b) (&Boolean::Is(ref a), &Boolean::Is(ref b)) | (&Boolean::Not(ref a), &Boolean::Not(ref b)) => { // no matter what is in the variables, we just collapse it to constant `false` @@ -757,13 +646,10 @@ impl Boolean { } /// Perform AND over two boolean operands - pub fn and<'a, E, CS>( - cs: &mut CS, - a: &'a Self, - b: &'a Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn and<'a, E, CS>(cs: &mut CS, a: &'a Self, b: &'a Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { match (a, b) { // false AND x is always false @@ -771,28 +657,19 @@ impl Boolean { // true AND x is always x (&Boolean::Constant(true), x) | (x, &Boolean::Constant(true)) => Ok(x.clone()), // a AND (NOT b) - (&Boolean::Is(ref is), &Boolean::Not(ref not)) | (&Boolean::Not(ref not), &Boolean::Is(ref is)) => { - Ok(Boolean::Is(AllocatedBit::and_not(cs, is, not)?)) - }, + (&Boolean::Is(ref is), &Boolean::Not(ref not)) | (&Boolean::Not(ref not), &Boolean::Is(ref is)) => Ok(Boolean::Is(AllocatedBit::and_not(cs, is, not)?)), // (NOT a) AND (NOT b) = a NOR b - (&Boolean::Not(ref a), &Boolean::Not(ref b)) => { - Ok(Boolean::Is(AllocatedBit::nor(cs, a, b)?)) - }, + (&Boolean::Not(ref a), &Boolean::Not(ref b)) => Ok(Boolean::Is(AllocatedBit::nor(cs, a, b)?)), // a AND b - (&Boolean::Is(ref a), &Boolean::Is(ref b)) => { - Ok(Boolean::Is(AllocatedBit::and(cs, a, b)?)) - } + (&Boolean::Is(ref a), &Boolean::Is(ref b)) => Ok(Boolean::Is(AllocatedBit::and(cs, a, b)?)), } } /// Perform OR over two boolean operands - pub fn or<'a, E, CS>( - cs: &mut CS, - a: &'a Self, - b: &'a Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn or<'a, E, CS>(cs: &mut CS, a: &'a Self, b: &'a Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { match (a, b) { // true OR x is always true @@ -800,71 +677,54 @@ impl Boolean { // false OR x is always x (&Boolean::Constant(false), x) | (x, &Boolean::Constant(false)) => Ok(x.clone()), // a OR (NOT b) - (&Boolean::Is(ref is), &Boolean::Not(ref not)) | (&Boolean::Not(ref not), &Boolean::Is(ref is)) => { - Ok(Boolean::Not(AllocatedBit::and_not(cs, not, is)?)) - }, + (&Boolean::Is(ref is), &Boolean::Not(ref not)) | (&Boolean::Not(ref not), &Boolean::Is(ref is)) => Ok(Boolean::Not(AllocatedBit::and_not(cs, not, is)?)), // (NOT a) OR (NOT b) = a NOR b - (&Boolean::Not(ref a), &Boolean::Not(ref b)) => { - Ok(Boolean::Not(AllocatedBit::and(cs, a, b)?)) - }, + (&Boolean::Not(ref a), &Boolean::Not(ref b)) => Ok(Boolean::Not(AllocatedBit::and(cs, a, b)?)), // a OR b - (&Boolean::Is(ref a), &Boolean::Is(ref b)) => { - Ok(Boolean::Is(AllocatedBit::or(cs, a, b)?)) - } + (&Boolean::Is(ref a), &Boolean::Is(ref b)) => Ok(Boolean::Is(AllocatedBit::or(cs, a, b)?)), } } - pub fn conditionally_select>( - cs: &mut CS, - flag: &Self, - a: &Self, - b: &Self - ) -> Result { + pub fn conditionally_select>(cs: &mut CS, flag: &Self, a: &Self, b: &Self) -> Result { Self::sha256_ch(cs, &flag, a, b) } /// Computes (a and b) xor ((not a) and c) - pub fn sha256_ch<'a, E, CS>( - cs: &mut CS, - a: &'a Self, - b: &'a Self, - c: &'a Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn sha256_ch<'a, E, CS>(cs: &mut CS, a: &'a Self, b: &'a Self, c: &'a Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { let ch_value = match (a.get_value(), b.get_value(), c.get_value()) { (Some(a), Some(b), Some(c)) => { // (a and b) xor ((not a) and c) Some((a & b) ^ ((!a) & c)) - }, - _ => None + } + _ => None, }; match (a, b, c) { - (&Boolean::Constant(_), - &Boolean::Constant(_), - &Boolean::Constant(_)) => { + (&Boolean::Constant(_), &Boolean::Constant(_), &Boolean::Constant(_)) => { // They're all constants, so we can just compute the value. return Ok(Boolean::Constant(ch_value.expect("they're all constants"))); - }, + } (_, &Boolean::Constant(false), &Boolean::Constant(false)) => { // Regardless of a we have // (a and b) xor ((not a) and c) // equals // false xor false // that is always false - return Ok(Boolean::Constant(false)) - }, + return Ok(Boolean::Constant(false)); + } (_, &Boolean::Constant(true), &Boolean::Constant(true)) => { // Regardless of a we have // (a and b) xor ((not a) and c) // equals // a xor (not (a)) // that is always true - return Ok(Boolean::Constant(true)) - }, + return Ok(Boolean::Constant(true)); + } (&Boolean::Constant(false), _, c) => { // If a is false // (a and b) xor ((not a) and c) @@ -873,29 +733,21 @@ impl Boolean { // equals // c return Ok(c.clone()); - }, + } (a, &Boolean::Constant(false), c) => { // If b is false // (a and b) xor ((not a) and c) // equals // ((not a) and c) - return Boolean::and( - cs, - &a.not(), - &c - ); - }, + return Boolean::and(cs, &a.not(), &c); + } (a, b, &Boolean::Constant(false)) => { // If c is false // (a and b) xor ((not a) and c) // equals // (a and b) - return Boolean::and( - cs, - &a, - &b - ); - }, + return Boolean::and(cs, &a, &b); + } (a, b, &Boolean::Constant(true)) => { // If c is true // (a and b) xor ((not a) and c) @@ -903,12 +755,8 @@ impl Boolean { // (a and b) xor (not a) // equals // not (a and (not b)) - return Ok(Boolean::and( - cs, - &a, - &b.not() - )?.not()); - }, + return Ok(Boolean::and(cs, &a, &b.not())?.not()); + } (a, &Boolean::Constant(true), c) => { // If b is true // (a and b) xor ((not a) and c) @@ -916,12 +764,8 @@ impl Boolean { // a xor ((not a) and c) // equals // not ((not a) and (not c)) - return Ok(Boolean::and( - cs, - &a.not(), - &c.not() - )?.not()); - }, + return Ok(Boolean::and(cs, &a.not(), &c.not())?.not()); + } (&Boolean::Constant(true), b, _) => { // If a is true // (a and b) xor ((not a) and c) @@ -929,17 +773,16 @@ impl Boolean { // b xor false // equals // b - return Ok(b.clone()) - }, - (&Boolean::Is(_), &Boolean::Is(_), &Boolean::Is(_)) | - (&Boolean::Is(_), &Boolean::Is(_), &Boolean::Not(_)) | - (&Boolean::Is(_), &Boolean::Not(_), &Boolean::Is(_)) | - (&Boolean::Is(_), &Boolean::Not(_), &Boolean::Not(_)) | - (&Boolean::Not(_), &Boolean::Is(_), &Boolean::Is(_)) | - (&Boolean::Not(_), &Boolean::Is(_), &Boolean::Not(_)) | - (&Boolean::Not(_), &Boolean::Not(_), &Boolean::Is(_)) | - (&Boolean::Not(_), &Boolean::Not(_), &Boolean::Not(_)) - => {} + return Ok(b.clone()); + } + (&Boolean::Is(_), &Boolean::Is(_), &Boolean::Is(_)) + | (&Boolean::Is(_), &Boolean::Is(_), &Boolean::Not(_)) + | (&Boolean::Is(_), &Boolean::Not(_), &Boolean::Is(_)) + | (&Boolean::Is(_), &Boolean::Not(_), &Boolean::Not(_)) + | (&Boolean::Not(_), &Boolean::Is(_), &Boolean::Is(_)) + | (&Boolean::Not(_), &Boolean::Is(_), &Boolean::Not(_)) + | (&Boolean::Not(_), &Boolean::Not(_), &Boolean::Is(_)) + | (&Boolean::Not(_), &Boolean::Not(_), &Boolean::Not(_)) => {} } assert!(!a.is_constant()); @@ -948,23 +791,10 @@ impl Boolean { // so check and use a specialized one may be if is_selector_specialized_gate::() { - return Self::conditionally_select_for_special_main_gate( - cs, - a, - b, - c - ); + return Self::conditionally_select_for_special_main_gate(cs, a, b, c); } - let ch = cs.alloc(|| { - ch_value.get().map(|v| { - if *v { - E::Fr::one() - } else { - E::Fr::zero() - } - }) - })?; + let ch = cs.alloc(|| ch_value.get().map(|v| if *v { E::Fr::one() } else { E::Fr::zero() }))?; // a, b and c are not constant here, so // all constraints below are live and can not be optimized away @@ -998,11 +828,11 @@ impl Boolean { gate_term.add_assign(ArithmeticTerm::from_variable(c.get_variable())); cs.allocate_main_gate(gate_term)?; - }, + } (Boolean::Is(ref a), Boolean::Not(ref c)) => { // a = a // c = 1 - c - // a * tmp - ch + c = 0 -> + // a * tmp - ch + c = 0 -> // a * tmp - ch - c + 1 = 0 let mut gate_term = MainGateTerm::new(); @@ -1014,11 +844,11 @@ impl Boolean { gate_term.add_assign(ArithmeticTerm::constant(E::Fr::one())); cs.allocate_main_gate(gate_term)?; - }, + } (Boolean::Not(ref a), Boolean::Is(ref c)) => { // a = 1 - a // c = c - // a * tmp - ch + c = 0 -> + // a * tmp - ch + c = 0 -> // - a * tmp + tmp - ch + c = 0 let mut gate_term = MainGateTerm::new(); @@ -1030,11 +860,11 @@ impl Boolean { gate_term.add_assign(ArithmeticTerm::from_variable(c.get_variable())); cs.allocate_main_gate(gate_term)?; - }, + } (Boolean::Not(ref a), Boolean::Not(ref c)) => { // a = 1 - a // c = 1 - c - // a * tmp - ch + c = 0 -> + // a * tmp - ch + c = 0 -> // - a * tmp + tmp - ch - c + 1 = 0 let mut gate_term = MainGateTerm::new(); @@ -1047,11 +877,11 @@ impl Boolean { gate_term.add_assign(ArithmeticTerm::constant(E::Fr::one())); cs.allocate_main_gate(gate_term)?; - }, + } // (Boolean::Constant(true), Boolean::Is(ref c)) => { // // a = 1 // // c = c - // // a * tmp - ch + c = 0 -> + // // a * tmp - ch + c = 0 -> // // tmp - ch + c = 0 // let mut gate_term = MainGateTerm::new(); @@ -1064,7 +894,7 @@ impl Boolean { // (Boolean::Constant(true), Boolean::Not(ref c)) => { // // a = 1 // // c = 1 - c - // // a * tmp - ch + c = 0 -> + // // a * tmp - ch + c = 0 -> // // tmp - ch - c + 1 = 0 // let mut gate_term = MainGateTerm::new(); @@ -1078,7 +908,7 @@ impl Boolean { // (Boolean::Constant(false), Boolean::Is(ref c)) => { // // a = 0 // // c = c - // // a * tmp - ch + c = 0 -> + // // a * tmp - ch + c = 0 -> // // - ch + c = 0 // let mut gate_term = MainGateTerm::new(); @@ -1090,7 +920,7 @@ impl Boolean { // (Boolean::Constant(false), Boolean::Not(ref c)) => { // // a = 0 // // c = 1 - c - // // a * tmp - ch + c = 0 -> + // // a * tmp - ch + c = 0 -> // // - ch - c + 1 = 0 // let mut gate_term = MainGateTerm::new(); @@ -1105,71 +935,50 @@ impl Boolean { } } - Ok(AllocatedBit { - value: ch_value, - variable: ch - }.into()) + Ok(AllocatedBit { value: ch_value, variable: ch }.into()) } /// Computes (a and b) xor (a and c) xor (b and c) - pub fn sha256_maj<'a, E, CS>( - cs: &mut CS, - a: &'a Self, - b: &'a Self, - c: &'a Self, - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn sha256_maj<'a, E, CS>(cs: &mut CS, a: &'a Self, b: &'a Self, c: &'a Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { let maj_value = match (a.get_value(), b.get_value(), c.get_value()) { (Some(a), Some(b), Some(c)) => { // (a and b) xor (a and c) xor (b and c) Some((a & b) ^ (a & c) ^ (b & c)) - }, - _ => None + } + _ => None, }; match (a, b, c) { - (&Boolean::Constant(_), - &Boolean::Constant(_), - &Boolean::Constant(_)) => { + (&Boolean::Constant(_), &Boolean::Constant(_), &Boolean::Constant(_)) => { // They're all constants, so we can just compute the value. return Ok(Boolean::Constant(maj_value.expect("they're all constants"))); - }, + } (&Boolean::Constant(false), b, c) => { // If a is false, // (a and b) xor (a and c) xor (b and c) // equals // (b and c) - return Boolean::and( - cs, - b, - c - ); - }, + return Boolean::and(cs, b, c); + } (a, &Boolean::Constant(false), c) => { // If b is false, // (a and b) xor (a and c) xor (b and c) // equals // (a and c) - return Boolean::and( - cs, - a, - c - ); - }, + return Boolean::and(cs, a, c); + } (a, b, &Boolean::Constant(false)) => { // If c is false, // (a and b) xor (a and c) xor (b and c) // equals // (a and b) - return Boolean::and( - cs, - a, - b - ); - }, + return Boolean::and(cs, a, b); + } (a, b, &Boolean::Constant(true)) => { // If c is true, // (a and b) xor (a and c) xor (b and c) @@ -1177,54 +986,33 @@ impl Boolean { // (a and b) xor (a) xor (b) // equals // not ((not a) and (not b)) - return Ok(Boolean::and( - cs, - &a.not(), - &b.not() - )?.not()); - }, + return Ok(Boolean::and(cs, &a.not(), &b.not())?.not()); + } (a, &Boolean::Constant(true), c) => { // If b is true, // (a and b) xor (a and c) xor (b and c) // equals // (a) xor (a and c) xor (c) - return Ok(Boolean::and( - cs, - &a.not(), - &c.not() - )?.not()); - }, + return Ok(Boolean::and(cs, &a.not(), &c.not())?.not()); + } (&Boolean::Constant(true), b, c) => { // If a is true, // (a and b) xor (a and c) xor (b and c) // equals // (b) xor (c) xor (b and c) - return Ok(Boolean::and( - cs, - &b.not(), - &c.not() - )?.not()); - }, - (&Boolean::Is(_), &Boolean::Is(_), &Boolean::Is(_)) | - (&Boolean::Is(_), &Boolean::Is(_), &Boolean::Not(_)) | - (&Boolean::Is(_), &Boolean::Not(_), &Boolean::Is(_)) | - (&Boolean::Is(_), &Boolean::Not(_), &Boolean::Not(_)) | - (&Boolean::Not(_), &Boolean::Is(_), &Boolean::Is(_)) | - (&Boolean::Not(_), &Boolean::Is(_), &Boolean::Not(_)) | - (&Boolean::Not(_), &Boolean::Not(_), &Boolean::Is(_)) | - (&Boolean::Not(_), &Boolean::Not(_), &Boolean::Not(_)) - => {} + return Ok(Boolean::and(cs, &b.not(), &c.not())?.not()); + } + (&Boolean::Is(_), &Boolean::Is(_), &Boolean::Is(_)) + | (&Boolean::Is(_), &Boolean::Is(_), &Boolean::Not(_)) + | (&Boolean::Is(_), &Boolean::Not(_), &Boolean::Is(_)) + | (&Boolean::Is(_), &Boolean::Not(_), &Boolean::Not(_)) + | (&Boolean::Not(_), &Boolean::Is(_), &Boolean::Is(_)) + | (&Boolean::Not(_), &Boolean::Is(_), &Boolean::Not(_)) + | (&Boolean::Not(_), &Boolean::Not(_), &Boolean::Is(_)) + | (&Boolean::Not(_), &Boolean::Not(_), &Boolean::Not(_)) => {} } - let maj = cs.alloc(|| { - maj_value.get().map(|v| { - if *v { - E::Fr::one() - } else { - E::Fr::zero() - } - }) - })?; + let maj = cs.alloc(|| maj_value.get().map(|v| if *v { E::Fr::one() } else { E::Fr::zero() }))?; // ¬(¬a ∧ ¬b) ∧ ¬(¬a ∧ ¬c) ∧ ¬(¬b ∧ ¬c) // (1 - ((1 - a) * (1 - b))) * (1 - ((1 - a) * (1 - c))) * (1 - ((1 - b) * (1 - c))) @@ -1235,11 +1023,7 @@ impl Boolean { // (b) * (c) = (bc) // (2bc - b - c) * (a) = bc - maj - let bc = Self::and( - cs, - b, - c - )?; + let bc = Self::and(cs, b, c)?; let mut two = E::Fr::one(); two.double(); @@ -1269,7 +1053,7 @@ impl Boolean { gate_term.add_assign(ArithmeticTerm::from_variable(maj)); cs.allocate_main_gate(gate_term)?; - }, + } (Boolean::Not(ref a), Boolean::Is(ref bc)) => { // a = 1 - a // bc = bc @@ -1284,53 +1068,39 @@ impl Boolean { gate_term.add_assign(ArithmeticTerm::from_variable(maj)); cs.allocate_main_gate(gate_term)?; - }, + } _ => { unreachable!("`a` and `bc` are not constant here, and `bc` can not be Not"); } } - Ok(AllocatedBit { - value: maj_value, - variable: maj - }.into()) + Ok(AllocatedBit { value: maj_value, variable: maj }.into()) } - - pub fn alloc_multiple, const N: usize>( - cs: &mut CS, - witness: Option<[bool; N]> - ) -> Result<[Self; N], SynthesisError> { + pub fn alloc_multiple, const N: usize>(cs: &mut CS, witness: Option<[bool; N]>) -> Result<[Self; N], SynthesisError> { let mut result = [Boolean::constant(false); N]; for (idx, r) in result.iter_mut().enumerate() { let witness = witness.map(|el| el[idx]); *r = Self::alloc(cs, witness)?; } - + Ok(result) } - pub fn get_value_multiple( - els: &[Self; N] - ) -> Option<[bool; N]> { + pub fn get_value_multiple(els: &[Self; N]) -> Option<[bool; N]> { let mut result = [false; N]; for (r, el) in result.iter_mut().zip(els.iter()) { if let Some(value) = el.get_value() { *r = value; } else { - return None + return None; } } - + Some(result) } - pub fn conditionally_select_multiple, const N: usize>( - cs: &mut CS, - flag: &Boolean, - a: &[Self; N], - b: &[Self; N] - ) -> Result<[Self; N], SynthesisError> { + pub fn conditionally_select_multiple, const N: usize>(cs: &mut CS, flag: &Boolean, a: &[Self; N], b: &[Self; N]) -> Result<[Self; N], SynthesisError> { let mut result = [Boolean::constant(false); N]; for ((a, b), r) in (a.iter().zip(b.iter())).zip(result.iter_mut()) { @@ -1340,12 +1110,7 @@ impl Boolean { Ok(result) } - fn conditionally_select_for_special_main_gate>( - cs: &mut CS, - flag: &Boolean, - a: &Self, - b: &Self - ) -> Result { + fn conditionally_select_for_special_main_gate>(cs: &mut CS, flag: &Boolean, a: &Self, b: &Self) -> Result { use bellman::plonk::better_better_cs::cs::GateInternal; use bellman::plonk::better_better_cs::gates::selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext; @@ -1356,15 +1121,10 @@ impl Boolean { match flag { Boolean::Not(ref not_flag) => { - // avoid manual work, just swap variables and manually negate the flag + // avoid manual work, just swap variables and manually negate the flag let not_flag = Boolean::from(*not_flag); - return Self::conditionally_select_for_special_main_gate( - cs, - ¬_flag, - &b, - &a - ); - }, + return Self::conditionally_select_for_special_main_gate(cs, ¬_flag, &b, &a); + } _ => {} } @@ -1372,19 +1132,11 @@ impl Boolean { (Some(a), Some(b), Some(c)) => { // (a and b) xor ((not a) and c) Some((a & b) ^ ((!a) & c)) - }, - _ => None + } + _ => None, }; - let ch = cs.alloc(|| { - ch_value.get().map(|v| { - if *v { - E::Fr::one() - } else { - E::Fr::zero() - } - }) - })?; + let ch = cs.alloc(|| ch_value.get().map(|v| if *v { E::Fr::one() } else { E::Fr::zero() }))?; let mg = CS::MainGate::default(); @@ -1419,13 +1171,8 @@ impl Boolean { vars[2] = b.get_variable(); vars[3] = ch; - cs.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - )?; - }, + cs.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[])?; + } (Boolean::Is(ref flag), Boolean::Is(ref a), Boolean::Not(ref b)) => { // flag * a + (1 - flag) * b - ch = 0 // flag = flag @@ -1449,13 +1196,8 @@ impl Boolean { vars[2] = b.get_variable(); vars[3] = ch; - cs.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - )?; - }, + cs.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[])?; + } (Boolean::Is(ref flag), Boolean::Not(ref a), Boolean::Is(ref b)) => { // flag * a + (1 - flag) * b - ch = 0 // flag = flag @@ -1478,13 +1220,8 @@ impl Boolean { vars[2] = b.get_variable(); vars[3] = ch; - cs.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - )?; - }, + cs.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[])?; + } (Boolean::Is(ref flag), Boolean::Not(ref a), Boolean::Not(ref b)) => { // flag * a + (1 - flag) * b - ch = 0 // flag = flag @@ -1507,22 +1244,14 @@ impl Boolean { vars[2] = b.get_variable(); vars[3] = ch; - cs.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - )?; - }, + cs.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[])?; + } _ => { unreachable!("Neither `flag`, `a` nor `b` are constants here"); } } - Ok(AllocatedBit { - value: ch_value, - variable: ch - }.into()) + Ok(AllocatedBit { value: ch_value, variable: ch }.into()) } } @@ -1555,7 +1284,6 @@ mod test { } } - #[test] fn test_and() { for a_val in [false, true].iter() { @@ -1622,10 +1350,7 @@ mod test { Boolean::enforce_equal(&mut cs, &a, &b).unwrap(); - assert_eq!( - cs.is_satisfied(), - (a_bool ^ a_neg) == (b_bool ^ b_neg) - ); + assert_eq!(cs.is_satisfied(), (a_bool ^ a_neg) == (b_bool ^ b_neg)); } { let mut cs = TrivialAssembly::::new(); @@ -1642,10 +1367,7 @@ mod test { Boolean::enforce_equal(&mut cs, &a, &b).unwrap(); - assert_eq!( - cs.is_satisfied(), - (a_bool ^ a_neg) == (b_bool ^ b_neg) - ); + assert_eq!(cs.is_satisfied(), (a_bool ^ a_neg) == (b_bool ^ b_neg)); } { let mut cs = TrivialAssembly::::new(); @@ -1662,10 +1384,7 @@ mod test { Boolean::enforce_equal(&mut cs, &a, &b).unwrap(); - assert_eq!( - cs.is_satisfied(), - (a_bool ^ a_neg) == (b_bool ^ b_neg) - ); + assert_eq!(cs.is_satisfied(), (a_bool ^ a_neg) == (b_bool ^ b_neg)); } { let mut cs = TrivialAssembly::::new(); @@ -1702,43 +1421,43 @@ mod test { let mut b = Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()); match b { - Boolean::Is(_) => {}, - _ => panic!("unexpected value") + Boolean::Is(_) => {} + _ => panic!("unexpected value"), } b = b.not(); match b { - Boolean::Not(_) => {}, - _ => panic!("unexpected value") + Boolean::Not(_) => {} + _ => panic!("unexpected value"), } b = b.not(); match b { - Boolean::Is(_) => {}, - _ => panic!("unexpected value") + Boolean::Is(_) => {} + _ => panic!("unexpected value"), } b = Boolean::constant(true); match b { - Boolean::Constant(true) => {}, - _ => panic!("unexpected value") + Boolean::Constant(true) => {} + _ => panic!("unexpected value"), } b = b.not(); match b { - Boolean::Constant(false) => {}, - _ => panic!("unexpected value") + Boolean::Constant(false) => {} + _ => panic!("unexpected value"), } b = b.not(); match b { - Boolean::Constant(true) => {}, - _ => panic!("unexpected value") + Boolean::Constant(true) => {} + _ => panic!("unexpected value"), } } @@ -1749,7 +1468,7 @@ mod test { AllocatedTrue, AllocatedFalse, NegatedAllocatedTrue, - NegatedAllocatedFalse + NegatedAllocatedFalse, } impl OperandType { @@ -1760,7 +1479,7 @@ mod test { OperandType::AllocatedTrue => false, OperandType::AllocatedFalse => false, OperandType::NegatedAllocatedTrue => false, - OperandType::NegatedAllocatedFalse => false + OperandType::NegatedAllocatedFalse => false, } } @@ -1771,12 +1490,11 @@ mod test { OperandType::AllocatedTrue => true, OperandType::AllocatedFalse => false, OperandType::NegatedAllocatedTrue => false, - OperandType::NegatedAllocatedFalse => true + OperandType::NegatedAllocatedFalse => true, } } } - #[test] fn test_boolean_xor() { let variants = [ @@ -1785,7 +1503,7 @@ mod test { OperandType::AllocatedTrue, OperandType::AllocatedFalse, OperandType::NegatedAllocatedTrue, - OperandType::NegatedAllocatedFalse + OperandType::NegatedAllocatedFalse, ]; for first_operand in variants.iter().cloned() { @@ -1796,15 +1514,13 @@ mod test { let b; { - let mut dyn_construct = |operand, _name| { - match operand { - OperandType::True => Boolean::constant(true), - OperandType::False => Boolean::constant(false), - OperandType::AllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()), - OperandType::AllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()), - OperandType::NegatedAllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()).not(), - OperandType::NegatedAllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()).not(), - } + let mut dyn_construct = |operand, _name| match operand { + OperandType::True => Boolean::constant(true), + OperandType::False => Boolean::constant(false), + OperandType::AllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()), + OperandType::AllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()), + OperandType::NegatedAllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()).not(), + OperandType::NegatedAllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()).not(), }; a = dyn_construct(first_operand, "a"); @@ -1816,81 +1532,81 @@ mod test { assert!(cs.is_satisfied()); match (first_operand, second_operand, c) { - (OperandType::True, OperandType::True, Boolean::Constant(false)) => {}, - (OperandType::True, OperandType::False, Boolean::Constant(true)) => {}, - (OperandType::True, OperandType::AllocatedTrue, Boolean::Not(_)) => {}, - (OperandType::True, OperandType::AllocatedFalse, Boolean::Not(_)) => {}, - (OperandType::True, OperandType::NegatedAllocatedTrue, Boolean::Is(_)) => {}, - (OperandType::True, OperandType::NegatedAllocatedFalse, Boolean::Is(_)) => {}, - - (OperandType::False, OperandType::True, Boolean::Constant(true)) => {}, - (OperandType::False, OperandType::False, Boolean::Constant(false)) => {}, - (OperandType::False, OperandType::AllocatedTrue, Boolean::Is(_)) => {}, - (OperandType::False, OperandType::AllocatedFalse, Boolean::Is(_)) => {}, - (OperandType::False, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {}, - (OperandType::False, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {}, - - (OperandType::AllocatedTrue, OperandType::True, Boolean::Not(_)) => {}, - (OperandType::AllocatedTrue, OperandType::False, Boolean::Is(_)) => {}, + (OperandType::True, OperandType::True, Boolean::Constant(false)) => {} + (OperandType::True, OperandType::False, Boolean::Constant(true)) => {} + (OperandType::True, OperandType::AllocatedTrue, Boolean::Not(_)) => {} + (OperandType::True, OperandType::AllocatedFalse, Boolean::Not(_)) => {} + (OperandType::True, OperandType::NegatedAllocatedTrue, Boolean::Is(_)) => {} + (OperandType::True, OperandType::NegatedAllocatedFalse, Boolean::Is(_)) => {} + + (OperandType::False, OperandType::True, Boolean::Constant(true)) => {} + (OperandType::False, OperandType::False, Boolean::Constant(false)) => {} + (OperandType::False, OperandType::AllocatedTrue, Boolean::Is(_)) => {} + (OperandType::False, OperandType::AllocatedFalse, Boolean::Is(_)) => {} + (OperandType::False, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {} + (OperandType::False, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {} + + (OperandType::AllocatedTrue, OperandType::True, Boolean::Not(_)) => {} + (OperandType::AllocatedTrue, OperandType::False, Boolean::Is(_)) => {} (OperandType::AllocatedTrue, OperandType::AllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::AllocatedTrue, OperandType::AllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } (OperandType::AllocatedTrue, OperandType::NegatedAllocatedTrue, Boolean::Not(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::AllocatedTrue, OperandType::NegatedAllocatedFalse, Boolean::Not(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } - (OperandType::AllocatedFalse, OperandType::True, Boolean::Not(_)) => {}, - (OperandType::AllocatedFalse, OperandType::False, Boolean::Is(_)) => {}, + (OperandType::AllocatedFalse, OperandType::True, Boolean::Not(_)) => {} + (OperandType::AllocatedFalse, OperandType::False, Boolean::Is(_)) => {} (OperandType::AllocatedFalse, OperandType::AllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } (OperandType::AllocatedFalse, OperandType::AllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::AllocatedFalse, OperandType::NegatedAllocatedTrue, Boolean::Not(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } (OperandType::AllocatedFalse, OperandType::NegatedAllocatedFalse, Boolean::Not(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } - (OperandType::NegatedAllocatedTrue, OperandType::True, Boolean::Is(_)) => {}, - (OperandType::NegatedAllocatedTrue, OperandType::False, Boolean::Not(_)) => {}, + (OperandType::NegatedAllocatedTrue, OperandType::True, Boolean::Is(_)) => {} + (OperandType::NegatedAllocatedTrue, OperandType::False, Boolean::Not(_)) => {} (OperandType::NegatedAllocatedTrue, OperandType::AllocatedTrue, Boolean::Not(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::NegatedAllocatedTrue, OperandType::AllocatedFalse, Boolean::Not(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } (OperandType::NegatedAllocatedTrue, OperandType::NegatedAllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::NegatedAllocatedTrue, OperandType::NegatedAllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } - (OperandType::NegatedAllocatedFalse, OperandType::True, Boolean::Is(_)) => {}, - (OperandType::NegatedAllocatedFalse, OperandType::False, Boolean::Not(_)) => {}, + (OperandType::NegatedAllocatedFalse, OperandType::True, Boolean::Is(_)) => {} + (OperandType::NegatedAllocatedFalse, OperandType::False, Boolean::Not(_)) => {} (OperandType::NegatedAllocatedFalse, OperandType::AllocatedTrue, Boolean::Not(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } (OperandType::NegatedAllocatedFalse, OperandType::AllocatedFalse, Boolean::Not(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::NegatedAllocatedFalse, OperandType::NegatedAllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } (OperandType::NegatedAllocatedFalse, OperandType::NegatedAllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } - _ => panic!("this should never be encountered") + _ => panic!("this should never be encountered"), } } } @@ -1904,7 +1620,7 @@ mod test { OperandType::AllocatedTrue, OperandType::AllocatedFalse, OperandType::NegatedAllocatedTrue, - OperandType::NegatedAllocatedFalse + OperandType::NegatedAllocatedFalse, ]; for first_operand in variants.iter().cloned() { @@ -1915,16 +1631,13 @@ mod test { let b; { - let mut dyn_construct = |operand, _name| { - - match operand { - OperandType::True => Boolean::constant(true), - OperandType::False => Boolean::constant(false), - OperandType::AllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()), - OperandType::AllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()), - OperandType::NegatedAllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()).not(), - OperandType::NegatedAllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()).not(), - } + let mut dyn_construct = |operand, _name| match operand { + OperandType::True => Boolean::constant(true), + OperandType::False => Boolean::constant(false), + OperandType::AllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()), + OperandType::AllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()), + OperandType::NegatedAllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()).not(), + OperandType::NegatedAllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()).not(), }; a = dyn_construct(first_operand, "a"); @@ -1936,79 +1649,79 @@ mod test { assert!(cs.is_satisfied()); match (first_operand, second_operand, c) { - (OperandType::True, OperandType::True, Boolean::Constant(true)) => {}, - (OperandType::True, OperandType::False, Boolean::Constant(false)) => {}, - (OperandType::True, OperandType::AllocatedTrue, Boolean::Is(_)) => {}, - (OperandType::True, OperandType::AllocatedFalse, Boolean::Is(_)) => {}, - (OperandType::True, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {}, - (OperandType::True, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {}, - - (OperandType::False, OperandType::True, Boolean::Constant(false)) => {}, - (OperandType::False, OperandType::False, Boolean::Constant(false)) => {}, - (OperandType::False, OperandType::AllocatedTrue, Boolean::Constant(false)) => {}, - (OperandType::False, OperandType::AllocatedFalse, Boolean::Constant(false)) => {}, - (OperandType::False, OperandType::NegatedAllocatedTrue, Boolean::Constant(false)) => {}, - (OperandType::False, OperandType::NegatedAllocatedFalse, Boolean::Constant(false)) => {}, - - (OperandType::AllocatedTrue, OperandType::True, Boolean::Is(_)) => {}, - (OperandType::AllocatedTrue, OperandType::False, Boolean::Constant(false)) => {}, + (OperandType::True, OperandType::True, Boolean::Constant(true)) => {} + (OperandType::True, OperandType::False, Boolean::Constant(false)) => {} + (OperandType::True, OperandType::AllocatedTrue, Boolean::Is(_)) => {} + (OperandType::True, OperandType::AllocatedFalse, Boolean::Is(_)) => {} + (OperandType::True, OperandType::NegatedAllocatedTrue, Boolean::Not(_)) => {} + (OperandType::True, OperandType::NegatedAllocatedFalse, Boolean::Not(_)) => {} + + (OperandType::False, OperandType::True, Boolean::Constant(false)) => {} + (OperandType::False, OperandType::False, Boolean::Constant(false)) => {} + (OperandType::False, OperandType::AllocatedTrue, Boolean::Constant(false)) => {} + (OperandType::False, OperandType::AllocatedFalse, Boolean::Constant(false)) => {} + (OperandType::False, OperandType::NegatedAllocatedTrue, Boolean::Constant(false)) => {} + (OperandType::False, OperandType::NegatedAllocatedFalse, Boolean::Constant(false)) => {} + + (OperandType::AllocatedTrue, OperandType::True, Boolean::Is(_)) => {} + (OperandType::AllocatedTrue, OperandType::False, Boolean::Constant(false)) => {} (OperandType::AllocatedTrue, OperandType::AllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } (OperandType::AllocatedTrue, OperandType::AllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::AllocatedTrue, OperandType::NegatedAllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::AllocatedTrue, OperandType::NegatedAllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } - (OperandType::AllocatedFalse, OperandType::True, Boolean::Is(_)) => {}, - (OperandType::AllocatedFalse, OperandType::False, Boolean::Constant(false)) => {}, + (OperandType::AllocatedFalse, OperandType::True, Boolean::Is(_)) => {} + (OperandType::AllocatedFalse, OperandType::False, Boolean::Constant(false)) => {} (OperandType::AllocatedFalse, OperandType::AllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::AllocatedFalse, OperandType::AllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::AllocatedFalse, OperandType::NegatedAllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::AllocatedFalse, OperandType::NegatedAllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } - (OperandType::NegatedAllocatedTrue, OperandType::True, Boolean::Not(_)) => {}, - (OperandType::NegatedAllocatedTrue, OperandType::False, Boolean::Constant(false)) => {}, + (OperandType::NegatedAllocatedTrue, OperandType::True, Boolean::Not(_)) => {} + (OperandType::NegatedAllocatedTrue, OperandType::False, Boolean::Constant(false)) => {} (OperandType::NegatedAllocatedTrue, OperandType::AllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::NegatedAllocatedTrue, OperandType::AllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::NegatedAllocatedTrue, OperandType::NegatedAllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::NegatedAllocatedTrue, OperandType::NegatedAllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } - (OperandType::NegatedAllocatedFalse, OperandType::True, Boolean::Not(_)) => {}, - (OperandType::NegatedAllocatedFalse, OperandType::False, Boolean::Constant(false)) => {}, + (OperandType::NegatedAllocatedFalse, OperandType::True, Boolean::Not(_)) => {} + (OperandType::NegatedAllocatedFalse, OperandType::False, Boolean::Constant(false)) => {} (OperandType::NegatedAllocatedFalse, OperandType::AllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } (OperandType::NegatedAllocatedFalse, OperandType::AllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::NegatedAllocatedFalse, OperandType::NegatedAllocatedTrue, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(false)); - }, + } (OperandType::NegatedAllocatedFalse, OperandType::NegatedAllocatedFalse, Boolean::Is(ref v)) => { assert_eq!(v.value, Some(true)); - }, + } _ => { panic!("unexpected behavior at {:?} AND {:?}", first_operand, second_operand); @@ -2074,7 +1787,7 @@ mod test { OperandType::AllocatedTrue, OperandType::AllocatedFalse, OperandType::NegatedAllocatedTrue, - OperandType::NegatedAllocatedFalse + OperandType::NegatedAllocatedFalse, ]; for first_operand in variants.iter().cloned() { @@ -2089,20 +1802,16 @@ mod test { let c; // ch = (a and b) xor ((not a) and c) - let expected = (first_operand.val() & second_operand.val()) ^ - ((!first_operand.val()) & third_operand.val()); + let expected = (first_operand.val() & second_operand.val()) ^ ((!first_operand.val()) & third_operand.val()); { - let mut dyn_construct = |operand, _name| { - - match operand { - OperandType::True => Boolean::constant(true), - OperandType::False => Boolean::constant(false), - OperandType::AllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()), - OperandType::AllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()), - OperandType::NegatedAllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()).not(), - OperandType::NegatedAllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()).not(), - } + let mut dyn_construct = |operand, _name| match operand { + OperandType::True => Boolean::constant(true), + OperandType::False => Boolean::constant(false), + OperandType::AllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()), + OperandType::AllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()), + OperandType::NegatedAllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()).not(), + OperandType::NegatedAllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()).not(), }; a = dyn_construct(first_operand, "a"); @@ -2119,19 +1828,11 @@ mod test { assert_eq!(ch.get_value().unwrap(), expected); - if first_operand.is_constant() || - second_operand.is_constant() || - third_operand.is_constant() - { - if first_operand.is_constant() && - second_operand.is_constant() && - third_operand.is_constant() - { + if first_operand.is_constant() || second_operand.is_constant() || third_operand.is_constant() { + if first_operand.is_constant() && second_operand.is_constant() && third_operand.is_constant() { assert_eq!(cs.n(), 0); } - } - else - { + } else { assert_eq!(ch.get_value().unwrap(), expected); } } @@ -2147,7 +1848,7 @@ mod test { OperandType::AllocatedTrue, OperandType::AllocatedFalse, OperandType::NegatedAllocatedTrue, - OperandType::NegatedAllocatedFalse + OperandType::NegatedAllocatedFalse, ]; for first_operand in variants.iter().cloned() { @@ -2160,21 +1861,16 @@ mod test { let c; // maj = (a and b) xor (a and c) xor (b and c) - let expected = (first_operand.val() & second_operand.val()) ^ - (first_operand.val() & third_operand.val()) ^ - (second_operand.val() & third_operand.val()); + let expected = (first_operand.val() & second_operand.val()) ^ (first_operand.val() & third_operand.val()) ^ (second_operand.val() & third_operand.val()); { - let mut dyn_construct = |operand, _name| { - - match operand { - OperandType::True => Boolean::constant(true), - OperandType::False => Boolean::constant(false), - OperandType::AllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()), - OperandType::AllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()), - OperandType::NegatedAllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()).not(), - OperandType::NegatedAllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()).not(), - } + let mut dyn_construct = |operand, _name| match operand { + OperandType::True => Boolean::constant(true), + OperandType::False => Boolean::constant(false), + OperandType::AllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()), + OperandType::AllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()), + OperandType::NegatedAllocatedTrue => Boolean::from(AllocatedBit::alloc(&mut cs, Some(true)).unwrap()).not(), + OperandType::NegatedAllocatedFalse => Boolean::from(AllocatedBit::alloc(&mut cs, Some(false)).unwrap()).not(), }; a = dyn_construct(first_operand, "a"); @@ -2188,19 +1884,11 @@ mod test { assert_eq!(maj.get_value().unwrap(), expected); - if first_operand.is_constant() || - second_operand.is_constant() || - third_operand.is_constant() - { - if first_operand.is_constant() && - second_operand.is_constant() && - third_operand.is_constant() - { + if first_operand.is_constant() || second_operand.is_constant() || third_operand.is_constant() { + if first_operand.is_constant() && second_operand.is_constant() && third_operand.is_constant() { assert_eq!(cs.n(), 0); } - } - else - { + } else { assert_eq!(maj.get_value().unwrap(), expected); } } diff --git a/crates/franklin-crypto/src/plonk/circuit/byte.rs b/crates/franklin-crypto/src/plonk/circuit/byte.rs index 3338837..d0a9ffb 100644 --- a/crates/franklin-crypto/src/plonk/circuit/byte.rs +++ b/crates/franklin-crypto/src/plonk/circuit/byte.rs @@ -1,37 +1,30 @@ +use super::allocated_num::*; +use super::boolean::Boolean; +use super::linear_combination::*; +use super::utils::*; use crate::bellman::pairing::ff::*; use crate::bellman::pairing::*; use crate::bellman::SynthesisError; use crate::plonk::circuit::bigint::{split_into_slices, split_some_into_slices}; -use super::allocated_num::*; -use super::linear_combination::*; -use super::boolean::Boolean; -use super::utils::*; -use crate::plonk::circuit::Assignment; use crate::plonk::circuit::bigint_new::constraint_bit_length; +use crate::plonk::circuit::Assignment; -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm -}; +use crate::bellman::plonk::better_better_cs::cs::{ArithmeticTerm, ConstraintSystem, MainGateTerm, Variable}; #[derive(Clone, Debug)] pub struct Byte { - pub inner: Num + pub inner: Num, } impl Copy for Byte {} impl Byte { pub fn empty() -> Self { - Self { - inner: Num::Constant(E::Fr::zero()) - } + Self { inner: Num::Constant(E::Fr::zero()) } } pub fn zero() -> Self { - Self {inner: Num::Constant(E::Fr::zero())} + Self { inner: Num::Constant(E::Fr::zero()) } } pub fn into_num(&self) -> Num { @@ -54,25 +47,18 @@ impl Byte { None } } - + pub fn from_u8_witness>(cs: &mut CS, value: Option) -> Result { - let var = AllocatedNum::alloc( - cs, - || { - let as_u8 = *value.get()?; - let fe = u64_to_fe(as_u8 as u64); + let var = AllocatedNum::alloc(cs, || { + let as_u8 = *value.get()?; + let fe = u64_to_fe(as_u8 as u64); - Ok(fe) - } - )?; + Ok(fe) + })?; let num = Num::Variable(var); constraint_bit_length(cs, &var, 8)?; - Ok( - Self { - inner: num - } - ) + Ok(Self { inner: num }) } pub fn from_u8_witness_multiple, const N: usize>(cs: &mut CS, value: Option<[u8; N]>) -> Result<[Self; N], SynthesisError> { @@ -91,25 +77,17 @@ impl Byte { let var = value.get_variable(); constraint_bit_length(cs, &var, 8)?; } - - Ok( - Self { - inner: value - } - ) + + Ok(Self { inner: value }) } pub fn from_num_unconstrained>(_cs: &mut CS, value: Num) -> Self { - Self { - inner: value - } + Self { inner: value } } pub fn constant(value: u8) -> Self { let value = E::Fr::from_str(&value.to_string()).expect("must convert constant u8"); - Self { - inner : Num::Constant(value) - } + Self { inner: Num::Constant(value) } } pub fn from_cnst(value: E::Fr) -> Self { @@ -117,29 +95,17 @@ impl Byte { if bits > 8 { panic!("Invalid bit length of Byte constant"); } - Self { - inner : Num::Constant(value) - } + Self { inner: Num::Constant(value) } } - pub fn conditionally_select>( - cs: &mut CS, - flag: &Boolean, - a: &Self, - b: &Self - ) -> Result { + pub fn conditionally_select>(cs: &mut CS, flag: &Boolean, a: &Self, b: &Self) -> Result { let new_inner = Num::conditionally_select(cs, flag, &a.inner, &b.inner)?; - let new = Self { - inner : new_inner - }; + let new = Self { inner: new_inner }; Ok(new) } - pub fn is_zero>( - &self, - cs: &mut CS - ) -> Result { + pub fn is_zero>(&self, cs: &mut CS) -> Result { self.inner.is_zero(cs) } @@ -189,10 +155,7 @@ pub trait IntoBytes { } } -pub fn uniquely_encode_le_bytes_into_num>( - cs: &mut CS, - bytes: &[Byte], -) -> Result, SynthesisError> { +pub fn uniquely_encode_le_bytes_into_num>(cs: &mut CS, bytes: &[Byte]) -> Result, SynthesisError> { assert!(bytes.len() <= (E::Fr::CAPACITY / 8) as usize); let mut lc = LinearCombination::zero(); let mut coeff = E::Fr::one(); @@ -208,10 +171,7 @@ pub fn uniquely_encode_le_bytes_into_num>( Ok(result) } -pub fn uniquely_encode_be_bytes_into_num>( - cs: &mut CS, - bytes: &[Byte], -) -> Result, SynthesisError> { +pub fn uniquely_encode_be_bytes_into_num>(cs: &mut CS, bytes: &[Byte]) -> Result, SynthesisError> { assert!(bytes.len() <= (E::Fr::CAPACITY / 8) as usize); let mut lc = LinearCombination::zero(); let mut coeff = E::Fr::one(); @@ -227,10 +187,7 @@ pub fn uniquely_encode_be_bytes_into_num>( Ok(result) } -pub fn uniquely_encode_be_bytes>( - cs: &mut CS, - bytes: &[Byte], -) -> Result>, SynthesisError> { +pub fn uniquely_encode_be_bytes>(cs: &mut CS, bytes: &[Byte]) -> Result>, SynthesisError> { let max_chunk = (E::Fr::CAPACITY / 8) as usize; let shift = E::Fr::from_str("256").unwrap(); @@ -250,14 +207,11 @@ pub fn uniquely_encode_be_bytes>( results.push(result); } - + Ok(results) } - -pub fn uniquely_encode_be_bytes_to_field_elements( - bytes: &[u8], -) -> Vec { +pub fn uniquely_encode_be_bytes_to_field_elements(bytes: &[u8]) -> Vec { let max_chunk = (F::CAPACITY / 8) as usize; let shift = F::from_str("256").unwrap(); @@ -277,15 +231,11 @@ pub fn uniquely_encode_be_bytes_to_field_elements( results.push(result); } - + results } -pub fn num_into_bytes_le>( - cs: &mut CS, - limb: Num, - width: usize -) -> Result>, SynthesisError> { +pub fn num_into_bytes_le>(cs: &mut CS, limb: Num, width: usize) -> Result>, SynthesisError> { assert!(width % 8 == 0); let num_bytes = width / 8; @@ -300,12 +250,7 @@ pub fn num_into_bytes_le>( lc.add_assign_number_with_coeff(&limb, minus_one); let witness = split_some_into_slices(var.get_value(), 8, num_bytes); for w in witness.into_iter() { - let allocated = AllocatedNum::alloc( - cs, - || { - Ok(*w.get()?) - } - )?; + let allocated = AllocatedNum::alloc(cs, || Ok(*w.get()?))?; let num = Num::Variable(allocated); let byte = Byte::from_num(cs, num.clone())?; result.push(byte); @@ -317,7 +262,7 @@ pub fn num_into_bytes_le>( lc.enforce_zero(cs)?; result - }, + } Num::Constant(constant) => { let mut result = Vec::with_capacity(num_bytes); let witness = split_into_slices(constant, 8, num_bytes); @@ -330,15 +275,11 @@ pub fn num_into_bytes_le>( result } }; - + Ok(result) } -pub fn num_into_bytes_be>( - cs: &mut CS, - limb: Num, - width: usize -) -> Result>, SynthesisError> { +pub fn num_into_bytes_be>(cs: &mut CS, limb: Num, width: usize) -> Result>, SynthesisError> { let mut encoding = num_into_bytes_le(cs, limb, width)?; encoding.reverse(); @@ -363,12 +304,7 @@ impl IntoBytes for Num { lc.add_assign_number_with_coeff(&self, minus_one); let witness = split_some_into_slices(var.get_value(), 8, num_bytes); for w in witness.into_iter() { - let allocated = AllocatedNum::alloc( - cs, - || { - Ok(*w.get()?) - } - )?; + let allocated = AllocatedNum::alloc(cs, || Ok(*w.get()?))?; let num = Num::Variable(allocated); let byte = Byte::from_num(cs, num.clone())?; result.push(byte); @@ -380,7 +316,7 @@ impl IntoBytes for Num { lc.enforce_zero(cs)?; result - }, + } Num::Constant(constant) => { let mut result = Vec::with_capacity(num_bytes); let witness = split_into_slices(constant, 8, num_bytes); @@ -393,7 +329,7 @@ impl IntoBytes for Num { result } }; - + Ok(result) } @@ -405,44 +341,25 @@ impl IntoBytes for Num { } } - impl IntoBytes for Boolean { fn into_le_bytes>(&self, cs: &mut CS) -> Result>, SynthesisError> { let num_bytes = 1; let result = match self { Boolean::Is(bit) => { - let fe_value = bit.get_value().map(|el| { - if el { - E::Fr::one() - } else { - E::Fr::zero() - } + let fe_value = bit.get_value().map(|el| if el { E::Fr::one() } else { E::Fr::zero() }); + let as_num = Num::Variable(AllocatedNum { + variable: bit.get_variable(), + value: fe_value, }); - let as_num = Num::Variable( - AllocatedNum { - variable: bit.get_variable(), - value: fe_value - } - ); - - let byte = Byte { - inner: as_num - }; + + let byte = Byte { inner: as_num }; vec![byte] - }, + } s @ Boolean::Not(..) => { - let fe_value = s.get_value().map(|el| { - if el { - E::Fr::one() - } else { - E::Fr::zero() - } - }); - let as_num = Num::Variable( - AllocatedNum::alloc(cs, || Ok(*fe_value.get()?))? - ); + let fe_value = s.get_value().map(|el| if el { E::Fr::one() } else { E::Fr::zero() }); + let as_num = Num::Variable(AllocatedNum::alloc(cs, || Ok(*fe_value.get()?))?); let mut minus_one = E::Fr::one(); minus_one.negate(); @@ -451,10 +368,8 @@ impl IntoBytes for Boolean { lc.add_assign_number_with_coeff(&as_num, minus_one); lc.add_assign_boolean_with_coeff(&s, E::Fr::one()); lc.enforce_zero(cs)?; - - let byte = Byte { - inner: as_num - }; + + let byte = Byte { inner: as_num }; vec![byte] } @@ -464,11 +379,11 @@ impl IntoBytes for Boolean { }; assert_eq!(result.len(), num_bytes); - + Ok(result) } fn into_be_bytes>(&self, cs: &mut CS) -> Result>, SynthesisError> { self.into_le_bytes(cs) } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/counter.rs b/crates/franklin-crypto/src/plonk/circuit/counter.rs index 47edf69..6a0f944 100644 --- a/crates/franklin-crypto/src/plonk/circuit/counter.rs +++ b/crates/franklin-crypto/src/plonk/circuit/counter.rs @@ -16,4 +16,4 @@ pub fn increment_counter_by(val: usize) { pub fn output_counter() -> usize { SOME_COUNTER.load(Ordering::Relaxed) -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/curve/endomorphism.rs b/crates/franklin-crypto/src/plonk/circuit/curve/endomorphism.rs index 3eeec00..08dded6 100644 --- a/crates/franklin-crypto/src/plonk/circuit/curve/endomorphism.rs +++ b/crates/franklin-crypto/src/plonk/circuit/curve/endomorphism.rs @@ -1,20 +1,8 @@ -use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, - GenericCurveProjective -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator, - ScalarEngine -}; - -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::pairing::{Engine, GenericCurveAffine, GenericCurveProjective}; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, ScalarEngine}; + +use crate::bellman::SynthesisError; use num_bigint::BigUint; use num_integer::Integer; @@ -22,9 +10,9 @@ use num_traits::Num; use crate::plonk::circuit::bigint::bigint::*; -// we use parameters for decomposition as +// we use parameters for decomposition as // k = k1 - \lambda * k2 -// so affine point is transformed as +// so affine point is transformed as // G1 -> (beta*x, -y) to be multiplied by +k2 #[derive(Clone, Debug)] pub struct EndomorphismParameters { @@ -38,7 +26,7 @@ pub struct EndomorphismParameters { pub target_scalar_width: usize, } -impl EndomorphismParameters { +impl EndomorphismParameters { pub fn calculate_decomposition(&self, val: E::Fr) -> (E::Fr, E::Fr) { // fast variant let value = repr_to_biguint::(&val.into_repr()); @@ -114,7 +102,7 @@ pub fn bn254_endomorphism_parameters() -> EndomorphismParameters where G::Base: PrimeField { +pub struct MultiexpTable<'a, E: Engine, G: GenericCurveAffine> +where + G::Base: PrimeField, +{ width_four_tables: Vec>; 2]>>, width_three_table: Option>; 2]>>, width_two_table: Option>; 2]>>, @@ -61,12 +38,12 @@ pub struct MultiexpTable<'a, E: Engine, G: GenericCurveAffine> where G::Base: Pr pub width: usize, } -impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base: PrimeField { +impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> +where + G::Base: PrimeField, +{ #[track_caller] - pub fn new>( - cs: &mut CS, - points: &[AffinePoint<'a, E, G>] - ) -> Result { + pub fn new>(cs: &mut CS, points: &[AffinePoint<'a, E, G>]) -> Result { let params = points[0].x.representation_params; let width = points.len(); @@ -98,7 +75,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base let mut width_two_table_elements = None; match remainder.len() { - 0 => {}, + 0 => {} 1 => { let mut point = remainder[0].clone(); let (minus_y, y) = point.y.clone().negated(cs)?; @@ -111,17 +88,17 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base } single_bit_pair = Some([point_negated, point]); - }, + } 2 => { let (t, e) = Self::make_width_two_table(cs, remainder)?; width_two_table = Some(t); width_two_table_elements = Some(e); - }, + } 3 => { let (t, e) = Self::make_width_three_table(cs, remainder)?; width_three_table = Some(t); width_three_table_elements = Some(e); - }, + } _ => { unreachable!() } @@ -136,17 +113,14 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base width_three_table_elements, width_two_table_elements, params: params, - width + width, }; Ok(table) } #[track_caller] - fn make_width_four_table>( - cs: &mut CS, - chunk: &[AffinePoint<'a, E, G>] - ) -> Result<(Vec<[SelectorTable< E, Term>; 2]>, Vec>), SynthesisError> { + fn make_width_four_table>(cs: &mut CS, chunk: &[AffinePoint<'a, E, G>]) -> Result<(Vec<[SelectorTable>; 2]>, Vec>), SynthesisError> { assert_eq!(chunk.len(), 4); // first we need to shuffle points themselves @@ -174,9 +148,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base let params = entry_0.x.representation_params; - let entries = vec![ - entry_0, entry_1, entry_2, entry_3, entry_4, entry_5, entry_6, entry_7 - ]; + let entries = vec![entry_0, entry_1, entry_2, entry_3, entry_4, entry_5, entry_6, entry_7]; // now make individual lookup tables for each limb @@ -201,10 +173,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base } #[track_caller] - fn make_width_three_table>( - cs: &mut CS, - chunk: &[AffinePoint<'a, E, G>] - ) -> Result<(Vec<[SelectorTable< E, Term>; 2]>, Vec>), SynthesisError> { + fn make_width_three_table>(cs: &mut CS, chunk: &[AffinePoint<'a, E, G>]) -> Result<(Vec<[SelectorTable>; 2]>, Vec>), SynthesisError> { assert_eq!(chunk.len(), 3); // first we need to shuffle points themselves @@ -226,9 +195,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base let params = entry_0.x.representation_params; - let entries = vec![ - entry_0, entry_1, entry_2, entry_3 - ]; + let entries = vec![entry_0, entry_1, entry_2, entry_3]; // now make individual lookup tables for each limb @@ -253,10 +220,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base } #[track_caller] - fn make_width_two_table>( - cs: &mut CS, - chunk: &[AffinePoint<'a, E, G>] - ) -> Result<(Vec<[SelectorTable< E, Term>; 2]>, Vec>), SynthesisError> { + fn make_width_two_table>(cs: &mut CS, chunk: &[AffinePoint<'a, E, G>]) -> Result<(Vec<[SelectorTable>; 2]>, Vec>), SynthesisError> { assert_eq!(chunk.len(), 2); // first we need to shuffle points themselves @@ -268,9 +232,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base let params = entry_0.x.representation_params; - let entries = vec![ - entry_0, entry_1 - ]; + let entries = vec![entry_0, entry_1]; // now make individual lookup tables for each limb @@ -298,7 +260,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base cs: &mut CS, tables: &Vec<[SelectorTable>; 2]>, bits: &[Boolean], - params: &'a RnsParameters + params: &'a RnsParameters, ) -> Result, SynthesisError> { assert!(bits.len() >= 2); assert!(bits.len() <= 4); @@ -306,7 +268,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base let mut selection_bits = Vec::with_capacity(bits.len() - 1); - for i in (0..(bits.len()-1)).rev() { + for i in (0..(bits.len() - 1)).rev() { let bb = Boolean::xor(cs, &negation_bit, &bits[i])?; selection_bits.push(bb); @@ -323,7 +285,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base selected_y_limb_terms.push(selected_y_term); } - // now reconstruct limbs (add bit width) and base field term + // now reconstruct limbs (add bit width) and base field term let mut shift_constant = E::Fr::one(); @@ -338,29 +300,24 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base let mut value_is_none = false; - for (limb_idx, ((x_term, y_term), max_value)) in selected_x_limb_terms.into_iter() - .zip(selected_y_limb_terms.into_iter()) - .zip(params.binary_limbs_max_values.iter().cloned()) - .enumerate() + for (limb_idx, ((x_term, y_term), max_value)) in selected_x_limb_terms + .into_iter() + .zip(selected_y_limb_terms.into_iter()) + .zip(params.binary_limbs_max_values.iter().cloned()) + .enumerate() { - let x_limb = Limb::new( - x_term.clone(), - max_value.clone() - ); + let x_limb = Limb::new(x_term.clone(), max_value.clone()); if let Some(v) = x_term.get_value() { - x_value += fe_to_biguint(&v) << (params.binary_limbs_params.limb_size_bits * limb_idx); + x_value += fe_to_biguint(&v) << (params.binary_limbs_params.limb_size_bits * limb_idx); } else { value_is_none = true; } - let y_limb = Limb::new( - y_term.clone(), - max_value.clone() - ); + let y_limb = Limb::new(y_term.clone(), max_value.clone()); if let Some(v) = y_term.get_value() { - y_value += fe_to_biguint(&v) << (params.binary_limbs_params.limb_size_bits * limb_idx); + y_value += fe_to_biguint(&v) << (params.binary_limbs_params.limb_size_bits * limb_idx); } else { value_is_none = true; } @@ -404,14 +361,14 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base binary_limbs: x_limbs, base_field_limb: x_base, value: x, - representation_params: params + representation_params: params, }; let selected_y = FieldElement:: { binary_limbs: y_limbs, base_field_limb: y_base, value: y, - representation_params: params + representation_params: params, }; let (negated_y, selected_y) = selected_y.negated(cs)?; @@ -425,26 +382,21 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base } Some(val) - }, - _ => { - None } + _ => None, }; let point = AffinePoint::<_, _> { x: selected_x, y: final_y, - value: point_value + value: point_value, }; Ok(point) } #[track_caller] - pub fn make_base>( - &self, - cs: &mut CS - ) -> Result, SynthesisError> { + pub fn make_base>(&self, cs: &mut CS) -> Result, SynthesisError> { let mut queries = vec![]; for w_4 in self.width_four_table_elements.iter() { queries.push(w_4[0].clone()); @@ -473,11 +425,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base } #[track_caller] - pub fn lookup_for_skewed_entries>( - &self, - cs: &mut CS, - bits: &[Boolean] - ) -> Result, SynthesisError> { + pub fn lookup_for_skewed_entries>(&self, cs: &mut CS, bits: &[Boolean]) -> Result, SynthesisError> { let mut queries = vec![]; assert!(self.width == bits.len()); @@ -496,7 +444,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base assert!(remainder.len() < 4); match remainder.len() { - 0 => {}, + 0 => {} 1 => { let w1 = self.width_one_elements.as_ref().unwrap(); let (y, _) = FieldElement::select(cs, &remainder[0], w1[0].y.clone(), w1[1].y.clone())?; @@ -512,24 +460,20 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base None }; - let point = AffinePoint::<_, _> { - x: x, - y: y, - value: new_value - }; + let point = AffinePoint::<_, _> { x: x, y: y, value: new_value }; queries.push(point); - }, + } 2 => { let w2 = self.width_two_table.as_ref().unwrap(); let q = Self::select_from_table_two_to_four(cs, w2, remainder, self.params)?; queries.push(q); - }, + } 3 => { let w3 = self.width_three_table.as_ref().unwrap(); let q = Self::select_from_table_two_to_four(cs, w3, remainder, self.params)?; queries.push(q); - }, + } _ => { unreachable!() } @@ -546,4 +490,4 @@ impl<'a, E: Engine, G: GenericCurveAffine> MultiexpTable<'a, E, G> where G::Base Ok(base) } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/curve/selection_table.rs b/crates/franklin-crypto/src/plonk/circuit/curve/selection_table.rs index deab450..6e3c837 100644 --- a/crates/franklin-crypto/src/plonk/circuit/curve/selection_table.rs +++ b/crates/franklin-crypto/src/plonk/circuit/curve/selection_table.rs @@ -1,50 +1,24 @@ -use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, - GenericCurveProjective -}; +use crate::bellman::pairing::{Engine, GenericCurveAffine, GenericCurveProjective}; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator, - ScalarEngine -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, ScalarEngine}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - TrivialAssembly, - PlonkCsWidth4WithNextStepParams, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; use super::super::allocated_num::{AllocatedNum, Num}; +use super::super::boolean::{AllocatedBit, Boolean}; use super::super::linear_combination::LinearCombination; use super::super::simple_term::Term; -use super::super::boolean::{Boolean, AllocatedBit}; use num_bigint::BigUint; use num_integer::Integer; -use super::super::bigint::field::*; use super::super::bigint::bigint::*; +use super::super::bigint::field::*; use super::sw_affine::*; @@ -66,7 +40,6 @@ pub trait TableSelectable: Sized + Clone { fn from_bit(bit: &Boolean) -> Self; } - impl TableSelectable for Term { fn add>(cs: &mut CS, first: Self, second: Self) -> Result { let result = first.add(cs, &second)?; @@ -152,14 +125,11 @@ impl TableSelectable for Term { #[derive(Clone, Debug)] pub struct SelectorTable> { entries: Vec, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl> SelectorTable { - pub fn new_from_entries>( - cs: &mut CS, - entries: &[T] - ) -> Result { + pub fn new_from_entries>(cs: &mut CS, entries: &[T]) -> Result { match entries.len() { 0 => { panic!("empty table!"); @@ -168,17 +138,17 @@ impl> SelectorTable { let new = Self::new_one_bit_table(entries); Ok(new) - }, + } 4 => { let new = Self::new_two_bit_table(cs, entries)?; Ok(new) - }, + } 8 => { let new = Self::new_three_bit_table(cs, entries)?; Ok(new) - }, + } l @ _ => { unimplemented!("large table length is not supported, or length {} is invalid", l); } @@ -188,14 +158,11 @@ impl> SelectorTable { fn new_one_bit_table(entries: &[T]) -> Self { Self { entries: entries.to_vec(), - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } - fn new_two_bit_table>( - cs: &mut CS, - entries: &[T] - ) -> Result { + fn new_two_bit_table>(cs: &mut CS, entries: &[T]) -> Result { assert_eq!(entries.len(), 4); // make a table of linear combinations @@ -215,16 +182,13 @@ impl> SelectorTable { let new = Self { entries: vec![entry_0, entry_1, entry_2, entry_3], - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok(new) } - fn new_three_bit_table>( - cs: &mut CS, - entries: &[T] - ) -> Result { + fn new_three_bit_table>(cs: &mut CS, entries: &[T]) -> Result { assert_eq!(entries.len(), 8); // make a table of linear combinations @@ -256,17 +220,13 @@ impl> SelectorTable { let new = Self { entries: vec![entry_0, entry_1, entry_2, entry_3, entry_4, entry_5, entry_6, entry_7], - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, }; Ok(new) } - pub fn select>( - &self, - cs: &mut CS, - bits: &[Boolean] - ) -> Result { + pub fn select>(&self, cs: &mut CS, bits: &[Boolean]) -> Result { match bits.len() { 0 => { panic!("empty table!"); @@ -275,28 +235,24 @@ impl> SelectorTable { let result = self.select_one_bit(cs, bits)?; Ok(result) - }, + } 2 => { let result = self.select_two_bits(cs, bits)?; Ok(result) - }, + } 3 => { let result = self.select_three_bits(cs, bits)?; Ok(result) - }, + } _ => { unimplemented!("large table length is not supported"); } } } - fn select_one_bit>( - &self, - cs: &mut CS, - bits: &[Boolean] - ) -> Result { + fn select_one_bit>(&self, cs: &mut CS, bits: &[Boolean]) -> Result { assert_eq!(bits.len(), 1); assert_eq!(self.entries.len(), 2); @@ -305,11 +261,7 @@ impl> SelectorTable { Ok(result) } - fn select_two_bits>( - &self, - cs: &mut CS, - bits: &[Boolean] - ) -> Result { + fn select_two_bits>(&self, cs: &mut CS, bits: &[Boolean]) -> Result { assert_eq!(bits.len(), 2); assert_eq!(self.entries.len(), 4); @@ -334,11 +286,7 @@ impl> SelectorTable { Ok(s2) } - fn select_three_bits>( - &self, - cs: &mut CS, - bits: &[Boolean] - ) -> Result { + fn select_three_bits>(&self, cs: &mut CS, bits: &[Boolean]) -> Result { assert_eq!(bits.len(), 3); assert_eq!(self.entries.len(), 8); @@ -363,11 +311,11 @@ impl> SelectorTable { mod test { use super::*; - use crate::bellman::pairing::bn256::{Fq, Bn256, Fr, G1Affine}; + use crate::bellman::pairing::bn256::{Bn256, Fq, Fr, G1Affine}; #[test] - fn test_one_bit_table(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_one_bit_table() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..10 { @@ -377,12 +325,7 @@ mod test { let mut terms = vec![]; for i in input.iter() { - let n = AllocatedNum::alloc( - &mut cs, - || { - Ok(*i) - } - ).unwrap(); + let n = AllocatedNum::alloc(&mut cs, || Ok(*i)).unwrap(); let t = Term::::from_allocated_num(n); terms.push(t); } @@ -401,8 +344,8 @@ mod test { } #[test] - fn test_two_bit_table(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_two_bit_table() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..10 { @@ -412,12 +355,7 @@ mod test { let mut terms = vec![]; for i in input.iter() { - let n = AllocatedNum::alloc( - &mut cs, - || { - Ok(*i) - } - ).unwrap(); + let n = AllocatedNum::alloc(&mut cs, || Ok(*i)).unwrap(); let t = Term::::from_allocated_num(n); terms.push(t); } @@ -458,8 +396,8 @@ mod test { } #[test] - fn test_three_bit_table(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_three_bit_table() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..10 { @@ -469,12 +407,7 @@ mod test { let mut terms = vec![]; for i in input.iter() { - let n = AllocatedNum::alloc( - &mut cs, - || { - Ok(*i) - } - ).unwrap(); + let n = AllocatedNum::alloc(&mut cs, || Ok(*i)).unwrap(); let t = Term::::from_allocated_num(n); terms.push(t); } @@ -498,4 +431,4 @@ mod test { } } } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/curve/sw_affine.rs b/crates/franklin-crypto/src/plonk/circuit/curve/sw_affine.rs index fbfa300..aa7ff5d 100644 --- a/crates/franklin-crypto/src/plonk/circuit/curve/sw_affine.rs +++ b/crates/franklin-crypto/src/plonk/circuit/curve/sw_affine.rs @@ -1,61 +1,41 @@ -use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, - GenericCurveProjective, -}; +use crate::bellman::pairing::{Engine, GenericCurveAffine, GenericCurveProjective}; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator, - ScalarEngine -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, ScalarEngine}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - TrivialAssembly, - PlonkCsWidth4WithNextStepParams, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; use crate::plonk::circuit::Assignment; use super::super::allocated_num::{AllocatedNum, Num}; +use super::super::boolean::{AllocatedBit, Boolean}; use super::super::linear_combination::LinearCombination; use super::super::simple_term::Term; -use super::super::boolean::{Boolean, AllocatedBit}; use num_bigint::BigUint; use num_integer::Integer; -use super::super::bigint::field::*; use super::super::bigint::bigint::*; +use super::super::bigint::field::*; #[derive(Clone, Debug)] -pub struct AffinePoint<'a, E: Engine, G: GenericCurveAffine> where ::Base: PrimeField { +pub struct AffinePoint<'a, E: Engine, G: GenericCurveAffine> +where + ::Base: PrimeField, +{ pub x: FieldElement<'a, E, G::Base>, pub y: FieldElement<'a, E, G::Base>, pub value: Option, } -impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where ::Base: PrimeField { +impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> +where + ::Base: PrimeField, +{ pub fn get_x(&self) -> FieldElement<'a, E, G::Base> { self.x.clone() } @@ -64,116 +44,67 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >( - cs: &mut CS, - value: Option, - params: &'a RnsParameters - ) -> Result { + pub fn alloc>(cs: &mut CS, value: Option, params: &'a RnsParameters) -> Result { let (x, y) = match value { Some(v) => { assert!(!v.is_zero()); let (x, y) = v.into_xy_unchecked(); (Some(x), Some(y)) - }, - None => { - (None, None) } + None => (None, None), }; - let x = FieldElement::new_allocated_in_field( - cs, - x, - params - )?; + let x = FieldElement::new_allocated_in_field(cs, x, params)?; - let y = FieldElement::new_allocated_in_field( - cs, - y, - params - )?; + let y = FieldElement::new_allocated_in_field(cs, y, params)?; // let x = FieldElement::new_allocated( - // cs, - // x, + // cs, + // x, // params // )?; // let y = FieldElement::new_allocated( - // cs, - // y, + // cs, + // y, // params // )?; - let new = Self { - x, - y, - value - }; + let new = Self { x, y, value }; Ok(new) } - pub fn from_xy_unchecked( - x: FieldElement<'a, E, G::Base>, - y: FieldElement<'a, E, G::Base>, - ) -> Self { + pub fn from_xy_unchecked(x: FieldElement<'a, E, G::Base>, y: FieldElement<'a, E, G::Base>) -> Self { let value = match (x.get_field_value(), y.get_field_value()) { - (Some(x), Some(y)) => { - Some(G::from_xy_unchecked(x, y)) - }, - _ => { - None - } + (Some(x), Some(y)) => Some(G::from_xy_unchecked(x, y)), + _ => None, }; - let new = Self { - x, - y, - value - }; + let new = Self { x, y, value }; new } - pub fn constant( - value: G, - params: &'a RnsParameters - ) -> Self { + pub fn constant(value: G, params: &'a RnsParameters) -> Self { assert!(!value.is_zero()); let (x, y) = value.into_xy_unchecked(); - let x = FieldElement::new_constant( - x, - params - ); + let x = FieldElement::new_constant(x, params); - let y = FieldElement::new_constant( - y, - params - ); + let y = FieldElement::new_constant(y, params); - let new = Self { - x, - y, - value: Some(value) - }; + let new = Self { x, y, value: Some(value) }; new } - pub fn zero( - params: &'a RnsParameters - ) -> Self - { + pub fn zero(params: &'a RnsParameters) -> Self { let x = FieldElement::zero(params); let y = FieldElement::zero(params); - let new = Self { - x, - y, - value: Some(G::zero()) - }; + let new = Self { x, y, value: Some(G::zero()) }; new } @@ -186,10 +117,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >( - self, - cs: &mut CS - ) -> Result { + fn normalize_coordinates>(self, cs: &mut CS) -> Result { let this_value = self.value; let this_x = self.x.force_reduce_close_to_modulus(cs)?; @@ -198,18 +126,13 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >( - cs: &mut CS, - this: Self, - other: Self, - ) -> Result<(Boolean, (Self, Self)), SynthesisError> - { + pub fn equals>(cs: &mut CS, this: Self, other: Self) -> Result<(Boolean, (Self, Self)), SynthesisError> { let this = this.normalize_coordinates(cs)?; let other = other.normalize_coordinates(cs)?; @@ -226,47 +149,40 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >( - self, - cs: &mut CS, - ) -> Result<(Self, Self), SynthesisError> { + pub fn negate>(self, cs: &mut CS) -> Result<(Self, Self), SynthesisError> { let this_value = self.get_value(); let this_x = self.x; let this_y = self.y; let (this_y_negated, this_y) = this_y.negated(cs)?; - + let new_value = match this_value { Some(this) => { let mut tmp = this; tmp.negate(); Some(tmp) - }, - _ => None + } + _ => None, }; - + let new = Self { x: this_x.clone(), y: this_y_negated, - value: new_value + value: new_value, }; let this = Self { x: this_x, y: this_y, - value: this_value + value: this_value, }; Ok((new, this)) } - pub fn conditionally_negate>( - self, - cs: &mut CS, - flag: &Boolean - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn conditionally_negate>(self, cs: &mut CS, flag: &Boolean) -> Result<(Self, (Self, Self)), SynthesisError> { let this_value = self.get_value(); let this_value_nagated = this_value.map(|el| { let mut tmp = el; @@ -282,8 +198,8 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where None + } + _ => None, }; let this_x = self.x; @@ -292,38 +208,34 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn add_unequal>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { match (self.get_value(), other.get_value()) { (Some(first), Some(second)) => { assert!(first != second, "points are actually equal with value {}", first); - }, + } _ => {} } @@ -344,24 +256,19 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn add_unequal_unchecked>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { match (self.get_value(), other.get_value()) { (Some(first), Some(second)) => { assert!(first != second, "points are actually equal with value {}", first); - }, + } _ => {} } // since we are in a circuit we don't use projective coodinates cause inversions are - // "cheap" in terms of constraints + // "cheap" in terms of constraints // we also do not want to have branching here, - // so this function implicitly requires that + // so this function implicitly requires that // points are not equal // we need to calculate lambda = (y' - y)/(x' - x). We don't care about a particular @@ -403,48 +310,40 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where None - }; - - let new = Self { - x: new_x, - y: new_y, - value: new_value + } + _ => None, }; + let new = Self { x: new_x, y: new_y, value: new_value }; + let this = Self { x: this_x, y: this_y, - value: this_value + value: this_value, }; let other = Self { x: other_x, y: other_y, - value: other_value + value: other_value, }; Ok((new, (this, other))) } #[track_caller] - pub fn sub_unequal>( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn sub_unequal>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { match (self.get_value(), other.get_value()) { (Some(first), Some(second)) => { assert!(first != second, "points are actually equal with value {}", first); - }, + } _ => {} } // since we are in a circuit we don't use projective coodinates cause inversions are - // "cheap" in terms of constraints + // "cheap" in terms of constraints // we also do not want to have branching here, - // so this function implicitly requires that + // so this function implicitly requires that // points are not equal // we need to calculate lambda = (y' - y)/(x' - x). We don't care about a particular @@ -479,7 +378,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where AffinePoint<'a, E, G> where None - }; - - let new = Self { - x: new_x, - y: new_y, - value: new_value + } + _ => None, }; + let new = Self { x: new_x, y: new_y, value: new_value }; + let this = Self { x: this_x, y: this_y, - value: this_value + value: this_value, }; let other = Self { x: other_x, y: other_y, - value: other_value + value: other_value, }; - Ok((new, (this, other))) } #[track_caller] - pub fn double>( - self, - cs: &mut CS, - ) -> Result<(Self, Self), SynthesisError> { + pub fn double>(self, cs: &mut CS) -> Result<(Self, Self), SynthesisError> { // since we are in a circuit we don't use projective coodinates cause inversions are - // "cheap" in terms of constraints + // "cheap" in terms of constraints // we also do not want to have branching here, - // so this function implicitly requires that + // so this function implicitly requires that // points are not equal // we need to calculate lambda = (y' - y)/(x' - x). We don't care about a particular @@ -563,32 +454,19 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where None - }; - - let new = Self { - x: new_x, - y: new_y, - value: new_value + } + _ => None, }; - let this = Self { - x: x, - y: y, - value: this_value - }; + let new = Self { x: new_x, y: new_y, value: new_value }; + let this = Self { x: x, y: y, value: this_value }; Ok((new, this)) } #[track_caller] - pub fn double_and_add>( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn double_and_add>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { // doubles self and adds other // even though https://www.researchgate.net/publication/283556724_New_Fast_Algorithms_for_Elliptic_Curve_Arithmetic_in_Affine_Coordinates exists @@ -611,13 +489,8 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn double_and_add_unchecked>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { // doubles self and adds other // even though https://www.researchgate.net/publication/283556724_New_Fast_Algorithms_for_Elliptic_Curve_Arithmetic_in_Affine_Coordinates exists @@ -678,46 +551,32 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where None - }; - - let new = Self { - x: new_x, - y: new_y, - value: new_value + } + _ => None, }; + let new = Self { x: new_x, y: new_y, value: new_value }; + let this = Self { x: this_x, y: this_y, - value: this_value + value: this_value, }; let other = Self { x: other_x, y: other_y, - value: other_value + value: other_value, }; Ok((new, (this, other))) } - pub fn mul_by_fixed_scalar>( - self, - _cs: &mut CS, - _scalar: &G::Scalar - ) -> Result<(Self, Self), SynthesisError> { + pub fn mul_by_fixed_scalar>(self, _cs: &mut CS, _scalar: &G::Scalar) -> Result<(Self, Self), SynthesisError> { unimplemented!() } - pub fn select>( - cs: &mut CS, - flag: &Boolean, - first: Self, - second: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { - + pub fn select>(cs: &mut CS, flag: &Boolean, first: Self, second: Self) -> Result<(Self, (Self, Self)), SynthesisError> { let first_value = first.get_value(); let second_value = second.get_value(); let (x, (first_x, second_x)) = FieldElement::select(cs, flag, first.x, second.x)?; @@ -726,36 +585,28 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where Some(p), (Some(false), _, Some(p)) => Some(p), - (_, _, _) => None + (_, _, _) => None, }; - let selected = AffinePoint { - x : x, - y : y, - value - }; + let selected = AffinePoint { x: x, y: y, value }; let first = Self { x: first_x, y: first_y, - value: first_value + value: first_value, }; let second = Self { x: second_x, y: second_y, - value: second_value + value: second_value, }; Ok((selected, (first, second))) } #[track_caller] - pub fn is_on_curve_for_zero_a>( - self, - cs: &mut CS, - curve_b: G::Base - ) -> Result<(Boolean, Self), SynthesisError> { + pub fn is_on_curve_for_zero_a>(self, cs: &mut CS, curve_b: G::Base) -> Result<(Boolean, Self), SynthesisError> { let params = self.x.representation_params; assert_eq!(curve_b, G::b_coeff()); let b = FieldElement::new_constant(curve_b, params); @@ -780,21 +631,12 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >( - self, - cs: &mut CS, - entries: &[Boolean], - offset_generator: G, - ) -> Result<(Self, Self), SynthesisError> { + pub fn mul_by_skewed_scalar_decomposition>(self, cs: &mut CS, entries: &[Boolean], offset_generator: G) -> Result<(Self, Self), SynthesisError> { let params = self.x.representation_params; let this_value = self.get_value(); let this_copy = self.clone(); @@ -815,8 +657,8 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where { let mut val = val; @@ -825,15 +667,11 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where None + } + _ => None, }; - let t = Self { - x: x, - y: selected_y, - value: t_value - }; + let t = Self { x: x, y: selected_y, value: t_value }; let (new_acc, (_, t)) = acc.double_and_add(cs, t)?; @@ -861,8 +699,8 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where None + } + _ => None, }; let (final_acc_x, _) = FieldElement::select(cs, last_entry, with_skew_x, acc_x)?; @@ -877,7 +715,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where AffinePoint<'a, E, G> where AffinePoint<'a, E, E::G1Affine> { #[track_caller] - pub fn mul>( - self, - cs: &mut CS, - scalar: &Num::, - bit_limit: Option - ) -> Result<(Self, Self), SynthesisError> { + pub fn mul>(self, cs: &mut CS, scalar: &Num, bit_limit: Option) -> Result<(Self, Self), SynthesisError> { if let Some(value) = scalar.get_value() { assert!(!value.is_zero(), "can not multiply by zero in the current approach"); } @@ -913,10 +746,7 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { // we add a random point to the accumulator to avoid having zero anywhere (with high probability) // and unknown discrete log allows us to be "safe" - let offset_generator = crate::constants::make_random_points_with_unknown_discrete_log_proj::( - &crate::constants::MULTIEXP_DST[..], - 1 - )[0]; + let offset_generator = crate::constants::make_random_points_with_unknown_discrete_log_proj::(&crate::constants::MULTIEXP_DST[..], 1)[0]; let generator = Self::constant(offset_generator, params); @@ -932,8 +762,8 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { let (minus_y, y) = y.negated(cs)?; for e in entries_without_first_and_last.iter() { - let (selected_y, _) = FieldElement::select(cs, e, minus_y.clone(), y.clone())?; - + let (selected_y, _) = FieldElement::select(cs, e, minus_y.clone(), y.clone())?; + let t_value = match (this_value, e.get_value()) { (Some(val), Some(bit)) => { let mut val = val; @@ -942,15 +772,11 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { } Some(val) - }, - _ => None + } + _ => None, }; - let t = Self { - x: x, - y: selected_y, - value: t_value - }; + let t = Self { x: x, y: selected_y, value: t_value }; let (new_acc, (_, t)) = acc.double_and_add(cs, t)?; @@ -978,8 +804,8 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { } else { Some(a_value) } - }, - _ => None + } + _ => None, }; let (final_acc_x, _) = FieldElement::select(cs, last_entry, with_skew_x, acc_x)?; @@ -993,7 +819,7 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { let result = Self { x: final_acc_x, y: final_acc_y, - value: final_value + value: final_value, }; let (result, _) = result.sub_unequal(cs, offset)?; @@ -1002,12 +828,7 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { } #[track_caller] - pub fn multiexp>( - cs: &mut CS, - scalars: &[Num::], - points: &[Self], - bit_limit: Option - ) -> Result { + pub fn multiexp>(cs: &mut CS, scalars: &[Num], points: &[Self], bit_limit: Option) -> Result { assert_eq!(scalars.len(), points.len()); let params = points[0].x.representation_params; @@ -1034,10 +855,7 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { // we add a random point to the accumulator to avoid having zero anywhere (with high probability) // and unknown discrete log allows us to be "safe" - let offset_generator = crate::constants::make_random_points_with_unknown_discrete_log_proj::( - &crate::constants::MULTIEXP_DST[..], - 1 - )[0]; + let offset_generator = crate::constants::make_random_points_with_unknown_discrete_log_proj::(&crate::constants::MULTIEXP_DST[..], 1)[0]; let generator = Self::constant(offset_generator, params); @@ -1088,8 +906,8 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { } else { Some(a_value) } - }, - _ => None + } + _ => None, }; let (final_acc_x, _) = FieldElement::select(cs, last_entry, with_skew_x, acc_x)?; @@ -1098,26 +916,26 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { let result = Self { x: final_acc_x, y: final_acc_y, - value: final_value + value: final_value, }; acc = result; } - + let shift = BigUint::from(1u64) << num_doubles; let as_scalar_repr = biguint_to_repr::(shift); let offset_value = offset_generator.mul(as_scalar_repr).into_affine(); let offset = Self::constant(offset_value, params); let (result, _) = acc.sub_unequal(cs, offset)?; - + Ok(result) } #[track_caller] pub fn multiexp_using_endomorphism>( cs: &mut CS, - scalars: &[Num::], + scalars: &[Num], points: &[Self], endo_parameters: &super::endomorphism::EndomorphismParameters, ) -> Result { @@ -1139,15 +957,11 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { let (x_beta, (x, _)) = x.mul(cs, beta.clone())?; let (y_negated, y) = y.negated(cs)?; - let p = AffinePoint { - x, - y, - value, - }; + let p = AffinePoint { x, y, value }; let p_endo = AffinePoint { x: x_beta, - y: y_negated, + y: y_negated, value: endo_value, }; @@ -1168,7 +982,7 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { // let (k1, k2) = endo_parameters.calculate_decomposition(*c); // (Num::Constant(k1), Num::Constant(k1)) - }, + } Num::Variable(var) => { let (k1_val, k2_val) = if let Some(val) = var.get_value() { let (k1, k2) = endo_parameters.calculate_decomposition(val); @@ -1177,7 +991,7 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { reconstruction.mul_assign(&endo_parameters.lambda); reconstruction.negate(); reconstruction.add_assign(&k1); - + assert_eq!(reconstruction, val); (Some(k1), Some(k2)) @@ -1215,18 +1029,11 @@ impl<'a, E: Engine> AffinePoint<'a, E, E::G1Affine> { } #[track_caller] -pub fn decompose_allocated_num_into_skewed_table>( - cs: &mut CS, - num: &AllocatedNum, - bit_limit: Option -) -> Result, SynthesisError> { +pub fn decompose_allocated_num_into_skewed_table>(cs: &mut CS, num: &AllocatedNum, bit_limit: Option) -> Result, SynthesisError> { let bit_values = compute_skewed_naf_table(&num.get_value(), bit_limit); let mut bits = Vec::with_capacity(bit_values.len()); for b in bit_values { - let a = Boolean::from(AllocatedBit::alloc( - cs, - b - )?); + let a = Boolean::from(AllocatedBit::alloc(cs, b)?); bits.push(a); } @@ -1302,16 +1109,12 @@ fn get_bit(repr: &R, bit: usize) -> bool { #[track_caller] fn compute_skewed_naf_table(value: &Option, bit_limit: Option) -> Vec> { - let bit_limit = if let Some(limit) = bit_limit { - limit - } else { - F::NUM_BITS as usize - }; + let bit_limit = if let Some(limit) = bit_limit { limit } else { F::NUM_BITS as usize }; assert!(bit_limit > 0); if value.is_none() { - return vec![None; bit_limit+1]; + return vec![None; bit_limit + 1]; } let value = value.unwrap(); @@ -1319,7 +1122,7 @@ fn compute_skewed_naf_table(value: &Option, bit_limit: Option< let one_repr = F::one().into_repr(); - let mut bits = vec![None; bit_limit+1]; + let mut bits = vec![None; bit_limit + 1]; if get_bit(&value_repr, 0) == false { *bits.last_mut().unwrap() = Some(true); @@ -1331,7 +1134,7 @@ fn compute_skewed_naf_table(value: &Option, bit_limit: Option< let inner_bits = &mut bits[1..bit_limit]; for (i, bit) in inner_bits.iter_mut().rev().enumerate() { - let b = get_bit(&value_repr, i+1); + let b = get_bit(&value_repr, i + 1); if b { *bit = Some(false); } else { @@ -1359,19 +1162,11 @@ fn compute_skewed_naf_table(value: &Option, bit_limit: Option< reconstructed.double(); let high_bit = bits[i].unwrap(); - let mut high_contribution = if high_bit { - minus_one - } else { - F::one() - }; + let mut high_contribution = if high_bit { minus_one } else { F::one() }; high_contribution.double(); - let low_bit = bits[i+1].unwrap(); - let low_contribution = if low_bit { - minus_one - } else { - F::one() - }; + let low_bit = bits[i + 1].unwrap(); + let low_contribution = if low_bit { minus_one } else { F::one() }; reconstructed.add_assign(&high_contribution); reconstructed.add_assign(&low_contribution); @@ -1380,7 +1175,7 @@ fn compute_skewed_naf_table(value: &Option, bit_limit: Option< if bit_limit & 1 == 1 { reconstructed.double(); - let last_bit = bits[bit_limit-1].unwrap(); + let last_bit = bits[bit_limit - 1].unwrap(); if last_bit { reconstructed.add_assign(&minus_one); } else { @@ -1402,10 +1197,7 @@ fn simulate_multiplication(point: E::G1Affine, scalar: E::Fr, num_bit let entries = compute_skewed_naf_table(&Some(scalar), num_bits); let base = point; - let offset_generator = crate::constants::make_random_points_with_unknown_discrete_log_proj::( - &crate::constants::MULTIEXP_DST[..], - 1 - )[0]; + let offset_generator = crate::constants::make_random_points_with_unknown_discrete_log_proj::(&crate::constants::MULTIEXP_DST[..], 1)[0]; let mut accumulator = base.into_projective(); accumulator.add_assign_mixed(&offset_generator); @@ -1469,12 +1261,12 @@ fn simulate_multiplication(point: E::G1Affine, scalar: E::Fr, num_bit mod test { use super::*; + use crate::bellman::pairing::bn256::{Bn256, Fq, Fr, G1Affine}; use crate::plonk::circuit::*; - use crate::bellman::pairing::bn256::{Fq, Bn256, Fr, G1Affine}; #[test] - fn test_add_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_add_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -1484,18 +1276,10 @@ mod test { let a_f: G1Affine = rng.gen(); let b_f: G1Affine = rng.gen(); - let a = AffinePoint::alloc( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let b = AffinePoint::alloc( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); - + let a = AffinePoint::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); + + let b = AffinePoint::alloc(&mut cs, Some(b_f), ¶ms).unwrap(); + let (result, (a, b)) = a.add_unequal(&mut cs, b).unwrap(); assert!(cs.is_satisfied()); @@ -1524,10 +1308,9 @@ mod test { } } - #[test] - fn test_add_with_constant_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_add_with_constant_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -1537,17 +1320,10 @@ mod test { let a_f: G1Affine = rng.gen(); let b_f: G1Affine = rng.gen(); - let a = AffinePoint::alloc( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let b = AffinePoint::constant( - b_f, - ¶ms - ); - + let a = AffinePoint::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); + + let b = AffinePoint::constant(b_f, ¶ms); + let (result, (a, b)) = a.add_unequal(&mut cs, b).unwrap(); assert!(cs.is_satisfied()); @@ -1577,8 +1353,8 @@ mod test { } #[test] - fn test_sub_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_sub_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -1588,18 +1364,10 @@ mod test { let a_f: G1Affine = rng.gen(); let b_f: G1Affine = rng.gen(); - let a = AffinePoint::alloc( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let b = AffinePoint::alloc( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); - + let a = AffinePoint::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); + + let b = AffinePoint::alloc(&mut cs, Some(b_f), ¶ms).unwrap(); + let (result, (a, b)) = a.sub_unequal(&mut cs, b).unwrap(); assert!(cs.is_satisfied()); @@ -1629,8 +1397,8 @@ mod test { } #[test] - fn test_double_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_double_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -1640,12 +1408,8 @@ mod test { let a_f: G1Affine = rng.gen(); - let a = AffinePoint::alloc( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - + let a = AffinePoint::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); + let (result, a) = a.double(&mut cs).unwrap(); assert!(cs.is_satisfied()); @@ -1671,8 +1435,8 @@ mod test { } #[test] - fn test_double_and_add_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_double_and_add_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -1683,18 +1447,10 @@ mod test { let a_f: G1Affine = rng.gen(); let b_f: G1Affine = rng.gen(); - let a = AffinePoint::alloc( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let b = AffinePoint::alloc( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); - + let a = AffinePoint::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); + + let b = AffinePoint::alloc(&mut cs, Some(b_f), ¶ms).unwrap(); + let (result, (a, b)) = a.double_and_add(&mut cs, b).unwrap(); let mut result_recalcualted = a_f.into_projective(); @@ -1735,21 +1491,20 @@ mod test { } #[test] - fn test_skewed_decomposition_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_skewed_decomposition_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _i in 0..100 { let a_f: Fr = rng.gen(); let _ = compute_skewed_naf_table(&Some(a_f), None); - } } #[test] - fn test_allocated_skewed_decomposition_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_allocated_skewed_decomposition_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for i in 0..100 { @@ -1757,12 +1512,7 @@ mod test { let a_f: Fr = rng.gen(); - let a = AllocatedNum::alloc( - &mut cs, - || { - Ok(a_f) - } - ).unwrap(); + let a = AllocatedNum::alloc(&mut cs, || Ok(a_f)).unwrap(); let _ = decompose_allocated_num_into_skewed_table(&mut cs, &a, None).unwrap(); @@ -1774,13 +1524,12 @@ mod test { } } - #[test] - fn test_allocated_skewed_decomposition_bls12_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_allocated_skewed_decomposition_bls12_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - use crate::bellman::pairing::bls12_381::{Bls12, Fr, Fq, G1Affine, G1}; + use crate::bellman::pairing::bls12_381::{Bls12, Fq, Fr, G1Affine, G1}; let mut four = Fr::one(); four.double(); @@ -1793,12 +1542,7 @@ mod test { let a_f: Fr = rng.gen(); - let a = AllocatedNum::alloc( - &mut cs, - || { - Ok(a_f) - } - ).unwrap(); + let a = AllocatedNum::alloc(&mut cs, || Ok(a_f)).unwrap(); let _ = decompose_allocated_num_into_skewed_table(&mut cs, &a, None).unwrap(); @@ -1811,8 +1555,8 @@ mod test { } #[test] - fn test_base_curve_multiplication_by_two_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_base_curve_multiplication_by_two_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -1824,23 +1568,14 @@ mod test { let mut b_f: Fr = Fr::one(); b_f.double(); - let a = AffinePoint::alloc( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(b_f) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(b_f)).unwrap(); let b = Num::Variable(b); // simulate_multiplication::(a_f, b_f, Some(2)); - + let (result, a) = a.mul(&mut cs, &b, Some(2)).unwrap(); let result_recalculated = a_f.mul(b_f.into_repr()).into_affine(); @@ -1875,8 +1610,8 @@ mod test { } #[test] - fn test_base_curve_multiplication_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_base_curve_multiplication_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -1887,21 +1622,12 @@ mod test { let a_f: G1Affine = rng.gen(); let b_f: Fr = rng.gen(); - let a = AffinePoint::alloc( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(b_f) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(b_f)).unwrap(); let b = Num::Variable(b); - + let (result, a) = a.mul(&mut cs, &b, None).unwrap(); let result_recalculated = a_f.mul(b_f.into_repr()).into_affine(); @@ -1936,11 +1662,11 @@ mod test { } #[test] - fn test_base_curve_multiplication_with_range_table(){ - use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + fn test_base_curve_multiplication_with_range_table() { + use crate::plonk::circuit::bigint::single_table_range_constraint::{print_stats, reset_stats}; use crate::plonk::circuit::bigint::*; - use crate::plonk::circuit::bigint::single_table_range_constraint::{reset_stats, print_stats}; - use rand::{XorShiftRng, SeedableRng, Rng}; + use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let info = RangeConstraintInfo { @@ -1950,13 +1676,7 @@ mod test { linear_terms_used: 3, strategy: RangeConstraintStrategy::SingleTableInvocation, }; - let params = RnsParameters::::new_for_field_with_strategy( - 68, - 110, - 4, - info, - true - ); + let params = RnsParameters::::new_for_field_with_strategy(68, 110, 4, info, true); for i in 0..10 { let mut cs = TrivialAssembly::::new(); @@ -1964,21 +1684,12 @@ mod test { let a_f: G1Affine = rng.gen(); let b_f: Fr = rng.gen(); - let a = AffinePoint::alloc( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(b_f) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(b_f)).unwrap(); let b = Num::Variable(b); - + let (result, a) = a.mul(&mut cs, &b, None).unwrap(); let result_recalculated = a_f.mul(b_f.into_repr()).into_affine(); @@ -2017,11 +1728,11 @@ mod test { } #[test] - fn test_bn254_multiexp_10_with_range_table(){ - use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + fn test_bn254_multiexp_10_with_range_table() { + use crate::plonk::circuit::bigint::single_table_range_constraint::{print_stats, reset_stats}; use crate::plonk::circuit::bigint::*; - use crate::plonk::circuit::bigint::single_table_range_constraint::{reset_stats, print_stats}; - use rand::{XorShiftRng, SeedableRng, Rng}; + use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let info = RangeConstraintInfo { @@ -2031,13 +1742,7 @@ mod test { linear_terms_used: 3, strategy: RangeConstraintStrategy::SingleTableInvocation, }; - let params = RnsParameters::::new_for_field_with_strategy( - 68, - 110, - 4, - info, - true - ); + let params = RnsParameters::::new_for_field_with_strategy(68, 110, 4, info, true); for i in 0..10 { let mut cs = TrivialAssembly::::new(); @@ -2052,14 +1757,10 @@ mod test { a_s.push(a_f); b_s.push(b_f); } - + let mut a_p = vec![]; for a in a_s.iter() { - let a = AffinePoint::alloc( - &mut cs, - Some(*a), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(*a), ¶ms).unwrap(); a_p.push(a); } @@ -2067,12 +1768,7 @@ mod test { let mut b_n = vec![]; for b in b_s.iter() { - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap(); let b = Num::Variable(b); b_n.push(b); @@ -2119,11 +1815,11 @@ mod test { } #[test] - fn test_bn254_multiexp_10_with_endo_and_range_table(){ - use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + fn test_bn254_multiexp_10_with_endo_and_range_table() { + use crate::plonk::circuit::bigint::single_table_range_constraint::{print_stats, reset_stats}; use crate::plonk::circuit::bigint::*; - use crate::plonk::circuit::bigint::single_table_range_constraint::{reset_stats, print_stats}; - use rand::{XorShiftRng, SeedableRng, Rng}; + use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let info = RangeConstraintInfo { @@ -2133,13 +1829,7 @@ mod test { linear_terms_used: 3, strategy: RangeConstraintStrategy::SingleTableInvocation, }; - let params = RnsParameters::::new_for_field_with_strategy( - 68, - 110, - 4, - info, - true - ); + let params = RnsParameters::::new_for_field_with_strategy(68, 110, 4, info, true); let endo_parameters = super::super::endomorphism::bn254_endomorphism_parameters(); for i in 0..10 { @@ -2155,14 +1845,10 @@ mod test { a_s.push(a_f); b_s.push(b_f); } - + let mut a_p = vec![]; for a in a_s.iter() { - let a = AffinePoint::alloc( - &mut cs, - Some(*a), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(*a), ¶ms).unwrap(); a_p.push(a); } @@ -2170,12 +1856,7 @@ mod test { let mut b_n = vec![]; for b in b_s.iter() { - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap(); let b = Num::Variable(b); b_n.push(b); @@ -2222,8 +1903,8 @@ mod test { } #[test] - fn test_base_curve_multiexp_1_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_base_curve_multiexp_1_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -2234,18 +1915,9 @@ mod test { let a_f: G1Affine = rng.gen(); let b_f: Fr = rng.gen(); - let a = AffinePoint::alloc( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(a_f), ¶ms).unwrap(); - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(b_f) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(b_f)).unwrap(); let b = Num::Variable(b); @@ -2283,8 +1955,8 @@ mod test { } #[test] - fn test_base_curve_multiexp_2_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_base_curve_multiexp_2_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -2301,14 +1973,10 @@ mod test { a_s.push(a_f); b_s.push(b_f); } - + let mut a_p = vec![]; for a in a_s.iter() { - let a = AffinePoint::alloc( - &mut cs, - Some(*a), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(*a), ¶ms).unwrap(); a_p.push(a); } @@ -2316,12 +1984,7 @@ mod test { let mut b_n = vec![]; for b in b_s.iter() { - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap(); let b = Num::Variable(b); b_n.push(b); @@ -2364,8 +2027,8 @@ mod test { } #[test] - fn test_base_curve_multiexp_3_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_base_curve_multiexp_3_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -2382,14 +2045,10 @@ mod test { a_s.push(a_f); b_s.push(b_f); } - + let mut a_p = vec![]; for a in a_s.iter() { - let a = AffinePoint::alloc( - &mut cs, - Some(*a), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(*a), ¶ms).unwrap(); a_p.push(a); } @@ -2397,12 +2056,7 @@ mod test { let mut b_n = vec![]; for b in b_s.iter() { - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap(); let b = Num::Variable(b); b_n.push(b); @@ -2445,8 +2099,8 @@ mod test { } #[test] - fn test_base_curve_multiexp_4_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_base_curve_multiexp_4_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -2463,14 +2117,10 @@ mod test { a_s.push(a_f); b_s.push(b_f); } - + let mut a_p = vec![]; for a in a_s.iter() { - let a = AffinePoint::alloc( - &mut cs, - Some(*a), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(*a), ¶ms).unwrap(); a_p.push(a); } @@ -2478,12 +2128,7 @@ mod test { let mut b_n = vec![]; for b in b_s.iter() { - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap(); let b = Num::Variable(b); b_n.push(b); @@ -2526,8 +2171,8 @@ mod test { } #[test] - fn test_base_curve_multiexp_10_on_random_witnesses(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_base_curve_multiexp_10_on_random_witnesses() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let params = RnsParameters::::new_for_field(68, 110, 4); @@ -2544,14 +2189,10 @@ mod test { a_s.push(a_f); b_s.push(b_f); } - + let mut a_p = vec![]; for a in a_s.iter() { - let a = AffinePoint::alloc( - &mut cs, - Some(*a), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(*a), ¶ms).unwrap(); a_p.push(a); } @@ -2559,12 +2200,7 @@ mod test { let mut b_n = vec![]; for b in b_s.iter() { - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap(); let b = Num::Variable(b); b_n.push(b); @@ -2612,10 +2248,10 @@ mod test { #[test] fn test_base_curve_multiexp_10_bls_12_on_random_witnesses() { - use rand::{XorShiftRng, SeedableRng, Rng}; + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - use crate::bellman::pairing::bls12_381::{Bls12, Fr, Fq, G1Affine, G1}; + use crate::bellman::pairing::bls12_381::{Bls12, Fq, Fr, G1Affine, G1}; use super::super::super::bigint::get_range_constraint_info; @@ -2627,9 +2263,9 @@ mod test { // let strats = get_range_constraint_info(&cs); // let mut params = RnsParameters::::new_for_field_with_strategy( - // 96, - // 110, - // 6, + // 96, + // 110, + // 6, // strats[0], // true // ); @@ -2646,14 +2282,10 @@ mod test { a_s.push(a_f); b_s.push(b_f); } - + let mut a_p = vec![]; for a in a_s.iter() { - let a = AffinePoint::alloc( - &mut cs, - Some(*a), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(*a), ¶ms).unwrap(); a_p.push(a); } @@ -2661,12 +2293,7 @@ mod test { let mut b_n = vec![]; for b in b_s.iter() { - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap(); let b = Num::Variable(b); b_n.push(b); @@ -2712,12 +2339,12 @@ mod test { #[test] fn test_base_curve_multiexp_10_bls_12_using_tables_on_random_witnesses() { - use crate::bellman::plonk::better_better_cs::cs::*; use super::super::super::bigint::get_range_constraint_info; - use rand::{XorShiftRng, SeedableRng, Rng}; + use crate::bellman::plonk::better_better_cs::cs::*; + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - use crate::bellman::pairing::bls12_381::{Bls12, Fr, Fq, G1Affine, G1}; + use crate::bellman::pairing::bls12_381::{Bls12, Fq, Fr, G1Affine, G1}; let mut cs = TrivialAssembly::::new(); @@ -2728,13 +2355,7 @@ mod test { let strats = get_range_constraint_info(&cs); - let mut params = RnsParameters::::new_for_field_with_strategy( - 96, - 110, - 6, - strats[0], - true - ); + let mut params = RnsParameters::::new_for_field_with_strategy(96, 110, 6, strats[0], true); params.set_prefer_double_limb_carry_propagation(false); @@ -2748,14 +2369,10 @@ mod test { a_s.push(a_f); b_s.push(b_f); } - + let mut a_p = vec![]; for a in a_s.iter() { - let a = AffinePoint::alloc( - &mut cs, - Some(*a), - ¶ms - ).unwrap(); + let a = AffinePoint::alloc(&mut cs, Some(*a), ¶ms).unwrap(); a_p.push(a); } @@ -2763,12 +2380,7 @@ mod test { let mut b_n = vec![]; for b in b_s.iter() { - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap(); let b = Num::Variable(b); b_n.push(b); @@ -2791,4 +2403,4 @@ mod test { assert!(cs.is_satisfied()); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/curve/sw_projective.rs b/crates/franklin-crypto/src/plonk/circuit/curve/sw_projective.rs index 2566ac1..9e7386d 100644 --- a/crates/franklin-crypto/src/plonk/circuit/curve/sw_projective.rs +++ b/crates/franklin-crypto/src/plonk/circuit/curve/sw_projective.rs @@ -1,60 +1,40 @@ -use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, - GenericCurveProjective -}; +use crate::bellman::pairing::{Engine, GenericCurveAffine, GenericCurveProjective}; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator, - ScalarEngine -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, ScalarEngine}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - TrivialAssembly, - PlonkCsWidth4WithNextStepParams, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; use super::super::allocated_num::{AllocatedNum, Num}; +use super::super::boolean::{AllocatedBit, Boolean}; use super::super::linear_combination::LinearCombination; use super::super::simple_term::Term; -use super::super::boolean::{Boolean, AllocatedBit}; use num_bigint::BigUint; use num_integer::Integer; -use super::super::bigint::field::*; use super::super::bigint::bigint::*; +use super::super::bigint::field::*; #[derive(Clone, Debug)] -pub struct PointProjective<'a, E: Engine, G: GenericCurveAffine> where ::Base: PrimeField { +pub struct PointProjective<'a, E: Engine, G: GenericCurveAffine> +where + ::Base: PrimeField, +{ pub x: FieldElement<'a, E, G::Base>, pub y: FieldElement<'a, E, G::Base>, pub z: FieldElement<'a, E, G::Base>, pub value: Option, } -impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where ::Base: PrimeField { +impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> +where + ::Base: PrimeField, +{ pub fn get_x(&self) -> FieldElement<'a, E, G::Base> { self.x.clone() } @@ -67,42 +47,24 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where >( - cs: &mut CS, - value: Option, - params: &'a RnsParameters - ) -> Result { + pub fn alloc_from_affine_non_zero>(cs: &mut CS, value: Option, params: &'a RnsParameters) -> Result { let (x, y) = match value { Some(v) => { assert!(!v.is_zero()); let (x, y) = v.into_xy_unchecked(); (Some(x), Some(y)) - }, - None => { - (None, None) } + None => (None, None), }; - let val = if let Some(value) = value { - Some(value.into_projective()) - } else { - None - }; + let val = if let Some(value) = value { Some(value.into_projective()) } else { None }; - let x = FieldElement::new_allocated( - cs, - x, - params - )?; + let x = FieldElement::new_allocated(cs, x, params)?; let (x_is_zero, x) = x.is_zero(cs)?; - let y = FieldElement::new_allocated( - cs, - y, - params - )?; + let y = FieldElement::new_allocated(cs, y, params)?; let (y_is_zero, y) = y.is_zero(cs)?; @@ -111,79 +73,42 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where >( - cs: &mut CS, - value: Option, - params: &'a RnsParameters - ) -> Result { + pub fn alloc_from_affine_may_be_zero>(cs: &mut CS, value: Option, params: &'a RnsParameters) -> Result { let (x, y) = match value { Some(v) => { assert!(!v.is_zero()); let (x, y) = v.into_xy_unchecked(); (Some(x), Some(y)) - }, - None => { - (None, None) } + None => (None, None), }; - let val = if let Some(value) = value { - Some(value.into_projective()) - } else { - None - }; + let val = if let Some(value) = value { Some(value.into_projective()) } else { None }; - let x = FieldElement::new_allocated( - cs, - x, - params - )?; + let x = FieldElement::new_allocated(cs, x, params)?; - let y = FieldElement::new_allocated( - cs, - y, - params - )?; + let y = FieldElement::new_allocated(cs, y, params)?; let z = FieldElement::new_constant(G::Base::one(), params); - let new = Self { - x, - y, - z, - value: val - }; + let new = Self { x, y, z, value: val }; Ok(new) } - pub fn constant_from_affine( - value: G, - params: &'a RnsParameters - ) -> Self { + pub fn constant_from_affine(value: G, params: &'a RnsParameters) -> Self { assert!(!value.is_zero()); let (x, y) = value.into_xy_unchecked(); - let x = FieldElement::new_constant( - x, - params - ); + let x = FieldElement::new_constant(x, params); - let y = FieldElement::new_constant( - y, - params - ); + let y = FieldElement::new_constant(y, params); let z = FieldElement::new_constant(G::Base::one(), params); @@ -191,16 +116,13 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where - ) -> Self - { + pub fn zero(params: &'a RnsParameters) -> Self { let x = FieldElement::zero(params); let y = FieldElement::one(params); let z = FieldElement::zero(params); @@ -209,7 +131,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where PointProjective<'a, E, G> where >( - &self, - _cs: &mut CS, - _other: &Self, - ) -> Result - { + pub fn equals>(&self, _cs: &mut CS, _other: &Self) -> Result { Ok(Boolean::constant(false)) // let x_check = self.x.equals(cs, &other.x)?; // let y_check = self.y.equals(cs, &other.y)?; // Boolean::and(cs, &x_check, &y_check) } - pub fn negate>( - self, - cs: &mut CS, - ) -> Result<(Self, Self), SynthesisError> { + pub fn negate>(self, cs: &mut CS) -> Result<(Self, Self), SynthesisError> { let this_value = self.value; let this_x = self.x; @@ -246,26 +160,26 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where PointProjective<'a, E, G> where >( - self, - cs: &mut CS, - other: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { + pub fn add>(self, cs: &mut CS, other: Self) -> Result<(Self, (Self, Self)), SynthesisError> { let params = self.x.representation_params; let curve_b = G::b_coeff(); - let b = FieldElement::new_constant( - curve_b, - params - ); + let b = FieldElement::new_constant(curve_b, params); let this_value = self.value; let other_value = other.value; @@ -298,69 +205,69 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where PointProjective<'a, E, G> where None + } + _ => None, }; - + let new = Self { x: x3, y: y3, z: z3, - value: new_value + value: new_value, }; let this = Self { x: x1, y: y1, z: z1, - value: this_value + value: this_value, }; let other = Self { x: x2, y: y2, z: z2, - value: other_value + value: other_value, }; Ok((new, (this, other))) @@ -407,10 +314,10 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where Result<(Self, (Self, Self)), SynthesisError> { // // since we are in a circuit we don't use projective coodinates cause inversions are - // // "cheap" in terms of constraints + // // "cheap" in terms of constraints // // we also do not want to have branching here, - // // so this function implicitly requires that + // // so this function implicitly requires that // // points are not equal // // we need to calculate lambda = (y' - y)/(x' - x). We don't care about a particular @@ -449,7 +356,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where PointProjective<'a, E, G> where None // }; - + // let new = Self { // x: new_x, // y: new_y, @@ -483,63 +390,55 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where >( - self, - cs: &mut CS, - ) -> Result<(Self, Self), SynthesisError> { - + pub fn double>(self, cs: &mut CS) -> Result<(Self, Self), SynthesisError> { let params = self.x.representation_params; let curve_b = G::b_coeff(); - let b = FieldElement::new_constant( - curve_b, - params - ); + let b = FieldElement::new_constant(curve_b, params); let this_value = self.value; let x = self.x; let y = self.y; let z = self.z; - // 1. t0 ← Y · Y + // 1. t0 ← Y · Y let (t0, y) = y.square(cs)?; - // 2. Z3 ← t0 + t0 + // 2. Z3 ← t0 + t0 let (z3, t0) = t0.double(cs)?; // 3. Z3 ← Z3 + Z3 let (z3, _) = z3.double(cs)?; - // 4. Z3 ← Z3 + Z3 + // 4. Z3 ← Z3 + Z3 let (z3, _) = z3.double(cs)?; - // 5. t1 ← Y · Z + // 5. t1 ← Y · Z let (t1, (y, z)) = y.mul(cs, z)?; // 6. t2 ← Z · Z let (t2, z) = z.square(cs)?; - // 7. t2 ← b3 · t2 + // 7. t2 ← b3 · t2 let (t2, _) = b.mul(cs, t2)?; - // 8. X3 ← t2 · Z3 + // 8. X3 ← t2 · Z3 let (x3, (t2, z3)) = t2.mul(cs, z3)?; // 9. Y3 ← t0 + t2 let (y3, (t0, t2)) = t0.add(cs, t2)?; - // 10. Z3 ← t1 · Z3 + // 10. Z3 ← t1 · Z3 let (z3, (t1, _)) = t1.mul(cs, z3)?; - // 11. t1 ← t2 + t2 + // 11. t1 ← t2 + t2 let (t1, t2) = t2.double(cs)?; // 12. t2 ← t1 + t2 let (t2, (t1, _)) = t1.add(cs, t2)?; - // 13. t0 ← t0 − t2 + // 13. t0 ← t0 − t2 let (t0, (_, t2)) = t0.sub(cs, t2)?; - // 14. Y3 ← t0 · Y3 + // 14. Y3 ← t0 · Y3 let (y3, (t0, _)) = t0.mul(cs, y3)?; // 15. Y3 ← X3 + Y3 let (y3, (x3, _)) = x3.add(cs, y3)?; - // 16. t1 ← X · Y + // 16. t1 ← X · Y let (t1, (x, y)) = x.mul(cs, y)?; - // 17. X3 ← t0 · t1 + // 17. X3 ← t0 · t1 let (x3, (t0, t1)) = t0.mul(cs, t1)?; // 18. X3 ← X3 + X3 let (x3, _) = x3.double(cs)?; @@ -550,39 +449,24 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where >( - self, - _cs: &mut CS, - _scalar: &G::Scalar - ) -> Result<(Self, Self), SynthesisError> { + pub fn mul_by_fixed_scalar>(self, _cs: &mut CS, _scalar: &G::Scalar) -> Result<(Self, Self), SynthesisError> { unimplemented!() } - pub fn select>( - cs: &mut CS, - flag: &Boolean, - first: Self, - second: Self - ) -> Result<(Self, (Self, Self)), SynthesisError> { - + pub fn select>(cs: &mut CS, flag: &Boolean, first: Self, second: Self) -> Result<(Self, (Self, Self)), SynthesisError> { let first_value = first.value; let second_value = second.value; let (x, (first_x, second_x)) = FieldElement::select(cs, flag, first.x, second.x)?; @@ -592,28 +476,23 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where Some(p), (Some(false), _, Some(p)) => Some(p), - (_, _, _) => None + (_, _, _) => None, }; - let selected = Self { - x: x, - y: y, - z: z, - value - }; + let selected = Self { x: x, y: y, z: z, value }; let first = Self { x: first_x, y: first_y, z: first_z, - value: first_value + value: first_value, }; let second = Self { x: second_x, y: second_y, z: second_z, - value: second_value + value: second_value, }; Ok((selected, (first, second))) @@ -650,7 +529,6 @@ impl<'a, E: Engine, G: GenericCurveAffine> PointProjective<'a, E, G> where PointProjective<'a, E, G> where PointProjective<'a, E, E::G1Affine> { #[allow(unused_variables)] #[track_caller] - pub fn mul>( - self, - cs: &mut CS, - scalar: &Num::, - _bit_limit: Option - ) -> Result<(Self, Self), SynthesisError> { + pub fn mul>(self, cs: &mut CS, scalar: &Num, _bit_limit: Option) -> Result<(Self, Self), SynthesisError> { if let Some(value) = scalar.get_value() { assert!(!value.is_zero(), "can not multiply by zero in the current approach"); } @@ -693,11 +566,10 @@ impl<'a, E: Engine> PointProjective<'a, E, E::G1Affine> { (Some(scalar), Some(value), Some(result)) => { let tmp = value.mul(scalar.into_repr()); assert_eq!(tmp.into_affine(), result); - }, + } _ => {} } - Ok((result, this)) } @@ -735,7 +607,7 @@ impl<'a, E: Engine> PointProjective<'a, E, E::G1Affine> { // // and unknown discrete log allows us to be "safe" // let offset_generator = crate::constants::make_random_points_with_unknown_discrete_log::( - // &crate::constants::MULTIEXP_DST[..], + // &crate::constants::MULTIEXP_DST[..], // 1 // )[0]; @@ -803,7 +675,7 @@ impl<'a, E: Engine> PointProjective<'a, E, E::G1Affine> { // acc = result; // } - + // let shift = BigUint::from(1u64) << num_doubles; // let as_scalar_repr = biguint_to_repr::(shift); // let offset_value = offset_generator.mul(as_scalar_repr).into_affine(); @@ -820,15 +692,15 @@ impl<'a, E: Engine> PointProjective<'a, E, E::G1Affine> { mod test { use super::*; + use crate::bellman::pairing::bn256::{Bn256, Fq, Fr, G1Affine}; use crate::plonk::circuit::*; - use crate::bellman::pairing::bn256::{Fq, Bn256, Fr, G1Affine}; #[test] - fn test_add_on_random_witnesses(){ - use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + fn test_add_on_random_witnesses() { + use crate::plonk::circuit::bigint::single_table_range_constraint::{print_stats, reset_stats}; use crate::plonk::circuit::bigint::*; - use crate::plonk::circuit::bigint::single_table_range_constraint::{reset_stats, print_stats}; - use rand::{XorShiftRng, SeedableRng, Rng}; + use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let info = RangeConstraintInfo { @@ -838,37 +710,23 @@ mod test { linear_terms_used: 3, strategy: RangeConstraintStrategy::SingleTableInvocation, }; - let params = RnsParameters::::new_for_field_with_strategy( - 68, - 110, - 4, - info, - true - ); - + let params = RnsParameters::::new_for_field_with_strategy(68, 110, 4, info, true); + for i in 0..100 { let mut cs = TrivialAssembly::::new(); inscribe_default_range_table_for_bit_width_over_first_three_columns(&mut cs, 17).unwrap(); reset_stats(); let a_f: G1Affine = rng.gen(); let b_f: G1Affine = rng.gen(); - let a = PointProjective::alloc_from_affine_non_zero( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); - - let b = PointProjective::alloc_from_affine_non_zero( - &mut cs, - Some(b_f), - ¶ms - ).unwrap(); + let a = PointProjective::alloc_from_affine_non_zero(&mut cs, Some(a_f), ¶ms).unwrap(); + + let b = PointProjective::alloc_from_affine_non_zero(&mut cs, Some(b_f), ¶ms).unwrap(); let mut addition_result = a_f.into_projective(); addition_result.add_assign_mixed(&b_f); let addition_result = addition_result.into_affine(); - + let (result, (a, b)) = a.add(&mut cs, b).unwrap(); assert!(cs.is_satisfied()); @@ -900,7 +758,6 @@ mod test { } } - // #[test] // fn test_add_with_constant_on_random_witnesses(){ // use rand::{XorShiftRng, SeedableRng, Rng}; @@ -914,8 +771,8 @@ mod test { // let a_f: G1Affine = rng.gen(); // let b_f: G1Affine = rng.gen(); // let a = AffinePoint::alloc( - // &mut cs, - // Some(a_f), + // &mut cs, + // Some(a_f), // ¶ms // ).unwrap(); @@ -923,7 +780,7 @@ mod test { // b_f, // ¶ms // ); - + // let (result, (a, b)) = a.add_unequal(&mut cs, b).unwrap(); // assert!(cs.is_satisfied()); @@ -965,17 +822,17 @@ mod test { // let a_f: G1Affine = rng.gen(); // let b_f: G1Affine = rng.gen(); // let a = AffinePoint::alloc( - // &mut cs, - // Some(a_f), + // &mut cs, + // Some(a_f), // ¶ms // ).unwrap(); // let b = AffinePoint::alloc( - // &mut cs, - // Some(b_f), + // &mut cs, + // Some(b_f), // ¶ms // ).unwrap(); - + // let (result, (a, b)) = a.sub_unequal(&mut cs, b).unwrap(); // assert!(cs.is_satisfied()); @@ -1017,11 +874,11 @@ mod test { // let a_f: G1Affine = rng.gen(); // let a = AffinePoint::alloc( - // &mut cs, - // Some(a_f), + // &mut cs, + // Some(a_f), // ¶ms // ).unwrap(); - + // let (result, a) = a.double(&mut cs).unwrap(); // assert!(cs.is_satisfied()); @@ -1047,11 +904,11 @@ mod test { // } #[test] - fn test_base_curve_multiplication_with_range_table(){ - use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + fn test_base_curve_multiplication_with_range_table() { + use crate::plonk::circuit::bigint::single_table_range_constraint::{print_stats, reset_stats}; use crate::plonk::circuit::bigint::*; - use crate::plonk::circuit::bigint::single_table_range_constraint::{reset_stats, print_stats}; - use rand::{XorShiftRng, SeedableRng, Rng}; + use crate::plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns; + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let info = RangeConstraintInfo { @@ -1061,13 +918,7 @@ mod test { linear_terms_used: 3, strategy: RangeConstraintStrategy::SingleTableInvocation, }; - let params = RnsParameters::::new_for_field_with_strategy( - 68, - 110, - 4, - info, - true - ); + let params = RnsParameters::::new_for_field_with_strategy(68, 110, 4, info, true); for i in 0..10 { let mut cs = TrivialAssembly::::new(); @@ -1076,21 +927,12 @@ mod test { let a_f: G1Affine = rng.gen(); let b_f: Fr = rng.gen(); - let a = PointProjective::alloc_from_affine_non_zero( - &mut cs, - Some(a_f), - ¶ms - ).unwrap(); + let a = PointProjective::alloc_from_affine_non_zero(&mut cs, Some(a_f), ¶ms).unwrap(); - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(b_f) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(b_f)).unwrap(); let b = Num::Variable(b); - + let (result, a) = a.mul(&mut cs, &b, None).unwrap(); let result_recalculated = a_f.mul(b_f.into_repr()).into_affine(); @@ -1142,13 +984,13 @@ mod test { // let b_f: Fr = rng.gen(); // let a = AffinePoint::alloc( - // &mut cs, - // Some(a_f), + // &mut cs, + // Some(a_f), // ¶ms // ).unwrap(); // let b = AllocatedNum::alloc( - // &mut cs, + // &mut cs, // || { // Ok(b_f) // } @@ -1208,12 +1050,12 @@ mod test { // a_s.push(a_f); // b_s.push(b_f); // } - + // let mut a_p = vec![]; // for a in a_s.iter() { // let a = AffinePoint::alloc( - // &mut cs, - // Some(*a), + // &mut cs, + // Some(*a), // ¶ms // ).unwrap(); @@ -1224,7 +1066,7 @@ mod test { // for b in b_s.iter() { // let b = AllocatedNum::alloc( - // &mut cs, + // &mut cs, // || { // Ok(*b) // } @@ -1289,12 +1131,12 @@ mod test { // a_s.push(a_f); // b_s.push(b_f); // } - + // let mut a_p = vec![]; // for a in a_s.iter() { // let a = AffinePoint::alloc( - // &mut cs, - // Some(*a), + // &mut cs, + // Some(*a), // ¶ms // ).unwrap(); @@ -1305,7 +1147,7 @@ mod test { // for b in b_s.iter() { // let b = AllocatedNum::alloc( - // &mut cs, + // &mut cs, // || { // Ok(*b) // } @@ -1370,12 +1212,12 @@ mod test { // a_s.push(a_f); // b_s.push(b_f); // } - + // let mut a_p = vec![]; // for a in a_s.iter() { // let a = AffinePoint::alloc( - // &mut cs, - // Some(*a), + // &mut cs, + // Some(*a), // ¶ms // ).unwrap(); @@ -1386,7 +1228,7 @@ mod test { // for b in b_s.iter() { // let b = AllocatedNum::alloc( - // &mut cs, + // &mut cs, // || { // Ok(*b) // } @@ -1451,12 +1293,12 @@ mod test { // a_s.push(a_f); // b_s.push(b_f); // } - + // let mut a_p = vec![]; // for a in a_s.iter() { // let a = AffinePoint::alloc( - // &mut cs, - // Some(*a), + // &mut cs, + // Some(*a), // ¶ms // ).unwrap(); @@ -1467,7 +1309,7 @@ mod test { // for b in b_s.iter() { // let b = AllocatedNum::alloc( - // &mut cs, + // &mut cs, // || { // Ok(*b) // } @@ -1534,9 +1376,9 @@ mod test { // // let strats = get_range_constraint_info(&cs); // // let mut params = RnsParameters::::new_for_field_with_strategy( - // // 96, - // // 110, - // // 6, + // // 96, + // // 110, + // // 6, // // strats[0], // // true // // ); @@ -1553,12 +1395,12 @@ mod test { // a_s.push(a_f); // b_s.push(b_f); // } - + // let mut a_p = vec![]; // for a in a_s.iter() { // let a = AffinePoint::alloc( - // &mut cs, - // Some(*a), + // &mut cs, + // Some(*a), // ¶ms // ).unwrap(); @@ -1569,7 +1411,7 @@ mod test { // for b in b_s.iter() { // let b = AllocatedNum::alloc( - // &mut cs, + // &mut cs, // || { // Ok(*b) // } @@ -1636,9 +1478,9 @@ mod test { // let strats = get_range_constraint_info(&cs); // let mut params = RnsParameters::::new_for_field_with_strategy( - // 96, - // 110, - // 6, + // 96, + // 110, + // 6, // strats[0], // true // ); @@ -1655,12 +1497,12 @@ mod test { // a_s.push(a_f); // b_s.push(b_f); // } - + // let mut a_p = vec![]; // for a in a_s.iter() { // let a = AffinePoint::alloc( - // &mut cs, - // Some(*a), + // &mut cs, + // Some(*a), // ¶ms // ).unwrap(); @@ -1671,7 +1513,7 @@ mod test { // for b in b_s.iter() { // let b = AllocatedNum::alloc( - // &mut cs, + // &mut cs, // || { // Ok(*b) // } @@ -1698,4 +1540,4 @@ mod test { // assert!(cs.is_satisfied()); // } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/curve_new/mod.rs b/crates/franklin-crypto/src/plonk/circuit/curve_new/mod.rs index 55077f5..3b4a366 100644 --- a/crates/franklin-crypto/src/plonk/circuit/curve_new/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/curve_new/mod.rs @@ -5,4 +5,4 @@ pub mod sw_projective; pub use self::sw_projective::*; pub mod secp256k1; -pub use self::secp256k1::*; \ No newline at end of file +pub use self::secp256k1::*; diff --git a/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/fq.rs b/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/fq.rs index 62fcfd0..d57c731 100644 --- a/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/fq.rs +++ b/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/fq.rs @@ -1,8 +1,7 @@ use crate::bellman::pairing::ff::*; - // base field, Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F #[derive(PrimeField)] #[PrimeFieldModulus = "115792089237316195423570985008687907853269984665640564039457584007908834671663"] #[PrimeFieldGenerator = "2"] -pub struct Fq(FqRepr); \ No newline at end of file +pub struct Fq(FqRepr); diff --git a/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/fr.rs b/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/fr.rs index 891e1f9..81f7535 100644 --- a/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/fr.rs +++ b/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/fr.rs @@ -1,8 +1,7 @@ use crate::bellman::pairing::ff::*; - // base field, R = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 #[derive(PrimeField)] #[PrimeFieldModulus = "115792089237316195423570985008687907852837564279074904382605163141518161494337"] #[PrimeFieldGenerator = "2"] -pub struct Fr(FrRepr); \ No newline at end of file +pub struct Fr(FrRepr); diff --git a/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/mod.rs b/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/mod.rs index 13aa8ab..cb6a7ea 100644 --- a/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/curve_new/secp256k1/mod.rs @@ -1,27 +1,24 @@ use crate::bellman::pairing::ff::BitIterator; -use crate::bellman::pairing::{GenericCurveAffine, GenericCurveProjective, GroupDecodingError, EncodingBytes, GenericUncompressedEncodable, GenericCompressedEncodable}; use crate::bellman::pairing::ff::*; +use crate::bellman::pairing::{EncodingBytes, GenericCompressedEncodable, GenericCurveAffine, GenericCurveProjective, GenericUncompressedEncodable, GroupDecodingError}; use rand::*; - -pub mod fr; pub mod fq; +pub mod fr; -use self::fr::*; use self::fq::*; - +use self::fr::*; #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct PointAffine { pub(crate) x: Fq, pub(crate) y: Fq, - pub(crate) infinity: bool + pub(crate) infinity: bool, } static NAME_STR: &'static str = "Secp256k1"; -impl ::std::fmt::Display for PointAffine -{ +impl ::std::fmt::Display for PointAffine { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { if self.infinity { write!(f, "{}(Infinity)", NAME_STR) @@ -35,11 +32,10 @@ impl ::std::fmt::Display for PointAffine pub struct PointProjective { pub(crate) x: Fq, pub(crate) y: Fq, - pub(crate) z: Fq + pub(crate) z: Fq, } -impl ::std::fmt::Display for PointProjective -{ +impl ::std::fmt::Display for PointProjective { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "{}", self.into_affine()) } @@ -92,7 +88,9 @@ impl PointAffine { let mut res = PointProjective::zero(); for i in bits { res.double(); - if i { res.add_assign_mixed(self) } + if i { + res.add_assign_mixed(self) + } } res } @@ -115,12 +113,8 @@ impl PointAffine { PointAffine { x: x, - y: if (y < negy) ^ greatest { - y - } else { - negy - }, - infinity: false + y: if (y < negy) ^ greatest { y } else { negy }, + infinity: false, } }) } @@ -152,7 +146,7 @@ impl GenericCurveAffine for PointAffine { PointAffine { x: Fq::zero(), y: Fq::one(), - infinity: true + infinity: true, } } @@ -183,7 +177,7 @@ impl GenericCurveAffine for PointAffine { fn as_xy(&self) -> (&Self::Base, &Self::Base) { (&self.x, &self.y) } - + #[inline(always)] fn into_xy_unchecked(self) -> (Self::Base, Self::Base) { (self.x, self.y) @@ -192,20 +186,12 @@ impl GenericCurveAffine for PointAffine { #[inline(always)] fn from_xy_unchecked(x: Self::Base, y: Self::Base) -> Self { let infinity = x.is_zero() && y.is_zero(); - Self { - x: x, - y: y, - infinity - } + Self { x: x, y: y, infinity } } fn from_xy_checked(x: Self::Base, y: Self::Base) -> Result { let infinity = x.is_zero() && y.is_zero(); - let affine = Self { - x: x, - y: y, - infinity - }; + let affine = Self { x: x, y: y, infinity }; if !affine.is_on_curve() { Err(GroupDecodingError::NotOnCurve) @@ -234,7 +220,7 @@ impl GenericCurveProjective for PointProjective { PointProjective { x: Fq::zero(), y: Fq::one(), - z: Fq::zero() + z: Fq::zero(), } } @@ -252,8 +238,7 @@ impl GenericCurveProjective for PointProjective { self.is_zero() || self.z == Fq::one() } - fn batch_normalization(v: &mut [Self]) - { + fn batch_normalization(v: &mut [Self]) { // Montgomery’s Trick and Fast Implementation of Masked AES // Genelle, Prouff and Quisquater // Section 3.2 @@ -261,9 +246,10 @@ impl GenericCurveProjective for PointProjective { // First pass: compute [a, ab, abc, ...] let mut prod = Vec::with_capacity(v.len()); let mut tmp = Fq::one(); - for g in v.iter_mut() - // Ignore normalized elements - .filter(|g| !g.is_normalized()) + for g in v + .iter_mut() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) { tmp.mul_assign(&g.z); prod.push(tmp); @@ -273,13 +259,14 @@ impl GenericCurveProjective for PointProjective { tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero. // Second pass: iterate backwards to compute inverses - for (g, s) in v.iter_mut() - // Backwards - .rev() - // Ignore normalized elements - .filter(|g| !g.is_normalized()) - // Backwards, skip last element, fill in one for last term. - .zip(prod.into_iter().rev().skip(1).chain(Some(Fq::one()))) + for (g, s) in v + .iter_mut() + // Backwards + .rev() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) + // Backwards, skip last element, fill in one for last term. + .zip(prod.into_iter().rev().skip(1).chain(Some(Fq::one()))) { // tmp := tmp * g.z; g.z := tmp * s = 1/z let mut newtmp = tmp; @@ -290,9 +277,7 @@ impl GenericCurveProjective for PointProjective { } // Perform affine transformations - for g in v.iter_mut() - .filter(|g| !g.is_normalized()) - { + for g in v.iter_mut().filter(|g| !g.is_normalized()) { let mut z = g.z; // 1/z z.square(); // 1/z^2 g.x.mul_assign(&z); // x/z^2 @@ -550,8 +535,7 @@ impl GenericCurveProjective for PointProjective { let mut found_one = false; - for i in BitIterator::new(other.into()) - { + for i in BitIterator::new(other.into()) { if found_one { res.double(); } else { @@ -581,17 +565,13 @@ impl GenericCurveProjective for PointProjective { fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) { (&self.x, &self.y, &self.z) } - + fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) { (self.x, self.y, self.z) } fn from_xyz_unchecked(x: Self::Base, y: Self::Base, z: Self::Base) -> Self { - Self { - x, - y, - z - } + Self { x, y, z } } fn from_xyz_checked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Result { @@ -606,11 +586,7 @@ impl From for PointProjective { if p.is_zero() { PointProjective::zero() } else { - PointProjective { - x: p.x, - y: p.y, - z: Fq::one() - } + PointProjective { x: p.x, y: p.y, z: Fq::one() } } } } @@ -623,11 +599,7 @@ impl From for PointAffine { PointAffine::zero() } else if p.z == Fq::one() { // If Z is one, the point is already normalized. - PointAffine { - x: p.x, - y: p.y, - infinity: false - } + PointAffine { x: p.x, y: p.y, infinity: false } } else { // Z is nonzero, so it must have an inverse in a field. let zinv = p.z.inverse().unwrap(); @@ -643,11 +615,7 @@ impl From for PointAffine { zinv_powered.mul_assign(&zinv); y.mul_assign(&zinv_powered); - PointAffine { - x: x, - y: y, - infinity: false - } + PointAffine { x: x, y: y, infinity: false } } } } @@ -695,7 +663,7 @@ impl PointAffine { Self { x: crate::bellman::pairing::ff::from_hex::("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798").unwrap(), y: crate::bellman::pairing::ff::from_hex::("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8").unwrap(), - infinity: false + infinity: false, } } } @@ -714,8 +682,7 @@ impl PointProjective { } fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { - const RECOMMENDATIONS: [usize; 12] = - [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; + const RECOMMENDATIONS: [usize; 12] = [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; let mut ret = 4; for r in &RECOMMENDATIONS { @@ -755,4 +722,3 @@ impl GenericCompressedEncodable<32> for PointAffine { todo!() } } - diff --git a/crates/franklin-crypto/src/plonk/circuit/curve_new/sw_affine.rs b/crates/franklin-crypto/src/plonk/circuit/curve_new/sw_affine.rs index 769c76c..9ff47fc 100644 --- a/crates/franklin-crypto/src/plonk/circuit/curve_new/sw_affine.rs +++ b/crates/franklin-crypto/src/plonk/circuit/curve_new/sw_affine.rs @@ -1,47 +1,21 @@ -use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, - GenericCurveProjective, -}; +use crate::bellman::pairing::{Engine, GenericCurveAffine, GenericCurveProjective}; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator, - ScalarEngine -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, ScalarEngine}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - TrivialAssembly, - PlonkCsWidth4WithNextStepParams, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; +use crate::plonk::circuit::hashes_with_tables::utils::{u64_to_ff, IdentifyFirstLast}; use crate::plonk::circuit::Assignment; -use crate::plonk::circuit::hashes_with_tables::utils::{IdentifyFirstLast, u64_to_ff}; use super::super::allocated_num::{AllocatedNum, Num}; +use super::super::boolean::{AllocatedBit, Boolean}; use super::super::linear_combination::LinearCombination; use super::super::simple_term::Term; -use super::super::boolean::{Boolean, AllocatedBit}; use num_bigint::BigUint; use num_integer::Integer; @@ -49,12 +23,14 @@ use num_integer::Integer; use crate::plonk::circuit::bigint_new::*; use crate::plonk::circuit::curve_new::sw_projective::*; - #[derive(Clone, Debug)] -pub struct AffinePoint<'a, E: Engine, G: GenericCurveAffine> where ::Base: PrimeField { +pub struct AffinePoint<'a, E: Engine, G: GenericCurveAffine> +where + ::Base: PrimeField, +{ pub x: FieldElement<'a, E, G::Base>, pub y: FieldElement<'a, E, G::Base>, - // the used paradigm is zero abstraction: we won't pay for this flag if it is never used and + // the used paradigm is zero abstraction: we won't pay for this flag if it is never used and // all our points are regular (i.e. not points at infinity) // for this purpose we introduce lazy_select // if current point is actually a point at infinity than x, y may contain any values and are actually meaningless @@ -62,7 +38,10 @@ pub struct AffinePoint<'a, E: Engine, G: GenericCurveAffine> where , } -impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where ::Base: PrimeField { +impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> +where + ::Base: PrimeField, +{ pub fn get_x(&self) -> FieldElement<'a, E, G::Base> { self.x.clone() } @@ -72,49 +51,40 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >( - cs: &mut CS, value: Option, params: &'a RnsParameters - ) -> Result { + pub fn alloc>(cs: &mut CS, value: Option, params: &'a RnsParameters) -> Result { let (new, _x_decomposition, _y_decomposition) = Self::alloc_ext(cs, value, params)?; Ok(new) } #[track_caller] pub fn alloc_ext>( - cs: &mut CS, value: Option, params: &'a RnsParameters - ) -> Result<(Self, RangeCheckDecomposition, RangeCheckDecomposition), SynthesisError> { + cs: &mut CS, + value: Option, + params: &'a RnsParameters, + ) -> Result<(Self, RangeCheckDecomposition, RangeCheckDecomposition), SynthesisError> { let (x, y) = match value { Some(v) => { assert!(!v.is_zero()); let (x, y) = v.into_xy_unchecked(); (Some(x), Some(y)) - }, - None => { - (None, None) } + None => (None, None), }; let (x, x_decomposition) = FieldElement::alloc_ext(cs, x, params)?; let (y, y_decomposition) = FieldElement::alloc_ext(cs, y, params)?; - let new = Self { x, y, value}; + let new = Self { x, y, value }; Ok((new, x_decomposition, y_decomposition)) } - pub unsafe fn from_xy_unchecked( - x: FieldElement<'a, E, G::Base>, - y: FieldElement<'a, E, G::Base>, - ) -> Self { + pub unsafe fn from_xy_unchecked(x: FieldElement<'a, E, G::Base>, y: FieldElement<'a, E, G::Base>) -> Self { let value = match (x.get_field_value(), y.get_field_value()) { - (Some(x), Some(y)) => { - Some(G::from_xy_unchecked(x, y)) - }, - _ => { - None - } + (Some(x), Some(y)) => Some(G::from_xy_unchecked(x, y)), + _ => None, }; - let new = Self {x, y, value }; + let new = Self { x, y, value }; new } @@ -128,14 +98,16 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where (&self, cs: &mut CS) -> Result>, SynthesisError> - where CS: ConstraintSystem { + pub fn get_raw_limbs_representation(&self, cs: &mut CS) -> Result>, SynthesisError> + where + CS: ConstraintSystem, + { let mut res = self.x.get_raw_limbs_representation(cs)?; let extension = self.y.get_raw_limbs_representation(cs)?; res.extend_from_slice(&extension[..]); Ok(res) } - + pub fn is_constant(&self) -> bool { self.x.is_constant() & self.y.is_constant() } @@ -154,20 +126,22 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where (cs: &mut CS, this: &mut Self, other: &mut Self) -> Result<(), SynthesisError> - where CS: ConstraintSystem + pub fn enforce_equal(cs: &mut CS, this: &mut Self, other: &mut Self) -> Result<(), SynthesisError> + where + CS: ConstraintSystem, { FieldElement::enforce_equal(cs, &mut this.x, &mut other.x)?; FieldElement::enforce_equal(cs, &mut this.y, &mut other.y) } - pub fn equals(cs: &mut CS, this: &mut Self, other: &mut Self) -> Result - where CS: ConstraintSystem + pub fn equals(cs: &mut CS, this: &mut Self, other: &mut Self) -> Result + where + CS: ConstraintSystem, { let x_check = FieldElement::equals(cs, &mut this.x, &mut other.x)?; let y_check = FieldElement::equals(cs, &mut this.y, &mut other.y)?; let equals = Boolean::and(cs, &x_check, &y_check)?; - + Ok(equals) } @@ -181,14 +155,15 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where (&self, cs: &mut CS, flag: &Boolean) -> Result - where CS: ConstraintSystem + pub fn conditionally_negate(&self, cs: &mut CS, flag: &Boolean) -> Result + where + CS: ConstraintSystem, { let y_negated = self.y.conditionally_negate(cs, flag)?; let new_value = self.value.map(|x| { @@ -199,14 +174,15 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where (cs: &mut CS, flag: &Boolean, first: &Self, second: &Self) -> Result - where CS: ConstraintSystem + pub fn select(cs: &mut CS, flag: &Boolean, first: &Self, second: &Self) -> Result + where + CS: ConstraintSystem, { let first_value = first.get_value(); let second_value = second.get_value(); @@ -216,7 +192,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where Some(p), (Some(false), _, Some(p)) => Some(p), - (_, _, _) => None + (_, _, _) => None, }; let selected = AffinePoint { x, y, value }; @@ -224,8 +200,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where >(&self, cs: &mut CS, curve_b: G::Base - ) -> Result { + pub fn is_on_curve_for_zero_a>(&self, cs: &mut CS, curve_b: G::Base) -> Result { let params = &self.x.representation_params; assert_eq!(curve_b, G::b_coeff()); let b = FieldElement::constant(curve_b, params); @@ -239,8 +214,9 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where (&mut self, cs: &mut CS, other: &mut Self) -> Result - where CS: ConstraintSystem + pub fn add_unequal(&mut self, cs: &mut CS, other: &mut Self) -> Result + where + CS: ConstraintSystem, { // only enforce that x != x' FieldElement::enforce_not_equal(cs, &mut self.x, &mut other.x)?; @@ -248,16 +224,17 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where (&self, cs: &mut CS, other: &Self) -> Result - where CS: ConstraintSystem + pub fn add_unequal_unchecked(&self, cs: &mut CS, other: &Self) -> Result + where + CS: ConstraintSystem, { match (self.get_value(), other.get_value()) { (Some(first), Some(second)) => { assert!(first != second, "points are actually equal with value {}", first); - }, + } _ => {} } - // since we are in a circuit we don't use projective coodinates: inversions are "cheap" in terms of constraints + // since we are in a circuit we don't use projective coodinates: inversions are "cheap" in terms of constraints // we also do not want to have branching here, so this function implicitly requires that points are not equal // we need to calculate lambda = (y' - y)/(x' - x). We don't care about a particular // value of y' - y, so we don't add them explicitly and just use in inversion witness @@ -265,7 +242,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where AffinePoint<'a, E, G> where None - }; - - let new = Self { - x: new_x, - y: new_y, - value: new_value + } + _ => None, }; + + let new = Self { x: new_x, y: new_y, value: new_value }; Ok(new) } #[track_caller] - pub fn sub_unequal(&mut self, cs: &mut CS, other: &mut Self) -> Result - where CS: ConstraintSystem + pub fn sub_unequal(&mut self, cs: &mut CS, other: &mut Self) -> Result + where + CS: ConstraintSystem, { // only enforce that x != x' FieldElement::enforce_not_equal(cs, &mut self.x, &mut other.x)?; @@ -305,13 +279,14 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where (&mut self, cs: &mut CS, other: &mut Self) -> Result - where CS: ConstraintSystem + pub fn sub_unequal_unchecked(&mut self, cs: &mut CS, other: &mut Self) -> Result + where + CS: ConstraintSystem, { match (self.get_value(), other.get_value()) { (Some(first), Some(second)) => { assert!(first != second, "points are actually equal with value {}", first); - }, + } _ => {} } @@ -340,15 +315,11 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where None - }; - - let new = Self { - x: new_x, - y: new_y, - value: new_value + } + _ => None, }; + + let new = Self { x: new_x, y: new_y, value: new_value }; Ok(new) } @@ -377,19 +348,16 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where (&mut self, cs: &mut CS, other: &mut Self) -> Result - where CS: ConstraintSystem + pub fn double_and_add(&mut self, cs: &mut CS, other: &mut Self) -> Result + where + CS: ConstraintSystem, { // even though https://www.researchgate.net/publication/283556724_New_Fast_Algorithms_for_Elliptic_Curve_Arithmetic_in_Affine_Coordinates exists // inversions are cheap, so Montgomery ladder is better @@ -400,19 +368,20 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where (&self, cs: &mut CS, other: &Self) -> Result - where CS: ConstraintSystem + pub fn double_and_add_unchecked(&self, cs: &mut CS, other: &Self) -> Result + where + CS: ConstraintSystem, { let other_x_minus_this_x = other.x.sub(cs, &self.x)?; let mut chain = FieldElementsChain::new(); - chain.add_pos_term(&other.y).add_neg_term(&self.y); + chain.add_pos_term(&other.y).add_neg_term(&self.y); let lambda = FieldElement::div_with_chain(cs, chain, &other_x_minus_this_x)?; // lambda^2 + (-x' - x) let mut chain = FieldElementsChain::new(); chain.add_neg_term(&other.x).add_neg_term(&self.x); let new_x = lambda.square_with_chain(cs, chain)?; - + let new_x_minus_this_x = new_x.sub(cs, &self.x)?; let two_y = self.y.double(cs)?; let t0 = two_y.div(cs, &new_x_minus_this_x)?; @@ -421,7 +390,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where AffinePoint<'a, E, G> where None - }; - - let new = Self { - x: new_x, - y: new_y, - value: new_value + } + _ => None, }; + + let new = Self { x: new_x, y: new_y, value: new_value }; Ok(new) } } - // we are particularly interested in three curves: secp256k1, bn256 and bls12-281 // unfortunately, only bls12-381 has a cofactor -impl<'a, E: Engine, G: GenericCurveAffine + rand::Rand> AffinePoint<'a, E, G> where ::Base: PrimeField { +impl<'a, E: Engine, G: GenericCurveAffine + rand::Rand> AffinePoint<'a, E, G> +where + ::Base: PrimeField, +{ #[track_caller] - pub fn mul_by_scalar_for_composite_order_curve>( - &mut self, cs: &mut CS, scalar: &mut FieldElement<'a, E, G::Scalar> - ) -> Result { + pub fn mul_by_scalar_for_composite_order_curve>(&mut self, cs: &mut CS, scalar: &mut FieldElement<'a, E, G::Scalar>) -> Result { if let Some(value) = scalar.get_field_value() { assert!(!value.is_zero(), "can not multiply by zero in the current approach"); } if scalar.is_constant() { unimplemented!(); } - + let params = self.x.representation_params; let entries = scalar.decompose_into_skewed_representation(cs)?; - + // we add a random point to the accumulator to avoid having zero anywhere (with high probability) // and unknown discrete log allows us to be "safe" - let offset_generator = crate::constants::make_random_points_with_unknown_discrete_log::( - &crate::constants::MULTIEXP_DST[..], 1 - )[0]; + let offset_generator = crate::constants::make_random_points_with_unknown_discrete_log::(&crate::constants::MULTIEXP_DST[..], 1)[0]; let mut generator = Self::constant(offset_generator, params); let mut acc = self.add_unequal(cs, &mut generator)?; @@ -481,7 +444,7 @@ impl<'a, E: Engine, G: GenericCurveAffine + rand::Rand> AffinePoint<'a, E, G> wh minus_y.reduce_loose(cs)?; for e in entries_without_first_and_last.iter() { - let selected_y = FieldElement::conditionally_select(cs, e, &minus_y, &self.y)?; + let selected_y = FieldElement::conditionally_select(cs, e, &minus_y, &self.y)?; let t_value = match (self.value, e.get_value()) { (Some(val), Some(bit)) => { let mut val = val; @@ -489,14 +452,10 @@ impl<'a, E: Engine, G: GenericCurveAffine + rand::Rand> AffinePoint<'a, E, G> wh val.negate(); } Some(val) - }, - _ => None - }; - let mut t = Self { - x: x, - y: selected_y, - value: t_value + } + _ => None, }; + let mut t = Self { x: x, y: selected_y, value: t_value }; acc = acc.double_and_add(cs, &mut t)?; num_doubles += 1; @@ -521,8 +480,8 @@ impl<'a, E: Engine, G: GenericCurveAffine + rand::Rand> AffinePoint<'a, E, G> wh } else { Some(a_value) } - }, - _ => None + } + _ => None, }; let final_acc_x = FieldElement::conditionally_select(cs, last_entry, &with_skew_x, &acc_x)?; @@ -537,7 +496,7 @@ impl<'a, E: Engine, G: GenericCurveAffine + rand::Rand> AffinePoint<'a, E, G> wh let mut result = Self { x: final_acc_x, y: final_acc_y, - value: final_value + value: final_value, }; let result = result.sub_unequal(cs, &mut offset)?; @@ -545,11 +504,11 @@ impl<'a, E: Engine, G: GenericCurveAffine + rand::Rand> AffinePoint<'a, E, G> wh } } - -impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where ::Base: PrimeField { - pub fn mul_by_scalar_for_prime_order_curve>( - &mut self, cs: &mut CS, scalar: &mut FieldElement<'a, E, G::Scalar> - ) -> Result, SynthesisError> { +impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> +where + ::Base: PrimeField, +{ + pub fn mul_by_scalar_for_prime_order_curve>(&mut self, cs: &mut CS, scalar: &mut FieldElement<'a, E, G::Scalar>) -> Result, SynthesisError> { let params = self.x.representation_params; let scalar_decomposition = scalar.decompose_into_binary_representation(cs)?; @@ -562,20 +521,19 @@ impl<'a, E: Engine, G: GenericCurveAffine> AffinePoint<'a, E, G> where where ::Base: PrimeField { +pub struct ProjectivePoint<'a, E: Engine, G: GenericCurveAffine> +where + ::Base: PrimeField, +{ pub x: FieldElement<'a, E, G::Base>, pub y: FieldElement<'a, E, G::Base>, pub z: FieldElement<'a, E, G::Base>, pub value: Option, } - impl<'a, E: Engine, G: GenericCurveAffine> From> for ProjectivePoint<'a, E, G> -where ::Base: PrimeField +where + ::Base: PrimeField, { fn from(affine_pt: AffinePoint<'a, E, G>) -> Self { let params = affine_pt.x.representation_params; - let AffinePoint { x, y, value} = affine_pt; + let AffinePoint { x, y, value } = affine_pt; ProjectivePoint:: { - x, y, + x, + y, z: FieldElement::one(¶ms), value: value.map(|x| x.into_projective()), } - } + } } - -impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> where ::Base: PrimeField { +impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> +where + ::Base: PrimeField, +{ pub fn get_x(&self) -> FieldElement<'a, E, G::Base> { self.x.clone() } @@ -83,10 +62,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> where - ) -> Self - { + pub fn zero(params: &'a RnsParameters) -> Self { let x = FieldElement::zero(params); let y = FieldElement::one(params); let z = FieldElement::zero(params); @@ -110,12 +86,12 @@ impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> where ProjectivePoint<'a, E, G> where (&self, cs: &mut CS) -> Result, SynthesisError> - where CS: ConstraintSystem { + pub unsafe fn convert_to_affine(&self, cs: &mut CS) -> Result, SynthesisError> + where + CS: ConstraintSystem, + { let x = self.x.div(cs, &self.z)?; let y = self.y.div(cs, &self.z)?; let value = self.get_value(); @@ -135,9 +113,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> where >( - &mut self, cs: &mut CS, default: &AffinePoint<'a, E, G> - ) -> Result<(AffinePoint<'a, E, G>, Boolean), SynthesisError> { + pub fn convert_to_affine_or_default>(&mut self, cs: &mut CS, default: &AffinePoint<'a, E, G>) -> Result<(AffinePoint<'a, E, G>, Boolean), SynthesisError> { let params = self.x.representation_params; let is_point_at_infty = self.z.is_zero(cs)?; let safe_z = FieldElement::conditionally_select(cs, &is_point_at_infty, &FieldElement::one(params), &self.z)?; @@ -161,12 +137,12 @@ impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> where ProjectivePoint<'a, E, G> where ProjectivePoint<'a, E, G> where None + } + _ => None, }; - + let new = Self { x: x3, y: y3, z: z3, - value: new_value + value: new_value, }; Ok(new) } @@ -269,10 +245,10 @@ impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> where ProjectivePoint<'a, E, G> where ProjectivePoint<'a, E, G> where (&self, cs: &mut CS, other: &AffinePoint<'a, E, G>) -> Result - where CS: ConstraintSystem + pub fn add_mixed(&self, cs: &mut CS, other: &AffinePoint<'a, E, G>) -> Result + where + CS: ConstraintSystem, { // this formula is only valid for curve with zero j-ivariant assert!(G::a_coeff().is_zero()); - + let params = self.x.representation_params; let curve_b = G::b_coeff(); let mut curve_b3 = curve_b; curve_b3.double(); - curve_b3.add_assign(&curve_b); + curve_b3.add_assign(&curve_b); let b3 = FieldElement::constant(curve_b3, params); let x1 = self.x.clone(); @@ -352,55 +329,55 @@ impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> where ProjectivePoint<'a, E, G> where None + } + _ => None, }; - + let new = Self { x: x3, y: y3, z: z3, - value: new_value + value: new_value, }; Ok(new) } - pub fn conditionally_select>( - cs: &mut CS, flag: &Boolean, first: &Self, second: &Self - ) -> Result { - + pub fn conditionally_select>(cs: &mut CS, flag: &Boolean, first: &Self, second: &Self) -> Result { let first_value = first.value; let second_value = second.value; let x = FieldElement::conditionally_select(cs, flag, &first.x, &second.x)?; @@ -436,7 +410,7 @@ impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> where Some(p), (Some(false), _, Some(p)) => Some(p), - (_, _, _) => None + (_, _, _) => None, }; let selected = Self { x, y, z, value }; @@ -444,15 +418,14 @@ impl<'a, E: Engine, G: GenericCurveAffine> ProjectivePoint<'a, E, G> where GateInternal for Nonlinearity5CustomGate { } fn variable_polynomials(&self) -> &'static [PolyIdentifier] { - const POLYS: [PolyIdentifier; 3] = [ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2), - ]; + const POLYS: [PolyIdentifier; 3] = [PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; &POLYS } @@ -105,7 +90,7 @@ impl GateInternal for Nonlinearity5CustomGate { tmp.square(); tmp.mul_assign(&b_value); tmp.sub_assign(&c_value); - + tmp } @@ -114,14 +99,14 @@ impl GateInternal for Nonlinearity5CustomGate { } fn contribute_into_quotient( - &self, + &self, domain_size: usize, poly_storage: &mut AssembledPolynomialStorage, - monomials_storage: & AssembledPolynomialStorageForMonomialForms, + monomials_storage: &AssembledPolynomialStorageForMonomialForms, challenges: &[E::Fr], omegas_bitreversed: &BitReversedOmegas, _omegas_inv_bitreversed: &OmegasInvBitreversed, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { assert!(domain_size.is_power_of_two()); assert_eq!(challenges.len(), >::num_quotient_terms(&self)); @@ -132,100 +117,81 @@ impl GateInternal for Nonlinearity5CustomGate { assert!(poly_storage.is_bitreversed); let coset_factor = E::Fr::multiplicative_generator(); - + for &p in >::all_queried_polynomials(&self).into_iter() { - ensure_in_map_or_create(&worker, - p, - domain_size, - omegas_bitreversed, - lde_factor, - coset_factor, - monomials_storage, - poly_storage - )?; + ensure_in_map_or_create(&worker, p, domain_size, omegas_bitreversed, lde_factor, coset_factor, monomials_storage, poly_storage)?; } let ldes_storage = &*poly_storage; - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); let mut tmp = a_ref.clone(); // just allocate, we don't actually use it drop(a_ref); - let a_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ).as_ref(); + let a_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage).as_ref(); - let b_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), - ldes_storage - ).as_ref(); + let b_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), ldes_storage).as_ref(); - let c_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), - ldes_storage - ).as_ref(); + let c_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), ldes_storage).as_ref(); - tmp.map_indexed(&worker, - |i, el| { - let a_value = a_raw_ref[i]; - let b_value = b_raw_ref[i]; - let c_value = c_raw_ref[i]; + tmp.map_indexed(&worker, |i, el| { + let a_value = a_raw_ref[i]; + let b_value = b_raw_ref[i]; + let c_value = c_raw_ref[i]; - // a^3 - b = 0 - let mut result = a_value; - result.square(); - result.mul_assign(&a_value); - result.sub_assign(&b_value); + // a^3 - b = 0 + let mut result = a_value; + result.square(); + result.mul_assign(&a_value); + result.sub_assign(&b_value); - result.mul_assign(&challenges[0]); + result.mul_assign(&challenges[0]); - // a^2 * b - c = 0 - let mut tmp = a_value; - tmp.square(); - tmp.mul_assign(&b_value); - tmp.sub_assign(&c_value); + // a^2 * b - c = 0 + let mut tmp = a_value; + tmp.square(); + tmp.mul_assign(&b_value); + tmp.sub_assign(&c_value); - tmp.mul_assign(&challenges[1]); + tmp.mul_assign(&challenges[1]); - result.add_assign(&tmp); + result.add_assign(&tmp); - *el = result; - }, - ); + *el = result; + }); Ok(tmp) } fn contribute_into_linearization( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, - _monomials_storage: & AssembledPolynomialStorageForMonomialForms, + _monomials_storage: &AssembledPolynomialStorageForMonomialForms, _challenges: &[E::Fr], - _worker: &Worker + _worker: &Worker, ) -> Result, SynthesisError> { unreachable!("this gate does not contribute into linearization"); } fn contribute_into_verification_equation( - &self, + &self, _domain_size: usize, _at: E::Fr, queried_values: &std::collections::HashMap, challenges: &[E::Fr], ) -> Result { assert_eq!(challenges.len(), >::num_quotient_terms(&self)); - - let a_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) + + let a_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) .ok_or(SynthesisError::AssignmentMissing)?; - let b_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) + let b_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) .ok_or(SynthesisError::AssignmentMissing)?; - let c_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) + let c_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) .ok_or(SynthesisError::AssignmentMissing)?; // a^3 - b = 0 @@ -254,7 +220,7 @@ impl GateInternal for Nonlinearity5CustomGate { } fn contribute_into_linearization_commitment( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, @@ -267,48 +233,32 @@ impl GateInternal for Nonlinearity5CustomGate { impl Gate for Nonlinearity5CustomGate {} -pub fn apply_5th_power>( - cs: &mut CS, - el: &AllocatedNum, - existing_5th: Option>, -) -> Result, SynthesisError> { - let third = AllocatedNum::alloc( - cs, - || { - let val = *el.get_value().get()?; - let mut tmp = val; - tmp.square(); - tmp.mul_assign(&val); +pub fn apply_5th_power>(cs: &mut CS, el: &AllocatedNum, existing_5th: Option>) -> Result, SynthesisError> { + let third = AllocatedNum::alloc(cs, || { + let val = *el.get_value().get()?; + let mut tmp = val; + tmp.square(); + tmp.mul_assign(&val); - Ok(tmp) - } - )?; + Ok(tmp) + })?; let fifth = if let Some(f) = existing_5th { f } else { - AllocatedNum::alloc( - cs, - || { - let third = *third.get_value().get()?; - let val = *el.get_value().get()?; - let mut tmp = val; - tmp.square(); - tmp.mul_assign(&third); - - Ok(tmp) - } - )? + AllocatedNum::alloc(cs, || { + let third = *third.get_value().get()?; + let val = *el.get_value().get()?; + let mut tmp = val; + tmp.square(); + tmp.mul_assign(&third); + + Ok(tmp) + })? }; // we take a value and make 5th power from it - cs.new_single_gate_for_trace_step( - &Nonlinearity5CustomGate::default(), - &[], - &[el.get_variable(), third.get_variable(), fifth.get_variable()], - &[] - )?; + cs.new_single_gate_for_trace_step(&Nonlinearity5CustomGate::default(), &[], &[el.get_variable(), third.get_variable(), fifth.get_variable()], &[])?; Ok(fifth) } - diff --git a/crates/franklin-crypto/src/plonk/circuit/custom_rescue_gate.rs b/crates/franklin-crypto/src/plonk/circuit/custom_rescue_gate.rs index ceca4e9..5558462 100644 --- a/crates/franklin-crypto/src/plonk/circuit/custom_rescue_gate.rs +++ b/crates/franklin-crypto/src/plonk/circuit/custom_rescue_gate.rs @@ -1,29 +1,18 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::SynthesisError; -use crate::bellman::worker::Worker; use crate::bellman::plonk::better_better_cs::cs::*; -use crate::bellman::plonk::polynomials::*; use crate::bellman::plonk::fft::cooley_tukey_ntt::*; +use crate::bellman::plonk::polynomials::*; +use crate::bellman::worker::Worker; +use crate::bellman::SynthesisError; use crate::plonk::circuit::Assignment; -use super::allocated_num::{ - AllocatedNum -}; +use super::allocated_num::AllocatedNum; -use super::linear_combination::{ - LinearCombination -}; +use super::linear_combination::LinearCombination; use crate::rescue::*; @@ -44,7 +33,7 @@ impl GateInternal for Rescue5CustomGate { } fn all_queried_polynomials(&self) -> &'static [PolynomialInConstraint] { - const POLYS : [PolynomialInConstraint; 4] = [ + const POLYS: [PolynomialInConstraint; 4] = [ PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), @@ -59,7 +48,7 @@ impl GateInternal for Rescue5CustomGate { } fn variable_polynomials(&self) -> &'static [PolyIdentifier] { - const POLYS : [PolyIdentifier; 4] = [ + const POLYS: [PolyIdentifier; 4] = [ PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2), @@ -90,7 +79,7 @@ impl GateInternal for Rescue5CustomGate { let b_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(1), row); let c_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(2), row); let d_value = poly_storage.get_poly_at_step(PolyIdentifier::VariablesPolynomial(3), row); - + let mut tmp = a_value; tmp.square(); tmp.sub_assign(&b_value); @@ -119,14 +108,14 @@ impl GateInternal for Rescue5CustomGate { } fn contribute_into_quotient( - &self, + &self, domain_size: usize, poly_storage: &mut AssembledPolynomialStorage, - monomials_storage: & AssembledPolynomialStorageForMonomialForms, + monomials_storage: &AssembledPolynomialStorageForMonomialForms, challenges: &[E::Fr], omegas_bitreversed: &BitReversedOmegas, _omegas_inv_bitreversed: &OmegasInvBitreversed, - worker: &Worker + worker: &Worker, ) -> Result, SynthesisError> { assert!(domain_size.is_power_of_two()); assert_eq!(challenges.len(), >::num_quotient_terms(&self)); @@ -137,115 +126,94 @@ impl GateInternal for Rescue5CustomGate { assert!(poly_storage.is_bitreversed); let coset_factor = E::Fr::multiplicative_generator(); - + for &p in >::all_queried_polynomials(&self).into_iter() { - ensure_in_map_or_create(&worker, - p, - domain_size, - omegas_bitreversed, - lde_factor, - coset_factor, - monomials_storage, - poly_storage - )?; + ensure_in_map_or_create(&worker, p, domain_size, omegas_bitreversed, lde_factor, coset_factor, monomials_storage, poly_storage)?; } let ldes_storage = &*poly_storage; - let a_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ); + let a_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage); let mut tmp = a_ref.clone(); // just allocate, we don't actually use it drop(a_ref); - let a_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), - ldes_storage - ).as_ref(); + let a_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0)), ldes_storage).as_ref(); - let b_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), - ldes_storage - ).as_ref(); + let b_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1)), ldes_storage).as_ref(); - let c_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), - ldes_storage - ).as_ref(); + let c_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2)), ldes_storage).as_ref(); - let d_raw_ref = get_from_map_unchecked( - PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), - ldes_storage - ).as_ref(); + let d_raw_ref = get_from_map_unchecked(PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3)), ldes_storage).as_ref(); - tmp.map_indexed(&worker, - |i, el| { - let a_value = a_raw_ref[i]; - let b_value = b_raw_ref[i]; - let c_value = c_raw_ref[i]; - let d_value = d_raw_ref[i]; + tmp.map_indexed(&worker, |i, el| { + let a_value = a_raw_ref[i]; + let b_value = b_raw_ref[i]; + let c_value = c_raw_ref[i]; + let d_value = d_raw_ref[i]; - // a^2 - b = 0 - let mut result = a_value; - result.square(); - result.sub_assign(&b_value); + // a^2 - b = 0 + let mut result = a_value; + result.square(); + result.sub_assign(&b_value); - result.mul_assign(&challenges[0]); + result.mul_assign(&challenges[0]); - // b^2 - c = 0 - let mut tmp = b_value; - tmp.square(); - tmp.sub_assign(&c_value); + // b^2 - c = 0 + let mut tmp = b_value; + tmp.square(); + tmp.sub_assign(&c_value); - tmp.mul_assign(&challenges[1]); + tmp.mul_assign(&challenges[1]); - result.add_assign(&tmp); + result.add_assign(&tmp); - // c*a - d = 0; - let mut tmp = c_value; - tmp.mul_assign(&a_value); - tmp.sub_assign(&d_value); + // c*a - d = 0; + let mut tmp = c_value; + tmp.mul_assign(&a_value); + tmp.sub_assign(&d_value); - tmp.mul_assign(&challenges[2]); + tmp.mul_assign(&challenges[2]); - result.add_assign(&tmp); + result.add_assign(&tmp); - *el = result; - }, - ); + *el = result; + }); Ok(tmp) } fn contribute_into_linearization( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, - _monomials_storage: & AssembledPolynomialStorageForMonomialForms, + _monomials_storage: &AssembledPolynomialStorageForMonomialForms, _challenges: &[E::Fr], - _worker: &Worker + _worker: &Worker, ) -> Result, SynthesisError> { unreachable!("this gate does not contribute into linearization"); } fn contribute_into_verification_equation( - &self, + &self, _domain_size: usize, _at: E::Fr, queried_values: &std::collections::HashMap, challenges: &[E::Fr], ) -> Result { assert_eq!(challenges.len(), >::num_quotient_terms(&self)); - - let a_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) + + let a_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(0))) .ok_or(SynthesisError::AssignmentMissing)?; - let b_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) + let b_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(1))) .ok_or(SynthesisError::AssignmentMissing)?; - let c_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) + let c_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(2))) .ok_or(SynthesisError::AssignmentMissing)?; - let d_value = *queried_values.get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) + let d_value = *queried_values + .get(&PolynomialInConstraint::from_id(PolyIdentifier::VariablesPolynomial(3))) .ok_or(SynthesisError::AssignmentMissing)?; // a^2 - b = 0 @@ -281,7 +249,7 @@ impl GateInternal for Rescue5CustomGate { } fn contribute_into_linearization_commitment( - &self, + &self, _domain_size: usize, _at: E::Fr, _queried_values: &std::collections::HashMap, @@ -294,44 +262,30 @@ impl GateInternal for Rescue5CustomGate { impl Gate for Rescue5CustomGate {} -pub fn apply_5th_power>( - cs: &mut CS, - el: &AllocatedNum, - existing_5th: Option>, -) -> Result, SynthesisError> { - - let squared = AllocatedNum::alloc( - cs, - || { - let mut val = *el.get_value().get()?; - val.square(); +pub fn apply_5th_power>(cs: &mut CS, el: &AllocatedNum, existing_5th: Option>) -> Result, SynthesisError> { + let squared = AllocatedNum::alloc(cs, || { + let mut val = *el.get_value().get()?; + val.square(); - Ok(val) - } - )?; + Ok(val) + })?; - let quad = AllocatedNum::alloc( - cs, - || { - let mut val = *squared.get_value().get()?; - val.square(); + let quad = AllocatedNum::alloc(cs, || { + let mut val = *squared.get_value().get()?; + val.square(); - Ok(val) - } - )?; + Ok(val) + })?; let fifth = if let Some(f) = existing_5th { f } else { - AllocatedNum::alloc( - cs, - || { - let mut val = *quad.get_value().get()?; - val.mul_assign(el.get_value().get()?); - - Ok(val) - } - )? + AllocatedNum::alloc(cs, || { + let mut val = *quad.get_value().get()?; + val.mul_assign(el.get_value().get()?); + + Ok(val) + })? }; let one = E::Fr::one(); @@ -340,12 +294,11 @@ pub fn apply_5th_power>( // we take a value and make 5th power from it cs.new_single_gate_for_trace_step( - &Rescue5CustomGate::default(), - &[], - &[el.get_variable(), squared.get_variable(), quad.get_variable(), fifth.get_variable()], - &[] + &Rescue5CustomGate::default(), + &[], + &[el.get_variable(), squared.get_variable(), quad.get_variable(), fifth.get_variable()], + &[], )?; Ok(fifth) } - diff --git a/crates/franklin-crypto/src/plonk/circuit/edwards/bn256/mod.rs b/crates/franklin-crypto/src/plonk/circuit/edwards/bn256/mod.rs index aad5448..2d55d26 100644 --- a/crates/franklin-crypto/src/plonk/circuit/edwards/bn256/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/edwards/bn256/mod.rs @@ -1,11 +1,11 @@ use super::edwards::CircuitTwistedEdwardsCurveImplementor; -use crate::generic_twisted_edwards::bn256::*; use crate::bellman::pairing::bn256::Bn256; +use crate::generic_twisted_edwards::bn256::*; pub struct CircuitAltBabyJubjubBn256; impl CircuitAltBabyJubjubBn256 { pub fn get_implementor() -> CircuitTwistedEdwardsCurveImplementor { let implementor = AltBabyJubjubBn256::get_implementor(); - CircuitTwistedEdwardsCurveImplementor {implementor } + CircuitTwistedEdwardsCurveImplementor { implementor } } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/edwards/edwards.rs b/crates/franklin-crypto/src/plonk/circuit/edwards/edwards.rs index 3ec69b5..32ccfec 100644 --- a/crates/franklin-crypto/src/plonk/circuit/edwards/edwards.rs +++ b/crates/franklin-crypto/src/plonk/circuit/edwards/edwards.rs @@ -1,13 +1,13 @@ -use crate::generic_twisted_edwards::edwards::*; use crate::bellman::plonk::better_better_cs::cs::ConstraintSystem; use crate::bellman::{Engine, Field, PrimeField, SqrtField, SynthesisError}; -use crate::plonk::circuit::Assignment; +use crate::generic_twisted_edwards::edwards::*; use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; use crate::plonk::circuit::simple_term::Term; +use crate::plonk::circuit::Assignment; use crate::plonk::circuit::{boolean::Boolean, linear_combination::LinearCombination}; pub struct CircuitTwistedEdwardsCurveImplementor> { - pub implementor: TwistedEdwardsCurveImplementor + pub implementor: TwistedEdwardsCurveImplementor, } impl> CircuitTwistedEdwardsCurveImplementor { @@ -15,15 +15,10 @@ impl> CircuitTwistedEdwardsCurveImple let out_of_circuit_implementor = TwistedEdwardsCurveImplementor::new_from_params(params); Self { - implementor: out_of_circuit_implementor + implementor: out_of_circuit_implementor, } } - pub fn add>( - &self, - cs: &mut CS, - p: &CircuitTwistedEdwardsPoint, - q: &CircuitTwistedEdwardsPoint, - ) -> Result, SynthesisError> { + pub fn add>(&self, cs: &mut CS, p: &CircuitTwistedEdwardsPoint, q: &CircuitTwistedEdwardsPoint) -> Result, SynthesisError> { if !self.implementor.curve_params.is_param_a_equals_minus_one() { unimplemented!("not yet implemented for a != -1"); } @@ -65,11 +60,7 @@ impl> CircuitTwistedEdwardsCurveImple Ok(CircuitTwistedEdwardsPoint { x: x3, y: y3 }) } - pub fn double>( - &self, - cs: &mut CS, - p: &CircuitTwistedEdwardsPoint, - ) -> Result, SynthesisError> { + pub fn double>(&self, cs: &mut CS, p: &CircuitTwistedEdwardsPoint) -> Result, SynthesisError> { if !self.implementor.curve_params.is_param_a_equals_minus_one() { unimplemented!("not yet implemented for a != -1"); } @@ -105,12 +96,7 @@ impl> CircuitTwistedEdwardsCurveImple Ok(CircuitTwistedEdwardsPoint { x: x3, y: y3 }) } - pub fn mul>( - &self, - cs: &mut CS, - p: &CircuitTwistedEdwardsPoint, - s: &[Boolean], - ) -> Result, SynthesisError> { + pub fn mul>(&self, cs: &mut CS, p: &CircuitTwistedEdwardsPoint, s: &[Boolean]) -> Result, SynthesisError> { if !self.implementor.curve_params.is_param_a_equals_minus_one() { unimplemented!("not yet implemented for a != -1"); } @@ -171,11 +157,7 @@ impl> CircuitTwistedEdwardsCurveImple // Ok(()) // } - pub fn is_in_main_subgroup>( - &self, - cs: &mut CS, - p: &CircuitTwistedEdwardsPoint, - ) -> Result { + pub fn is_in_main_subgroup>(&self, cs: &mut CS, p: &CircuitTwistedEdwardsPoint) -> Result { if !self.implementor.curve_params.is_param_a_equals_minus_one() { unimplemented!("not yet implemented for a != -1"); } @@ -192,17 +174,9 @@ impl> CircuitTwistedEdwardsCurveImple } } - CircuitTwistedEdwardsPoint::equals( - cs, - &CircuitTwistedEdwardsPoint::zero(), - &tmp - ) + CircuitTwistedEdwardsPoint::equals(cs, &CircuitTwistedEdwardsPoint::zero(), &tmp) } - pub fn mul_by_generator>( - &self, - cs: &mut CS, - s: &[Boolean], - ) -> Result, SynthesisError> { + pub fn mul_by_generator>(&self, cs: &mut CS, s: &[Boolean]) -> Result, SynthesisError> { if !self.implementor.curve_params.is_param_a_equals_minus_one() { unimplemented!("not yet implemented for a != -1"); } @@ -211,11 +185,7 @@ impl> CircuitTwistedEdwardsCurveImple self.mul(cs, &generator, s) } - pub fn alloc_point_enforce_on_curve>( - &self, - cs: &mut CS, - p: Option>, - ) -> Result, SynthesisError> { + pub fn alloc_point_enforce_on_curve>(&self, cs: &mut CS, p: Option>) -> Result, SynthesisError> { let p = p.map(|p| p.into_xy()); let x_witness = p.map(|p| p.0); @@ -228,11 +198,7 @@ impl> CircuitTwistedEdwardsCurveImple Ok(CircuitTwistedEdwardsPoint { x, y }) } - pub fn alloc_point_unchecked>( - &self, - cs: &mut CS, - p: Option>, - ) -> Result, SynthesisError> { + pub fn alloc_point_unchecked>(&self, cs: &mut CS, p: Option>) -> Result, SynthesisError> { let p = p.map(|p| p.into_xy()); let x_witness = p.map(|p| p.0); @@ -251,7 +217,7 @@ impl> CircuitTwistedEdwardsCurveImple let x = p.x; let y = p.y; - + // x^2 let x2 = x.mul(cs, &x)?; @@ -270,8 +236,7 @@ impl> CircuitTwistedEdwardsCurveImple Num::equals(cs, &lhs, &rhs) } - pub fn generator(&self) -> CircuitTwistedEdwardsPoint - { + pub fn generator(&self) -> CircuitTwistedEdwardsPoint { let gen = self.implementor.curve_params.generator(); let (x, y) = gen.into_xy(); let x = Num::Constant(x); @@ -292,12 +257,7 @@ impl> CircuitTwistedEdwardsCurveImple // Ok(CircuitTwistedEdwardsPoint { x, y }) // } - pub fn from_xy_assert_on_curve( - &self, - cs: &mut CS, - x: &Num, - y: &Num, - ) -> Result, SynthesisError> + pub fn from_xy_assert_on_curve(&self, cs: &mut CS, x: &Num, y: &Num) -> Result, SynthesisError> where CS: ConstraintSystem, { @@ -322,10 +282,7 @@ impl> CircuitTwistedEdwardsCurveImple lhs.enforce_equal(cs, &rhs)?; - Ok(CircuitTwistedEdwardsPoint { - x: x.clone(), - y: y.clone(), - }) + Ok(CircuitTwistedEdwardsPoint { x: x.clone(), y: y.clone() }) } } @@ -340,29 +297,17 @@ impl Copy for CircuitTwistedEdwardsPoint {} impl CircuitTwistedEdwardsPoint { pub fn zero() -> Self { - Self { - x: Num::zero(), - y: Num::one(), - } + Self { x: Num::zero(), y: Num::one() } } - pub fn conditionally_select>( - cs: &mut CS, - flag: &Boolean, - first: &Self, - second: &Self, - ) -> Result { + pub fn conditionally_select>(cs: &mut CS, flag: &Boolean, first: &Self, second: &Self) -> Result { let x = Num::conditionally_select(cs, flag, &first.x, &second.x)?; let y = Num::conditionally_select(cs, flag, &first.y, &second.y)?; Ok(Self { x, y }) } - pub fn equals>( - cs: &mut CS, - first: &Self, - second: &Self - ) -> Result { + pub fn equals>(cs: &mut CS, first: &Self, second: &Self) -> Result { let a = Num::equals(cs, &first.x, &second.x)?; let b = Num::equals(cs, &first.y, &second.y)?; diff --git a/crates/franklin-crypto/src/plonk/circuit/edwards/mod.rs b/crates/franklin-crypto/src/plonk/circuit/edwards/mod.rs index 93585cc..8c4dab3 100644 --- a/crates/franklin-crypto/src/plonk/circuit/edwards/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/edwards/mod.rs @@ -1,7 +1,7 @@ -pub mod edwards; pub mod bn256; +pub mod edwards; pub use self::edwards::{CircuitTwistedEdwardsCurveImplementor, CircuitTwistedEdwardsPoint}; #[cfg(test)] -mod tests; \ No newline at end of file +mod tests; diff --git a/crates/franklin-crypto/src/plonk/circuit/edwards/tests.rs b/crates/franklin-crypto/src/plonk/circuit/edwards/tests.rs index b2e86fa..19a5424 100644 --- a/crates/franklin-crypto/src/plonk/circuit/edwards/tests.rs +++ b/crates/franklin-crypto/src/plonk/circuit/edwards/tests.rs @@ -1,13 +1,11 @@ mod tests { - use super::super::edwards::*; use super::super::bn256::*; - use crate::bellman::plonk::better_better_cs::cs::{ - PlonkCsWidth4WithNextStepAndCustomGatesParams, TrivialAssembly, Width4MainGateWithDNext, - }; - use crate::bellman::pairing::bn256::{Bn256, Fr}; - use crate::bellman::pairing::ff::BitIterator; + use super::super::edwards::*; use crate::alt_babyjubjub::fs::Fs; use crate::alt_babyjubjub::AltJubjubBn256; + use crate::bellman::pairing::bn256::{Bn256, Fr}; + use crate::bellman::pairing::ff::BitIterator; + use crate::bellman::plonk::better_better_cs::cs::{PlonkCsWidth4WithNextStepAndCustomGatesParams, TrivialAssembly, Width4MainGateWithDNext}; use crate::bellman::{Field, PrimeField}; use crate::jubjub::edwards::Point; use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; @@ -18,11 +16,7 @@ mod tests { fn test_new_altjubjub_addition() { let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let mut cs = TrivialAssembly::< - Bn256, - PlonkCsWidth4WithNextStepAndCustomGatesParams, - Width4MainGateWithDNext, - >::new(); + let mut cs = TrivialAssembly::::new(); let params = AltJubjubBn256::new(); @@ -31,19 +25,13 @@ mod tests { let (p_x, p_y) = p.into_xy(); let p_x_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(p_x)).unwrap()); let p_y_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(p_y)).unwrap()); - let p_allocated = CircuitTwistedEdwardsPoint { - x: p_x_num, - y: p_y_num, - }; + let p_allocated = CircuitTwistedEdwardsPoint { x: p_x_num, y: p_y_num }; let q = Point::::rand(rng, ¶ms).mul_by_cofactor(¶ms); let (q_x, q_y) = q.into_xy(); let q_x_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(q_x)).unwrap()); let q_y_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(q_y)).unwrap()); - let q_allocated = CircuitTwistedEdwardsPoint { - x: q_x_num, - y: q_y_num, - }; + let q_allocated = CircuitTwistedEdwardsPoint { x: q_x_num, y: q_y_num }; let expected = p.add(&q, ¶ms); let (expected_x, expected_y) = expected.into_xy(); @@ -68,11 +56,7 @@ mod tests { fn test_new_altjubjub_doubling() { let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let mut cs = TrivialAssembly::< - Bn256, - PlonkCsWidth4WithNextStepAndCustomGatesParams, - Width4MainGateWithDNext, - >::new(); + let mut cs = TrivialAssembly::::new(); let params = AltJubjubBn256::new(); @@ -85,10 +69,7 @@ mod tests { let p_x_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(p_x)).unwrap()); let p_y_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(p_y)).unwrap()); - let p_allocated = CircuitTwistedEdwardsPoint { - x: p_x_num, - y: p_y_num, - }; + let p_allocated = CircuitTwistedEdwardsPoint { x: p_x_num, y: p_y_num }; let curve = CircuitAltBabyJubjubBn256::get_implementor(); let result = curve.double(&mut cs, &p_allocated).unwrap(); @@ -111,11 +92,7 @@ mod tests { fn test_new_altjubjub_multiplication() { let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let mut cs = TrivialAssembly::< - Bn256, - PlonkCsWidth4WithNextStepAndCustomGatesParams, - Width4MainGateWithDNext, - >::new(); + let mut cs = TrivialAssembly::::new(); let params = AltJubjubBn256::new(); @@ -125,10 +102,7 @@ mod tests { let p_x_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(p_x)).unwrap()); let p_y_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(p_y)).unwrap()); - let p_allocated = CircuitTwistedEdwardsPoint { - x: p_x_num, - y: p_y_num, - }; + let p_allocated = CircuitTwistedEdwardsPoint { x: p_x_num, y: p_y_num }; let s = Fs::rand(rng); @@ -167,11 +141,7 @@ mod tests { fn test_new_altjubjub_is_on_curve() { let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let mut cs = TrivialAssembly::< - Bn256, - PlonkCsWidth4WithNextStepAndCustomGatesParams, - Width4MainGateWithDNext, - >::new(); + let mut cs = TrivialAssembly::::new(); let params = AltJubjubBn256::new(); @@ -182,10 +152,7 @@ mod tests { let p_x_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(p_x)).unwrap()); let p_y_num = Num::Variable(AllocatedNum::alloc(&mut cs, || Ok(p_y)).unwrap()); - let _p_allocated = CircuitTwistedEdwardsPoint { - x: p_x_num, - y: p_y_num, - }; + let _p_allocated = CircuitTwistedEdwardsPoint { x: p_x_num, y: p_y_num }; let curve = CircuitAltBabyJubjubBn256::get_implementor(); let result = curve.from_xy_assert_on_curve(&mut cs, &p_x_num, &p_y_num).unwrap(); @@ -236,11 +203,7 @@ mod tests { use crate::jubjub::{FixedGenerators, JubjubParams}; let rng = &mut XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let mut cs = TrivialAssembly::< - Bn256, - PlonkCsWidth4WithNextStepAndCustomGatesParams, - Width4MainGateWithDNext, - >::new(); + let mut cs = TrivialAssembly::::new(); let params = AltJubjubBn256::new(); diff --git a/crates/franklin-crypto/src/plonk/circuit/goldilocks/mod.rs b/crates/franklin-crypto/src/plonk/circuit/goldilocks/mod.rs index 4a0a830..fad6ba4 100644 --- a/crates/franklin-crypto/src/plonk/circuit/goldilocks/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/goldilocks/mod.rs @@ -1,68 +1,35 @@ use num_traits::ops::overflowing; -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use plonk::circuit::boolean::Boolean; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - PlonkCsWidth4WithNextStepParams, - TrivialAssembly + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; -use crate::plonk::circuit::Assignment; -use super::*; use super::bigint::*; +use super::*; +use crate::plonk::circuit::Assignment; use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; -use crate::plonk::circuit::simple_term::{Term}; use crate::plonk::circuit::linear_combination::LinearCombination; +use crate::plonk::circuit::simple_term::Term; -use plonk::circuit::bigint_new::{ - enforce_range_check_using_naive_approach, - enforce_range_check_using_bitop_table, - BITWISE_LOGICAL_OPS_TABLE_NAME -}; +use plonk::circuit::bigint_new::{enforce_range_check_using_bitop_table, enforce_range_check_using_naive_approach, BITWISE_LOGICAL_OPS_TABLE_NAME}; -use boojum::field::{ - goldilocks::GoldilocksField as GL, - U64Representable, - PrimeField as PF, - goldilocks::GoldilocksExt2, - ExtensionField -}; +use boojum::field::{goldilocks::GoldilocksExt2, goldilocks::GoldilocksField as GL, ExtensionField, PrimeField as PF, U64Representable}; -use std::result; -use std::sync::Arc; -use std::sync::atomic::{AtomicUsize, Ordering}; use derivative::*; use std::hash::{Hash, Hasher}; +use std::result; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; pub mod prime_field_like; @@ -79,11 +46,7 @@ impl Hash for GoldilocksField { } } -fn range_check_for_num_bits>( - cs: &mut CS, - num: &Num, - num_bits: usize -) -> Result<(), SynthesisError> { +fn range_check_for_num_bits>(cs: &mut CS, num: &Num, num_bits: usize) -> Result<(), SynthesisError> { assert!(num_bits % 16 == 0); if let Num::Constant(value) = num { @@ -145,39 +108,28 @@ impl GoldilocksField { pub fn into_field(self) -> Option { self.into_u64().map(|value| GL::from_u64_unchecked(value)) } - + pub fn is_constant(&self) -> bool { self.inner.is_constant() } - pub fn alloc>( - cs: &mut CS, - witness: Option - ) -> Result { + pub fn alloc>(cs: &mut CS, witness: Option) -> Result { let num = Num::alloc(cs, witness)?; Self::from_num(cs, num) } - pub fn alloc_from_u64>( - cs: &mut CS, - witness: Option - ) -> Result { + pub fn alloc_from_u64>(cs: &mut CS, witness: Option) -> Result { let witness = witness.map(|value| E::Fr::from_repr(value.into()).unwrap()); Self::alloc(cs, witness) } - pub fn alloc_from_field>( - cs: &mut CS, - witness: Option - ) -> Result { + pub fn alloc_from_field>(cs: &mut CS, witness: Option) -> Result { let witness = witness.map(|value| value.as_u64_reduced()); Self::alloc_from_u64(cs, witness) } pub unsafe fn from_num_unchecked(num: Num) -> Result { - Ok(Self { - inner: num, - }) + Ok(Self { inner: num }) } pub fn from_num>(cs: &mut CS, num: Num) -> Result { @@ -187,9 +139,7 @@ impl GoldilocksField { let check = num.add(cs, &remainder)?; range_check_for_num_bits(cs, &check, 64)?; - Ok(Self { - inner: num, - }) + Ok(Self { inner: num }) } pub fn into_num(&self) -> Num { @@ -200,15 +150,9 @@ impl GoldilocksField { /// from random Bn256 scalar field element. Usually, we use N = 3. /// Note: we lose some information during this conversion, but it's OK. /// We only care about good output distribution. - pub fn from_num_to_multiple_with_reduction, const N: usize>( - cs: &mut CS, - num: Num, - ) -> Result<[Self; N], SynthesisError> { + pub fn from_num_to_multiple_with_reduction, const N: usize>(cs: &mut CS, num: Num) -> Result<[Self; N], SynthesisError> { assert_eq!(Self::ORDER_BITS, 64, "Only this case is supported for now"); - assert!( - N * Self::ORDER_BITS <= E::Fr::CAPACITY as usize, - "Scalar field capacity is too small" - ); + assert!(N * Self::ORDER_BITS <= E::Fr::CAPACITY as usize, "Scalar field capacity is too small"); let mut result = [Self::constant(0); N]; if let Num::Constant(value) = num { @@ -256,11 +200,7 @@ impl GoldilocksField { lc.enforce_zero(cs)?; // Now we check that there is no overflow - assert_eq!( - allocated_chunks.len(), - 4, - "Only this case is supported for now" - ); + assert_eq!(allocated_chunks.len(), 4, "Only this case is supported for now"); let mut first_u128_chunk: LinearCombination = allocated_chunks[0].into(); first_u128_chunk.add_assign_number_with_coeff(&allocated_chunks[1], shift); @@ -272,12 +212,7 @@ impl GoldilocksField { let max_field_element = minus_one; let (first_max_element_chunk, second_max_element_chunk) = { - let fe_repr: Vec<_> = max_field_element - .into_repr() - .as_ref() - .iter() - .map(|value| E::Fr::from_repr((*value).into()).unwrap()) - .collect(); + let fe_repr: Vec<_> = max_field_element.into_repr().as_ref().iter().map(|value| E::Fr::from_repr((*value).into()).unwrap()).collect(); let mut first_chunk = fe_repr[1]; first_chunk.mul_assign(&shift); @@ -320,20 +255,13 @@ impl GoldilocksField { Ok(result) } - pub fn negate>( - &self, - cs: &mut CS, - ) -> Result { + pub fn negate>(&self, cs: &mut CS) -> Result { let order = Num::Constant(E::Fr::from_repr(Self::ORDER.into()).unwrap()); let negate = order.sub(cs, &self.inner)?; Ok(Self { inner: negate }) } - pub fn add>( - &self, - cs: &mut CS, - other: &Self, - ) -> Result { + pub fn add>(&self, cs: &mut CS, other: &Self) -> Result { if let (Num::Constant(a), Num::Constant(b)) = (&self.inner, &other.inner) { let a = a.into_repr().as_ref()[0] as u128; let b = b.into_repr().as_ref()[0] as u128; @@ -367,11 +295,8 @@ impl GoldilocksField { Self::from_num(cs, result) } - - pub fn inverse>( - &self, - cs: &mut CS, - ) -> Result { + + pub fn inverse>(&self, cs: &mut CS) -> Result { let mut inverse_witness = self.into_field(); inverse_witness = inverse_witness.map(|el| el.inverse().expect("should be invertible")); let inverse = Self::alloc_from_field(cs, inverse_witness)?; @@ -382,23 +307,14 @@ impl GoldilocksField { Ok(inverse) } - pub fn mul>( - &self, - cs: &mut CS, - other: &Self, - ) -> Result { + pub fn mul>(&self, cs: &mut CS, other: &Self) -> Result { let zero = Self::constant(0); self.mul_add(cs, other, &zero) } /// self * other + third - pub fn mul_add>( - &self, - cs: &mut CS, - other: &Self, - third: &Self, - ) -> Result { + pub fn mul_add>(&self, cs: &mut CS, other: &Self, third: &Self) -> Result { if let (Num::Constant(a), Num::Constant(b), Num::Constant(c)) = (&self.inner, &other.inner, &third.inner) { let a = a.into_repr().as_ref()[0] as u128; let b = b.into_repr().as_ref()[0] as u128; @@ -435,37 +351,21 @@ impl GoldilocksField { Self::from_num(cs, result) } - pub fn equals>( - cs: &mut CS, - this: &Self, - other: &Self, - ) -> Result { - Num::equals(cs, &this.inner,&other.inner) + pub fn equals>(cs: &mut CS, this: &Self, other: &Self) -> Result { + Num::equals(cs, &this.inner, &other.inner) } - pub fn enforce_equal>( - &self, - cs: &mut CS, - other: &Self, - ) -> Result<(), SynthesisError> { + pub fn enforce_equal>(&self, cs: &mut CS, other: &Self) -> Result<(), SynthesisError> { self.inner.enforce_equal(cs, &other.inner) } - pub fn conditionally_select>( - cs: &mut CS, - bit: Boolean, - first: &Self, - second: &Self - ) -> Result { + pub fn conditionally_select>(cs: &mut CS, bit: Boolean, first: &Self, second: &Self) -> Result { let result = Num::conditionally_select(cs, &bit, &first.inner, &second.inner)?; - Ok(Self { inner: result} ) + Ok(Self { inner: result }) } - pub fn spread_into_bits, const LIMIT: usize>( - &self, - cs: &mut CS, - ) -> Result<[Boolean; LIMIT], SynthesisError> { + pub fn spread_into_bits, const LIMIT: usize>(&self, cs: &mut CS) -> Result<[Boolean; LIMIT], SynthesisError> { let witness = match self.inner.get_value() { Some(value) => { let repr = value.into_repr(); @@ -506,7 +406,7 @@ impl GoldilocksField { } } -pub type GLExt = ExtensionField::; +pub type GLExt = ExtensionField; /// Extension with poly x^2 - 7 #[derive(Derivative)] @@ -546,10 +446,7 @@ impl GoldilocksFieldExt { } } - pub fn alloc_from_field_ext>( - cs: &mut CS, - witness: Option - ) -> Result { + pub fn alloc_from_field_ext>(cs: &mut CS, witness: Option) -> Result { let (x_witness, y_witness); if let Some(witness) = witness { x_witness = Some(witness.coeffs[0]); @@ -560,10 +457,7 @@ impl GoldilocksFieldExt { }; Ok(Self { - inner: [ - GoldilocksField::alloc_from_field(cs, x_witness)?, - GoldilocksField::alloc_from_field(cs, y_witness)?, - ] + inner: [GoldilocksField::alloc_from_field(cs, x_witness)?, GoldilocksField::alloc_from_field(cs, y_witness)?], }) } @@ -571,15 +465,9 @@ impl GoldilocksFieldExt { Self::from_coords([GoldilocksField::constant_from_field(value), GoldilocksField::zero()]) } - pub fn from_num_coords>( - cs: &mut CS, - inner: [Num; 2] - ) -> Result { - Ok(Self { - inner: [ - GoldilocksField::from_num(cs, inner[0])?, - GoldilocksField::from_num(cs, inner[1])?, - ] + pub fn from_num_coords>(cs: &mut CS, inner: [Num; 2]) -> Result { + Ok(Self { + inner: [GoldilocksField::from_num(cs, inner[0])?, GoldilocksField::from_num(cs, inner[1])?], }) } @@ -587,10 +475,7 @@ impl GoldilocksFieldExt { let order = GoldilocksField::::ORDER; assert!(value[0] < order && value[1] < order); Self { - inner: [ - GoldilocksField::constant(value[0]), - GoldilocksField::constant(value[1]), - ], + inner: [GoldilocksField::constant(value[0]), GoldilocksField::constant(value[1])], } } @@ -598,21 +483,14 @@ impl GoldilocksFieldExt { self.inner[0].is_constant() && self.inner[1].is_constant() } - pub fn negate>( - &self, - cs: &mut CS, - ) -> Result { + pub fn negate>(&self, cs: &mut CS) -> Result { let x = self.inner[0].negate(cs)?; let y = self.inner[1].negate(cs)?; - + Ok(GoldilocksFieldExt::from_coords([x, y]).into()) } - pub fn add>( - &self, - cs: &mut CS, - other: &Self, - ) -> Result { + pub fn add>(&self, cs: &mut CS, other: &Self) -> Result { let mut result = [GoldilocksField::zero(); 2]; for i in 0..Self::EXTENSION_DEGREE { result[i] = self.inner[i].add(cs, &other.inner[i])?; @@ -621,10 +499,7 @@ impl GoldilocksFieldExt { Ok(Self::from_coords(result)) } - pub fn inverse>( - &self, - cs: &mut CS, - ) -> Result { + pub fn inverse>(&self, cs: &mut CS) -> Result { let mut field_ext = self.into_field_ext(); field_ext = field_ext.map(|x| x.inverse().expect("should be non-zero")); let inversed = Self::alloc_from_field_ext(cs, field_ext)?; @@ -638,22 +513,16 @@ impl GoldilocksFieldExt { } /// self * other + third - pub fn mul_add>( - &self, - cs: &mut CS, - other: &Self, - third: &Self, - ) -> Result { + pub fn mul_add>(&self, cs: &mut CS, other: &Self, third: &Self) -> Result { let mut res_witness = [None; 2]; let mut divs = [None; 2]; - if let ( - Some(a_x), Some(a_y), - Some(b_x), Some(b_y), - Some(c_x), Some(c_y), - ) = ( - &self.inner[0].inner.get_value(), &self.inner[1].inner.get_value(), - &other.inner[0].inner.get_value(), &other.inner[1].inner.get_value(), - &third.inner[0].inner.get_value(), &third.inner[1].inner.get_value(), + if let (Some(a_x), Some(a_y), Some(b_x), Some(b_y), Some(c_x), Some(c_y)) = ( + &self.inner[0].inner.get_value(), + &self.inner[1].inner.get_value(), + &other.inner[0].inner.get_value(), + &other.inner[1].inner.get_value(), + &third.inner[0].inner.get_value(), + &third.inner[1].inner.get_value(), ) { let a_x = a_x.into_repr().as_ref()[0] as u128; let a_y = a_y.into_repr().as_ref()[0] as u128; @@ -694,22 +563,12 @@ impl GoldilocksFieldExt { } if self.is_constant() && other.is_constant() && third.is_constant() { - return Ok( - Self::constant( - [res_witness[0].unwrap(), res_witness[1].unwrap()] - ) - ); + return Ok(Self::constant([res_witness[0].unwrap(), res_witness[1].unwrap()])); } - let result = [ - GoldilocksField::alloc_from_u64(cs, res_witness[0])?, - GoldilocksField::alloc_from_u64(cs, res_witness[1])?, - ]; + let result = [GoldilocksField::alloc_from_u64(cs, res_witness[0])?, GoldilocksField::alloc_from_u64(cs, res_witness[1])?]; - let divs = [ - Num::alloc(cs, divs[0])?, - Num::alloc(cs, divs[1])? - ]; + let divs = [Num::alloc(cs, divs[0])?, Num::alloc(cs, divs[1])?]; range_check_for_num_bits(cs, &divs[0], 80)?; range_check_for_num_bits(cs, &divs[1], 80)?; @@ -722,7 +581,6 @@ impl GoldilocksFieldExt { let mut minus_order = E::Fr::from_repr(order.into()).unwrap(); minus_order.negate(); - // check first coordinate let v_0 = self.inner[0].inner.mul(cs, &other.inner[0].inner)?; let v_1 = self.inner[1].inner.mul(cs, &other.inner[1].inner)?; @@ -735,7 +593,6 @@ impl GoldilocksFieldExt { lc.add_assign_number_with_coeff(&divs[0], minus_order); lc.enforce_zero(cs)?; - // check second coordinate let v_0 = self.inner[0].inner.mul(cs, &other.inner[1].inner)?; let v_1 = self.inner[1].inner.mul(cs, &other.inner[0].inner)?; @@ -748,23 +605,14 @@ impl GoldilocksFieldExt { lc.add_assign_number_with_coeff(&divs[1], minus_order); lc.enforce_zero(cs)?; - Ok(Self::from_coords(result)) } - pub fn mul>( - &self, - cs: &mut CS, - other: &Self, - ) -> Result { + pub fn mul>(&self, cs: &mut CS, other: &Self) -> Result { self.mul_add(cs, other, &Self::zero()) } - pub fn mul_by_base_field>( - &self, - cs: &mut CS, - other: &GoldilocksField, - ) -> Result { + pub fn mul_by_base_field>(&self, cs: &mut CS, other: &GoldilocksField) -> Result { let mut result = [GoldilocksField::zero(); 2]; for i in 0..Self::EXTENSION_DEGREE { result[i] = self.inner[i].mul(cs, &other)?; @@ -773,40 +621,22 @@ impl GoldilocksFieldExt { Ok(Self::from_coords(result)) } - fn enforce_equal>( - &self, - cs: &mut CS, - other: &Self, - ) -> Result<(), SynthesisError> { + fn enforce_equal>(&self, cs: &mut CS, other: &Self) -> Result<(), SynthesisError> { self.inner[0].enforce_equal(cs, &other.inner[0])?; self.inner[1].enforce_equal(cs, &other.inner[1])?; Ok(()) } - pub fn conditionally_select>( - cs: &mut CS, - bit: Boolean, - first: &Self, - second: &Self - ) -> Result { + pub fn conditionally_select>(cs: &mut CS, bit: Boolean, first: &Self, second: &Self) -> Result { let mut result = [GoldilocksField::zero(); 2]; for i in 0..Self::EXTENSION_DEGREE { - result[i] = GoldilocksField::conditionally_select( - cs, - bit.clone(), - &first.inner[i], - &second.inner[i] - )?; + result[i] = GoldilocksField::conditionally_select(cs, bit.clone(), &first.inner[i], &second.inner[i])?; } Ok(Self::from_coords(result)) } - pub fn evaluate_poly>( - cs: &mut CS, - point: &Self, - poly: &[Self], - ) -> Result { + pub fn evaluate_poly>(cs: &mut CS, point: &Self, poly: &[Self]) -> Result { if poly.len() == 0 { return Ok(Self::zero()); } @@ -825,12 +655,12 @@ mod test { use super::*; use crate::bellman::plonk::better_better_cs::cs::*; extern crate boojum; - + use crate::bellman::pairing::bn256::{Bn256, Fr}; - use rand::Rng; - use boojum::field::U64Representable; - use boojum::field::SmallField; use boojum::field::Field; + use boojum::field::SmallField; + use boojum::field::U64Representable; + use rand::Rng; #[test] fn test_goldilocks_field() { @@ -841,10 +671,8 @@ mod test { let buffer_u64 = [0; 10].map(|_| rng.gen_range(0, GL::CHAR)); let buffer_gl = buffer_u64.map(|x| GL::from_u64_unchecked(x)); - let buffer_circuit = buffer_u64.map(|x| - GoldilocksField::alloc_from_u64(&mut assembly, Some(x)).unwrap() - ); - // let buffer_circuit = buffer_u64.map(|x| + let buffer_circuit = buffer_u64.map(|x| GoldilocksField::alloc_from_u64(&mut assembly, Some(x)).unwrap()); + // let buffer_circuit = buffer_u64.map(|x| // GoldilocksField::constant(x) // ); @@ -855,29 +683,13 @@ mod test { assert_eq!(Some(gl_sum.as_u64_reduced()), circuit_sum.into_u64()); // add table for range check - let columns3 = vec![ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2), - ]; - + let columns3 = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; let name = BITWISE_LOGICAL_OPS_TABLE_NAME; - let bitwise_logic_table = LookupTableApplication::new( - name, - TwoKeysOneValueBinopTable::::new(8, name), - columns3.clone(), - None, - true, - ); + let bitwise_logic_table = LookupTableApplication::new(name, TwoKeysOneValueBinopTable::::new(8, name), columns3.clone(), None, true); assembly.add_table(bitwise_logic_table).unwrap(); - - let circuit_fma = buffer_circuit[2].mul_add( - &mut assembly, - &buffer_circuit[3], - &buffer_circuit[4] - ).unwrap(); + let circuit_fma = buffer_circuit[2].mul_add(&mut assembly, &buffer_circuit[3], &buffer_circuit[4]).unwrap(); let mut gl_fma = buffer_gl[2]; gl_fma.mul_assign(&buffer_gl[3]); @@ -887,10 +699,7 @@ mod test { let mut repr = Fr::default().into_repr(); repr.as_mut()[..3].copy_from_slice(&buffer_u64[5..8]); - let combined = Num::alloc( - &mut assembly, - Some(Fr::from_repr(repr).unwrap()) - ).unwrap(); + let combined = Num::alloc(&mut assembly, Some(Fr::from_repr(repr).unwrap())).unwrap(); let parts = GoldilocksField::from_num_to_multiple_with_reduction::<_, 3>(&mut assembly, combined).unwrap(); @@ -909,28 +718,16 @@ mod test { let mut rng = rand::thread_rng(); let buffer_u64 = [0; 10].map(|_| rng.gen_range(0, GL::CHAR)); - let buffer_circuit = buffer_u64.map(|x| - GoldilocksField::alloc_from_u64(&mut assembly, Some(x)).unwrap() - ); - // let buffer_circuit = buffer_u64.map(|x| + let buffer_circuit = buffer_u64.map(|x| GoldilocksField::alloc_from_u64(&mut assembly, Some(x)).unwrap()); + // let buffer_circuit = buffer_u64.map(|x| // GoldilocksField::constant(x) // ); // add table for range check - let columns3 = vec![ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2), - ]; + let columns3 = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; let name = BITWISE_LOGICAL_OPS_TABLE_NAME; - let bitwise_logic_table = LookupTableApplication::new( - name, - TwoKeysOneValueBinopTable::::new(8, name), - columns3.clone(), - None, - true, - ); + let bitwise_logic_table = LookupTableApplication::new(name, TwoKeysOneValueBinopTable::::new(8, name), columns3.clone(), None, true); assembly.add_table(bitwise_logic_table).unwrap(); let a = GoldilocksFieldExt::::from_coords([buffer_circuit[0], buffer_circuit[1]]); @@ -960,5 +757,4 @@ mod test { assert!(assembly.is_satisfied()); } - -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/goldilocks/prime_field_like.rs b/crates/franklin-crypto/src/plonk/circuit/goldilocks/prime_field_like.rs index a7d26f2..ffafd5a 100644 --- a/crates/franklin-crypto/src/plonk/circuit/goldilocks/prime_field_like.rs +++ b/crates/franklin-crypto/src/plonk/circuit/goldilocks/prime_field_like.rs @@ -1,7 +1,7 @@ use super::*; -use boojum::field::traits::field_like::PrimeFieldLike; use boojum::field::goldilocks::GoldilocksField as GL; +use boojum::field::traits::field_like::PrimeFieldLike; #[derive(Derivative)] #[derivative(Clone, Copy, Debug(bound = ""), Hash(bound = ""))] @@ -114,7 +114,6 @@ where } } - #[derive(Derivative)] #[derivative(Clone, Copy, Debug(bound = ""), Hash(bound = ""))] pub struct GoldilocksExtAsFieldWrapper> { @@ -156,32 +155,19 @@ impl> GoldilocksExtAsFieldWrapper { } pub fn from_wrapper_coeffs_in_base(coeffs: [GoldilocksAsFieldWrapper; 2]) -> Self { - let coeffs = [ - coeffs[0].inner, - coeffs[1].inner, - ]; + let coeffs = [coeffs[0].inner, coeffs[1].inner]; Self::from_coeffs_in_base(coeffs) } - pub fn mul_by_base_and_accumulate_into( - dst: &mut Self, - base: &GoldilocksAsFieldWrapper, - other: &Self, - cs: &mut CS, - ) -> Result<(), SynthesisError> { - for (dst, src) in dst.inner.inner.iter_mut() - .zip(other.inner.inner.iter()) { + pub fn mul_by_base_and_accumulate_into(dst: &mut Self, base: &GoldilocksAsFieldWrapper, other: &Self, cs: &mut CS) -> Result<(), SynthesisError> { + for (dst, src) in dst.inner.inner.iter_mut().zip(other.inner.inner.iter()) { *dst = src.mul_add(cs, &base.inner, dst)?; } Ok(()) } - pub fn mul_assign_by_base( - &mut self, - cs: &mut CS, - base: &GoldilocksAsFieldWrapper - ) -> Result<(), SynthesisError> { + pub fn mul_assign_by_base(&mut self, cs: &mut CS, base: &GoldilocksAsFieldWrapper) -> Result<(), SynthesisError> { for dst in self.inner.inner.iter_mut() { *dst = dst.mul(cs, &base.inner)?; } @@ -262,9 +248,9 @@ where fn inverse(&self, ctx: &mut Self::Context) -> Self { self.inner.inverse(ctx).unwrap().into() } - + // constant creation fn constant(value: Self::Base, _ctx: &mut Self::Context) -> Self { GoldilocksFieldExt::constant_from_field(value).into() } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/gadgets.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/gadgets.rs index 453a713..7c3f996 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/gadgets.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/gadgets.rs @@ -1,53 +1,45 @@ use itertools::Itertools; +use crate::bellman::pairing::ff::*; +use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::plonk::better_better_cs::lookup_tables::*; use crate::bellman::plonk::better_better_cs::utils; -use crate::bellman::pairing::ff::*; -use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; -use crate::bellman::SynthesisError; use crate::bellman::Engine; -use crate::plonk::circuit::allocated_num::{ - AllocatedNum, - Num, -}; +use crate::bellman::SynthesisError; +use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; +use crate::plonk::circuit::assignment::Assignment; +use crate::plonk::circuit::bigint_new::bigint::split_some_into_fixed_number_of_limbs; +use crate::plonk::circuit::bigint_new::range_checks::enforce_range_check_using_bitop_table; use crate::plonk::circuit::bigint_new::*; use crate::plonk::circuit::boolean::*; -use crate::plonk::circuit::byte::{ - Byte, -}; -use crate::plonk::circuit::assignment::{ - Assignment -}; -use crate::plonk::circuit::bigint_new::range_checks::enforce_range_check_using_bitop_table; -use crate::plonk::circuit::bigint_new::bigint::split_some_into_fixed_number_of_limbs; +use crate::plonk::circuit::byte::Byte; -use super::tables::*; -use super::super::utils::*; use super::super::tables::*; -use super::super::{NumExtension, AllocatedNumExtension}; +use super::super::utils::*; +use super::super::{AllocatedNumExtension, NumExtension}; +use super::tables::*; -use std::collections::BTreeMap; -use std::sync::Arc; use crate::splitmut::SplitMut; -use std::{ iter, mem }; -use std::collections::HashMap; use std::cell::RefCell; +use std::collections::BTreeMap; +use std::collections::HashMap; use std::ops::Index; +use std::sync::Arc; +use std::{iter, mem}; type Result = std::result::Result; -const CHUNK_SIZE : usize = 8; -const REG_WIDTH : usize = 32; -const SHIFT4 : usize = 4; -const SHIFT7 : usize = 7; -const BLAKE2S_STATE_WIDTH : usize = 16; -const CS_WIDTH : usize = 4; -const BLAKE2S_NUM_ROUNDS : usize = 10; - +const CHUNK_SIZE: usize = 8; +const REG_WIDTH: usize = 32; +const SHIFT4: usize = 4; +const SHIFT7: usize = 7; +const BLAKE2S_STATE_WIDTH: usize = 16; +const CS_WIDTH: usize = 4; +const BLAKE2S_NUM_ROUNDS: usize = 10; #[derive(Clone)] -pub struct DecomposedNum { +pub struct DecomposedNum { pub r0: Num, pub r1: Num, pub r2: Num, @@ -57,9 +49,9 @@ pub struct DecomposedNum { impl Default for DecomposedNum { fn default() -> Self { DecomposedNum { - r0: Num::default(), - r1: Num::default(), - r2: Num::default(), + r0: Num::default(), + r1: Num::default(), + r2: Num::default(), r3: Num::default(), } } @@ -79,7 +71,6 @@ impl Index for DecomposedNum { } } - #[derive(Clone)] pub struct Reg { full: Num, @@ -89,7 +80,7 @@ pub struct Reg { impl Default for Reg { fn default() -> Self { Reg { - full : Num::default(), + full: Num::default(), decomposed: DecomposedNum::default(), } } @@ -105,16 +96,14 @@ impl Reg { } } - #[derive(Clone, Default)] pub struct HashState(Vec>); - // the purpose of this (and the following) struct is explained in the comments of the main text // all linear variables are represented in the form (bool, coef, var) // where the boolean flag asserts that variable was actually assigned a value (for self-test and debugging assistance) #[derive(Clone)] -pub struct GateVarHelper{ +pub struct GateVarHelper { is_assigned: bool, coef: E::Fr, val: Num, @@ -137,7 +126,7 @@ pub struct GateAllocHelper { cnst_sel: E::Fr, d_next_sel: E::Fr, - table: Option>> + table: Option>>, } impl Default for GateAllocHelper { @@ -146,7 +135,7 @@ impl Default for GateAllocHelper { vars: <[GateVarHelper; CS_WIDTH]>::default(), cnst_sel: E::Fr::zero(), d_next_sel: E::Fr::zero(), - table: None, + table: None, } } } @@ -157,8 +146,7 @@ impl GateAllocHelper { } // force variable - checks that the variable is indeed AllocatedVar and not constant - pub fn set_var(&mut self, idx: usize, coef: E::Fr, input: Num, force_allocated: bool) - { + pub fn set_var(&mut self, idx: usize, coef: E::Fr, input: Num, force_allocated: bool) { assert!(idx < CS_WIDTH); if force_allocated && input.is_constant() { panic!("The variable should be actually allocated.") @@ -182,35 +170,33 @@ impl GateAllocHelper { pub fn is_prepared(&self) -> bool { self.vars.iter().all(|x| x.is_assigned) - } + } } - #[derive(Clone)] pub struct XorRotOutput { pub z: Reg, - pub qs : [Num; 4], + pub qs: [Num; 4], pub ws: [Num; 3], pub q_ch_rots: Option<(Num, Num)>, pub shifts: [usize; 4], pub start_idx: usize, } - pub struct Blake2sGadget { use_additional_tables: bool, xor_table: Arc>, - + xor_rotate4_table: Option>>, xor_rotate7_table: Option>>, compound_rot4_7_table: Option>>, - + iv: [u64; 8], iv0_twist: u64, - sigmas : [[usize; 16]; 10], + sigmas: [[usize; 16]; 10], declared_cnsts: RefCell::Repr, AllocatedNum>>, - allocated_cnsts : RefCell::Repr, AllocatedNum>>, + allocated_cnsts: RefCell::Repr, AllocatedNum>>, // constants heavily used zero: E::Fr, @@ -227,8 +213,8 @@ impl Blake2sGadget { let r3 = Num::Constant(u64_to_ff((n >> (3 * CHUNK_SIZE)) & 0xff)); Reg { - full, - decomposed: DecomposedNum { r0, r1, r2, r3} + full, + decomposed: DecomposedNum { r0, r1, r2, r3 }, } } @@ -240,37 +226,38 @@ impl Blake2sGadget { let x = enforce_range_check_using_bitop_table(cs, &var, 32, table, false)?; let dcmps = x.get_vars(); Reg { - full: num.clone(), - decomposed: DecomposedNum { - r0: Num::Variable(dcmps[0].clone()), r1: Num::Variable(dcmps[1].clone()), - r2: Num::Variable(dcmps[2].clone()), r3: Num::Variable(dcmps[3].clone()) - } + full: num.clone(), + decomposed: DecomposedNum { + r0: Num::Variable(dcmps[0].clone()), + r1: Num::Variable(dcmps[1].clone()), + r2: Num::Variable(dcmps[2].clone()), + r3: Num::Variable(dcmps[3].clone()), + }, } - }, + } }; - + Ok(res) } - fn decompose_total_len_var>( - &self, cs: &mut CS, var: &AllocatedNum, max_total_len: u64 - ) -> Result<(Reg, Reg)> - { + fn decompose_total_len_var>(&self, cs: &mut CS, var: &AllocatedNum, max_total_len: u64) -> Result<(Reg, Reg)> { let val = some_fe_to_biguint(&var.get_value()); let table = self.xor_table.clone(); let max_low_val = max_total_len & ((1 << REG_WIDTH) - 1); let max_high_val = max_total_len >> REG_WIDTH; let bitlens = [num_bits::(max_low_val), num_bits::(max_high_val)]; - + if bitlens[1] == 0 { let x = enforce_range_check_using_bitop_table(cs, &var, bitlens[0], table.clone(), false)?; let dcmps = x.get_vars(); let low = Reg { - full: Num::Variable(var.clone()), - decomposed: DecomposedNum { - r0: Num::Variable(dcmps[0].clone()), r1: Num::Variable(dcmps[1].clone()), - r2: Num::Variable(dcmps[2].clone()), r3: Num::Variable(dcmps[3].clone()) - } + full: Num::Variable(var.clone()), + decomposed: DecomposedNum { + r0: Num::Variable(dcmps[0].clone()), + r1: Num::Variable(dcmps[1].clone()), + r2: Num::Variable(dcmps[2].clone()), + r3: Num::Variable(dcmps[3].clone()), + }, }; return Ok((low, Reg::default())); } @@ -287,27 +274,27 @@ impl Blake2sGadget { let dcmps = x.get_vars(); let reg = Reg { - full: Num::Variable(var), - decomposed: DecomposedNum { - r0: Num::Variable(dcmps[0].clone()), r1: Num::Variable(dcmps[1].clone()), - r2: Num::Variable(dcmps[2].clone()), r3: Num::Variable(dcmps[3].clone()) - } + full: Num::Variable(var), + decomposed: DecomposedNum { + r0: Num::Variable(dcmps[0].clone()), + r1: Num::Variable(dcmps[1].clone()), + r2: Num::Variable(dcmps[2].clone()), + r3: Num::Variable(dcmps[3].clone()), + }, }; *out = reg; }; - }; + } let mut shift = E::Fr::one(); for _ in 0..REG_WIDTH { shift.double(); } - + let low_term = ArithmeticTerm::from_variable(regs[0].full.get_variable().get_variable()); - let high_term = ArithmeticTerm::from_variable_and_coeff( - regs[1].full.get_variable().get_variable(), shift - ); + let high_term = ArithmeticTerm::from_variable_and_coeff(regs[1].full.get_variable().get_variable(), shift); let total_term = ArithmeticTerm::from_variable(var.get_variable()); - + let mut gate = MainGateTerm::new(); gate.add_assign(low_term); gate.add_assign(high_term); @@ -318,30 +305,30 @@ impl Blake2sGadget { } fn alloc_num_from_u64>(&self, cs: &mut CS, n: Option) -> Result> { - let val = n.map(|num| { u64_to_ff(num) }); - let new_var = AllocatedNum::alloc(cs, || {val.grab()})?; + let val = n.map(|num| u64_to_ff(num)); + let new_var = AllocatedNum::alloc(cs, || val.grab())?; Ok(Num::Variable(new_var)) } fn alloc_reg_from_u64>(&self, cs: &mut CS, n: Option) -> Result> { - let full_val = n.map(|num| { u64_to_ff(num) }); - let full = Num::Variable(AllocatedNum::alloc(cs, || {full_val.grab()})?); - - let r0_val = n.map(|num| { u64_to_ff(num & 0xff) }); - let r0 = Num::Variable(AllocatedNum::alloc(cs, || {r0_val.grab()})?); + let full_val = n.map(|num| u64_to_ff(num)); + let full = Num::Variable(AllocatedNum::alloc(cs, || full_val.grab())?); + + let r0_val = n.map(|num| u64_to_ff(num & 0xff)); + let r0 = Num::Variable(AllocatedNum::alloc(cs, || r0_val.grab())?); - let r1_val = n.map(|num| { u64_to_ff((num >> CHUNK_SIZE) & 0xff) }); - let r1 = Num::Variable(AllocatedNum::alloc(cs, || {r1_val.grab()})?); + let r1_val = n.map(|num| u64_to_ff((num >> CHUNK_SIZE) & 0xff)); + let r1 = Num::Variable(AllocatedNum::alloc(cs, || r1_val.grab())?); - let r2_val = n.map(|num| { u64_to_ff((num >> (2 * CHUNK_SIZE)) & 0xff) }); - let r2 = Num::Variable(AllocatedNum::alloc(cs, || {r2_val.grab()})?); + let r2_val = n.map(|num| u64_to_ff((num >> (2 * CHUNK_SIZE)) & 0xff)); + let r2 = Num::Variable(AllocatedNum::alloc(cs, || r2_val.grab())?); - let r3_val = n.map(|num| { u64_to_ff((num >> (3 * CHUNK_SIZE)) & 0xff) }); - let r3 = Num::Variable(AllocatedNum::alloc(cs, || {r3_val.grab()})?); + let r3_val = n.map(|num| u64_to_ff((num >> (3 * CHUNK_SIZE)) & 0xff)); + let r3 = Num::Variable(AllocatedNum::alloc(cs, || r3_val.grab())?); let res = Reg { - full, - decomposed: DecomposedNum { r0, r1, r2, r3} + full, + decomposed: DecomposedNum { r0, r1, r2, r3 }, }; Ok(res) } @@ -352,86 +339,52 @@ impl Blake2sGadget { _ => panic!("should be allocated"), } } - + pub fn new>(cs: &mut CS, use_additional_tables: bool) -> Result { - let columns3 = vec![ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2) - ]; + let columns3 = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; let name1: &'static str = "xor_table"; - let xor_table = LookupTableApplication::new( - name1, - XorRotateTable::new(CHUNK_SIZE, 0, name1), - columns3.clone(), - None, - true - ); + let xor_table = LookupTableApplication::new(name1, XorRotateTable::new(CHUNK_SIZE, 0, name1), columns3.clone(), None, true); let xor_table = add_table_once(cs, xor_table)?; let xor_rotate4_table = if use_additional_tables { - let name2 : &'static str = "xor_rotate4_table"; - let xor_rotate4_table = LookupTableApplication::new( - name2, - XorRotateTable::new(CHUNK_SIZE, SHIFT4 as u32, name2), - columns3.clone(), - None, - true - ); + let name2: &'static str = "xor_rotate4_table"; + let xor_rotate4_table = LookupTableApplication::new(name2, XorRotateTable::new(CHUNK_SIZE, SHIFT4 as u32, name2), columns3.clone(), None, true); Some(add_table_once(cs, xor_rotate4_table)?) - } - else { + } else { None }; let xor_rotate7_table = if use_additional_tables { - let name3 : &'static str = "xor_rotate7_table"; - let xor_rotate7_table = LookupTableApplication::new( - name3, - XorRotateTable::new(CHUNK_SIZE, SHIFT7 as u32, name3), - columns3.clone(), - None, - true - ); + let name3: &'static str = "xor_rotate7_table"; + let xor_rotate7_table = LookupTableApplication::new(name3, XorRotateTable::new(CHUNK_SIZE, SHIFT7 as u32, name3), columns3.clone(), None, true); Some(add_table_once(cs, xor_rotate7_table)?) - } - else { + } else { None }; let compound_rot4_7_table = if !use_additional_tables { - let name4 : &'static str = "compound_rot4_7_table"; - let compound_rot4_7_table = LookupTableApplication::new( - name4, - CompoundRotTable::new(CHUNK_SIZE, SHIFT4, SHIFT7, name4), - columns3.clone(), - None, - true - ); + let name4: &'static str = "compound_rot4_7_table"; + let compound_rot4_7_table = LookupTableApplication::new(name4, CompoundRotTable::new(CHUNK_SIZE, SHIFT4, SHIFT7, name4), columns3.clone(), None, true); Some(add_table_once(cs, compound_rot4_7_table)?) - } - else { + } else { None }; - - let iv = [ - 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, - 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19, - ]; - let iv0_twist = 0x6A09E667 ^ 0x01010000 ^ 32; + + let iv = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19]; + let iv0_twist = 0x6A09E667 ^ 0x01010000 ^ 32; let sigmas: [[usize; 16]; 10] = [ - [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], - [ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ], - [ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ], - [ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ], - [ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ], - [ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ], - [ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ], - [ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ], - [ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ], - [ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 ] + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], + [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], + [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], + [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], + [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], + [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], + [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], + [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], + [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], ]; let declared_cnsts = RefCell::new(BTreeMap::new()); @@ -440,7 +393,7 @@ impl Blake2sGadget { let zero = E::Fr::zero(); let one = E::Fr::one(); let mut minus_one = E::Fr::one(); - minus_one.negate(); + minus_one.negate(); Ok(Blake2sGadget { use_additional_tables, @@ -476,7 +429,7 @@ impl Blake2sGadget { let gate_term = MainGateTerm::new(); let (mut vars, mut coefs) = CS::MainGate::format_term(gate_term, dummy)?; - let mut cnst = gate_alloc_helper.cnst_sel; + let mut cnst = gate_alloc_helper.cnst_sel; // plug-in all linear terms for (pos, idx) in range_of_linear_terms.zip(0..CS_WIDTH) { @@ -484,12 +437,12 @@ impl Blake2sGadget { Num::Variable(var) => { vars[idx] = var.get_variable(); coefs[pos] = gate_alloc_helper.vars[idx].coef; - }, + } Num::Constant(fr) => { let mut tmp = fr; tmp.mul_assign(&gate_alloc_helper.vars[idx].coef); cnst.add_assign(&tmp); - }, + } } } @@ -507,22 +460,23 @@ impl Blake2sGadget { } cs.begin_gates_batch_for_step()?; - + // apply table lookup if we have one if let Some(table) = gate_alloc_helper.table { cs.apply_single_lookup_gate(&vars[..table.width()], table.clone())?; } - // apply main gate + // apply main gate let mg = CS::MainGate::default(); cs.new_gate_in_batch(&mg, &coefs, &vars, &[])?; cs.end_gates_batch_for_step()?; - + Ok(()) } fn xor_rot(&self, cs: &mut CS, a: &Num, b: &Num, rot: usize) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { AllocatedNum::alloc(cs, || { let a = a.get_value().grab()?; @@ -538,28 +492,28 @@ impl Blake2sGadget { }) } - fn xor>(&self, cs: &mut CS, a: &Num, b: &Num) -> Result> - { + fn xor>(&self, cs: &mut CS, a: &Num, b: &Num) -> Result> { self.xor_rot(cs, a, b, 0) } fn rot>(&self, cs: &mut CS, a: &Num, rot: usize) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let dummy = Num::Variable(AllocatedNum::zero(cs)); self.xor_rot(cs, a, &dummy, rot) } fn constraint_all_allocated_cnsts>(&self, cs: &mut CS) -> Result<()> { - let mut allocated_cnsts_dict = self.allocated_cnsts.borrow_mut(); + let mut allocated_cnsts_dict = self.allocated_cnsts.borrow_mut(); let declared_cnsts_dict = std::mem::replace(&mut *self.declared_cnsts.borrow_mut(), BTreeMap::new()); for (fr_repr, variable) in declared_cnsts_dict { - // for fr in keys.into_iter() { + // for fr in keys.into_iter() { // let variable = declared_cnsts_dict.remove(&fr).unwrap(); let self_term = ArithmeticTerm::from_variable(variable.get_variable()); let fr = E::Fr::from_repr(fr_repr).unwrap(); let other_term = ArithmeticTerm::constant(fr); - + let mut term = MainGateTerm::new(); term.add_assign(self_term); term.sub_assign(other_term); @@ -578,8 +532,7 @@ impl Blake2sGadget { Num::Constant(fr) => { if fr.is_zero() { Num::Variable(AllocatedNum::zero(cs)) - } - else { + } else { let allocated_map = self.allocated_cnsts.borrow(); let mut declared_map = self.declared_cnsts.borrow_mut(); let fr_repr = fr.into_repr(); @@ -587,19 +540,19 @@ impl Blake2sGadget { Some(entry) => entry.clone(), None => { if let Some(var) = declared_map.get(&fr_repr).cloned() { - var + var } else { let var = AllocatedNum::alloc(cs, || Ok(*fr))?; let prev = declared_map.insert(fr_repr, var); assert!(prev.is_none()); - + var } - }, + } }; Num::Variable(var) } - }, + } }; Ok(res) @@ -630,31 +583,32 @@ impl Blake2sGadget { // no constraints will be allocated, just return the new constant (NB: what if t will be a variable) // 2) all of a, b, x are variables: there will be 3 rows: - // [y0, y1, y2, y3] - decomposed parts of resulted y: y = y0 + 2^8 * y1 + 2^16 * y2 + 2^24 * y3: + // [y0, y1, y2, y3] - decomposed parts of resulted y: y = y0 + 2^8 * y1 + 2^16 * y2 + 2^24 * y3: // [a, b, x, y] - where y = a + b + x - 2^32 * of (using of via d_next selector) // [of, t, of ^ t, of] - range check for of and t // 3) if we are in between these two corner cases we are going to use the sceme as in case (2), the only difference is that // we are going to replace all instances of costant variables with dummy placeholders and push them instead into constant selector // e.g: assume thta a - is variable (AllocatedVar) and b, x - are constants : than in any case y, of, y0, y1, y2, y3 -a re variables - // and the second row will be replaced by: + // and the second row will be replaced by: // [a, dummy, dummy, y], and constant selector will contain the value of x + y // this identical approach to handling constant and variables is hidden under the GateAllocHelper facade - + // NB: there is inversion in computation: we first precompute the value of y and split it into corresponding - // chunks y0, y1, y2, y3 BEFORE allocating contraint defining y itself! this inversion will be a recurring pattern + // chunks y0, y1, y2, y3 BEFORE allocating contraint defining y itself! this inversion will be a recurring pattern // in our optimization // also - there is a place for additional 8-bit variable t on the last row, so there is a possibility to multiplex two // oveflow checks on the same row: for current of and (yet unknown) t // and yes, we are going to explot the inversion trick again: we take t from overflow check of step 3! - // due to such an extended use of inversion trick we have to split all equation generations it two phases: + // due to such an extended use of inversion trick we have to split all equation generations it two phases: // setup - where we aforehead define all variables and compute their values // and actual gate allocation // setup of first step: given a, b, x - return [y, of] (in that order) fn g_ternary_additon_setup(&self, cs: &mut CS, a: &Reg, b: &Reg, x: &Num) -> Result<(Reg, Num)> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let (y, of) = match (&a.full, &b.full, &x) { (Num::Constant(fr1), Num::Constant(fr2), Num::Constant(fr3)) => { @@ -664,7 +618,7 @@ impl Blake2sGadget { let f_repr = temp.into_repr(); let y = f_repr.as_ref()[0] & ((1 << REG_WIDTH) - 1); (self.u64_to_reg(y), Num::default()) - }, + } (_, _, _) => { let fr1 = a.get_value(); let fr2 = b.get_value(); @@ -678,34 +632,38 @@ impl Blake2sGadget { let y = f_repr.as_ref()[0] & ((1 << REG_WIDTH) - 1); let of = f_repr.as_ref()[0] >> REG_WIDTH; (Some(y), Some(of)) - }, - (_, _, _) => (None, None) + } + (_, _, _) => (None, None), }; - + let y = self.alloc_reg_from_u64(cs, y_val)?; let of = self.alloc_num_from_u64(cs, of_val)?; (y, of) - }, + } }; Ok((y, of)) } fn g_ternary_addition_process>( - &self, cs: &mut CS, - a: &Reg, b: &Reg, x: &Num, // known in advance - y: &Reg, of: &Num, t: &Num, // generated during setup phase - ) -> Result<()> - { + &self, + cs: &mut CS, + a: &Reg, + b: &Reg, + x: &Num, // known in advance + y: &Reg, + of: &Num, + t: &Num, // generated during setup phase + ) -> Result<()> { if a.is_const() && b.is_const() && x.is_constant() { assert!(t.is_constant()); - return Ok(()) + return Ok(()); } let zero = self.zero.clone(); let one = self.one.clone(); let minus_one = self.minus_one.clone(); - // [y0, y1, y2, y3] - decomposed parts of resulted y: y = y0 + 2^8 * y1 + 2^16 * y2 + 2^24 * y3: + // [y0, y1, y2, y3] - decomposed parts of resulted y: y = y0 + 2^8 * y1 + 2^16 * y2 + 2^24 * y3: // [a, b, x, y] - where y = a + b + x - 2^32 * of (using of via d_next selector) // [of, t, of ^ t, of] - range check for of and t @@ -721,7 +679,7 @@ impl Blake2sGadget { second_row.set_var(1, one.clone(), b.full.clone(), false); second_row.set_var(2, one.clone(), x.clone(), false); second_row.set_var(3, minus_one.clone(), y.full.clone(), true); - let mut coef : E::Fr = u64_to_ff(1u64 << REG_WIDTH); + let mut coef: E::Fr = u64_to_ff(1u64 << REG_WIDTH); coef.negate(); second_row.link_with_next_row(coef); @@ -761,8 +719,9 @@ impl Blake2sGadget { // when a, b are varibles we have only one equation of the form: // [y, a, b, of], y = a + b - 2^32 * of // and range check of of is multiplexed with range check for ternary addition (here where t there comes from!) - fn g_binary_addition_setup(&self, cs: &mut CS, a: &Reg, b: &Reg) -> Result<(Reg, Num)> - where CS: ConstraintSystem + fn g_binary_addition_setup(&self, cs: &mut CS, a: &Reg, b: &Reg) -> Result<(Reg, Num)> + where + CS: ConstraintSystem, { let (y, of) = match (&a.full, &b.full) { (Num::Constant(fr1), Num::Constant(fr2)) => { @@ -771,7 +730,7 @@ impl Blake2sGadget { let f_repr = temp.into_repr(); let y = f_repr.as_ref()[0] & ((1 << REG_WIDTH) - 1); (self.u64_to_reg(y), Num::default()) - }, + } (_, _) => { let fr1 = a.get_value(); let fr2 = b.get_value(); @@ -783,23 +742,24 @@ impl Blake2sGadget { let y = f_repr.as_ref()[0] & ((1 << REG_WIDTH) - 1); let of = f_repr.as_ref()[0] >> REG_WIDTH; (Some(y), Some(of)) - }, - (_, _) => (None, None) + } + (_, _) => (None, None), }; - + let y = self.alloc_reg_from_u64(cs, y_val)?; let of = self.alloc_num_from_u64(cs, of_val)?; (y, of) - }, + } }; Ok((y, of)) } fn g_binary_addition_process(&self, cs: &mut CS, a: &Reg, b: &Reg, y: &Reg, of: &Num) -> Result<()> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { if a.is_const() && b.is_const() { - return Ok(()) + return Ok(()); } // [y, a, b, of], y = a + b - 2^32 * of @@ -813,14 +773,14 @@ impl Blake2sGadget { row.set_var(1, minus_one.clone(), a.full.clone(), false); row.set_var(2, minus_one.clone(), b.full.clone(), false); row.set_var(3, u64_to_ff(1 << REG_WIDTH), of.clone(), true); - + self.allocate_gate(cs, row)?; Ok(()) - } + } // rotate step is of the form: z = (x ^ y) >>> R // there are two possibilities: R is multiple of CHUNK_SIZE = 8 or not - + // if R is multiple of CHUNKS_SIZE // we will always have the following 4 rows (in case any of (x, y) is actually a variable) // z = /sum z[idx_k] * 8^[idx_k] ([idx_k] is permuted array of [0, 1, 2, 3]) @@ -828,19 +788,20 @@ impl Blake2sGadget { // [x[1], y[1], z[idx_1], z - z[idx_0] * 8^[idx_0] = w0 // x[2], y[2], z[idx_2], z - z[idx_0] * 8^[idx_0] - z[idx_1] * 8^[idx_1] = w1 // x[3], y[3], z[idx_3], z - z[idx_0] * 8^[idx_0] - z[idx_1] * 8^[idx_1] - z[idx_2] * 8^[idx_2] = w2 - + // on the first 3 rows we have the link to the next row via d_next // on the last row we need only to check that c * 8^[idx_3] = d - // when R is a multiple of CHUNK_LEN = 8 ( R is 8 or 16) z is already decomposed into chunks + // when R is a multiple of CHUNK_LEN = 8 ( R is 8 or 16) z is already decomposed into chunks // (just take [z_idx] in the right order), so no additional decomposition constraints are needed fn g_xor_rot_setup_impl_rot_8_16(&self, cs: &mut CS, a: &Reg, b: &Reg, rot: usize) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let q0 = Num::Variable(self.xor(cs, &a.decomposed.r0, &b.decomposed.r0)?); let q1 = Num::Variable(self.xor(cs, &a.decomposed.r1, &b.decomposed.r1)?); let q2 = Num::Variable(self.xor(cs, &a.decomposed.r2, &b.decomposed.r2)?); let q3 = Num::Variable(self.xor(cs, &a.decomposed.r3, &b.decomposed.r3)?); - + let fr1 = a.get_value(); let fr2 = b.get_value(); let z_full_val = match (fr1, fr2) { @@ -850,27 +811,36 @@ impl Blake2sGadget { let n_xor_m = (n ^ m) as u32; let tmp = n_xor_m.rotate_right(rot as u32); Some(tmp as u64) - - }, + } (_, _) => None, }; let z_full = self.alloc_num_from_u64(cs, z_full_val)?; - let (z, shifts) = match rot { + let (z, shifts) = match rot { 8 => { let reg = Reg { full: z_full, - decomposed : DecomposedNum { r0: q1.clone(), r1: q2.clone(), r2: q3.clone(), r3: q0.clone() } + decomposed: DecomposedNum { + r0: q1.clone(), + r1: q2.clone(), + r2: q3.clone(), + r3: q0.clone(), + }, }; (reg, [24, 0, 8, 16]) - }, + } 16 => { let reg = Reg { full: z_full, - decomposed : DecomposedNum { r0: q2.clone(), r1: q3.clone(), r2: q0.clone(), r3: q1.clone() } + decomposed: DecomposedNum { + r0: q2.clone(), + r1: q3.clone(), + r2: q0.clone(), + r3: q1.clone(), + }, }; (reg, [16, 24, 0, 8]) - }, + } _ => unreachable!(), }; @@ -886,14 +856,14 @@ impl Blake2sGadget { let mut tmp_val = q.get_value().grab()?; tmp_val.mul_assign(&coef); cur_val.sub_assign(&tmp_val); - + Ok(cur_val) })?; - + *w = Num::Variable(new_var); cur = w; } - + let res = XorRotOutput { z, qs, @@ -908,11 +878,11 @@ impl Blake2sGadget { // when R is not a multiple of CHUNK_LEN = 8 ( R is 8 or 16) // we extend previous constraints with decomposition of z into z[0], z[1], z[2], z[3] - + // if we don't use any additional tables, then the rows will be the following: // x[i0], y[i0], q[i0], allocated_zero (NB: room for small optimization here as d register is unused) // z[0], z[1], z[2], z[3] - decomposition of z into chunks (exploting d_next) - // q[i0], q[i0]_rot4, q[i0]_rot7, z, + // q[i0], q[i0]_rot4, q[i0]_rot7, z, // x[i1], y[i1], q[i1], z - q[i0] * 8^[i0] = w0 // x[i2], y[i2], z[i2], z - q[i0] * 8^[i0] - q[i1] * 8^[i1] = w1 // x[i3], y[i3], z[i3], z - q[i0] * 8^[i0] - q[i1] * 8^[i1] - q[i2] * 8^[i2] = w2 @@ -924,30 +894,27 @@ impl Blake2sGadget { // x[i2], y[i2], z[i2], z - q[i0] * 8^[i0] - q[i1] * 8^[i1] = w1 // x[i3], y[i3], z[i3], z - q[i0] * 8^[i0] - q[i1] * 8^[i1] - q[i2] * 8^[i2] = w2 fn g_xor_rot_setup_impl_rot_7_12(&self, cs: &mut CS, a: &Reg, b: &Reg, rot: usize) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { - let mut start_idx = if rot == 7 {0} else {1}; + let mut start_idx = if rot == 7 { 0 } else { 1 }; let (q_i0, q_ch_rots) = if self.use_additional_tables { let q_i0 = Num::Variable(self.xor_rot(cs, &a.decomposed[start_idx], &b.decomposed[start_idx], rot % CHUNK_SIZE)?); (q_i0, None) - } - else { + } else { let q_i0 = Num::Variable(self.xor(cs, &a.decomposed[start_idx], &b.decomposed[start_idx])?); - let q_ch_rots = ( - Num::Variable(self.rot(cs, &q_i0, 4)?), - Num::Variable(self.rot(cs, &q_i0, 7)?), - ); + let q_ch_rots = (Num::Variable(self.rot(cs, &q_i0, 4)?), Num::Variable(self.rot(cs, &q_i0, 7)?)); (q_i0, Some(q_ch_rots)) }; start_idx = (start_idx + 1) % 4; - + let q_i1 = Num::Variable(self.xor(cs, &a.decomposed[start_idx], &b.decomposed[start_idx])?); start_idx = (start_idx + 1) % 4; let q_i2 = Num::Variable(self.xor(cs, &a.decomposed[start_idx], &b.decomposed[start_idx])?); start_idx = (start_idx + 1) % 4; let q_i3 = Num::Variable(self.xor(cs, &a.decomposed[start_idx], &b.decomposed[start_idx])?); start_idx = (start_idx + 1) % 4; - + let fr1 = a.get_value(); let fr2 = b.get_value(); let z_full_val = match (fr1, fr2) { @@ -957,15 +924,14 @@ impl Blake2sGadget { let n_xor_m = (n ^ m) as u32; let tmp = n_xor_m.rotate_right(rot as u32); Some(tmp as u64) - - }, + } (_, _) => None, }; let z = self.alloc_reg_from_u64(cs, z_full_val)?; - let shifts = match rot { - 7 => [0, 1, 9, 17], - 12 => [0, 4, 12, 20], + let shifts = match rot { + 7 => [0, 1, 9, 17], + 12 => [0, 4, 12, 20], _ => unreachable!(), }; @@ -989,14 +955,14 @@ impl Blake2sGadget { let mut tmp_val = q.get_value().grab()?; tmp_val.mul_assign(&coef); cur_val.sub_assign(&tmp_val); - + Ok(cur_val) })?; - + *w = Num::Variable(new_var); cur = w; } - + let res = XorRotOutput { z, qs, @@ -1010,7 +976,8 @@ impl Blake2sGadget { } fn g_xor_rot_setup(&self, cs: &mut CS, a: &Reg, b: &Reg, rot: usize) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let res = match (&a.full, &b.full) { (Num::Constant(fr1), Num::Constant(fr2)) => { @@ -1028,12 +995,11 @@ impl Blake2sGadget { shifts: [0, 0, 0, 0], start_idx: 0, } - }, + } (_, _) => match rot { 8 | 16 => self.g_xor_rot_setup_impl_rot_8_16(cs, a, b, rot)?, 7 | 12 => self.g_xor_rot_setup_impl_rot_7_12(cs, a, b, rot)?, _ => unreachable!(), - }, }; @@ -1041,16 +1007,17 @@ impl Blake2sGadget { } fn g_xor_rot_process(&self, cs: &mut CS, x: &Reg, y: &Reg, xor_rot_data: XorRotOutput, rot: usize) -> Result<()> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { if x.is_const() && y.is_const() { - return Ok(()) + return Ok(()); } let zero = self.zero.clone(); let one = self.one.clone(); let minus_one = self.minus_one.clone(); - let needs_decomposition : bool = (rot % CHUNK_SIZE) != 0; + let needs_decomposition: bool = (rot % CHUNK_SIZE) != 0; let z = xor_rot_data.z; let qs = xor_rot_data.qs; @@ -1068,22 +1035,21 @@ impl Blake2sGadget { let (d, cnst_sel) = match is_empty_flag { true => (Num::Variable(AllocatedNum::zero(cs)), E::Fr::zero()), false => { - let mut output_dict = self.allocated_cnsts.borrow_mut(); let mut input_dict = self.declared_cnsts.borrow_mut(); let key = input_dict.keys().next().unwrap().clone(); let val = input_dict.remove(&key).unwrap(); - + let d = Num::Variable(val.clone()); let mut cnst_sel = E::Fr::from_repr(key).unwrap(); cnst_sel.negate(); let prev = output_dict.insert(key, val); assert!(prev.is_none()); - + (d, cnst_sel) - }, + } }; let mut row = GateAllocHelper::default(); @@ -1096,7 +1062,7 @@ impl Blake2sGadget { let table = self.xor_table.clone(); row.set_table(table); self.allocate_gate(cs, row)?; - } + } if needs_decomposition { // [y0, y1, y2, y3] @@ -1123,20 +1089,18 @@ impl Blake2sGadget { if rot == 12 { row.set_var(1, coef, b, true); row.set_var(2, zero.clone(), c, true); - } - else { + } else { row.set_var(1, zero.clone(), b, true); row.set_var(2, coef, c, true); } row.set_var(3, minus_one.clone(), d, true); - + row.link_with_next_row(one.clone()); let table = self.compound_rot4_7_table.as_ref().unwrap().clone(); row.set_table(table); self.allocate_gate(cs, row)?; - } - else { + } else { // x[i0], y[i0], z[i0], z, - here the xor_rot_table is called let a = self.to_allocated(cs, &x.decomposed[start_idx])?; let b = self.to_allocated(cs, &y.decomposed[start_idx])?; @@ -1149,7 +1113,7 @@ impl Blake2sGadget { row.set_var(1, zero.clone(), b, true); row.set_var(2, coef, c, true); row.set_var(3, minus_one.clone(), d, true); - + row.link_with_next_row(one.clone()); let table = self.choose_table_by_rot(rot); row.set_table(table); @@ -1161,7 +1125,7 @@ impl Blake2sGadget { let a = self.to_allocated(cs, &x.decomposed[start_idx])?; let b = self.to_allocated(cs, &y.decomposed[start_idx])?; let c = qs[i].clone(); - let d = ws[i-1].clone(); + let d = ws[i - 1].clone(); let coef = u64_to_ff(1 << xor_rot_data.shifts[i]); let mut row = GateAllocHelper::default(); @@ -1169,7 +1133,7 @@ impl Blake2sGadget { row.set_var(1, zero.clone(), b, true); row.set_var(2, coef, c, true); row.set_var(3, minus_one.clone(), d, true); - + if i != 3 { row.link_with_next_row(one.clone()); } @@ -1184,7 +1148,8 @@ impl Blake2sGadget { } fn g(&self, cs: &mut CS, v: &mut HashState, idx_arr: [usize; 4], x: &Num, y: &Num) -> Result<()> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let mut regs = v.0.get_muts(); let a = regs.at(idx_arr[0]).unwrap(); @@ -1198,28 +1163,28 @@ impl Blake2sGadget { let temp_d = xor_rot_data1.z.clone(); let (temp_c, of2) = self.g_binary_addition_setup(cs, c, &temp_d)?; let xor_rot_data2 = self.g_xor_rot_setup(cs, b, &temp_c, 12)?; - let temp_b = xor_rot_data2.z.clone(); + let temp_b = xor_rot_data2.z.clone(); // first half of g function - burn preallocated variables to protoboard self.g_ternary_addition_process(cs, a, b, x, &temp_a, &of1, &of2)?; self.g_xor_rot_process(cs, &temp_a, d, xor_rot_data1, 16)?; self.g_binary_addition_process(cs, c, &temp_d, &temp_c, &of2)?; self.g_xor_rot_process(cs, b, &temp_c, xor_rot_data2, 12)?; - + // second half of g function - setup let (new_a, of1) = self.g_ternary_additon_setup(cs, &temp_a, &temp_b, y)?; let xor_rot_data1 = self.g_xor_rot_setup(cs, &new_a, &temp_d, 8)?; let new_d = xor_rot_data1.z.clone(); let (new_c, of2) = self.g_binary_addition_setup(cs, &temp_c, &new_d)?; let xor_rot_data2 = self.g_xor_rot_setup(cs, &temp_b, &new_c, 7)?; - let new_b = xor_rot_data2.z.clone(); + let new_b = xor_rot_data2.z.clone(); // second half of g function - burn preallocated variables to protoboard self.g_ternary_addition_process(cs, &temp_a, &temp_b, y, &new_a, &of1, &of2)?; self.g_xor_rot_process(cs, &new_a, &temp_d, xor_rot_data1, 8)?; self.g_binary_addition_process(cs, &temp_c, &new_d, &new_c, &of2)?; self.g_xor_rot_process(cs, &temp_b, &new_c, xor_rot_data2, 7)?; - + *a = new_a; *b = new_b; *c = new_c; @@ -1237,8 +1202,7 @@ impl Blake2sGadget { // if there are n -rows (and 1 <= n <= 3) modifed there will be n+1 constraints // if all rows are modified (n = 4) there will be 4 constraints - fn var_xor_const>(&self, cs: &mut CS, input: &DecomposedNum, cnst: u64) -> Result> - { + fn var_xor_const>(&self, cs: &mut CS, input: &DecomposedNum, cnst: u64) -> Result> { assert_ne!(cnst, 0); let zero = E::Fr::zero(); let one = E::Fr::one(); @@ -1255,7 +1219,7 @@ impl Blake2sGadget { Ok(u64_to_ff(n)) })?; let full = Num::Variable(full_var); - + let mut idx_used = [false, false, false, false]; let mut res_chunks = [input.r0.clone(), input.r1.clone(), input.r2.clone(), input.r3.clone()]; let mut d = full.clone(); @@ -1268,7 +1232,7 @@ impl Blake2sGadget { let num = Num::Constant(u64_to_ff(byte_val)); let b = self.to_allocated(cs, &num)?; - + let c = Num::Variable(self.xor(cs, &a, &b)?); res_chunks[i] = c.clone(); @@ -1277,8 +1241,8 @@ impl Blake2sGadget { row.set_var(1, zero.clone(), b, true); row.set_var(2, u64_to_ff(1u64 << (CHUNK_SIZE * i)), c.clone(), true); row.set_var(3, minus_one.clone(), d.clone(), true); - - if i != 3 || idx_used.iter().any(|flag| !flag) { + + if i != 3 || idx_used.iter().any(|flag| !flag) { row.link_with_next_row(one.clone()); } row.set_table(self.xor_table.clone()); @@ -1290,7 +1254,7 @@ impl Blake2sGadget { let mut c_val = c.get_value().grab()?; c_val.mul_assign(&coef); d_val.sub_assign(&c_val); - + Ok(d_val) })?; d = Num::Variable(w) @@ -1308,7 +1272,9 @@ impl Blake2sGadget { let mut row = GateAllocHelper::default(); for i in 0..3 { - while pos < 4 && idx_used[pos] { pos += 1}; + while pos < 4 && idx_used[pos] { + pos += 1 + } let var = match pos { 0 | 1 | 2 | 3 => input[pos].clone(), _ => dummy.clone(), @@ -1323,15 +1289,17 @@ impl Blake2sGadget { let reg = Reg { full, - decomposed : DecomposedNum { - r0: res_chunks[0].clone(), r1 : res_chunks[1].clone(), r2: res_chunks[2].clone(), r3: res_chunks[3].clone(), + decomposed: DecomposedNum { + r0: res_chunks[0].clone(), + r1: res_chunks[1].clone(), + r2: res_chunks[2].clone(), + r3: res_chunks[3].clone(), }, }; Ok(reg) } - fn var_xor_var>(&self, cs: &mut CS, x: &DecomposedNum, y: &DecomposedNum) -> Result> - { + fn var_xor_var>(&self, cs: &mut CS, x: &DecomposedNum, y: &DecomposedNum) -> Result> { let zero = E::Fr::zero(); let one = E::Fr::one(); let mut minus_one = one.clone(); @@ -1352,12 +1320,12 @@ impl Blake2sGadget { Ok(u64_to_ff(n ^ m)) })?; - + let full = Num::Variable(full_var); let mut res_chunks = <[Num; 4]>::default(); let mut d = full.clone(); - for i in 0..4 { + for i in 0..4 { let a = x[i].clone(); let b = y[i].clone(); let c = Num::Variable(self.xor(cs, &a, &b)?); @@ -1368,7 +1336,7 @@ impl Blake2sGadget { row.set_var(1, zero.clone(), b, true); row.set_var(2, u64_to_ff(1 << (CHUNK_SIZE * i)), c.clone(), true); row.set_var(3, minus_one.clone(), d.clone(), true); - + if i != 3 { row.link_with_next_row(one.clone()); } @@ -1381,16 +1349,19 @@ impl Blake2sGadget { let mut c_val = c.get_value().grab()?; c_val.mul_assign(&coef); d_val.sub_assign(&c_val); - + Ok(d_val) })?; d = Num::Variable(w) } - + let reg = Reg { full, - decomposed : DecomposedNum { - r0: res_chunks[0].clone(), r1 : res_chunks[1].clone(), r2: res_chunks[2].clone(), r3: res_chunks[3].clone(), + decomposed: DecomposedNum { + r0: res_chunks[0].clone(), + r1: res_chunks[1].clone(), + r2: res_chunks[2].clone(), + r3: res_chunks[3].clone(), }, }; Ok(reg) @@ -1398,9 +1369,10 @@ impl Blake2sGadget { // for description look comments preceeding "apply ternary xor" fn var_xor_var_with_multiplexing(&self, cs: &mut CS, x: &DecomposedNum, y: &DecomposedNum) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { - let mut temp_chunks = <[Num; 4]>::default(); + let mut temp_chunks = <[Num; 4]>::default(); let zero = E::Fr::zero(); let one = E::Fr::one(); @@ -1419,14 +1391,14 @@ impl Blake2sGadget { let mut output_dict = self.allocated_cnsts.borrow_mut(); let key = input_dict.keys().next().unwrap().clone(); let val = input_dict.remove(&key).unwrap(); - + let d = Num::Variable(val.clone()); let mut cnst_sel = E::Fr::from_repr(key).unwrap(); cnst_sel.negate(); let prev = output_dict.insert(key, val); assert!(prev.is_none()); - + (d, cnst_sel) } }; @@ -1438,12 +1410,15 @@ impl Blake2sGadget { row.set_var(3, one.clone(), d, true); row.set_cnst_sel(cnst_sel); row.set_table(self.xor_table.clone()); - + self.allocate_gate(cs, row)?; } - Ok(DecomposedNum { - r0 : temp_chunks[0].clone(), r1: temp_chunks[1].clone(), r2: temp_chunks[2].clone(), r3: temp_chunks[3].clone() + Ok(DecomposedNum { + r0: temp_chunks[0].clone(), + r1: temp_chunks[1].clone(), + r2: temp_chunks[2].clone(), + r3: temp_chunks[3].clone(), }) } @@ -1461,7 +1436,7 @@ impl Blake2sGadget { // as well as d register remains vacant // we nay exploit the fact multiplexing xor-table-check with constant allocation! // more precisely: if there are any constant cnst0 waiting to be allocated, we may burn the following row: - // a[i], b[i], temp[i], cnst, with the main gate equation d = const_cel = cnst! + // a[i], b[i], temp[i], cnst, with the main gate equation d = const_cel = cnst! fn apply_ternary_xor>(&self, cs: &mut CS, a: &Reg, b: &Reg, c: &Reg) -> Result> { let res = match ((a.is_const(), a), (b.is_const(), b), (c.is_const(), c)) { // all are constants @@ -1470,17 +1445,15 @@ impl Blake2sGadget { let n1 = cnst_reg1.full.get_value().unwrap().into_repr().as_ref()[0]; let n2 = cnst_reg2.full.get_value().unwrap().into_repr().as_ref()[0]; self.u64_to_reg(n0 ^ n1 ^ n2) - }, + } // one variable and two are constants - ((false, var_reg), (true, cnst_reg0), (true, cnst_reg1)) | ((true, cnst_reg0), (false, var_reg), (true, cnst_reg1)) | - ((true, cnst_reg0), (true, cnst_reg1), (false, var_reg)) => { + ((false, var_reg), (true, cnst_reg0), (true, cnst_reg1)) | ((true, cnst_reg0), (false, var_reg), (true, cnst_reg1)) | ((true, cnst_reg0), (true, cnst_reg1), (false, var_reg)) => { let n0 = cnst_reg0.full.get_value().unwrap().into_repr().as_ref()[0]; let n1 = cnst_reg1.full.get_value().unwrap().into_repr().as_ref()[0]; self.var_xor_const(cs, &var_reg.decomposed, n0 ^ n1)? - }, + } // two are variables and one is constant - ((false, var_reg0), (true, cnst_reg), (false, var_reg1)) | ((true, cnst_reg), (false, var_reg0), (false, var_reg1)) | - ((false, var_reg0), (false, var_reg1), (true, cnst_reg)) => { + ((false, var_reg0), (true, cnst_reg), (false, var_reg1)) | ((true, cnst_reg), (false, var_reg0), (false, var_reg1)) | ((false, var_reg0), (false, var_reg1), (true, cnst_reg)) => { let tmp = self.var_xor_var_with_multiplexing(cs, &var_reg0.decomposed, &var_reg1.decomposed)?; let n = cnst_reg.get_value().unwrap().into_repr().as_ref()[0]; self.var_xor_const(cs, &tmp, n)? @@ -1492,35 +1465,29 @@ impl Blake2sGadget { } }; - Ok(res) + Ok(res) } - fn apply_xor_with_const>(&self, cs: &mut CS, reg: &Reg, cnst: u64) -> Result> - { + fn apply_xor_with_const>(&self, cs: &mut CS, reg: &Reg, cnst: u64) -> Result> { if reg.is_const() { let temp = reg.full.get_value().unwrap(); let f_repr = temp.into_repr(); let n = f_repr.as_ref()[0]; - return Ok(self.u64_to_reg(n ^ cnst)) + return Ok(self.u64_to_reg(n ^ cnst)); } self.var_xor_const(cs, ®.decomposed, cnst) } - fn apply_xor>(&self, cs: &mut CS, a: &Reg, b: &Reg) -> Result> - { + fn apply_xor>(&self, cs: &mut CS, a: &Reg, b: &Reg) -> Result> { match (a.is_const(), b.is_const()) { (true, true) | (false, true) => self.apply_xor_with_const(cs, a, ff_to_u64(&b.get_value().unwrap())), (true, false) => self.var_xor_const(cs, &b.decomposed, ff_to_u64(&a.get_value().unwrap())), - (false, false) => self.var_xor_var(cs, &a.decomposed, &b.decomposed) + (false, false) => self.var_xor_var(cs, &a.decomposed, &b.decomposed), } } - fn f>( - &self, cs: &mut CS, hash_state: HashState, m: &[Num], total_len: &Num, - is_last_block: Boolean, max_total_len: u64 - ) -> Result> - where - { + fn f>(&self, cs: &mut CS, hash_state: HashState, m: &[Num], total_len: &Num, is_last_block: Boolean, max_total_len: u64) -> Result> +where { // Initialize local work vector v[0..15] let mut v = HashState(Vec::with_capacity(BLAKE2S_STATE_WIDTH)); // First half from state. @@ -1537,29 +1504,29 @@ impl Blake2sGadget { Num::Constant(fr) => { let total_len_as_u64 = ff_to_u64(fr); // Low word of the offset. - v.0[12] = self.apply_xor_with_const(cs, &mut v.0[12], total_len_as_u64 & ((1 << REG_WIDTH) - 1))?; + v.0[12] = self.apply_xor_with_const(cs, &mut v.0[12], total_len_as_u64 & ((1 << REG_WIDTH) - 1))?; // High word. - v.0[13] = self.apply_xor_with_const(cs, &mut v.0[13], total_len_as_u64 >> REG_WIDTH)?; + v.0[13] = self.apply_xor_with_const(cs, &mut v.0[13], total_len_as_u64 >> REG_WIDTH)?; } Num::Variable(var) => { let (low, high) = self.decompose_total_len_var(cs, &var, max_total_len)?; - v.0[12] = self.apply_xor(cs, &mut v.0[12], &low)?; - v.0[13] = self.apply_xor(cs, &mut v.0[13], &high)?; + v.0[12] = self.apply_xor(cs, &mut v.0[12], &low)?; + v.0[13] = self.apply_xor(cs, &mut v.0[13], &high)?; } } - - // NB: xoring with very special constant: y = x ^ 0xffffffff (invert all bits of x) + + // NB: xoring with very special constant: y = x ^ 0xffffffff (invert all bits of x) // is equal to y = 0xffffffff - x match is_last_block { Boolean::Constant(true) => { v.0[14] = self.apply_xor_with_const(cs, &mut v.0[14], 0xffffffff)?; - }, - Boolean::Constant(false) => {}, + } + Boolean::Constant(false) => {} Boolean::Is(_flag) | Boolean::Not(_flag) => { let inverted = self.apply_xor_with_const(cs, &mut v.0[14], 0xffffffff)?; // NB: it is actually a hack as we only modify the full value and let individual chunks of // the decomposition to remain unchanged. This means, that full and decomposed fields of reg - // become incostintent, but as soon as we don't need the decomposition from now on it is not + // become incostintent, but as soon as we don't need the decomposition from now on it is not // a problem for us. However, with modifications of the code, this caveat should be kept in mind. // The same trick is applied also for the case of Bollean::Not(_) v.0[14].full = Num::conditionally_select(cs, &is_last_block, &inverted.full, &v.0[14].full)?; @@ -1591,10 +1558,9 @@ impl Blake2sGadget { Ok(res) } - pub fn digest>(&self, cs: &mut CS, data: &[Num], message_len: usize) -> Result>> - { + pub fn digest>(&self, cs: &mut CS, data: &[Num], message_len: usize) -> Result>> { // h[0..7] := IV[0..7] // Initialization Vector. - let mut total_len_as_u64 : u64 = 0; + let mut total_len_as_u64: u64 = 0; let mut hash_state = HashState(Vec::with_capacity(BLAKE2S_STATE_WIDTH / 2)); for i in 0..(BLAKE2S_STATE_WIDTH / 2) { let num = if i == 0 { self.iv0_twist } else { self.iv[i] }; @@ -1602,13 +1568,12 @@ impl Blake2sGadget { hash_state.0.push(reg); } - for (_is_first, is_last, block) in data.chunks(16).identify_first_last() - { + for (_is_first, is_last, block) in data.chunks(16).identify_first_last() { assert_eq!(block.len(), 16); total_len_as_u64 += 64; total_len_as_u64 = std::cmp::min(total_len_as_u64, message_len as u64); let total_len = Num::Constant(u64_to_ff(total_len_as_u64)); - let is_last = Boolean::Constant(is_last); + let is_last = Boolean::Constant(is_last); hash_state = self.f(cs, hash_state, &block[..], &total_len, is_last, total_len_as_u64)?; } @@ -1622,25 +1587,23 @@ impl Blake2sGadget { Ok(res) } - pub fn digest_words32>(&self, cs: &mut CS, words32: &[Num]) -> Result>> - { + pub fn digest_words32>(&self, cs: &mut CS, words32: &[Num]) -> Result>> { let last_block_size = words32.len() % 16; - let num_of_zero_words = if last_block_size > 0 { 16 - last_block_size} else {0}; - + let num_of_zero_words = if last_block_size > 0 { 16 - last_block_size } else { 0 }; + let mut padded = vec![]; padded.extend(words32.iter().cloned()); padded.extend(iter::repeat(Num::Constant(E::Fr::zero())).take(num_of_zero_words)); assert_eq!(padded.len() % 16, 0); - self.digest(cs, &padded[..], words32.len() * 4) + self.digest(cs, &padded[..], words32.len() * 4) } - pub fn digest_bytes>(&self, cs: &mut CS, bytes: &[Byte]) -> Result>> - { + pub fn digest_bytes>(&self, cs: &mut CS, bytes: &[Byte]) -> Result>> { // padding with zeroes until length of message is multiple of 64 let last_block_size = bytes.len() % 64; - let num_of_zero_bytes = if last_block_size > 0 { 64 - last_block_size} else {0}; - + let num_of_zero_bytes = if last_block_size > 0 { 64 - last_block_size } else { 0 }; + let mut padded = vec![]; padded.extend(bytes.iter().cloned()); padded.extend(iter::repeat(Byte::from_cnst(E::Fr::zero())).take(num_of_zero_bytes)); @@ -1651,23 +1614,23 @@ impl Blake2sGadget { let mut words32 = Vec::with_capacity(padded.len() % 4); let cfs = [E::Fr::one(), u64_to_ff(1 << 8), u64_to_ff(1 << 16), u64_to_ff(1 << 24)]; for chunk in padded.chunks(4) { - let tmp = Num::lc( - cs, - &cfs, - &[chunk[0].into_num(), chunk[1].into_num(), chunk[2].into_num(), chunk[3].into_num()], - )?; + let tmp = Num::lc(cs, &cfs, &[chunk[0].into_num(), chunk[1].into_num(), chunk[2].into_num(), chunk[3].into_num()])?; words32.push(tmp); } - self.digest(cs, &words32[..], bytes.len()) + self.digest(cs, &words32[..], bytes.len()) } pub fn round_function>( - &self, cs: &mut CS, hash_state: [Num; BLAKE2S_STATE_WIDTH / 2], - round_input: &[Num; BLAKE2S_STATE_WIDTH], total_len: Num, max_total_len: u64, - is_first_chunk: Boolean, is_last_chunk: Boolean - ) -> Result<([Num; BLAKE2S_STATE_WIDTH / 2], Num)> - { + &self, + cs: &mut CS, + hash_state: [Num; BLAKE2S_STATE_WIDTH / 2], + round_input: &[Num; BLAKE2S_STATE_WIDTH], + total_len: Num, + max_total_len: u64, + is_first_chunk: Boolean, + is_last_chunk: Boolean, + ) -> Result<([Num; BLAKE2S_STATE_WIDTH / 2], Num)> { let mut raw_hash_state = HashState(Vec::with_capacity(BLAKE2S_STATE_WIDTH / 2)); for (i, cur_state_elem) in hash_state.iter().enumerate() { let iv_as_u64 = if i == 0 { self.iv0_twist } else { self.iv[i] }; @@ -1678,12 +1641,8 @@ impl Blake2sGadget { let block_size_as_num = Num::Constant(u64_to_ff(64)); let total_len_incremented = total_len.add(cs, &block_size_as_num)?; - let selected_total_len = Num::conditionally_select( - cs, &is_first_chunk, &block_size_as_num, &total_len_incremented - )?; - raw_hash_state = self.f( - cs, raw_hash_state, &round_input[..], &selected_total_len, is_last_chunk, max_total_len - )?; + let selected_total_len = Num::conditionally_select(cs, &is_first_chunk, &block_size_as_num, &total_len_incremented)?; + raw_hash_state = self.f(cs, raw_hash_state, &round_input[..], &selected_total_len, is_last_chunk, max_total_len)?; // allocate all remaining consts self.constraint_all_allocated_cnsts(cs)?; diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/mod.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/mod.rs index 5031e29..07a00c8 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/mod.rs @@ -1,3 +1,3 @@ -pub mod tables; pub mod gadgets; -pub mod test; \ No newline at end of file +pub mod tables; +pub mod test; diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/tables.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/tables.rs index cb68da7..07b5921 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/tables.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/tables.rs @@ -1,14 +1,13 @@ +use crate::bellman::pairing::ff::*; use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::plonk::better_better_cs::lookup_tables::*; use crate::bellman::plonk::better_better_cs::utils; -use crate::bellman::pairing::ff::*; -use crate::bellman::SynthesisError; use crate::bellman::Engine; +use crate::bellman::SynthesisError; use super::super::utils::*; - -// for columns (a, b, c) asserts that b = a >>> rot1, c = a >>> rot2 (cyclic shifts of 32bit numbers) +// for columns (a, b, c) asserts that b = a >>> rot1, c = a >>> rot2 (cyclic shifts of 32bit numbers) #[derive(Clone)] pub struct CompoundRotTable { table_entries: [Vec; 3], @@ -19,9 +18,7 @@ pub struct CompoundRotTable { name: &'static str, } - impl CompoundRotTable { - pub fn new(bits: usize, rot1: usize, rot2: usize, name: &'static str) -> Self { assert!(rot1 < bits); assert!(rot2 < bits); @@ -30,13 +27,13 @@ impl CompoundRotTable { let mut keys = Vec::with_capacity(1 << bits); let mut values1 = Vec::with_capacity(1 << bits); - let mut values2 = Vec::with_capacity(1 << bits); + let mut values2 = Vec::with_capacity(1 << bits); let mut map = std::collections::HashMap::with_capacity(1 << bits); for x in 0..(1 << bits) { let y = (x as u32).rotate_right(rot1 as u32); let z = (x as u32).rotate_right(rot2 as u32); - + let x = u64_to_ff(x as u64); let y = u64_to_ff(y as u64); let z = u64_to_ff(z as u64); @@ -45,7 +42,7 @@ impl CompoundRotTable { values1.push(y); values2.push(z); - map.insert(x, (y, z)); + map.insert(x, (y, z)); } Self { @@ -59,7 +56,6 @@ impl CompoundRotTable { } } - impl std::fmt::Debug for CompoundRotTable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("CompoundShiftTable") @@ -70,7 +66,6 @@ impl std::fmt::Debug for CompoundRotTable { } } - impl LookupTableInternal for CompoundRotTable { fn name(&self) -> &'static str { self.name @@ -118,10 +113,9 @@ impl LookupTableInternal for CompoundRotTable { assert!(keys.len() == self.num_keys()); if let Some(entry) = self.table_lookup_map.get(&keys[0]) { - return Ok(vec![entry.0, entry.1]) + return Ok(vec![entry.0, entry.1]); } Err(SynthesisError::Unsatisfiable) } } - diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/test.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/test.rs index 71aa03d..def93a8 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/test.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/blake2s/test.rs @@ -1,25 +1,19 @@ #[cfg(test)] mod test { - use crate::bellman::plonk::better_better_cs::cs::*; + use crate::bellman::pairing::bn256::{Bn256, Fr}; use crate::bellman::pairing::ff::*; - use crate::bellman::SynthesisError; + use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::Engine; - use crate::bellman::pairing::bn256::{Bn256, Fr}; + use crate::bellman::SynthesisError; use crate::blake2::{Blake2s, Digest}; - use crate::plonk::circuit::allocated_num::{ - AllocatedNum, - Num, - }; - use crate::plonk::circuit::byte::{ - Byte, - }; + use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; + use crate::plonk::circuit::byte::Byte; - use super::super::gadgets::*; use super::super::super::utils::*; + use super::super::gadgets::*; use rand::{Rng, SeedableRng, StdRng}; - - struct TestBlake2sCircuit{ + struct TestBlake2sCircuit { input: Vec, input_len_in_bytes: usize, output: [E::Fr; 8], @@ -32,50 +26,41 @@ mod test { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Width4MainGateWithDNext::default().into_internal(), - ] - ) + Ok(vec![Width4MainGateWithDNext::default().into_internal()]) } - fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> - { + fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { let mut actual_output_vars = Vec::with_capacity(8); for value in self.output.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc_input(cs, || Ok(value.clone()))?; actual_output_vars.push(Num::Variable(new_var)); - } - else { + } else { actual_output_vars.push(Num::Constant(value.clone())); } } let blake2s_gadget = Blake2sGadget::new(cs, self.use_additional_tables)?; - let supposed_output_vars = if !self.is_byte_test { + let supposed_output_vars = if !self.is_byte_test { let mut input_vars = Vec::with_capacity(self.input.len()); for value in self.input.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc(cs, || Ok(value.clone()))?; input_vars.push(Num::Variable(new_var)); - } - else { + } else { input_vars.push(Num::Constant(value.clone())); } } blake2s_gadget.digest(cs, &input_vars[..], self.input_len_in_bytes)? - } - else { + } else { let mut input_vars = Vec::with_capacity(self.input.len()); for value in self.input.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc(cs, || Ok(value.clone()))?; let byte = Byte::from_num_unconstrained(cs, Num::Variable(new_var)); input_vars.push(byte); - } - else { + } else { let byte = Byte::from_cnst(value.clone()); input_vars.push(byte); } @@ -93,13 +78,12 @@ mod test { fn slice_to_ff(slice: &[u8]) -> Fr { assert_eq!(slice.len(), 4); - let mut repr : ::Repr = Fr::zero().into_repr(); + let mut repr: ::Repr = Fr::zero().into_repr(); repr.as_mut()[0] = slice[0] as u64 + ((slice[1] as u64) << 8) + ((slice[2] as u64) << 16) + ((slice[3] as u64) << 24); Fr::from_repr(repr).expect("should parse") } - fn blake2s_gadget_test_impl(num_of_blocks: usize, use_additional_tables: bool, is_const_test: bool, is_byte_test: bool) - { + fn blake2s_gadget_test_impl(num_of_blocks: usize, use_additional_tables: bool, is_const_test: bool, is_byte_test: bool) { let seed: &[_] = &[1, 2, 3, 4, 5]; let mut rng: StdRng = SeedableRng::from_seed(seed); @@ -122,8 +106,8 @@ mod test { for (i, block) in output.chunks(4).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestBlake2sCircuit::{ + + let circuit = TestBlake2sCircuit:: { input: input_fr_arr, input_len_in_bytes: num_of_blocks * 16 * 4, output: output_fr_arr, @@ -141,38 +125,33 @@ mod test { } #[test] - fn blake2s_gadget_single_block_test() - { - blake2s_gadget_test_impl(1, false, false, false) + fn blake2s_gadget_single_block_test() { + blake2s_gadget_test_impl(1, false, false, false) } #[test] - fn blake2s_gadget_multiple_blocks_test() - { - blake2s_gadget_test_impl(3, false, false, false) + fn blake2s_gadget_multiple_blocks_test() { + blake2s_gadget_test_impl(3, false, false, false) } #[test] - fn blake2s_gadget_additional_tables_test() - { - blake2s_gadget_test_impl(2, true, false, false) + fn blake2s_gadget_additional_tables_test() { + blake2s_gadget_test_impl(2, true, false, false) } #[test] - fn blake2s_gadget_additional_tables_const_test() - { - blake2s_gadget_test_impl(2, true, true, false) + fn blake2s_gadget_additional_tables_const_test() { + blake2s_gadget_test_impl(2, true, true, false) } #[test] - fn blake2s_gadget_const_test() - { - blake2s_gadget_test_impl(3, false, true, false) + fn blake2s_gadget_const_test() { + blake2s_gadget_test_impl(3, false, true, false) } #[test] fn test_blake2s_on_real_prover() { - let num_of_blocks : usize = 1; + let num_of_blocks: usize = 1; let seed: &[_] = &[1, 2, 3, 4, 5]; let mut rng: StdRng = SeedableRng::from_seed(seed); @@ -195,16 +174,16 @@ mod test { for (i, block) in output.chunks(4).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestBlake2sCircuit::{ + + let circuit = TestBlake2sCircuit:: { input: input_fr_arr, input_len_in_bytes: num_of_blocks * 16 * 4, output: output_fr_arr, use_additional_tables: false, is_const_test: false, - is_byte_test: false + is_byte_test: false, }; - + let mut assembly = TrivialAssembly::::new(); circuit.synthesize(&mut assembly).expect("must work"); println!("Assembly contains {} gates", assembly.n()); @@ -213,49 +192,47 @@ mod test { assert!(assembly.is_satisfied()); use crate::bellman::kate_commitment::{Crs, CrsForMonomialForm}; - use crate::bellman::worker::Worker; - use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; use crate::bellman::plonk::better_better_cs::setup::VerificationKey; use crate::bellman::plonk::better_better_cs::verifier::verify; + use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; + use crate::bellman::worker::Worker; let worker = Worker::new(); let setup_size = assembly.n().next_power_of_two(); let crs = Crs::::crs_42(setup_size, &worker); - let setup = assembly.create_setup::>(&worker).unwrap(); + let setup = assembly.create_setup::>(&worker).unwrap(); let vk = VerificationKey::from_setup(&setup, &worker, &crs).unwrap(); - let proof = assembly - .create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs, None) - .unwrap(); + let proof = assembly.create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs, None).unwrap(); let valid = verify::<_, _, RollingKeccakTranscript>(&vk, &proof, None).unwrap(); assert!(valid); } - struct TestBlake2sWordsDigest{ + struct TestBlake2sWordsDigest { input: Vec, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl Circuit for TestBlake2sWordsDigest { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Width4MainGateWithDNext::default().into_internal(), - ] - ) + Ok(vec![Width4MainGateWithDNext::default().into_internal()]) } fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { use plonk::circuit::bigint_new::inscribe_default_bitop_range_table; inscribe_default_bitop_range_table(cs)?; - let input_as_nums = self.input.iter().map(|x| { - let var = AllocatedNum::alloc(cs, || Ok(u64_to_ff::(*x as u64)))?; - Ok(Num::Variable(var)) - }).collect::>, SynthesisError>>()?; - + let input_as_nums = self + .input + .iter() + .map(|x| { + let var = AllocatedNum::alloc(cs, || Ok(u64_to_ff::(*x as u64)))?; + Ok(Num::Variable(var)) + }) + .collect::>, SynthesisError>>()?; + let blake2s_gadget = Blake2sGadget::new(cs, false)?; blake2s_gadget.digest_words32(cs, &input_as_nums[..])?; let public_input = AllocatedNum::alloc_input(cs, || Ok(E::Fr::one()))?; @@ -267,11 +244,14 @@ mod test { #[test] fn test_blake2s_digest_words() { let input = vec![ - 0xb19e846f, 0xc81dcb26, 0xc388b57e, 0xeb82d44f, 0x9513868e, 0x73b092c9, 0x79df880b, 0x8a1b262f, - 0x142ba2e1, 0x8df6d502, 0x7d01cf7d, 0x318b4d4a, 0x3a4068cb, 0x3d1d3655, 0x29dbfa1b, 0x255f0103 + 0xb19e846f, 0xc81dcb26, 0xc388b57e, 0xeb82d44f, 0x9513868e, 0x73b092c9, 0x79df880b, 0x8a1b262f, 0x142ba2e1, 0x8df6d502, 0x7d01cf7d, 0x318b4d4a, 0x3a4068cb, 0x3d1d3655, 0x29dbfa1b, + 0x255f0103, ]; - let circuit = TestBlake2sWordsDigest { input, _marker: std::marker::PhantomData:: }; + let circuit = TestBlake2sWordsDigest { + input, + _marker: std::marker::PhantomData::, + }; let mut assembly = TrivialAssembly::::new(); circuit.synthesize(&mut assembly).expect("must work"); println!("Assembly contains {} gates", assembly.n()); @@ -280,21 +260,19 @@ mod test { assert!(assembly.is_satisfied()); use crate::bellman::kate_commitment::{Crs, CrsForMonomialForm}; - use crate::bellman::worker::Worker; - use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; use crate::bellman::plonk::better_better_cs::setup::VerificationKey; use crate::bellman::plonk::better_better_cs::verifier::verify; + use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; + use crate::bellman::worker::Worker; let worker = Worker::new(); let setup_size = assembly.n().next_power_of_two(); let crs = Crs::::crs_42(setup_size, &worker); - let setup = assembly.create_setup::>(&worker).unwrap(); + let setup = assembly.create_setup::>(&worker).unwrap(); let vk = VerificationKey::from_setup(&setup, &worker, &crs).unwrap(); - let proof = assembly - .create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs, None) - .unwrap(); + let proof = assembly.create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs, None).unwrap(); let valid = verify::<_, _, RollingKeccakTranscript>(&vk, &proof, None).unwrap(); assert!(valid); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/gadgets.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/gadgets.rs index 21116a3..a3da1f1 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/gadgets.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/gadgets.rs @@ -1,75 +1,66 @@ +use crate::bellman::pairing::ff::*; +use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::plonk::better_better_cs::lookup_tables::*; use crate::bellman::plonk::better_better_cs::utils; -use crate::bellman::pairing::ff::*; -use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; -use crate::bellman::SynthesisError; use crate::bellman::Engine; +use crate::bellman::SynthesisError; -use crate::plonk::circuit::allocated_num::{ - AllocatedNum, - Num, -}; +use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; +use crate::plonk::circuit::assignment::Assignment; use crate::plonk::circuit::boolean::Boolean; -use crate::plonk::circuit::byte::{ - Byte, -}; -use crate::plonk::circuit::assignment::{ - Assignment -}; +use crate::plonk::circuit::byte::Byte; +use super::super::tables::*; +use super::super::utils::*; +use super::super::{AllocatedNumExtension, NumExtension}; use super::tables::*; use super::utils::*; -use super::super::utils::*; -use super::super::tables::*; -use super::super::{NumExtension, AllocatedNumExtension}; -use std::convert::TryInto; -use std::sync::Arc; use std::collections::HashMap; -use std::ops::{Index, IndexMut}; +use std::convert::TryInto; use std::iter; +use std::ops::{Index, IndexMut}; +use std::sync::Arc; use crate::num_bigint::BigUint; use crate::num_traits::cast::ToPrimitive; -use crate::num_traits::{Zero, One}; +use crate::num_traits::{One, Zero}; use itertools::Itertools; type Result = std::result::Result; - // keccak full_width = 1600 bits = 200 bytes // rate = 136 byte = 1088 bits = 17 (64-bit) words -pub const KECCAK_RATE_WORDS_SIZE : usize = 17; -pub const DEFAULT_KECCAK_DIGEST_WORDS_SIZE : usize = 4; -pub const DEFAULT_BINARY_NUM_OF_CHUNKS : usize = 16; // 2^16 is fine -pub const DEFAULT_FIRST_BASE_NUM_OF_CHUNKS : usize = 4; -pub const DEFAULT_SECOND_BASE_NUM_OF_CHUNKS : usize = 5; +pub const KECCAK_RATE_WORDS_SIZE: usize = 17; +pub const DEFAULT_KECCAK_DIGEST_WORDS_SIZE: usize = 4; +pub const DEFAULT_BINARY_NUM_OF_CHUNKS: usize = 16; // 2^16 is fine +pub const DEFAULT_FIRST_BASE_NUM_OF_CHUNKS: usize = 4; +pub const DEFAULT_SECOND_BASE_NUM_OF_CHUNKS: usize = 5; pub const BINARY_BASE: u64 = 2; -// keccak state has 5 x 5 x 64 - bits, +// keccak state has 5 x 5 x 64 - bits, // each row of 64 bits is a lane. -pub const KECCAK_STATE_WIDTH : usize = 5; -pub const KECCAK_LANE_WIDTH : usize = 64; -pub const KECCAK_NUM_ROUNDS : usize = 24; +pub const KECCAK_STATE_WIDTH: usize = 5; +pub const KECCAK_LANE_WIDTH: usize = 64; +pub const KECCAK_NUM_ROUNDS: usize = 24; // TODO: compute actual number of offsets! // it will reduce number of constraints drastically! -pub const MAX_OF_COUNT_PER_ITER : u64 = 50; +pub const MAX_OF_COUNT_PER_ITER: u64 = 50; pub const DEFAULT_RANGE_TABLE_WIDTH: usize = 16; - #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum KeccakStateBase { First, Second, Binary, - Unknown + Unknown, } #[derive(Clone, Copy, Debug)] pub struct KeccakState { pub state: [[Num; KECCAK_STATE_WIDTH]; KECCAK_STATE_WIDTH], - pub base: KeccakStateBase + pub base: KeccakStateBase, } impl KeccakState { @@ -129,7 +120,6 @@ impl IndexMut<(usize, usize)> for KeccakState { } } - #[derive(Copy, Clone)] pub enum KeccakBase { Binary, @@ -147,42 +137,35 @@ pub struct Keccak256Gadget { // table used to convert elements from second base: either to binary form or back to first sparse base from_second_base_converter_table: Arc>, range_table: Arc>, - + binary_base_num_of_chunks: usize, first_base_num_of_chunks: usize, second_base_num_of_chunks: usize, - offsets : [[usize; KECCAK_STATE_WIDTH]; KECCAK_STATE_WIDTH], - of_transformed : Vec, - round_cnsts_in_first_base : [E::Fr; KECCAK_NUM_ROUNDS], - round_cnsts_in_second_base : [E::Fr; KECCAK_NUM_ROUNDS], + offsets: [[usize; KECCAK_STATE_WIDTH]; KECCAK_STATE_WIDTH], + of_transformed: Vec, + round_cnsts_in_first_base: [E::Fr; KECCAK_NUM_ROUNDS], + round_cnsts_in_second_base: [E::Fr; KECCAK_NUM_ROUNDS], digest_size: usize, } impl Keccak256Gadget { pub fn new>( - cs: &mut CS, + cs: &mut CS, binary_base_num_of_chunks: Option, first_base_num_of_chunks: Option, second_base_num_of_chunks: Option, - digest_size : Option, + digest_size: Option, use_global_range_table: bool, global_range_table_name: &str, - ) -> Result - { + ) -> Result { let binary_base_num_of_chunks = binary_base_num_of_chunks.unwrap_or(DEFAULT_BINARY_NUM_OF_CHUNKS); let first_base_num_of_chunks = first_base_num_of_chunks.unwrap_or(DEFAULT_FIRST_BASE_NUM_OF_CHUNKS); let second_base_num_of_chunks = second_base_num_of_chunks.unwrap_or(DEFAULT_SECOND_BASE_NUM_OF_CHUNKS); let digest_size = digest_size.unwrap_or(DEFAULT_KECCAK_DIGEST_WORDS_SIZE); - let offsets = [ - [64, 28, 61, 23, 46], - [63, 20, 54, 19, 62], - [2, 58, 21, 49, 3], - [36, 9, 39, 43, 8], - [37, 44, 25, 56, 50] - ]; - + let offsets = [[64, 28, 61, 23, 46], [63, 20, 54, 19, 62], [2, 58, 21, 49, 3], [36, 9, 39, 43, 8], [37, 44, 25, 56, 50]]; + let mut counts = vec![0; first_base_num_of_chunks - 1]; for max_offset in offsets.iter().flat_map(|r| r.iter()) { let mut cur_offset = 1; @@ -195,35 +178,25 @@ impl Keccak256Gadget { cur_offset += step; } } - - let columns3 = vec![ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2) - ]; + + let columns3 = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; use plonk::circuit::hashes_with_tables::get_or_create_table; let name1: &'static str = "from_binary_converter_table"; - let from_binary_converter_table = get_or_create_table( - cs, - name1, - || { - LookupTableApplication::new( - name1, - MultiBaseNormalizationTable::new( - binary_base_num_of_chunks, BINARY_BASE, KECCAK_FIRST_SPARSE_BASE, KECCAK_SECOND_SPARSE_BASE, |x| {x}, |x| {x}, name1, - ), - columns3.clone(), - None, - true - ) - } - )?; + let from_binary_converter_table = get_or_create_table(cs, name1, || { + LookupTableApplication::new( + name1, + MultiBaseNormalizationTable::new(binary_base_num_of_chunks, BINARY_BASE, KECCAK_FIRST_SPARSE_BASE, KECCAK_SECOND_SPARSE_BASE, |x| x, |x| x, name1), + columns3.clone(), + None, + true, + ) + })?; + + let name2: &'static str = "first_to_second_base_converter_table"; + let f = |x| keccak_u64_first_converter(x); - let name2 : &'static str = "first_to_second_base_converter_table"; - let f = |x| { keccak_u64_first_converter(x)}; - // we have 25 shifted rows so there are at most 50 overflows // let g(0) = 0, g(1) = 0, g(2) = 1 // g(3) should be than at least 51 @@ -233,13 +206,13 @@ impl Keccak256Gadget { of_transformed.extend([0, 0].iter()); for c in counts.iter() { assert!(*c > 0); - let elem = of_transformed.last().cloned().unwrap(); + let elem = of_transformed.last().cloned().unwrap(); //assert that is nonempty! of_transformed.push(c * elem + 1); } let range_table_bitlen = { - let num = of_transformed.last().cloned().unwrap(); + let num = of_transformed.last().cloned().unwrap(); let mut pow = 0; while (1 << pow) <= num { @@ -247,62 +220,46 @@ impl Keccak256Gadget { } pow }; - - let g = |x| { of_transformed[x as usize] }; - let first_to_second_base_converter_table = get_or_create_table( - cs, - name2, - || { - LookupTableApplication::new( - name2, - ExtendedBaseConverterTable::new( - first_base_num_of_chunks, KECCAK_FIRST_SPARSE_BASE, KECCAK_SECOND_SPARSE_BASE, f, g, name2 - ), - columns3.clone(), - None, - true - ) - } - )?; - - let name3 : &'static str = "of_first_to_second_base_converter_table"; - let f = |x| { keccak_u64_first_converter(x)}; - let of_first_to_second_base_converter_table = get_or_create_table( - cs, - name3, - || { - LookupTableApplication::new( - name3, - OverflowCognizantConverterTable::new( - KECCAK_FIRST_SPARSE_BASE, KECCAK_SECOND_SPARSE_BASE, KECCAK_LANE_WIDTH as u64, f, name3, - ), - columns3.clone(), - None, - true - ) - } - )?; - - let name4 : &'static str = "from_second_base_converter_table"; - let f = |x| { keccak_u64_second_converter(x)}; - let from_second_base_converter_table = get_or_create_table( - cs, - name4, - || { LookupTableApplication::new( + + let g = |x| of_transformed[x as usize]; + let first_to_second_base_converter_table = get_or_create_table(cs, name2, || { + LookupTableApplication::new( + name2, + ExtendedBaseConverterTable::new(first_base_num_of_chunks, KECCAK_FIRST_SPARSE_BASE, KECCAK_SECOND_SPARSE_BASE, f, g, name2), + columns3.clone(), + None, + true, + ) + })?; + + let name3: &'static str = "of_first_to_second_base_converter_table"; + let f = |x| keccak_u64_first_converter(x); + let of_first_to_second_base_converter_table = get_or_create_table(cs, name3, || { + LookupTableApplication::new( + name3, + OverflowCognizantConverterTable::new(KECCAK_FIRST_SPARSE_BASE, KECCAK_SECOND_SPARSE_BASE, KECCAK_LANE_WIDTH as u64, f, name3), + columns3.clone(), + None, + true, + ) + })?; + + let name4: &'static str = "from_second_base_converter_table"; + let f = |x| keccak_u64_second_converter(x); + let from_second_base_converter_table = get_or_create_table(cs, name4, || { + LookupTableApplication::new( name4, - MultiBaseNormalizationTable::new( - second_base_num_of_chunks, KECCAK_SECOND_SPARSE_BASE, KECCAK_FIRST_SPARSE_BASE, BINARY_BASE, f, f, name4 - ), + MultiBaseNormalizationTable::new(second_base_num_of_chunks, KECCAK_SECOND_SPARSE_BASE, KECCAK_FIRST_SPARSE_BASE, BINARY_BASE, f, f, name4), columns3.clone(), None, - true - )}, - )?; + true, + ) + })?; let f = |mut input: u64, step: u64| -> E::Fr { - let mut acc = BigUint::default(); + let mut acc = BigUint::default(); let mut base = BigUint::one(); - + while input > 0 { let bit = input & 1; input >>= 1; @@ -318,31 +275,67 @@ impl Keccak256Gadget { true => { let table = cs.get_table(global_range_table_name); table.expect("Existing range constraint table not found") - }, + } false => { let range_table = LookupTableApplication::new_range_table_of_width_3(range_table_bitlen, columns3)?; add_table_once(cs, range_table)? - }, + } }; let t = KECCAK_FIRST_SPARSE_BASE; let round_cnsts_in_first_base = [ - f(0x0000000000000001, t), f(0x0000000000008082, t), f(0x800000000000808A, t), f(0x8000000080008000, t), - f(0x000000000000808B, t), f(0x0000000080000001, t), f(0x8000000080008081, t), f(0x8000000000008009, t), - f(0x000000000000008A, t), f(0x0000000000000088, t), f(0x0000000080008009, t), f(0x000000008000000A, t), - f(0x000000008000808B, t), f(0x800000000000008B, t), f(0x8000000000008089, t), f(0x8000000000008003, t), - f(0x8000000000008002, t), f(0x8000000000000080, t), f(0x000000000000800A, t), f(0x800000008000000A, t), - f(0x8000000080008081, t), f(0x8000000000008080, t), f(0x0000000080000001, t), f(0x8000000080008008, t), + f(0x0000000000000001, t), + f(0x0000000000008082, t), + f(0x800000000000808A, t), + f(0x8000000080008000, t), + f(0x000000000000808B, t), + f(0x0000000080000001, t), + f(0x8000000080008081, t), + f(0x8000000000008009, t), + f(0x000000000000008A, t), + f(0x0000000000000088, t), + f(0x0000000080008009, t), + f(0x000000008000000A, t), + f(0x000000008000808B, t), + f(0x800000000000008B, t), + f(0x8000000000008089, t), + f(0x8000000000008003, t), + f(0x8000000000008002, t), + f(0x8000000000000080, t), + f(0x000000000000800A, t), + f(0x800000008000000A, t), + f(0x8000000080008081, t), + f(0x8000000000008080, t), + f(0x0000000080000001, t), + f(0x8000000080008008, t), ]; let r = KECCAK_SECOND_SPARSE_BASE; let round_cnsts_in_second_base = [ - f(0x0000000000000001, r), f(0x0000000000008082, r), f(0x800000000000808A, r), f(0x8000000080008000, r), - f(0x000000000000808B, r), f(0x0000000080000001, r), f(0x8000000080008081, r), f(0x8000000000008009, r), - f(0x000000000000008A, r), f(0x0000000000000088, r), f(0x0000000080008009, r), f(0x000000008000000A, r), - f(0x000000008000808B, r), f(0x800000000000008B, r), f(0x8000000000008089, r), f(0x8000000000008003, r), - f(0x8000000000008002, r), f(0x8000000000000080, r), f(0x000000000000800A, r), f(0x800000008000000A, r), - f(0x8000000080008081, r), f(0x8000000000008080, r), f(0x0000000080000001, r), f(0x8000000080008008, r), + f(0x0000000000000001, r), + f(0x0000000000008082, r), + f(0x800000000000808A, r), + f(0x8000000080008000, r), + f(0x000000000000808B, r), + f(0x0000000080000001, r), + f(0x8000000080008081, r), + f(0x8000000000008009, r), + f(0x000000000000008A, r), + f(0x0000000000000088, r), + f(0x0000000080008009, r), + f(0x000000008000000A, r), + f(0x000000008000808B, r), + f(0x800000000000008B, r), + f(0x8000000000008089, r), + f(0x8000000000008003, r), + f(0x8000000000008002, r), + f(0x8000000000000080, r), + f(0x000000000000800A, r), + f(0x800000008000000A, r), + f(0x8000000080008081, r), + f(0x8000000000008080, r), + f(0x0000000080000001, r), + f(0x8000000080008008, r), ]; Ok(Keccak256Gadget { @@ -351,7 +344,7 @@ impl Keccak256Gadget { of_first_to_second_base_converter_table, from_second_base_converter_table, range_table, - + binary_base_num_of_chunks, first_base_num_of_chunks, second_base_num_of_chunks, @@ -376,23 +369,20 @@ impl Keccak256Gadget { // if is_final is set, simply check: acc = coef * x // returns (f(x), g(x), acc_next) fn query_table_accumulate>( - &self, - cs: &mut CS, - table: &Arc>, + &self, + cs: &mut CS, + table: &Arc>, key: &AllocatedNum, prev_acc: &AllocatedNum, coef: &E::Fr, is_final: bool, - ) -> Result<(AllocatedNum, AllocatedNum, AllocatedNum)> - { + ) -> Result<(AllocatedNum, AllocatedNum, AllocatedNum)> { let (f_key, g_key) = match key.get_value() { - None => { - (None, None) - } + None => (None, None), Some(val) => { let vals = table.query(&[val])?; (Some(vals[0]), Some(vals[1])) - }, + } }; let f_key = AllocatedNum::alloc(cs, || f_key.grab())?; @@ -408,8 +398,7 @@ impl Keccak256Gadget { let new_acc = if !is_final { AllocatedNum::alloc(cs, lambda)? - } - else { + } else { let val = lambda().unwrap_or(E::Fr::zero()); assert!(val.is_zero()); AllocatedNum::zero(cs) @@ -431,7 +420,7 @@ impl Keccak256Gadget { cs.begin_gates_batch_for_step()?; cs.apply_single_lookup_gate(&vars[..table.width()], table.clone())?; - + let gate_term = MainGateTerm::new(); let (_, mut gate_coefs) = CS::MainGate::format_term(gate_term, dummy)?; @@ -444,20 +433,14 @@ impl Keccak256Gadget { } let mg = CS::MainGate::default(); - cs.new_gate_in_batch( - &mg, - &gate_coefs, - &vars, - &[] - )?; + cs.new_gate_in_batch(&mg, &gate_coefs, &vars, &[])?; cs.end_gates_batch_for_step()?; Ok((f_key, g_key, new_acc)) } - fn cnst_rotate_and_convert(&self, fr: &E::Fr, rot: usize) -> E::Fr - { + fn cnst_rotate_and_convert(&self, fr: &E::Fr, rot: usize) -> E::Fr { let mut input = BigUint::default(); let fr_repr = fr.into_repr(); for n in fr_repr.as_ref().iter().rev() { @@ -465,7 +448,7 @@ impl Keccak256Gadget { input += *n; } - let mut acc = BigUint::default(); + let mut acc = BigUint::default(); let init_base = biguint_pow(KECCAK_SECOND_SPARSE_BASE as usize, KECCAK_LANE_WIDTH - rot); let mut base = init_base.clone(); let mut iter_n = 0; @@ -475,19 +458,18 @@ impl Keccak256Gadget { let remainder = (input.clone() % BigUint::from(KECCAK_FIRST_SPARSE_BASE)).to_u64().unwrap(); if is_first || is_last { special_chunk += remainder; - } - else { + } else { let output_chunk = keccak_u64_first_converter(remainder); acc += base.clone() * output_chunk; } - + input /= KECCAK_FIRST_SPARSE_BASE; base *= KECCAK_SECOND_SPARSE_BASE; iter_n += 1; if iter_n == rot { base = BigUint::one(); - } + } } acc += keccak_u64_first_converter(special_chunk) * init_base; @@ -497,8 +479,7 @@ impl Keccak256Gadget { // helper functions for rho subroutine // returns expected num_of_chunks (if less than maximum possible value contained in a table) - fn check_offset_helper(base_num_of_chunks: usize, cur_offset: usize, max_offset: usize) -> usize - { + fn check_offset_helper(base_num_of_chunks: usize, cur_offset: usize, max_offset: usize) -> usize { if (cur_offset < max_offset) && (cur_offset + base_num_of_chunks > max_offset) { return max_offset - cur_offset; } @@ -509,7 +490,8 @@ impl Keccak256Gadget { } pub fn convert_binary_to_sparse_repr(&self, cs: &mut CS, input: &Num, sparse_base: KeccakBase) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let output_base = match sparse_base { KeccakBase::KeccakFirstSparseBase => KECCAK_FIRST_SPARSE_BASE, @@ -518,15 +500,13 @@ impl Keccak256Gadget { }; let res = match input { - Num::Constant(fr) => { - Num::Constant(func_normalizer(*fr, BINARY_BASE, output_base, |x| { x })) - }, + Num::Constant(fr) => Num::Constant(func_normalizer(*fr, BINARY_BASE, output_base, |x| x)), Num::Variable(var) => { let num_of_chunks = self.binary_base_num_of_chunks; let num_slices = round_up(KECCAK_LANE_WIDTH, num_of_chunks); - let mut input_slices : Vec> = Vec::with_capacity(num_slices); - let mut output_slices : Vec> = Vec::with_capacity(num_slices); + let mut input_slices: Vec> = Vec::with_capacity(num_slices); + let mut output_slices: Vec> = Vec::with_capacity(num_slices); let input_slice_modulus = pow(BINARY_BASE as usize, num_of_chunks); //let output1_slice_modulus = pow(output_base as usize, num_of_chunks); @@ -537,7 +517,7 @@ impl Keccak256Gadget { let witnesses = match var.get_value() { None => { vec![None; num_slices] - }, + } Some(f) => { let mut result = vec![]; // here we have to operate on row biguint number @@ -546,7 +526,7 @@ impl Keccak256Gadget { for n in f_repr.as_ref().iter().rev() { big_f <<= 64; big_f += *n; - } + } for _ in 0..num_slices { let remainder = (big_f.clone() % BigUint::from(input_slice_modulus)).to_u64().unwrap(); @@ -569,9 +549,7 @@ impl Keccak256Gadget { let mut coef = E::Fr::one(); let mut acc = var.clone(); for (_is_first, is_last, input_chunk) in input_slices.iter().identify_first_last() { - let (output1, output2, new_acc) = self.query_table_accumulate( - cs, &self.from_binary_converter_table, input_chunk, &acc, &coef, is_last - )?; + let (output1, output2, new_acc) = self.query_table_accumulate(cs, &self.from_binary_converter_table, input_chunk, &acc, &coef, is_last)?; coef.mul_assign(&input_slice_modulus_fr); acc = new_acc; @@ -580,25 +558,26 @@ impl Keccak256Gadget { KeccakBase::KeccakFirstSparseBase => output1, KeccakBase::KeccakSecondSparseBase => output2, KeccakBase::Binary => unreachable!(), - }; + }; output_slices.push(output); } - + let output_total = AllocatedNum::alloc(cs, || { let fr = var.get_value().grab()?; - Ok(func_normalizer(fr, BINARY_BASE, output_base, |x| { x })) + Ok(func_normalizer(fr, BINARY_BASE, output_base, |x| x)) })?; AllocatedNum::long_weighted_sum_eq(cs, &output_slices[..], &output_slice_modulus_fr, &output_total, false)?; Num::Variable(output_total) - }, + } }; Ok(res) } - fn handle_of_arr(&self, cs: &mut CS, input: &[AllocatedNum], total: u64) -> Result<()> - where CS: ConstraintSystem + fn handle_of_arr(&self, cs: &mut CS, input: &[AllocatedNum], total: u64) -> Result<()> + where + CS: ConstraintSystem, { let dummy = AllocatedNum::zero(cs); let zero = E::Fr::zero(); @@ -606,18 +585,18 @@ impl Keccak256Gadget { if total == 0 { AllocatedNum::long_weighted_sum_eq(cs, input, &one, &dummy, false)?; - return Ok(()) + return Ok(()); } let sum_of_inputs = AllocatedNum::alloc_sum(cs, input)?; AllocatedNum::long_weighted_sum_eq(cs, input, &one, &sum_of_inputs, true)?; - // now we need to check that sum_of_inputs <= total, + // now we need to check that sum_of_inputs <= total, // let a = total - sum_of_inputs, d = sum_of_inputs // we have the following row for range check: [a, 0, 0, d] // with arithmetic constraint: a + d - total = 0 - let mut total_fr : E::Fr = u64_to_ff(total); + let mut total_fr: E::Fr = u64_to_ff(total); let res = AllocatedNum::alloc(cs, || { let tmp = sum_of_inputs.get_value().grab()?; let mut res = total_fr.clone(); @@ -633,7 +612,7 @@ impl Keccak256Gadget { cs.begin_gates_batch_for_step()?; cs.apply_single_lookup_gate(&vars[..table.width()], table.clone())?; - + let gate_term = MainGateTerm::new(); let (_, mut gate_coefs) = CS::MainGate::format_term(gate_term, dummy.get_variable())?; @@ -646,12 +625,7 @@ impl Keccak256Gadget { gate_coefs[cnst_index] = total_fr; let mg = CS::MainGate::default(); - cs.new_gate_in_batch( - &mg, - &gate_coefs, - &vars, - &[] - )?; + cs.new_gate_in_batch(&mg, &gate_coefs, &vars, &[])?; cs.end_gates_batch_for_step()?; @@ -677,20 +651,20 @@ impl Keccak256Gadget { new_state.base = state.base; for (i, j) in (0..KECCAK_STATE_WIDTH).cartesian_product(0..KECCAK_STATE_WIDTH) { let inputs = [ - state[(i, j)].clone(), - c_vec[(i+KECCAK_STATE_WIDTH-1) % KECCAK_STATE_WIDTH].clone(), - c_vec[(i+1) % KECCAK_STATE_WIDTH].clone() + state[(i, j)].clone(), + c_vec[(i + KECCAK_STATE_WIDTH - 1) % KECCAK_STATE_WIDTH].clone(), + c_vec[(i + 1) % KECCAK_STATE_WIDTH].clone(), ]; new_state[(i, j)] = Num::lc(cs, &coeffs, &inputs[..])?; } - Ok(new_state) + Ok(new_state) } fn pi>(&self, _cs: &mut CS, state: KeccakState) -> Result> { let mut new_state = KeccakState::default(); new_state.base = state.base; for (i, j) in (0..KECCAK_STATE_WIDTH).cartesian_product(0..KECCAK_STATE_WIDTH) { - new_state[(i, j)] = state[((i + 3*j) % KECCAK_STATE_WIDTH, i)].clone(); + new_state[(i, j)] = state[((i + 3 * j) % KECCAK_STATE_WIDTH, i)].clone(); } Ok(new_state) } @@ -698,13 +672,13 @@ impl Keccak256Gadget { // we unite /rho (rotate) and conversion (FIRST_SPARSE_BASE -> SECOND_SPARSE_BASE) in one function fn rho>(&self, cs: &mut CS, state: KeccakState) -> Result> { let mut new_state = KeccakState::default(); - let mut of_map : std::collections::HashMap>> = HashMap::new(); - let num_slices_max = (KECCAK_LANE_WIDTH - 1) / self.first_base_num_of_chunks + 3; - + let mut of_map: std::collections::HashMap>> = HashMap::new(); + let num_slices_max = (KECCAK_LANE_WIDTH - 1) / self.first_base_num_of_chunks + 3; + let input_chunks_standard_step = u64_exp_to_ff(KECCAK_FIRST_SPARSE_BASE, self.first_base_num_of_chunks as u64); let output_chunks_standard_step = u64_exp_to_ff(KECCAK_SECOND_SPARSE_BASE, self.first_base_num_of_chunks as u64); let gap = u64_exp_to_ff(KECCAK_FIRST_SPARSE_BASE, KECCAK_LANE_WIDTH as u64); - + for (i, j) in (0..KECCAK_STATE_WIDTH).cartesian_product(0..KECCAK_STATE_WIDTH) { let offset = self.offsets[i][j]; @@ -716,23 +690,23 @@ impl Keccak256Gadget { let var = state[(i, j)].get_variable(); - let mut output_slices : Vec> = Vec::with_capacity(num_slices_max); - let mut output_coefs : Vec = Vec::with_capacity(num_slices_max); - + let mut output_slices: Vec> = Vec::with_capacity(num_slices_max); + let mut output_coefs: Vec = Vec::with_capacity(num_slices_max); + let mut cur_offset = 0; let mut cur_input_coef = E::Fr::one(); - let mut cur_output_coef : E::Fr = u64_exp_to_ff(KECCAK_SECOND_SPARSE_BASE, (KECCAK_LANE_WIDTH - offset) as u64); + let mut cur_output_coef: E::Fr = u64_exp_to_ff(KECCAK_SECOND_SPARSE_BASE, (KECCAK_LANE_WIDTH - offset) as u64); let mut acc = var; let has_value; let mut raw_value = BigUint::default(); - + let output_total = match var.get_value() { None => { has_value = false; None - }, + } Some(fr) => { let fr_repr = fr.into_repr(); for n in fr_repr.as_ref().iter().rev() { @@ -743,7 +717,7 @@ impl Keccak256Gadget { let value = self.cnst_rotate_and_convert(&fr, offset); Some(value) - }, + } }; let output_total = AllocatedNum::alloc(cs, || output_total.grab())?; @@ -757,8 +731,7 @@ impl Keccak256Gadget { raw_value /= divider; new_val - } - else { + } else { E::Fr::zero() }; @@ -766,8 +739,7 @@ impl Keccak256Gadget { cur_input_coef.mul_assign(&u64_to_ff(KECCAK_FIRST_SPARSE_BASE)); if offset == 1 { cur_output_coef = E::Fr::one(); - } - else { + } else { cur_output_coef.mul_assign(&u64_to_ff(KECCAK_SECOND_SPARSE_BASE)); } cur_offset += 1; @@ -785,29 +757,25 @@ impl Keccak256Gadget { raw_value /= divider; Some(new_val) - } - else { + } else { None }; let input_slice = AllocatedNum::alloc(cs, || input_slice.grab())?; - let (g_chunk, output_slice, new_acc) = self.query_table_accumulate( - cs, table, &input_slice, &acc, &cur_input_coef, false, - )?; + let (g_chunk, output_slice, new_acc) = self.query_table_accumulate(cs, table, &input_slice, &acc, &cur_input_coef, false)?; acc = new_acc; - + output_coefs.push(cur_output_coef.clone()); output_slices.push(output_slice); //increment offset cur_offset += chunk_count_bound; - + // modify input chunk coefficient - if chunk_count_bound == self.first_base_num_of_chunks { + if chunk_count_bound == self.first_base_num_of_chunks { cur_input_coef.mul_assign(&input_chunks_standard_step); - } - else { + } else { let coef_step = u64_exp_to_ff(KECCAK_FIRST_SPARSE_BASE, chunk_count_bound as u64); cur_input_coef.mul_assign(&coef_step); } @@ -815,12 +783,10 @@ impl Keccak256Gadget { // modify output_chunk coefficient if cur_offset == offset { cur_output_coef = E::Fr::one(); - } - else { - if chunk_count_bound == self.first_base_num_of_chunks { + } else { + if chunk_count_bound == self.first_base_num_of_chunks { cur_output_coef.mul_assign(&output_chunks_standard_step); - } - else { + } else { let coef_step = u64_exp_to_ff(KECCAK_SECOND_SPARSE_BASE, chunk_count_bound as u64); cur_output_coef.mul_assign(&coef_step); } @@ -840,8 +806,7 @@ impl Keccak256Gadget { raw_value /= divider; assert!(raw_value.is_zero()); new_val - } - else { + } else { E::Fr::zero() }; @@ -849,24 +814,18 @@ impl Keccak256Gadget { last_chunk_value.mul_assign(&gap); last_chunk_value.add_assign(&last_chunk_low_value); - let last_chunk = if has_value { - Some(last_chunk_value) - } else { - None - }; + let last_chunk = if has_value { Some(last_chunk_value) } else { None }; let last_chunk = AllocatedNum::alloc(cs, || last_chunk.grab())?; - let (_, output_slice, _) = self.query_table_accumulate( - cs, &self.of_first_to_second_base_converter_table, &last_chunk, &acc, &E::Fr::one(), true, - )?; + let (_, output_slice, _) = self.query_table_accumulate(cs, &self.of_first_to_second_base_converter_table, &last_chunk, &acc, &E::Fr::one(), true)?; output_coefs.push(last_coef.clone()); output_slices.push(output_slice); - + AllocatedNum::long_lc_eq(cs, &output_slices[..], &output_coefs[..], &output_total, false)?; new_state[(i, j)] = Num::Variable(output_total); } - + // handle offsets for i in 1..self.first_base_num_of_chunks { if let Some(arr) = of_map.get(&i) { @@ -875,15 +834,19 @@ impl Keccak256Gadget { } new_state.base = KeccakStateBase::Second; - - Ok(new_state) + + Ok(new_state) } fn xi_i>( - &self, cs: &mut CS, state: KeccakState, round: usize, - elems_to_squeeze: usize, elems_to_mix: Option<&[Num]>, is_final: bool, - ) -> Result<(KeccakState, Vec>)> - { + &self, + cs: &mut CS, + state: KeccakState, + round: usize, + elems_to_squeeze: usize, + elems_to_mix: Option<&[Num]>, + is_final: bool, + ) -> Result<(KeccakState, Vec>)> { // we cant's squeeze and mix simultantously: // if elems_to_squeeze > 0 && elems_to_mix.is_some() { // unreachable!(); @@ -895,15 +858,15 @@ impl Keccak256Gadget { if let Some(input_to_mix) = elems_to_mix { assert_eq!(input_to_mix.len(), KECCAK_RATE_WORDS_SIZE); } - + let mut new_state = KeccakState::default(); let mut iter_count = 0; let coeffs = [u64_to_ff(2), E::Fr::one(), u64_to_ff(3), u64_to_ff(2)]; let mut squeezed = Vec::with_capacity(elems_to_squeeze); - + let num_of_chunks = self.second_base_num_of_chunks; let num_slices = round_up(KECCAK_LANE_WIDTH, num_of_chunks); - + let input_slice_modulus = pow(KECCAK_SECOND_SPARSE_BASE as usize, num_of_chunks); //let output1_slice_modulus = pow(KECCAK_FIRST_SPARSE_BASE as usize, num_of_chunks); //let output2_slice_modulus = pow(BINARY_BASE as usize, num_of_chunks); @@ -917,9 +880,7 @@ impl Keccak256Gadget { let mut minus_one = E::Fr::one(); minus_one.negate(); - let keccak_ff_second_converter = | fr: E::Fr, output_base: u64 | { - func_normalizer(fr, KECCAK_SECOND_SPARSE_BASE, output_base, |n| { keccak_u64_second_converter(n) }) - }; + let keccak_ff_second_converter = |fr: E::Fr, output_base: u64| func_normalizer(fr, KECCAK_SECOND_SPARSE_BASE, output_base, |n| keccak_u64_second_converter(n)); for (j, i) in (0..KECCAK_STATE_WIDTH).cartesian_product(0..KECCAK_STATE_WIDTH) { // A′[x, y, z] = (A[x, y, z] ⊕ ((A[(x+1) mod 5, y, z] ⊕ 1) ⋅ A[(x+2) mod 5, y, z])) ⊕ D. @@ -930,15 +891,25 @@ impl Keccak256Gadget { // D is the next mixed input for the first KECCAK_RATE_WORDS_SIZE lanes (and zero for the rest) // there are 4-summands so always push result in d-next if not constant let d = match elems_to_mix { - None => if i == 0 && j == 0 {Num::Constant(self.round_cnsts_in_second_base[round].clone())} else { Num::default() }, + None => { + if i == 0 && j == 0 { + Num::Constant(self.round_cnsts_in_second_base[round].clone()) + } else { + Num::default() + } + } Some(input_to_mix) => { - let idx = j * KECCAK_STATE_WIDTH + i; - if idx < KECCAK_RATE_WORDS_SIZE { input_to_mix[idx].clone() } else { Num::default() } - }, + let idx = j * KECCAK_STATE_WIDTH + i; + if idx < KECCAK_RATE_WORDS_SIZE { + input_to_mix[idx].clone() + } else { + Num::default() + } + } }; let a = state[(i, j)].clone(); - let b = state[((i+1) % KECCAK_STATE_WIDTH, j)].clone(); - let c = state[((i+2) % KECCAK_STATE_WIDTH, j)].clone(); + let b = state[((i + 1) % KECCAK_STATE_WIDTH, j)].clone(); + let c = state[((i + 2) % KECCAK_STATE_WIDTH, j)].clone(); let inputs = [a, b, c, d]; let lc = Num::lc_with_d_next(cs, &coeffs[..], &inputs[..])?; @@ -954,15 +925,15 @@ impl Keccak256Gadget { } let var = lc.get_variable(); - - let mut input_slices : Vec> = Vec::with_capacity(num_slices); - let mut output1_slices : Vec> = Vec::with_capacity(num_slices); - let mut output2_slices : Vec> = Vec::with_capacity(num_slices); + + let mut input_slices: Vec> = Vec::with_capacity(num_slices); + let mut output1_slices: Vec> = Vec::with_capacity(num_slices); + let mut output2_slices: Vec> = Vec::with_capacity(num_slices); let witness = match var.get_value() { None => { vec![None; num_slices] - }, + } Some(f) => { let mut result = vec![]; // here we have to operate on row biguint number @@ -971,7 +942,7 @@ impl Keccak256Gadget { for n in f_repr.as_ref().iter().rev() { big_f <<= 64; big_f += *n; - } + } for _ in 0..num_slices { let remainder = (big_f.clone() % BigUint::from(input_slice_modulus)).to_u64().unwrap(); @@ -995,10 +966,7 @@ impl Keccak256Gadget { let mut coef = E::Fr::one(); let mut acc = var.clone(); for (_is_first, is_last, input_chunk) in input_slices.iter().identify_first_last() { - let (output1, output2, new_acc) = self.query_table_accumulate( - cs, &self.from_second_base_converter_table, input_chunk, &acc, &coef, is_last - )?; - + let (output1, output2, new_acc) = self.query_table_accumulate(cs, &self.from_second_base_converter_table, input_chunk, &acc, &coef, is_last)?; coef.mul_assign(&input_slice_modulus_fr); acc = new_acc; @@ -1030,19 +998,11 @@ impl Keccak256Gadget { iter_count += 1; } } - + Ok((new_state, squeezed)) } - fn xi_i_pure>( - &self, - cs: &mut CS, - state: KeccakState, - round: usize, - elems_to_squeeze: usize, - is_final: bool, - ) -> Result<(KeccakState, Vec>)> - { + fn xi_i_pure>(&self, cs: &mut CS, state: KeccakState, round: usize, elems_to_squeeze: usize, is_final: bool) -> Result<(KeccakState, Vec>)> { if elems_to_squeeze > 0 { assert!(is_final); } @@ -1051,10 +1011,10 @@ impl Keccak256Gadget { let mut iter_count = 0; let coeffs = [u64_to_ff(2), E::Fr::one(), u64_to_ff(3), u64_to_ff(2)]; let mut squeezed = Vec::with_capacity(elems_to_squeeze); - + let num_of_chunks = self.second_base_num_of_chunks; let num_slices = round_up(KECCAK_LANE_WIDTH, num_of_chunks); - + let second_sparse_base_modulus_usize = pow(KECCAK_SECOND_SPARSE_BASE as usize, num_of_chunks); let second_sparse_base_modulus_fr = u64_exp_to_ff(KECCAK_SECOND_SPARSE_BASE, num_of_chunks as u64); @@ -1064,19 +1024,21 @@ impl Keccak256Gadget { let mut minus_one = E::Fr::one(); minus_one.negate(); - let keccak_ff_second_converter = | fr: E::Fr, output_base: u64 | { - func_normalizer(fr, KECCAK_SECOND_SPARSE_BASE, output_base, |n| { keccak_u64_second_converter(n) }) - }; + let keccak_ff_second_converter = |fr: E::Fr, output_base: u64| func_normalizer(fr, KECCAK_SECOND_SPARSE_BASE, output_base, |n| keccak_u64_second_converter(n)); for (j, i) in (0..KECCAK_STATE_WIDTH).cartesian_product(0..KECCAK_STATE_WIDTH) { // A′[x, y, z] = (A[x, y, z] ⊕ ((A[(x+1) mod 5, y, z] ⊕ 1) ⋅ A[(x+2) mod 5, y, z])) ⊕ D. // the corresponding algebraic transform is y = 2a + b + 3c + 2d // D is always constant and nonzero only for lane[0][0] // there are 4-summands so always push result in d-next if not constant - let d = if i == 0 && j == 0 {Num::Constant(self.round_cnsts_in_second_base[round].clone())} else { Num::default() }; + let d = if i == 0 && j == 0 { + Num::Constant(self.round_cnsts_in_second_base[round].clone()) + } else { + Num::default() + }; let a = state[(i, j)].clone(); - let b = state[((i+1) % KECCAK_STATE_WIDTH, j)].clone(); - let c = state[((i+2) % KECCAK_STATE_WIDTH, j)].clone(); + let b = state[((i + 1) % KECCAK_STATE_WIDTH, j)].clone(); + let c = state[((i + 2) % KECCAK_STATE_WIDTH, j)].clone(); let inputs = [a, b, c, d]; let lc = Num::lc_with_d_next(cs, &coeffs[..], &inputs[..])?; @@ -1093,7 +1055,7 @@ impl Keccak256Gadget { if iter_count < elems_to_squeeze { squeezed.push(Num::Constant(keccak_ff_second_converter(fr, BINARY_BASE))); } - + new_state.base = KeccakStateBase::Binary; } iter_count += 1; @@ -1101,15 +1063,15 @@ impl Keccak256Gadget { } let var = lc.get_variable(); - - let mut input_slices : Vec> = Vec::with_capacity(num_slices); - let mut output1_slices : Vec> = Vec::with_capacity(num_slices); - let mut output2_slices : Vec> = Vec::with_capacity(num_slices); + + let mut input_slices: Vec> = Vec::with_capacity(num_slices); + let mut output1_slices: Vec> = Vec::with_capacity(num_slices); + let mut output2_slices: Vec> = Vec::with_capacity(num_slices); let witness = match var.get_value() { None => { vec![None; num_slices] - }, + } Some(f) => { let mut result = vec![]; // here we have to operate on row biguint number @@ -1118,7 +1080,7 @@ impl Keccak256Gadget { for n in f_repr.as_ref().iter().rev() { big_f <<= 64; big_f += *n; - } + } for _ in 0..num_slices { let remainder = (big_f.clone() % BigUint::from(second_sparse_base_modulus_usize)).to_u64().unwrap(); @@ -1142,10 +1104,7 @@ impl Keccak256Gadget { let mut coef = E::Fr::one(); let mut acc = var.clone(); for (_is_first, is_last, input_chunk) in input_slices.iter().identify_first_last() { - let (output1, output2, new_acc) = self.query_table_accumulate( - cs, &self.from_second_base_converter_table, input_chunk, &acc, &coef, is_last - )?; - + let (output1, output2, new_acc) = self.query_table_accumulate(cs, &self.from_second_base_converter_table, input_chunk, &acc, &coef, is_last)?; coef.mul_assign(&second_sparse_base_modulus_fr); acc = new_acc; @@ -1179,42 +1138,46 @@ impl Keccak256Gadget { iter_count += 1; } - new_state[(i,j)] = Num::Variable(output2_total); + new_state[(i, j)] = Num::Variable(output2_total); new_state.base = KeccakStateBase::Binary; } } - + Ok((new_state, squeezed)) } // ------------------------------------------------------------------------------------------------------------------------- - // Keccak single sponge evaluation + // Keccak single sponge evaluation // ------------------------------------------------------------------------------------------------------------------------- pub fn keccak_f>( - &self, cs: &mut CS, input_state: KeccakState, elems_to_squeeze: usize, - elems_to_mix: Option<&[Num]>, is_final: bool, is_fixed_length: bool - ) -> Result<(KeccakState, Option>>)> - { + &self, + cs: &mut CS, + input_state: KeccakState, + elems_to_squeeze: usize, + elems_to_mix: Option<&[Num]>, + is_final: bool, + is_fixed_length: bool, + ) -> Result<(KeccakState, Option>>)> { let mut state = input_state; - for round in 0..(KECCAK_NUM_ROUNDS-1) { + for round in 0..(KECCAK_NUM_ROUNDS - 1) { state = self.theta(cs, state)?; state = self.rho(cs, state)?; state = self.pi(cs, state)?; - + let (new_state, _) = self.xi_i(cs, state, round, 0, None, false)?; - state = new_state; + state = new_state; } state = self.theta(cs, state)?; state = self.rho(cs, state)?; state = self.pi(cs, state)?; - let (mut new_state, out) = self.xi_i(cs, state, KECCAK_NUM_ROUNDS-1, elems_to_squeeze, elems_to_mix, is_final)?; + let (mut new_state, out) = self.xi_i(cs, state, KECCAK_NUM_ROUNDS - 1, elems_to_squeeze, elems_to_mix, is_final)?; if elems_to_mix.is_some() && is_fixed_length { - new_state[(0, 0)] = new_state[(0, 0)].add(cs, &Num::Constant(self.round_cnsts_in_first_base[KECCAK_NUM_ROUNDS-1]))?; + new_state[(0, 0)] = new_state[(0, 0)].add(cs, &Num::Constant(self.round_cnsts_in_first_base[KECCAK_NUM_ROUNDS - 1]))?; } let squeezed = if elems_to_squeeze > 0 { Some(out) } else { None }; @@ -1228,8 +1191,8 @@ impl Keccak256Gadget { // we assume that data is split into 64-bit words pub fn digest>(&self, cs: &mut CS, data: &[Num]) -> Result>> { assert!(data.len() % KECCAK_RATE_WORDS_SIZE == 0); - - let mut state : KeccakState = KeccakState::default(); + + let mut state: KeccakState = KeccakState::default(); let mut res = Vec::with_capacity(self.digest_size); for (is_first, _is_last, data_block) in data.chunks(KECCAK_RATE_WORDS_SIZE).identify_first_last() { @@ -1239,14 +1202,14 @@ impl Keccak256Gadget { state[(idx % KECCAK_STATE_WIDTH, idx / KECCAK_STATE_WIDTH)] = out; state.base = KeccakStateBase::First; } - } - else { - let converted : Vec> = data_block.iter().map(|elem| { - self.convert_binary_to_sparse_repr(cs, elem, KeccakBase::KeccakSecondSparseBase) - }).collect::>>()?; + } else { + let converted: Vec> = data_block + .iter() + .map(|elem| self.convert_binary_to_sparse_repr(cs, elem, KeccakBase::KeccakSecondSparseBase)) + .collect::>>()?; let (new_state, _) = self.keccak_f(cs, state, 0, Some(&converted[..]), false, true)?; state = new_state; - } + } } while res.len() < self.digest_size { @@ -1261,12 +1224,10 @@ impl Keccak256Gadget { Ok(res) } - pub fn keccak_round_function_init>( - &self, cs: &mut CS, initial_absorbed_values: &[Num] - ) -> Result> { + pub fn keccak_round_function_init>(&self, cs: &mut CS, initial_absorbed_values: &[Num]) -> Result> { assert!(initial_absorbed_values.len() <= KECCAK_RATE_WORDS_SIZE); - let mut state : KeccakState = KeccakState::default(); + let mut state: KeccakState = KeccakState::default(); for (idx, elem) in initial_absorbed_values.iter().enumerate() { let out = self.convert_binary_to_sparse_repr(cs, elem, KeccakBase::KeccakFirstSparseBase)?; state[(idx % KECCAK_STATE_WIDTH, idx / KECCAK_STATE_WIDTH)] = out; @@ -1276,33 +1237,39 @@ impl Keccak256Gadget { } pub fn prepare_state(&self, cs: &mut CS, state: &mut KeccakState) -> Result<()> - where CS: ConstraintSystem { + where + CS: ConstraintSystem, + { for idx in (0..KECCAK_STATE_WIDTH).cartesian_product(0..KECCAK_STATE_WIDTH) { - state[idx] = self.convert_binary_to_sparse_repr( - cs, &state[idx], KeccakBase::KeccakFirstSparseBase - )?; + state[idx] = self.convert_binary_to_sparse_repr(cs, &state[idx], KeccakBase::KeccakFirstSparseBase)?; } state.base = KeccakStateBase::First; Ok(()) } pub fn normalize_state(&self, cs: &mut CS, state: &mut KeccakState) -> Result<()> - where CS: ConstraintSystem { + where + CS: ConstraintSystem, + { use std::cell::RefCell; let is_first_conversion = RefCell::new(true); - + let converter = |n: u64| -> u64 { - if *is_first_conversion.borrow() { (n & 1) << 1 } else { keccak_u64_second_converter(n) } + if *is_first_conversion.borrow() { + (n & 1) << 1 + } else { + keccak_u64_second_converter(n) + } }; for idx in (0..KECCAK_STATE_WIDTH).cartesian_product(0..KECCAK_STATE_WIDTH) { // we don't have trable for direct conversion from FIRST_SPARSE_BASE to BINARY_BASE // thus we have to take circuitous route through two table applications" - // FIRST_SPARSE_BASE -> SECOND_SPARSE_BASE -> mul 2 -> BINARY_BASE + // FIRST_SPARSE_BASE -> SECOND_SPARSE_BASE -> mul 2 -> BINARY_BASE let elem = state[idx].clone(); if elem.is_constant() { let fr = elem.get_value().unwrap(); - let res = func_normalizer(fr, KECCAK_FIRST_SPARSE_BASE, BINARY_BASE, |x| { x & 1}); + let res = func_normalizer(fr, KECCAK_FIRST_SPARSE_BASE, BINARY_BASE, |x| x & 1); state[idx] = Num::Constant(res); continue; } @@ -1310,31 +1277,35 @@ impl Keccak256Gadget { let aux_arr = [ ( - KECCAK_FIRST_SPARSE_BASE, KECCAK_SECOND_SPARSE_BASE, self.first_base_num_of_chunks, - self.first_to_second_base_converter_table.clone(), u64_to_ff(2), + KECCAK_FIRST_SPARSE_BASE, + KECCAK_SECOND_SPARSE_BASE, + self.first_base_num_of_chunks, + self.first_to_second_base_converter_table.clone(), + u64_to_ff(2), ), ( - KECCAK_SECOND_SPARSE_BASE, BINARY_BASE, self.second_base_num_of_chunks, - self.from_second_base_converter_table.clone(), E::Fr::one(), - + KECCAK_SECOND_SPARSE_BASE, + BINARY_BASE, + self.second_base_num_of_chunks, + self.from_second_base_converter_table.clone(), + E::Fr::one(), ), ]; - + *is_first_conversion.borrow_mut() = true; - for (in_base, out_base, num_of_chunks, table, scale) in std::array::IntoIter::new(aux_arr) - { + for (in_base, out_base, num_of_chunks, table, scale) in std::array::IntoIter::new(aux_arr) { let num_slices = round_up(KECCAK_LANE_WIDTH, num_of_chunks); - let mut input_slices : Vec> = Vec::with_capacity(num_slices); - let mut output_slices : Vec> = Vec::with_capacity(num_slices); - + let mut input_slices: Vec> = Vec::with_capacity(num_slices); + let mut output_slices: Vec> = Vec::with_capacity(num_slices); + let input_slice_modulus = pow(in_base as usize, num_of_chunks); let input_slice_modulus_fr = u64_exp_to_ff(in_base, num_of_chunks as u64); let output_slice_modulus_fr = u64_exp_to_ff(out_base, num_of_chunks as u64); - + let witnesses = match var.get_value() { None => { vec![None; num_slices] - }, + } Some(f) => { let mut result = vec![]; // here we have to operate on row biguint number @@ -1343,116 +1314,104 @@ impl Keccak256Gadget { for n in f_repr.as_ref().iter().rev() { big_f <<= 64u32; big_f += *n; - } - + } + for _ in 0..num_slices { let remainder = (big_f.clone() % BigUint::from(input_slice_modulus)).to_u64().unwrap(); let new_val = u64_to_ff(remainder); big_f /= input_slice_modulus; result.push(Some(new_val)); } - + assert!(big_f.is_zero()); result } }; - + for w in witnesses.into_iter() { let tmp = AllocatedNum::alloc(cs, || w.grab())?; input_slices.push(tmp); } - + let mut coef = E::Fr::one(); let mut acc = var.clone(); for (_is_first, is_last, input_chunk) in input_slices.iter().identify_first_last() { - let (_output1, output2, new_acc) = self.query_table_accumulate( - cs, &table, input_chunk, &acc, &coef, is_last - )?; - + let (_output1, output2, new_acc) = self.query_table_accumulate(cs, &table, input_chunk, &acc, &coef, is_last)?; + coef.mul_assign(&input_slice_modulus_fr); acc = new_acc; output_slices.push(output2); } - + var = AllocatedNum::alloc(cs, || { let fr = var.get_value().grab()?; Ok(func_normalizer(fr, in_base, out_base, converter)) })?; - let coefs = std::iter::repeat(()).take(num_slices).scan(scale.clone(), |acc, _el| { - let tmp = acc.clone(); - acc.mul_assign(&output_slice_modulus_fr); - Some(tmp) - }).collect::>(); + let coefs = std::iter::repeat(()) + .take(num_slices) + .scan(scale.clone(), |acc, _el| { + let tmp = acc.clone(); + acc.mul_assign(&output_slice_modulus_fr); + Some(tmp) + }) + .collect::>(); AllocatedNum::long_lc_eq(cs, &output_slices[..], &coefs[..], &var, false)?; *is_first_conversion.borrow_mut() = false; - }; - + } + state[idx] = Num::Variable(var) } Ok(()) } pub fn keccak_round_function>( - &self, - cs: &mut CS, - state: KeccakState, + &self, + cs: &mut CS, + state: KeccakState, elems_to_mix: [Num; KECCAK_RATE_WORDS_SIZE], is_first_block: Boolean, - ) -> Result<(KeccakState, Vec>)> - { + ) -> Result<(KeccakState, Vec>)> { let mut elems_to_absorb = [Num::::zero(); KECCAK_RATE_WORDS_SIZE]; let mut is_first = true; for (elem_in, elem_out) in elems_to_mix.iter().zip(elems_to_absorb.iter_mut()) { let tmp = if is_first { is_first = false; let tmp = self.convert_binary_to_sparse_repr(cs, &elem_in, KeccakBase::KeccakSecondSparseBase)?; - Num::conditionally_select( - cs, - &is_first_block, - &Num::Constant(self.round_cnsts_in_second_base[KECCAK_NUM_ROUNDS-1]), - &tmp - )? + Num::conditionally_select(cs, &is_first_block, &Num::Constant(self.round_cnsts_in_second_base[KECCAK_NUM_ROUNDS - 1]), &tmp)? } else { - // returns 0 if condition == `false` and `a` if condition == `true` + // returns 0 if condition == `false` and `a` if condition == `true` let tmp = Num::mask(cs, elem_in, &is_first_block.not())?; let tmp = self.convert_binary_to_sparse_repr(cs, &tmp, KeccakBase::KeccakSecondSparseBase)?; tmp }; *elem_out = tmp; } - - let (rolled_state, squeezed_wrapped) = self.keccak_f( - cs, state, DEFAULT_KECCAK_DIGEST_WORDS_SIZE, Some(&elems_to_absorb[..]), false, false - )?; + + let (rolled_state, squeezed_wrapped) = self.keccak_f(cs, state, DEFAULT_KECCAK_DIGEST_WORDS_SIZE, Some(&elems_to_absorb[..]), false, false)?; let squeezed = squeezed_wrapped.unwrap(); let mut new_state = KeccakState::::default(); for idx in 0..KECCAK_STATE_WIDTH * KECCAK_STATE_WIDTH { let rolled_state_elem = rolled_state[(idx % KECCAK_STATE_WIDTH, idx / KECCAK_STATE_WIDTH)].clone(); let tmp = if idx < KECCAK_RATE_WORDS_SIZE { - let converted_input = self.convert_binary_to_sparse_repr( - cs, &elems_to_mix[idx], KeccakBase::KeccakFirstSparseBase - )?; + let converted_input = self.convert_binary_to_sparse_repr(cs, &elems_to_mix[idx], KeccakBase::KeccakFirstSparseBase)?; Num::conditionally_select(cs, &is_first_block, &converted_input, &rolled_state_elem)? } else { Num::mask(cs, &rolled_state_elem, &is_first_block.not())? }; - new_state[(idx % KECCAK_STATE_WIDTH, idx / KECCAK_STATE_WIDTH)] = tmp; + new_state[(idx % KECCAK_STATE_WIDTH, idx / KECCAK_STATE_WIDTH)] = tmp; } - let round_cnst = Num::Constant(self.round_cnsts_in_first_base[KECCAK_NUM_ROUNDS-1]); - new_state[(0, 0)] = round_cnst.mask_by_boolean_into_accumulator( - cs, &is_first_block.not(), &new_state[(0, 0)] - )?; - + let round_cnst = Num::Constant(self.round_cnsts_in_first_base[KECCAK_NUM_ROUNDS - 1]); + new_state[(0, 0)] = round_cnst.mask_by_boolean_into_accumulator(cs, &is_first_block.not(), &new_state[(0, 0)])?; + Ok((new_state, squeezed)) } - pub fn digest_from_bytes>(&self, cs: &mut CS, bytes: &[Byte]) -> Result>> - { + pub fn digest_from_bytes>(&self, cs: &mut CS, bytes: &[Byte]) -> Result>> { // Keccak padding algorithm is the following: // padlen = align_bytes - used_bytes (here align is multiple of block size) // if padlen == 0: @@ -1470,42 +1429,40 @@ impl Keccak256Gadget { let padlen = block_size - last_block_size; if padlen == 1 { padded.push(Byte::from_cnst(u64_to_ff(0x81))); - } - else { + } else { padded.push(Byte::from_cnst(u64_to_ff(0x01))); padded.extend(iter::repeat(Byte::from_cnst(E::Fr::zero())).take(padlen - 2)); padded.push(Byte::from_cnst(u64_to_ff(0x80))); } - + assert_eq!(padded.len() % block_size, 0); // now convert the byte array to array of 64-bit words let mut words64 = Vec::with_capacity(padded.len() / 8); for chunk in padded.chunks(8) { let elems = [ - chunk[0].into_num(), chunk[1].into_num(), chunk[2].into_num(), chunk[3].into_num(), - chunk[4].into_num(), chunk[5].into_num(), chunk[6].into_num(), chunk[7].into_num() + chunk[0].into_num(), + chunk[1].into_num(), + chunk[2].into_num(), + chunk[3].into_num(), + chunk[4].into_num(), + chunk[5].into_num(), + chunk[6].into_num(), + chunk[7].into_num(), ]; let tmp = Num::long_weighted_sum(cs, &elems, &u64_to_ff(1 << 8))?; words64.push(tmp); } - self.digest(cs, &words64[..]) + self.digest(cs, &words64[..]) } - pub fn keccak_absorb_into_state_into_binary_base>( - &self, - cs: &mut CS, - state: KeccakState, - elems_to_mix: [Num; KECCAK_RATE_WORDS_SIZE], - ) -> Result>{ + pub fn keccak_absorb_into_state_into_binary_base>(&self, cs: &mut CS, state: KeccakState, elems_to_mix: [Num; KECCAK_RATE_WORDS_SIZE]) -> Result> { assert!(state.base == KeccakStateBase::Binary); let mut state = state; for row in state.state.iter_mut() { for el in row.iter_mut() { - *el = self.convert_binary_to_sparse_repr( - cs, el, KeccakBase::KeccakSecondSparseBase - )?; + *el = self.convert_binary_to_sparse_repr(cs, el, KeccakBase::KeccakSecondSparseBase)?; } } state.base = KeccakStateBase::Second; @@ -1517,17 +1474,15 @@ impl Keccak256Gadget { // convert input into second base for el in elems_to_mix.iter_mut() { - *el = self.convert_binary_to_sparse_repr( - cs, el, KeccakBase::KeccakSecondSparseBase - )?; + *el = self.convert_binary_to_sparse_repr(cs, el, KeccakBase::KeccakSecondSparseBase)?; } let mut new_state = KeccakState::default(); let coeffs = [u64_to_ff(2), E::Fr::one(), u64_to_ff(3), u64_to_ff(2)]; - + let num_of_chunks = self.second_base_num_of_chunks; let num_slices = round_up(KECCAK_LANE_WIDTH, num_of_chunks); - + let second_sparse_base_modulus_usize = pow(KECCAK_SECOND_SPARSE_BASE as usize, num_of_chunks); let second_sparse_base_modulus_fr = u64_exp_to_ff(KECCAK_SECOND_SPARSE_BASE, num_of_chunks as u64); @@ -1536,9 +1491,7 @@ impl Keccak256Gadget { let mut minus_one = E::Fr::one(); minus_one.negate(); - let keccak_ff_second_converter = | fr: E::Fr, output_base: u64 | { - func_normalizer(fr, KECCAK_SECOND_SPARSE_BASE, output_base, |n| { keccak_u64_second_converter(n) }) - }; + let keccak_ff_second_converter = |fr: E::Fr, output_base: u64| func_normalizer(fr, KECCAK_SECOND_SPARSE_BASE, output_base, |n| keccak_u64_second_converter(n)); for (j, i) in (0..KECCAK_STATE_WIDTH).cartesian_product(0..KECCAK_STATE_WIDTH) { // A′[x, y, z] = (A[x, y, z] ⊕ ((A[(x+1) mod 5, y, z] ⊕ 1) ⋅ A[(x+2) mod 5, y, z])) ⊕ D. @@ -1546,8 +1499,12 @@ impl Keccak256Gadget { // D is always constant and nonzero only for lane[0][0] // there are 4-summands so always push result in d-next if not constant let d = { - let idx = j * KECCAK_STATE_WIDTH + i; - if idx < KECCAK_RATE_WORDS_SIZE { elems_to_mix[idx].clone() } else { Num::default() } + let idx = j * KECCAK_STATE_WIDTH + i; + if idx < KECCAK_RATE_WORDS_SIZE { + elems_to_mix[idx].clone() + } else { + Num::default() + } }; let a = state[(i, j)].clone(); let b = Num::zero(); @@ -1562,14 +1519,14 @@ impl Keccak256Gadget { } let var = lc.get_variable(); - - let mut input_slices : Vec> = Vec::with_capacity(num_slices); - let mut output1_slices : Vec> = Vec::with_capacity(num_slices); + + let mut input_slices: Vec> = Vec::with_capacity(num_slices); + let mut output1_slices: Vec> = Vec::with_capacity(num_slices); let witness = match var.get_value() { None => { vec![None; num_slices] - }, + } Some(f) => { let mut result = vec![]; // here we have to operate on row biguint number @@ -1578,7 +1535,7 @@ impl Keccak256Gadget { for n in f_repr.as_ref().iter().rev() { big_f <<= 64; big_f += *n; - } + } for _ in 0..num_slices { let remainder = (big_f.clone() % BigUint::from(second_sparse_base_modulus_usize)).to_u64().unwrap(); @@ -1602,10 +1559,7 @@ impl Keccak256Gadget { let mut coef = E::Fr::one(); let mut acc = var.clone(); for (_is_first, is_last, input_chunk) in input_slices.iter().identify_first_last() { - let (output1, _output2, new_acc) = self.query_table_accumulate( - cs, &self.from_second_base_converter_table, input_chunk, &acc, &coef, is_last - )?; - + let (output1, _output2, new_acc) = self.query_table_accumulate(cs, &self.from_second_base_converter_table, input_chunk, &acc, &coef, is_last)?; coef.mul_assign(&second_sparse_base_modulus_fr); acc = new_acc; @@ -1628,30 +1582,26 @@ impl Keccak256Gadget { Ok(new_state) } - pub fn keccak_normal_rounds_function_state_in_first_base>( - &self, - cs: &mut CS, - state: KeccakState, - ) -> Result<(KeccakState, [Num; 4])> { + pub fn keccak_normal_rounds_function_state_in_first_base>(&self, cs: &mut CS, state: KeccakState) -> Result<(KeccakState, [Num; 4])> { let mut state = state; assert!(state.base == KeccakStateBase::First); // here we do all rounds without the last one - for round in 0..(KECCAK_NUM_ROUNDS-1) { + for round in 0..(KECCAK_NUM_ROUNDS - 1) { state = self.theta(cs, state)?; state = self.rho(cs, state)?; state = self.pi(cs, state)?; - + let (new_state, _) = self.xi_i_pure(cs, state, round, 0, false)?; - state = new_state; + state = new_state; } state = self.theta(cs, state)?; state = self.rho(cs, state)?; state = self.pi(cs, state)?; - let (new_state, out) = self.xi_i_pure(cs, state, KECCAK_NUM_ROUNDS-1, 4, true)?; + let (new_state, out) = self.xi_i_pure(cs, state, KECCAK_NUM_ROUNDS - 1, 4, true)?; let out: [Num; 4] = out.try_into().unwrap(); diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/mod.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/mod.rs index 46a4b9f..a1a39e8 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/mod.rs @@ -1,4 +1,4 @@ +pub mod gadgets; pub mod tables; +pub mod tests; pub mod utils; -pub mod gadgets; -pub mod tests; \ No newline at end of file diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/tables.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/tables.rs index 4ce29c0..79a3305 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/tables.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/tables.rs @@ -1,22 +1,21 @@ +use crate::bellman::pairing::ff::*; use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::plonk::better_better_cs::lookup_tables::*; use crate::bellman::plonk::better_better_cs::utils; -use crate::bellman::pairing::ff::*; -use crate::bellman::SynthesisError; use crate::bellman::Engine; +use crate::bellman::SynthesisError; use crate::plonk::circuit::bigint_new::fe_to_biguint; use itertools::Itertools; use super::super::utils::*; - -// for given bases (b, c), num_of_chunks n, -// base converter function f: [0, b) -> [0, c) +// for given bases (b, c), num_of_chunks n, +// base converter function f: [0, b) -> [0, c) // and block counting function g : [0, n) -> u64 // this table does the following transformation: // x = \sum_{i=0}^n x_i b^i -> y = \sum_{i=0}^m f(x_i) c^i. -// first column - input x; +// first column - input x; // second column - g(k), where k is the number of actual non-zero chunks // third column - output y; #[derive(Clone)] @@ -30,8 +29,10 @@ pub struct ExtendedBaseConverterTable { } impl ExtendedBaseConverterTable { - pub fn new(num_chunks: usize, base_b: u64, base_c: u64, transform_f: F, transform_counter: G, name: &'static str) -> Self - where F: Fn(u64) -> u64, G: Fn(u64) -> u64 + pub fn new(num_chunks: usize, base_b: u64, base_c: u64, transform_f: F, transform_counter: G, name: &'static str) -> Self + where + F: Fn(u64) -> u64, + G: Fn(u64) -> u64, { let table_size = pow(base_b as usize, num_chunks); let mut keys_vec = Vec::with_capacity(table_size); @@ -135,14 +136,13 @@ impl LookupTableInternal for ExtendedBaseConverterTable { assert!(keys.len() == self.num_keys()); if let Some(entry) = self.table_lookup_map.get(&keys[0]) { - return Ok(vec![entry.0, entry.1]) + return Ok(vec![entry.0, entry.1]); } Err(SynthesisError::Unsatisfiable) } } - #[derive(Clone)] pub struct OverflowCognizantConverterTable { table_entries: [Vec; 3], @@ -154,18 +154,15 @@ pub struct OverflowCognizantConverterTable { } impl OverflowCognizantConverterTable { - pub fn new u64>( - base_b: u64, base_c: u64, offset:u64, transform_f: F, name: &'static str - ) -> Self - { - let table_size = (base_b * (base_b+1)/2) as usize; + pub fn new u64>(base_b: u64, base_c: u64, offset: u64, transform_f: F, name: &'static str) -> Self { + let table_size = (base_b * (base_b + 1) / 2) as usize; let mut map = std::collections::HashMap::with_capacity(table_size); let offset_fr = u64_exp_to_ff::(base_b, offset); let zero_fr = E::Fr::zero(); let mut unsorted_table = Vec::with_capacity(table_size); for i in 0..base_b { - for j in 0..(base_b-i) { + for j in 0..(base_b - i) { let low = i; let high = j; @@ -215,7 +212,7 @@ impl LookupTableInternal for OverflowCognizantConverterTable { self.name } fn table_size(&self) -> usize { - let table_size = (self.base_b * (self.base_b+1)/2) as usize; + let table_size = (self.base_b * (self.base_b + 1) / 2) as usize; table_size } fn num_keys(&self) -> usize { @@ -258,7 +255,7 @@ impl LookupTableInternal for OverflowCognizantConverterTable { assert!(keys.len() == self.num_keys()); if let Some(entry) = self.table_lookup_map.get(&keys[0]) { - return Ok(vec![entry.0, entry.1]) + return Ok(vec![entry.0, entry.1]); } Err(SynthesisError::Unsatisfiable) diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/tests.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/tests.rs index b5371dc..7631ffb 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/tests.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/tests.rs @@ -1,31 +1,25 @@ #[cfg(test)] mod test { - use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::pairing::ff::*; - use crate::bellman::SynthesisError; + use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::Engine; + use crate::bellman::SynthesisError; + use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; use crate::plonk::circuit::boolean::AllocatedBit; - use crate::tiny_keccak::Keccak; - use crate::plonk::circuit::allocated_num::{ - AllocatedNum, - Num, - }; use crate::plonk::circuit::boolean::Boolean; - use crate::plonk::circuit::byte::{ - Byte, - }; + use crate::plonk::circuit::byte::Byte; + use crate::tiny_keccak::Keccak; use crate::bellman::pairing::bn256::{Bn256, Fr}; + use super::super::super::utils::*; use super::super::gadgets::*; use super::super::utils::*; - use super::super::super::utils::*; - + use rand::{Rng, SeedableRng, StdRng}; use std::convert::TryInto; - - struct TestKeccakCircuit{ + struct TestKeccakCircuit { input: Vec, output: [E::Fr; DEFAULT_KECCAK_DIGEST_WORDS_SIZE], is_const_test: bool, @@ -36,50 +30,41 @@ mod test { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Width4MainGateWithDNext::default().into_internal(), - ] - ) + Ok(vec![Width4MainGateWithDNext::default().into_internal()]) } - fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> - { + fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { let mut actual_output_vars = Vec::with_capacity(DEFAULT_KECCAK_DIGEST_WORDS_SIZE); for value in self.output.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc_input(cs, || Ok(value.clone()))?; actual_output_vars.push(Num::Variable(new_var)); - } - else { + } else { actual_output_vars.push(Num::Constant(value.clone())); } } let keccak_gadget = Keccak256Gadget::new(cs, None, None, None, None, false, "")?; - - let supposed_output_vars = if !self.is_byte_test { + + let supposed_output_vars = if !self.is_byte_test { let mut input_vars = Vec::with_capacity(self.input.len()); for value in self.input.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc(cs, || Ok(value.clone()))?; input_vars.push(Num::Variable(new_var)); - } - else { + } else { input_vars.push(Num::Constant(value.clone())); } } keccak_gadget.digest(cs, &input_vars[..])? - } - else { + } else { let mut input_vars = Vec::with_capacity(self.input.len()); for value in self.input.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc(cs, || Ok(value.clone()))?; let byte = Byte::from_num_unconstrained(cs, Num::Variable(new_var)); input_vars.push(byte); - } - else { + } else { let byte = Byte::from_cnst(value.clone()); input_vars.push(byte); } @@ -102,8 +87,7 @@ mod test { u64_to_ff(num) } - fn keccak_gadget_test_template(is_const_test: bool) - { + fn keccak_gadget_test_template(is_const_test: bool) { const NUM_OF_BLOCKS: usize = 4; let mut rng = rand::thread_rng(); @@ -115,7 +99,7 @@ mod test { let mut output: [u8; DEFAULT_KECCAK_DIGEST_WORDS_SIZE * 8] = [0; DEFAULT_KECCAK_DIGEST_WORDS_SIZE * 8]; Keccak::keccak256(&input[0..(input.len() - 1)], &mut output); - + let mut input_fr_arr = Vec::with_capacity(KECCAK_RATE_WORDS_SIZE * NUM_OF_BLOCKS); let mut output_fr_arr = [Fr::zero(); DEFAULT_KECCAK_DIGEST_WORDS_SIZE]; @@ -126,8 +110,8 @@ mod test { for (i, block) in output.chunks(8).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestKeccakCircuit::{ + + let circuit = TestKeccakCircuit:: { input: input_fr_arr, output: output_fr_arr, is_const_test, @@ -144,13 +128,13 @@ mod test { #[test] fn keccak_gadget_test() { - keccak_gadget_test_template(false) + keccak_gadget_test_template(false) } #[test] fn keccak_gadget_const_propagation_test() { - keccak_gadget_test_template(true) - } + keccak_gadget_test_template(true) + } #[test] fn keccak_gadget_bytes_test() { @@ -158,13 +142,11 @@ mod test { } #[test] - fn keccak_gadget_short_bytes_test() - { + fn keccak_gadget_short_bytes_test() { keccak_gadget_bytes_test_impl::<64>(); } - fn keccak_gadget_bytes_test_impl() - { + fn keccak_gadget_bytes_test_impl() { const IS_CONST_TEST: bool = false; let mut rng = rand::thread_rng(); @@ -174,18 +156,18 @@ mod test { } let mut output: [u8; DEFAULT_KECCAK_DIGEST_WORDS_SIZE * 8] = [0; DEFAULT_KECCAK_DIGEST_WORDS_SIZE * 8]; - Keccak::keccak256(&input[0..input.len() ], &mut output); - - let mut input_fr_arr : Vec<::Fr> = Vec::with_capacity(NUM_OF_BYTES); + Keccak::keccak256(&input[0..input.len()], &mut output); + + let mut input_fr_arr: Vec<::Fr> = Vec::with_capacity(NUM_OF_BYTES); let mut output_fr_arr = [Fr::zero(); DEFAULT_KECCAK_DIGEST_WORDS_SIZE]; input_fr_arr.extend(input.iter().map(|byte| u64_to_ff::<::Fr>(*byte as u64))); - + for (i, block) in output.chunks(8).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestKeccakCircuit::{ + + let circuit = TestKeccakCircuit:: { input: input_fr_arr, output: output_fr_arr, is_const_test: IS_CONST_TEST, @@ -200,8 +182,7 @@ mod test { assert!(assembly.is_satisfied()); } - - struct TestKeccakRoundFunctionCircuit{ + struct TestKeccakRoundFunctionCircuit { inputs: Vec>, outputs: Vec<[E::Fr; DEFAULT_KECCAK_DIGEST_WORDS_SIZE]>, } @@ -210,42 +191,31 @@ mod test { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Width4MainGateWithDNext::default().into_internal(), - ] - ) + Ok(vec![Width4MainGateWithDNext::default().into_internal()]) } - fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> - { + fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { let keccak_gadget = Keccak256Gadget::new(cs, None, None, None, None, false, "")?; let mut keccak_state = KeccakState::default(); - let input_chunks = self.inputs.iter().flat_map(|inner_vec| { - inner_vec.chunks(KECCAK_RATE_WORDS_SIZE).identify_first_last() - }); + let input_chunks = self.inputs.iter().flat_map(|inner_vec| inner_vec.chunks(KECCAK_RATE_WORDS_SIZE).identify_first_last()); let mut is_initialized = false; let mut output_block_idx = 0; - for (is_start_of_block, _is_end_of_block, in_chunk) in input_chunks - { + for (is_start_of_block, _is_end_of_block, in_chunk) in input_chunks { let mut elems_to_absorb = [Num::::zero(); KECCAK_RATE_WORDS_SIZE]; for (i, value) in in_chunk.iter().enumerate() { let new_var = AllocatedNum::alloc(cs, || Ok(value.clone()))?; elems_to_absorb[i] = Num::Variable(new_var); } - + if !is_initialized { is_initialized = true; keccak_state = keccak_gadget.keccak_round_function_init(cs, &elems_to_absorb[..])?; - } - else { + } else { let flag = Boolean::Is(AllocatedBit::alloc(cs, Some(is_start_of_block))?); - let (new_state, supposed_output_vars) = keccak_gadget.keccak_round_function( - cs, keccak_state, elems_to_absorb, flag - )?; + let (new_state, supposed_output_vars) = keccak_gadget.keccak_round_function(cs, keccak_state, elems_to_absorb, flag)?; keccak_state = new_state; if is_start_of_block { @@ -267,9 +237,7 @@ mod test { // there is one output remaining_to_be_checked let elems_to_absorb = [Num::::zero(); KECCAK_RATE_WORDS_SIZE]; let flag = Boolean::constant(true); - let (_new_state, supposed_output_vars) = keccak_gadget.keccak_round_function( - cs, keccak_state, elems_to_absorb, flag - )?; + let (_new_state, supposed_output_vars) = keccak_gadget.keccak_round_function(cs, keccak_state, elems_to_absorb, flag)?; let mut actual_output_vars = Vec::with_capacity(DEFAULT_KECCAK_DIGEST_WORDS_SIZE); for value in self.outputs[output_block_idx].iter() { @@ -283,14 +251,13 @@ mod test { output_block_idx += 1; assert_eq!(output_block_idx, self.outputs.len()); - + Ok(()) } } #[test] - fn keccak_round_function_test() - { + fn keccak_round_function_test() { let mut rng = rand::thread_rng(); // we test the following pattern: @@ -299,16 +266,16 @@ mod test { let mut inputs = vec![]; let mut outputs = vec![]; - for block_size in BLOCK_SIZES.iter() { + for block_size in BLOCK_SIZES.iter() { let mut input: Vec = Vec::with_capacity(KECCAK_RATE_WORDS_SIZE * block_size * 8); for _i in 0..(KECCAK_RATE_WORDS_SIZE * block_size * 8) { input.push(rng.gen()); } *(input.last_mut().unwrap()) = 0b10000001 as u8; let mut output: [u8; DEFAULT_KECCAK_DIGEST_WORDS_SIZE * 8] = [0; DEFAULT_KECCAK_DIGEST_WORDS_SIZE * 8]; - + Keccak::keccak256(&input[0..(input.len() - 1)], &mut output); - + let mut input_fr_arr = Vec::with_capacity(KECCAK_RATE_WORDS_SIZE * block_size); let mut output_fr_arr = [Fr::zero(); DEFAULT_KECCAK_DIGEST_WORDS_SIZE]; @@ -323,12 +290,9 @@ mod test { inputs.push(input_fr_arr); outputs.push(output_fr_arr); } - - let circuit = TestKeccakRoundFunctionCircuit::{ - inputs, - outputs, - }; - + + let circuit = TestKeccakRoundFunctionCircuit:: { inputs, outputs }; + let mut assembly = TrivialAssembly::::new(); circuit.synthesize(&mut assembly).expect("must work"); @@ -350,7 +314,7 @@ mod test { let mut output: [u8; DEFAULT_KECCAK_DIGEST_WORDS_SIZE * 8] = [0; DEFAULT_KECCAK_DIGEST_WORDS_SIZE * 8]; Keccak::keccak256(&input[0..(input.len() - 1)], &mut output); - + let mut input_fr_arr = Vec::with_capacity(KECCAK_RATE_WORDS_SIZE * NUM_OF_BLOCKS); let mut output_fr_arr = [Fr::zero(); DEFAULT_KECCAK_DIGEST_WORDS_SIZE]; @@ -361,8 +325,8 @@ mod test { for (i, block) in output.chunks(8).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestKeccakCircuit::{ + + let circuit = TestKeccakCircuit:: { input: input_fr_arr, output: output_fr_arr, is_const_test: false, @@ -378,25 +342,23 @@ mod test { assert!(assembly.is_satisfied()); use crate::bellman::kate_commitment::{Crs, CrsForMonomialForm}; - use crate::bellman::worker::Worker; - use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; use crate::bellman::plonk::better_better_cs::setup::VerificationKey; use crate::bellman::plonk::better_better_cs::verifier::verify; + use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; + use crate::bellman::worker::Worker; let worker = Worker::new(); //let required_size = assembly.n().next_power_of_two(); let crs = Crs::::dummy_crs(1 << 20); - let setup = assembly.create_setup::>(&worker).unwrap(); + let setup = assembly.create_setup::>(&worker).unwrap(); let vk = VerificationKey::from_setup(&setup, &worker, &crs).unwrap(); println!("set com: {}", vk.gate_setup_commitments.len()); println!("sel com: {}", vk.gate_selectors_commitments.len()); - let proof = assembly - .create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs, None) - .unwrap(); + let proof = assembly.create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs, None).unwrap(); let valid = verify::<_, _, RollingKeccakTranscript>(&vk, &proof, None).unwrap(); - assert!(valid); + assert!(valid); } #[test] @@ -405,16 +367,17 @@ mod test { let mut cs = TrivialAssembly::::new(); let mut rng = rand::thread_rng(); - let actual_state = std::iter::repeat(()).take(KECCAK_STATE_WIDTH * KECCAK_STATE_WIDTH).map(|_| { - u64_to_ff::(rng.gen()) - }).collect::>(); + let actual_state = std::iter::repeat(()) + .take(KECCAK_STATE_WIDTH * KECCAK_STATE_WIDTH) + .map(|_| u64_to_ff::(rng.gen())) + .collect::>(); let mut circuit_state = KeccakState::default(); let mut circuit_routine = || -> Result<(), SynthesisError> { for (i, j) in (0..KECCAK_STATE_WIDTH).cartesian_product(0..KECCAK_STATE_WIDTH) { let fr = actual_state[i * KECCAK_STATE_WIDTH + j].clone(); let var = AllocatedNum::alloc(&mut cs, || Ok(fr))?; - circuit_state[(i, j)] = Num::Variable(var); + circuit_state[(i, j)] = Num::Variable(var); } let keccak_gadget = Keccak256Gadget::new(&mut cs, None, None, None, None, false, "")?; keccak_gadget.prepare_state(&mut cs, &mut circuit_state)?; @@ -433,6 +396,3 @@ mod test { assert!(cs.is_satisfied()); } } - - - diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/utils.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/utils.rs index fa96b39..6c14b72 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/utils.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/keccak/utils.rs @@ -1,10 +1,8 @@ -use crate::bellman::pairing::ff::*; use super::super::utils::*; +use crate::bellman::pairing::ff::*; - -pub const KECCAK_FIRST_SPARSE_BASE : u64 = 13; -pub fn keccak_u64_first_converter(n: u64) -> u64 -{ +pub const KECCAK_FIRST_SPARSE_BASE: u64 = 13; +pub fn keccak_u64_first_converter(n: u64) -> u64 { assert!(n < KECCAK_FIRST_SPARSE_BASE); // simple xor n & 1 @@ -33,9 +31,9 @@ pub fn keccak_u64_first_converter(n: u64) -> u64 // | 15 | 1 | 1 | 1 | 1 | 0 | 8 | // -----------------------------------------|------------------| // this table shows that mapping f_alg -> f_log is indeed well-defined -pub const KECCAK_SECOND_SPARSE_BASE : u64 = 9; +pub const KECCAK_SECOND_SPARSE_BASE: u64 = 9; pub fn keccak_u64_second_converter(n: u64) -> u64 { assert!(n < KECCAK_SECOND_SPARSE_BASE); - let bit_table : [u64; KECCAK_SECOND_SPARSE_BASE as usize] = [0, 0, 1, 1, 0, 0, 1, 1, 0]; + let bit_table: [u64; KECCAK_SECOND_SPARSE_BASE as usize] = [0, 0, 1, 1, 0, 0, 1, 1, 0]; bit_table[n as usize] -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/mod.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/mod.rs index 24ae796..415b48b 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/mod.rs @@ -1,21 +1,16 @@ -pub mod utils; -pub mod tables; -pub mod sha256; pub mod blake2s; pub mod keccak; pub mod reinforcement_concrete; +pub mod sha256; +pub mod tables; +pub mod utils; - -use crate::bellman::SynthesisError; -use crate::bellman::Engine; use crate::bellman::pairing::ff::*; use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; use crate::bellman::plonk::better_better_cs::cs::*; -use crate::plonk::circuit::allocated_num::{ - AllocatedNum, - Num, - STATE_WIDTH -}; +use crate::bellman::Engine; +use crate::bellman::SynthesisError; +use crate::plonk::circuit::allocated_num::{AllocatedNum, Num, STATE_WIDTH}; use crate::plonk::circuit::Assignment; use std::iter; @@ -24,7 +19,7 @@ use std::iter; pub fn get_or_create_table, FN: FnOnce() -> LookupTableApplication>( cs: &mut CS, table_name: &str, - init_fn: FN + init_fn: FN, ) -> Result>, SynthesisError> { if let Ok(existing) = cs.get_table(table_name) { Ok(existing) @@ -36,29 +31,25 @@ pub fn get_or_create_table, FN: FnOnce() -> L } } -trait NumExtension : Sized -{ - fn lc_impl>( - cs: &mut CS, input_coeffs: &[E::Fr], inputs: &[Self], use_d_next: bool - ) -> Result; - +trait NumExtension: Sized { + fn lc_impl>(cs: &mut CS, input_coeffs: &[E::Fr], inputs: &[Self], use_d_next: bool) -> Result; + fn lc>(cs: &mut CS, input_coeffs: &[E::Fr], inputs: &[Self]) -> Result; fn lc_with_d_next>(cs: &mut CS, input_coeffs: &[E::Fr], inputs: &[Self]) -> Result; fn sum>(cs: &mut CS, nums: &[Self]) -> Result; fn sum_with_d_next>(cs: &mut CS, nums: &[Self]) -> Result; fn long_weighted_sum>(cs: &mut CS, vars: &[Self], base: &E::Fr) -> Result; -} - +} -impl NumExtension for Num -{ +impl NumExtension for Num { fn lc_impl(cs: &mut CS, input_coeffs: &[E::Fr], inputs: &[Num], use_d_next: bool) -> Result - where CS: ConstraintSystem + where + CS: ConstraintSystem, { assert_eq!(input_coeffs.len(), inputs.len()); // corner case: all our values are actually constants - if inputs.iter().all(| x | x.is_constant()) { + if inputs.iter().all(|x| x.is_constant()) { let value = inputs.iter().zip(input_coeffs.iter()).fold(E::Fr::zero(), |acc, (x, coef)| { let mut temp = x.get_value().unwrap(); temp.mul_assign(&coef); @@ -96,14 +87,12 @@ impl NumExtension for Num let mut temp = x.clone(); temp.mul_assign(&coef); constant_term.add_assign(&temp); - }, + } Num::Variable(x) => { - if vars.len() < STATE_WIDTH - { + if vars.len() < STATE_WIDTH { vars.push(x.clone()); coeffs.push(coef.clone()); - } - else { + } else { coeffs.reverse(); vars.reverse(); let tmp = AllocatedNum::quartic_lc_with_cnst(cs, &coeffs[..], &vars[..], &constant_term)?; @@ -123,8 +112,8 @@ impl NumExtension for Num match use_d_next { true => { AllocatedNum::quartic_lc_eq_with_cnst(cs, &coeffs[..], &vars[..], &res_var, &constant_term)?; - return Ok(Num::Variable(res_var)) - }, + return Ok(Num::Variable(res_var)); + } false => { let temp = AllocatedNum::quartic_lc_with_cnst(cs, &coeffs[..], &vars[..], &constant_term)?; constant_term = E::Fr::zero(); @@ -135,7 +124,7 @@ impl NumExtension for Num } // pad with dummy variables - for _i in vars.len()..(STATE_WIDTH-1) { + for _i in vars.len()..(STATE_WIDTH - 1) { vars.push(AllocatedNum::zero(cs)); coeffs.push(E::Fr::zero()); } @@ -144,31 +133,29 @@ impl NumExtension for Num coeffs.push(minus_one); coeffs.reverse(); vars.reverse(); - + AllocatedNum::general_lc_gate(cs, &coeffs[..], &vars[..], &constant_term, &E::Fr::zero(), &dummy)?; Ok(Num::Variable(res_var)) } - fn lc>(cs: &mut CS, input_coeffs: &[E::Fr], inputs: &[Num]) -> Result - { + fn lc>(cs: &mut CS, input_coeffs: &[E::Fr], inputs: &[Num]) -> Result { Self::lc_impl(cs, input_coeffs, inputs, false) } fn lc_with_d_next(cs: &mut CS, input_coeffs: &[E::Fr], inputs: &[Num]) -> Result - where CS: ConstraintSystem + where + CS: ConstraintSystem, { Self::lc_impl(cs, input_coeffs, inputs, true) } // same as lc but with all the coefficients set to be 1 - fn sum>(cs: &mut CS, nums: &[Num]) -> Result - { + fn sum>(cs: &mut CS, nums: &[Num]) -> Result { let coeffs = vec![E::Fr::one(); nums.len()]; Self::lc(cs, &coeffs[..], &nums[..]) } - fn sum_with_d_next>(cs: &mut CS, nums: &[Num]) -> Result - { + fn sum_with_d_next>(cs: &mut CS, nums: &[Num]) -> Result { let coeffs = vec![E::Fr::one(); nums.len()]; Self::lc_with_d_next(cs, &coeffs[..], &nums[..]) } @@ -176,7 +163,8 @@ impl NumExtension for Num // for given array of slices : [x0, x1, x2, ..., xn] of arbitrary length, base n and total accumulated x // validates that x = x0 + x1 * base + x2 * base^2 + ... + xn * base^n fn long_weighted_sum(cs: &mut CS, vars: &[Self], base: &E::Fr) -> Result - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let mut coeffs = Vec::with_capacity(vars.len()); let mut acc = E::Fr::one(); @@ -190,102 +178,34 @@ impl NumExtension for Num } } +trait AllocatedNumExtension: Sized { + fn alloc_from_lc>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], cnst: &E::Fr) -> Result; -trait AllocatedNumExtension : Sized -{ - fn alloc_from_lc>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - cnst: &E::Fr - ) -> Result; - - fn alloc_sum>( - cs: &mut CS, - vars: &[Self], - ) -> Result; - - fn general_lc_gate>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - cnst: &E::Fr, - next_row_coef: &E::Fr, - next_row_var: &Self, - ) -> Result<(), SynthesisError>; - - fn quartic_lc>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - ) -> Result; - - fn quartic_lc_with_cnst>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - cnst: &E::Fr, - ) -> Result; - - fn ternary_lc_eq>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - total: &Self, - ) -> Result<(), SynthesisError>; - - fn quartic_lc_eq>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - total: &Self, - ) -> Result<(), SynthesisError>; - - fn quartic_lc_eq_with_cnst>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - total: &Self, - cnst: &E::Fr, - ) -> Result<(), SynthesisError>; - - fn ternary_lc_with_cnst>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - cnst: &E::Fr, - ) -> Result; - - fn long_lc_eq>( - cs: &mut CS, - vars: &[Self], - coefs: &[E::Fr], - total: &Self, - use_d_next: bool - ) -> Result; - - fn long_weighted_sum_eq>( - cs: &mut CS, - vars: &[Self], - base: &E::Fr, - total: &Self, - use_d_next: bool - ) -> Result; -} + fn alloc_sum>(cs: &mut CS, vars: &[Self]) -> Result; + fn general_lc_gate>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], cnst: &E::Fr, next_row_coef: &E::Fr, next_row_var: &Self) -> Result<(), SynthesisError>; + fn quartic_lc>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self]) -> Result; -impl AllocatedNumExtension for AllocatedNum -{ - fn alloc_from_lc>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - cnst: &E::Fr - ) -> Result - { + fn quartic_lc_with_cnst>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], cnst: &E::Fr) -> Result; + + fn ternary_lc_eq>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], total: &Self) -> Result<(), SynthesisError>; + + fn quartic_lc_eq>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], total: &Self) -> Result<(), SynthesisError>; + + fn quartic_lc_eq_with_cnst>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], total: &Self, cnst: &E::Fr) -> Result<(), SynthesisError>; + + fn ternary_lc_with_cnst>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], cnst: &E::Fr) -> Result; + + fn long_lc_eq>(cs: &mut CS, vars: &[Self], coefs: &[E::Fr], total: &Self, use_d_next: bool) -> Result; + + fn long_weighted_sum_eq>(cs: &mut CS, vars: &[Self], base: &E::Fr, total: &Self, use_d_next: bool) -> Result; +} + +impl AllocatedNumExtension for AllocatedNum { + fn alloc_from_lc>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], cnst: &E::Fr) -> Result { assert_eq!(coefs.len(), vars.len()); - + let new_value = match vars.iter().all(|x| x.get_value().is_some()) { false => None, true => { @@ -296,17 +216,13 @@ impl AllocatedNumExtension for AllocatedNum res.add_assign(&tmp); } Some(res) - }, + } }; Self::alloc(cs, || new_value.grab()) } - fn alloc_sum>( - cs: &mut CS, - vars: &[Self], - ) -> Result - { + fn alloc_sum>(cs: &mut CS, vars: &[Self]) -> Result { let mut coefs = Vec::with_capacity(vars.len()); coefs.extend(iter::repeat(E::Fr::one()).take(vars.len())); Self::alloc_from_lc(cs, &coefs[..], vars, &E::Fr::zero()) @@ -316,22 +232,14 @@ impl AllocatedNumExtension for AllocatedNum // vector of vars: [var0, var1, var2, var3], // next row var and coef: c4 and var4 // and additional constant: cnst - // constrcut the gate asserting that: + // constrcut the gate asserting that: // c0 * var0 + c1 * var1 + c2 * var3 + c4 * var4 + cnst = 0 // here the state is [var0, var1, var2, var3] // and var4 should be placed on the next row with the help of d_next - fn general_lc_gate>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - cnst: &E::Fr, - next_row_coef: &E::Fr, - next_row_var: &Self, - ) -> Result<(), SynthesisError> - { + fn general_lc_gate>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], cnst: &E::Fr, next_row_coef: &E::Fr, next_row_var: &Self) -> Result<(), SynthesisError> { assert_eq!(coefs.len(), vars.len()); assert_eq!(coefs.len(), STATE_WIDTH); - + // check if equality indeed holds // TODO: do it only in debug mde! match (vars[0].get_value(), vars[1].get_value(), vars[2].get_value(), vars[3].get_value(), next_row_var.get_value()) { @@ -358,7 +266,7 @@ impl AllocatedNumExtension for AllocatedNum running_sum.add_assign(&cnst); assert_eq!(running_sum, E::Fr::zero()) } - _ => {}, + _ => {} }; let dummy = Self::zero(cs); @@ -368,7 +276,7 @@ impl AllocatedNumExtension for AllocatedNum for (i, idx) in range_of_linear_terms.enumerate() { local_coeffs[idx] = coefs[i].clone(); } - + let cnst_index = CS::MainGate::index_for_constant_term(); local_coeffs[cnst_index] = *cnst; @@ -378,12 +286,7 @@ impl AllocatedNumExtension for AllocatedNum let mg = CS::MainGate::default(); let local_vars = vec![vars[0].get_variable(), vars[1].get_variable(), vars[2].get_variable(), vars[3].get_variable()]; - cs.new_single_gate_for_trace_step( - &mg, - &local_coeffs, - &local_vars, - &[] - )?; + cs.new_single_gate_for_trace_step(&mg, &local_coeffs, &local_vars, &[])?; Ok(()) } @@ -393,13 +296,7 @@ impl AllocatedNumExtension for AllocatedNum // and additional constant: cnst // allocate new variable res equal to c0 * var0 + c1 * var1 + c2 * var2 + c3 * var3 // assuming res is placed in d register of the next row - fn quartic_lc_with_cnst>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - cnst: &E::Fr, - ) -> Result - { + fn quartic_lc_with_cnst>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], cnst: &E::Fr) -> Result { let res = AllocatedNum::alloc_from_lc(cs, coefs, vars, cnst)?; let mut minus_one = E::Fr::one(); minus_one.negate(); @@ -408,12 +305,7 @@ impl AllocatedNumExtension for AllocatedNum Ok(res) } - fn quartic_lc>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - ) -> Result - { + fn quartic_lc>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self]) -> Result { let zero = E::Fr::zero(); let res = AllocatedNum::alloc_from_lc(cs, coefs, vars, &zero)?; let mut minus_one = E::Fr::one(); @@ -423,40 +315,21 @@ impl AllocatedNumExtension for AllocatedNum Ok(res) } - fn quartic_lc_eq>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - total: &Self, - ) -> Result<(), SynthesisError> - { + fn quartic_lc_eq>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], total: &Self) -> Result<(), SynthesisError> { let mut minus_one = E::Fr::one(); minus_one.negate(); AllocatedNum::general_lc_gate(cs, coefs, vars, &E::Fr::zero(), &minus_one, &total) } - fn quartic_lc_eq_with_cnst>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - total: &Self, - cnst: &E::Fr, - ) -> Result<(), SynthesisError> - { + fn quartic_lc_eq_with_cnst>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], total: &Self, cnst: &E::Fr) -> Result<(), SynthesisError> { let mut minus_one = E::Fr::one(); minus_one.negate(); AllocatedNum::general_lc_gate(cs, coefs, vars, cnst, &minus_one, &total) } - fn ternary_lc_eq>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - total: &Self, - ) -> Result<(), SynthesisError> - { + fn ternary_lc_eq>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], total: &Self) -> Result<(), SynthesisError> { assert_eq!(coefs.len(), vars.len()); - assert_eq!(coefs.len(), STATE_WIDTH-1); + assert_eq!(coefs.len(), STATE_WIDTH - 1); let mut minus_one = E::Fr::one(); minus_one.negate(); @@ -464,26 +337,18 @@ impl AllocatedNumExtension for AllocatedNum let mut local_coefs = vec![]; local_coefs.extend_from_slice(coefs); local_coefs.push(minus_one); - + let mut local_vars = vec![]; local_vars.extend_from_slice(vars); local_vars.push(total.clone()); let dummy = AllocatedNum::zero(cs); - AllocatedNum::general_lc_gate( - cs, &local_coefs[..], &local_vars[..], &E::Fr::zero(), &E::Fr::zero(), &dummy, - ) + AllocatedNum::general_lc_gate(cs, &local_coefs[..], &local_vars[..], &E::Fr::zero(), &E::Fr::zero(), &dummy) } - fn ternary_lc_with_cnst>( - cs: &mut CS, - coefs: &[E::Fr], - vars: &[Self], - cnst: &E::Fr, - ) -> Result - { + fn ternary_lc_with_cnst>(cs: &mut CS, coefs: &[E::Fr], vars: &[Self], cnst: &E::Fr) -> Result { assert_eq!(coefs.len(), vars.len()); - assert_eq!(coefs.len(), STATE_WIDTH-1); + assert_eq!(coefs.len(), STATE_WIDTH - 1); let res = AllocatedNum::alloc_from_lc(cs, coefs, vars, cnst)?; let mut minus_one = E::Fr::one(); @@ -498,24 +363,15 @@ impl AllocatedNumExtension for AllocatedNum local_vars.push(res.clone()); let dummy = AllocatedNum::zero(cs); - AllocatedNum::general_lc_gate( - cs, &local_coefs[..], &local_vars[..], &E::Fr::zero(), &E::Fr::zero(), &dummy - )?; + AllocatedNum::general_lc_gate(cs, &local_coefs[..], &local_vars[..], &E::Fr::zero(), &E::Fr::zero(), &dummy)?; Ok(res) } - fn long_lc_eq>( - cs: &mut CS, - vars: &[Self], - coefs: &[E::Fr], - total: &Self, - use_d_next: bool - ) -> Result - { + fn long_lc_eq>(cs: &mut CS, vars: &[Self], coefs: &[E::Fr], total: &Self, use_d_next: bool) -> Result { let mut loc_coefs = Vec::with_capacity(STATE_WIDTH); let mut loc_vars = Vec::with_capacity(STATE_WIDTH); - + let mut minus_one = E::Fr::one(); minus_one.negate(); let dummy = AllocatedNum::zero(cs); @@ -524,8 +380,7 @@ impl AllocatedNumExtension for AllocatedNum if loc_vars.len() < STATE_WIDTH { loc_coefs.push(coef.clone()); loc_vars.push(var.clone()); - } - else { + } else { // we have filled in the whole vector! loc_coefs.reverse(); loc_vars.reverse(); @@ -539,12 +394,12 @@ impl AllocatedNumExtension for AllocatedNum if loc_vars.len() == STATE_WIDTH { loc_coefs.reverse(); loc_vars.reverse(); - + match use_d_next { true => { AllocatedNum::quartic_lc_eq(cs, &loc_coefs[..], &loc_vars[..], &total)?; - return Ok(true) - }, + return Ok(true); + } false => { // we have filled in the whole vector again! let temp = AllocatedNum::quartic_lc(cs, &loc_coefs[..], &loc_vars[..])?; @@ -552,11 +407,10 @@ impl AllocatedNumExtension for AllocatedNum loc_vars = vec![temp]; } } - } - + // pad with dummy variables - for _i in loc_vars.len()..(STATE_WIDTH-1) { + for _i in loc_vars.len()..(STATE_WIDTH - 1) { loc_vars.push(dummy.clone()); loc_coefs.push(E::Fr::zero()); } @@ -574,18 +428,11 @@ impl AllocatedNumExtension for AllocatedNum // validates that x = x0 + x1 * base + x2 * base^2 + ... + xn * base^n // use_d_next flag allows to place total on the next row, without expicitely constraiting it and leaving // is as a job for the next gate allocation. - fn long_weighted_sum_eq>( - cs: &mut CS, - vars: &[Self], - base: &E::Fr, - total: &Self, - use_d_next: bool - ) -> Result - { + fn long_weighted_sum_eq>(cs: &mut CS, vars: &[Self], base: &E::Fr, total: &Self, use_d_next: bool) -> Result { let mut acc_fr = E::Fr::one(); let mut loc_coefs = Vec::with_capacity(STATE_WIDTH); let mut loc_vars = Vec::with_capacity(STATE_WIDTH); - + let mut minus_one = E::Fr::one(); minus_one.negate(); let dummy = AllocatedNum::zero(cs); @@ -595,8 +442,7 @@ impl AllocatedNumExtension for AllocatedNum loc_coefs.push(acc_fr.clone()); acc_fr.mul_assign(&base); loc_vars.push(var.clone()); - } - else { + } else { // we have filled in the whole vector! loc_coefs.reverse(); loc_vars.reverse(); @@ -604,7 +450,7 @@ impl AllocatedNumExtension for AllocatedNum let temp = AllocatedNum::quartic_lc(cs, &loc_coefs[..], &loc_vars[..])?; loc_coefs = vec![E::Fr::one(), acc_fr.clone()]; loc_vars = vec![temp, var.clone()]; - + acc_fr.mul_assign(&base); } } @@ -612,12 +458,12 @@ impl AllocatedNumExtension for AllocatedNum if loc_vars.len() == STATE_WIDTH { loc_coefs.reverse(); loc_vars.reverse(); - + match use_d_next { true => { AllocatedNum::quartic_lc_eq(cs, &loc_coefs[..], &loc_vars[..], &total)?; - return Ok(true) - }, + return Ok(true); + } false => { // we have filled in the whole vector again! let temp = AllocatedNum::quartic_lc(cs, &loc_coefs[..], &loc_vars[..])?; @@ -625,11 +471,10 @@ impl AllocatedNumExtension for AllocatedNum loc_vars = vec![temp]; } } - } - + // pad with dummy variables - for _i in loc_vars.len()..(STATE_WIDTH-1) { + for _i in loc_vars.len()..(STATE_WIDTH - 1) { loc_vars.push(dummy.clone()); loc_coefs.push(E::Fr::zero()); } @@ -642,4 +487,4 @@ impl AllocatedNumExtension for AllocatedNum AllocatedNum::general_lc_gate(cs, &loc_coefs[..], &loc_vars[..], &E::Fr::zero(), &E::Fr::zero(), &dummy)?; Ok(false) } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/gadgets.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/gadgets.rs index c38f66c..8c4cd5a 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/gadgets.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/gadgets.rs @@ -1,45 +1,38 @@ +use crate::bellman::pairing::ff::*; +use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::plonk::better_better_cs::lookup_tables::*; use crate::bellman::plonk::better_better_cs::utils; -use crate::bellman::pairing::ff::*; -use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; -use crate::bellman::SynthesisError; use crate::bellman::Engine; -use crate::plonk::circuit::allocated_num::{ - AllocatedNum, - Num, -}; +use crate::bellman::SynthesisError; +use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; +use crate::plonk::circuit::assignment::Assignment; use crate::plonk::circuit::bigint_new::biguint_to_fe; -use crate::plonk::circuit::boolean::{Boolean, AllocatedBit}; -use crate::plonk::circuit::byte::{ - Byte, -}; -use crate::plonk::circuit::assignment::{ - Assignment -}; +use crate::plonk::circuit::bigint_new::repr_to_biguint; +use crate::plonk::circuit::boolean::{AllocatedBit, Boolean}; +use crate::plonk::circuit::byte::Byte; use crate::plonk::circuit::custom_5th_degree_gate_optimized::Nonlinearity5CustomGate; use crate::plonk::circuit::custom_rescue_gate::Rescue5CustomGate; -use crate::plonk::circuit::bigint_new::repr_to_biguint; use crate::plonk::circuit::linear_combination::*; -use super::tables::*; -use super::super::utils::*; use super::super::tables::*; -use super::super::{NumExtension, AllocatedNumExtension}; +use super::super::utils::*; +use super::super::{AllocatedNumExtension, NumExtension}; +use super::tables::*; use num_traits::signum; -use sha3::{digest::ExtendableOutput, digest::Update, Sha3XofReader, Shake128, digest::XofReader}; +use sha3::{digest::ExtendableOutput, digest::Update, digest::XofReader, Sha3XofReader, Shake128}; use crate::num_bigint::BigUint; use crate::num_traits::cast::ToPrimitive; -use crate::num_traits::{ Zero, One }; +use crate::num_traits::{One, Zero}; +use std::cmp::Ordering; use std::convert::TryInto; use std::ops::{Index, IndexMut}; -use std::cmp::Ordering; use std::sync::Arc; type Result = std::result::Result; -pub const RC_STATE_WIDTH : usize = 3; +pub const RC_STATE_WIDTH: usize = 3; pub const RC_RATE: usize = 2; pub const RC_PRE_ROUNDS_COUNT: usize = 3; pub const RC_POST_ROUNDS_COUNT: usize = 3; @@ -47,7 +40,6 @@ pub const RC_TOTAL_ROUNDS_COUNT: usize = RC_PRE_ROUNDS_COUNT + RC_POST_ROUNDS_CO pub const RC_ROUND_CONSTS_COUNT: usize = (RC_TOTAL_ROUNDS_COUNT + 1) * RC_STATE_WIDTH; pub const RC_INIT_SHAKE: &'static str = "ReinforcedConcrete"; - #[derive(Clone)] pub struct RCState([Num; RC_STATE_WIDTH]); @@ -84,22 +76,20 @@ impl IndexMut for RCState { } } - pub struct DecomposedNum { pub in_chunks: Vec>, pub out_chunks: Vec>, pub state_trns: Vec>, - pub ge_p_flags: Vec> -} - + pub ge_p_flags: Vec>, +} #[derive(Clone)] -pub struct ReinforcementConcreteGadget{ +pub struct ReinforcementConcreteGadget { // used tables rc_helper_table0: Arc>, rc_helper_table1: Arc>, - // constants + // constants alphas: [E::Fr; 2], betas: [E::Fr; 2], p_prime: u16, @@ -117,24 +107,18 @@ pub struct ReinforcementConcreteGadget{ impl ReinforcementConcreteGadget { pub fn new, F: Fn(u16) -> u16>( - cs: &mut CS, alphas: [E::Fr; 2], betas: [E::Fr; 2], p_prime: u16, s_arr: Vec, - perm_f: F, use_optimized_fifth_power: bool, - ) -> Result - { - let columns3 = vec![ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2) - ]; + cs: &mut CS, + alphas: [E::Fr; 2], + betas: [E::Fr; 2], + p_prime: u16, + s_arr: Vec, + perm_f: F, + use_optimized_fifth_power: bool, + ) -> Result { + let columns3 = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; let name0: &'static str = "rc_helper_table0"; - let rc_helper_table0 = LookupTableApplication::new( - name0, - ReinforcementConcreterHelperTable0::new(name0), - columns3.clone(), - None, - true - ); + let rc_helper_table0 = LookupTableApplication::new(name0, ReinforcementConcreterHelperTable0::new(name0), columns3.clone(), None, true); let rc_helper_table0 = cs.add_table(rc_helper_table0)?; // we are going to check that \prod s_i >= E::Fr::modulus @@ -159,13 +143,7 @@ impl ReinforcementConcreteGadget { b_arr.reverse(); let name1: &'static str = "rc_helper_table1"; - let rc_helper_table1 = LookupTableApplication::new( - name1, - ReinforcementConcreterHelperTable1::new(p_prime, perm_f, &s_arr, &u_arr, name1), - columns3.clone(), - None, - true - ); + let rc_helper_table1 = LookupTableApplication::new(name1, ReinforcementConcreterHelperTable1::new(p_prime, perm_f, &s_arr, &u_arr, name1), columns3.clone(), None, true); let rc_helper_table1 = cs.add_table(rc_helper_table1)?; // initialize MDS matrix: @@ -195,33 +173,36 @@ impl ReinforcementConcreteGadget { let mod_ = E::Fr::NUM_BITS % 8; let mask = if mod_ == 0 { 0xFF } else { (1u8 << mod_) - 1 }; - let round_constants : [E::Fr; RC_ROUND_CONSTS_COUNT] = ( - 0..RC_ROUND_CONSTS_COUNT - ).map(|_| { - let mut buf = vec![0u8; bytes]; - let mut word_buf = vec![0u64; words]; - let len = buf.len(); - - loop { - reader.read(&mut buf); - buf[len - 1] &= mask; - for i in 0..words { - let mut byte_array = [0u8; 8]; - for j in i * 8..std::cmp::min((i + 1) * 8, len) { - byte_array[j - i * 8] = buf[j]; + let round_constants: [E::Fr; RC_ROUND_CONSTS_COUNT] = (0..RC_ROUND_CONSTS_COUNT) + .map(|_| { + let mut buf = vec![0u8; bytes]; + let mut word_buf = vec![0u64; words]; + let len = buf.len(); + + loop { + reader.read(&mut buf); + buf[len - 1] &= mask; + for i in 0..words { + let mut byte_array = [0u8; 8]; + for j in i * 8..std::cmp::min((i + 1) * 8, len) { + byte_array[j - i * 8] = buf[j]; + } + word_buf[i] = u64::from_le_bytes(byte_array); } - word_buf[i] = u64::from_le_bytes(byte_array); - } - let mut tmp = ::Repr::default(); - tmp.as_mut().copy_from_slice(&word_buf); - let res = E::Fr::from_repr(tmp); + let mut tmp = ::Repr::default(); + tmp.as_mut().copy_from_slice(&word_buf); + let res = E::Fr::from_repr(tmp); - if let Ok(el) = res { - break el + if let Ok(el) = res { + break el; + } } - } - }).collect::>().as_slice().try_into().unwrap(); + }) + .collect::>() + .as_slice() + .try_into() + .unwrap(); Ok(ReinforcementConcreteGadget { rc_helper_table0, @@ -236,7 +217,7 @@ impl ReinforcementConcreteGadget { mds_matrix, round_constants, state: RCState::default(), - num_squeezed: 0 + num_squeezed: 0, }) } @@ -248,90 +229,66 @@ impl ReinforcementConcreteGadget { result.square(); result.mul_assign(constant); Num::Constant(result) - }, + } Num::Variable(var) => { let fifth_power_var = if self.use_optimized_fifth_power { - let third = AllocatedNum::alloc( - cs, - || { - let val = *var.get_value().get()?; - let mut tmp = val; - tmp.square(); - tmp.mul_assign(&val); - Ok(tmp) - } - )?; - - let fifth = AllocatedNum::alloc( - cs, - || { - let third = *third.get_value().get()?; - let val = *var.get_value().get()?; - let mut tmp = val; - tmp.square(); - tmp.mul_assign(&third); - - Ok(tmp) - } - )?; - - cs.new_single_gate_for_trace_step( - &Nonlinearity5CustomGate::default(), - &[], - &[var.get_variable(), third.get_variable(), fifth.get_variable()], - &[] - )?; - + let third = AllocatedNum::alloc(cs, || { + let val = *var.get_value().get()?; + let mut tmp = val; + tmp.square(); + tmp.mul_assign(&val); + Ok(tmp) + })?; + + let fifth = AllocatedNum::alloc(cs, || { + let third = *third.get_value().get()?; + let val = *var.get_value().get()?; + let mut tmp = val; + tmp.square(); + tmp.mul_assign(&third); + + Ok(tmp) + })?; + + cs.new_single_gate_for_trace_step(&Nonlinearity5CustomGate::default(), &[], &[var.get_variable(), third.get_variable(), fifth.get_variable()], &[])?; + fifth - } - else { - let squared = AllocatedNum::alloc( - cs, - || { - let mut val = *var.get_value().get()?; - val.square(); - Ok(val) - } - )?; - - let quad = AllocatedNum::alloc( - cs, - || { - let mut val = *squared.get_value().get()?; - val.square(); - Ok(val) - } - )?; - - let fifth = AllocatedNum::alloc( - cs, - || { - let mut val = *quad.get_value().get()?; - val.mul_assign(var.get_value().get()?); - - Ok(val) - } - )?; - + } else { + let squared = AllocatedNum::alloc(cs, || { + let mut val = *var.get_value().get()?; + val.square(); + Ok(val) + })?; + + let quad = AllocatedNum::alloc(cs, || { + let mut val = *squared.get_value().get()?; + val.square(); + Ok(val) + })?; + + let fifth = AllocatedNum::alloc(cs, || { + let mut val = *quad.get_value().get()?; + val.mul_assign(var.get_value().get()?); + + Ok(val) + })?; + let one = E::Fr::one(); let mut minus_one = one; minus_one.negate(); - + cs.new_single_gate_for_trace_step( - &Rescue5CustomGate::default(), - &[], - &[ - var.get_variable(), squared.get_variable(), - quad.get_variable(), fifth.get_variable() - ], - &[] + &Rescue5CustomGate::default(), + &[], + &[var.get_variable(), squared.get_variable(), quad.get_variable(), fifth.get_variable()], + &[], )?; - + fifth }; Num::Variable(fifth_power_var) - }, + } }; Ok(res) @@ -339,7 +296,8 @@ impl ReinforcementConcreteGadget { // compute y = x^2 + a x + b fn compute_quadratic_term(cs: &mut CS, x: &Num, alpha: &E::Fr, beta: &E::Fr) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let res = match x { Num::Constant(constant) => { @@ -350,11 +308,9 @@ impl ReinforcementConcreteGadget { res.add_assign(beta); res.add_assign(&x_squared); Num::Constant(res) - }, + } Num::Variable(var) => { - let quadratic_term = { - ArithmeticTerm::from_variable(var.variable).mul_by_variable(var.variable) - }; + let quadratic_term = { ArithmeticTerm::from_variable(var.variable).mul_by_variable(var.variable) }; let linear_term = ArithmeticTerm::from_variable_and_coeff(var.variable, alpha.clone()); let cnst_term = ArithmeticTerm::constant(beta.clone()); @@ -369,7 +325,7 @@ impl ReinforcementConcreteGadget { Ok(res) })?; let res_term = ArithmeticTerm::from_variable(res_var.variable); - + let mut gate = MainGateTerm::new(); gate.add_assign(quadratic_term); gate.add_assign(linear_term); @@ -378,14 +334,13 @@ impl ReinforcementConcreteGadget { cs.allocate_main_gate(gate)?; Num::Variable(res_var) - }, + } }; Ok(res) } - fn bricks>(&mut self, cs: &mut CS) -> Result<()> - { + fn bricks>(&mut self, cs: &mut CS) -> Result<()> { // Bricks(x_1, x_2, x_3) = (x_1^5, x_2 * (x_1^2 + a1 * x1 + b1), x_3 * (x_2^2 + a2 * x2 + b2)) // Bricks is encoded as the following set of constraints: // y_1 = x_1 ^ 5 (using custom gate) @@ -411,12 +366,9 @@ impl ReinforcementConcreteGadget { Ok(()) } - fn concrete>(&mut self, cs: &mut CS, round: usize) -> Result<()> - { + fn concrete>(&mut self, cs: &mut CS, round: usize) -> Result<()> { let mut new_state = RCState::default(); - let iter = self.mds_matrix.iter().zip( - self.round_constants[3 * round..3*(round+1)].iter()).zip(new_state.0.iter_mut() - ); + let iter = self.mds_matrix.iter().zip(self.round_constants[3 * round..3 * (round + 1)].iter()).zip(new_state.0.iter_mut()); for ((row, cnst), out) in iter { let mut lc = LinearCombination::zero(); for (coef, num) in row.iter().zip(self.state.0.iter()) { @@ -431,20 +383,13 @@ impl ReinforcementConcreteGadget { } fn wrap_fr_by_num(cs: &mut CS, val: E::Fr, is_const: bool, has_value: bool) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let res = if is_const { Num::Constant(val) - } - else { - let var = AllocatedNum::alloc(cs, || { - if has_value { - Ok(val) - } - else { - Err(SynthesisError::AssignmentMissing) - } - })?; + } else { + let var = AllocatedNum::alloc(cs, || if has_value { Ok(val) } else { Err(SynthesisError::AssignmentMissing) })?; Num::Variable(var) }; @@ -452,7 +397,8 @@ impl ReinforcementConcreteGadget { } fn wrap_int_by_num(cs: &mut CS, val: u16, is_const: bool, has_value: bool) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let fr = u64_to_ff(val as u64); Self::wrap_fr_by_num(cs, fr, is_const, has_value) @@ -463,7 +409,7 @@ impl ReinforcementConcreteGadget { let has_value = num.get_value().is_some(); let value = num.get_value().unwrap_or(E::Fr::zero()); let table = self.rc_helper_table1.clone(); - + let len = self.s_arr.len(); let mut in_chunks = Vec::with_capacity(len); let mut out_chunks = Vec::with_capacity(len); @@ -478,12 +424,11 @@ impl ReinforcementConcreteGadget { let ge_p_flag = (in_chunk >= self.p_prime) as u16 + is_first as u16; ge_p_flags.push(Self::wrap_int_by_num(cs, ge_p_flag, is_const, has_value)?); - let out_chunk = if in_chunk < self.p_prime { + let out_chunk = if in_chunk < self.p_prime { let keys = [u64_to_ff::(in_chunk as u64), E::Fr::one()]; let vals = table.query(&keys[..])?; vals[0] - } - else { + } else { u64_to_ff::(in_chunk as u64) }; out_chunks.push(Self::wrap_fr_by_num(cs, out_chunk, is_const, has_value)?) @@ -512,62 +457,52 @@ impl ReinforcementConcreteGadget { state_trns.push(Self::wrap_int_by_num(cs, trn, is_const, has_value)?); } - let in_chunks : Vec> = in_chunks.into_iter().rev().map(|x| { - Self::wrap_int_by_num(cs, x, is_const, has_value) - }).collect::>>()?; + let in_chunks: Vec> = in_chunks.into_iter().rev().map(|x| Self::wrap_int_by_num(cs, x, is_const, has_value)).collect::>>()?; Ok(DecomposedNum { in_chunks, out_chunks, state_trns, - ge_p_flags + ge_p_flags, }) } - // apply rc_table0 to the row [a, b, c, d] + // apply rc_table0 to the row [a, b, c, d] // alongside with the the following main gate: // if !is_final: // d = c * cnst + a // else: // d = (b - 1) * cnst + a = b * cnst - cnst + a // return computed d - fn apply_table0>( - &self, cs: &mut CS, a: &AllocatedNum, b: &AllocatedNum, c: &AllocatedNum, - cnst: &E::Fr, is_final: bool, - ) -> Result> - { + fn apply_table0>(&self, cs: &mut CS, a: &AllocatedNum, b: &AllocatedNum, c: &AllocatedNum, cnst: &E::Fr, is_final: bool) -> Result> { let table = self.rc_helper_table0.clone(); let mut minus_one = E::Fr::one(); minus_one.negate(); let dummy = AllocatedNum::zero(cs).get_variable(); let range_of_linear_terms = CS::MainGate::range_of_linear_terms(); - let cnst_term_idx = CS::MainGate:: index_for_constant_term(); + let cnst_term_idx = CS::MainGate::index_for_constant_term(); let d = match (a.get_value(), b.get_value(), c.get_value()) { - (Some(a_val), Some(b_val), Some(c_val)) => { - AllocatedNum::alloc(cs, || { - let mut res = if is_final { - let mut x = b_val; - x.sub_assign(&E::Fr::one()); - x - } - else { - c_val - }; - res.mul_assign(&cnst); - res.add_assign(&a_val); + (Some(a_val), Some(b_val), Some(c_val)) => AllocatedNum::alloc(cs, || { + let mut res = if is_final { + let mut x = b_val; + x.sub_assign(&E::Fr::one()); + x + } else { + c_val + }; + res.mul_assign(&cnst); + res.add_assign(&a_val); - Ok(res) - })? - }, + Ok(res) + })?, (_, _, _) => AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?, }; - + let vars = [a.get_variable(), b.get_variable(), c.get_variable(), d.get_variable()]; let coeffs = if is_final { [E::Fr::one(), cnst.clone(), E::Fr::zero(), minus_one.clone()] - } - else { + } else { [E::Fr::one(), E::Fr::zero(), cnst.clone(), minus_one.clone()] }; let cnst_term = if is_final { @@ -576,8 +511,8 @@ impl ReinforcementConcreteGadget { x } else { E::Fr::zero() - }; - + }; + cs.begin_gates_batch_for_step()?; cs.apply_single_lookup_gate(&vars[..table.width()], table.clone())?; @@ -587,7 +522,7 @@ impl ReinforcementConcreteGadget { gate_coefs[idx] = *coef; } gate_coefs[cnst_term_idx] = cnst_term; - + let mg = CS::MainGate::default(); cs.new_gate_in_batch(&mg, &gate_coefs, &vars, &[])?; cs.end_gates_batch_for_step()?; @@ -602,10 +537,15 @@ impl ReinforcementConcreteGadget { // if is_final is set, simply check: acc = coef * x // returns updated accumulator fn apply_table1_acc>( - &self, cs: &mut CS, x: &AllocatedNum, sig_seq: &AllocatedNum, y: &AllocatedNum, - acc: &mut AllocatedNum, coef: &E::Fr, is_final: bool - ) -> Result<()> - { + &self, + cs: &mut CS, + x: &AllocatedNum, + sig_seq: &AllocatedNum, + y: &AllocatedNum, + acc: &mut AllocatedNum, + coef: &E::Fr, + is_final: bool, + ) -> Result<()> { let new_acc = if !is_final { AllocatedNum::alloc(cs, || { let mut res = acc.get_value().grab()?; @@ -614,8 +554,7 @@ impl ReinforcementConcreteGadget { res.sub_assign(&tmp); Ok(res) })? - } - else { + } else { AllocatedNum::zero(cs) }; @@ -635,7 +574,7 @@ impl ReinforcementConcreteGadget { cs.begin_gates_batch_for_step()?; cs.apply_single_lookup_gate(&vars[..table.width()], table.clone())?; - + let gate_term = MainGateTerm::new(); let (_, mut gate_coefs) = CS::MainGate::format_term(gate_term, dummy)?; @@ -647,12 +586,7 @@ impl ReinforcementConcreteGadget { } let mg = CS::MainGate::default(); - cs.new_gate_in_batch( - &mg, - &gate_coefs, - &vars, - &[] - )?; + cs.new_gate_in_batch(&mg, &gate_coefs, &vars, &[])?; cs.end_gates_batch_for_step()?; @@ -663,13 +597,12 @@ impl ReinforcementConcreteGadget { fn bars>(&mut self, cs: &mut CS) -> Result<()> { let mut new_state = RCState::default(); let len = self.s_arr.len(); - + for (in_elem, out_elem) in self.state.0.iter().cloned().zip(new_state.0.iter_mut()) { - let decomposed_num = self.decompose(cs, &in_elem)?; if !in_elem.is_constant() { - // apply all tables invocations for all indexes i (except the last one): - // [trn_i, trn_(i+1), z_i, siq_seq_i], alongside with additional gate: + // apply all tables invocations for all indexes i (except the last one): + // [trn_i, trn_(i+1), z_i, siq_seq_i], alongside with additional gate: // sig_seq_i = z_i * DIGIT_SEP * (i+1) + trn_i, where DIGIT_SEP * (i+1) is a constant // the last row is however of the form: // [trn_n, z_n, trn_0, sig_seq_n] with additional gate being: @@ -681,11 +614,8 @@ impl ReinforcementConcreteGadget { // trn_n = 0 => in_chunk_n == u_n => chunk_n > p_prime => z_n = 1 let mut signal_sequence = Vec::with_capacity(len); let mut idx = 0; - let iter = { - decomposed_num.state_trns.windows(2).zip(decomposed_num.ge_p_flags.iter()) - }; - for (window, z) in iter - { + let iter = { decomposed_num.state_trns.windows(2).zip(decomposed_num.ge_p_flags.iter()) }; + for (window, z) in iter { idx += 1; let trn = window[0].get_variable(); let trn_next = window[1].get_variable(); @@ -693,7 +623,7 @@ impl ReinforcementConcreteGadget { let signal = self.apply_table0(cs, &trn, &trn_next, &z.get_variable(), &cnst, false)?; signal_sequence.push(signal); } - + // deal with the last row // [trn_n, z_n, trn_0, sig_seq_n] with additional gate being: // sig_seq_n = (z_n - 1) * DIGIT_SEP * (n+1) + trn_n @@ -704,22 +634,16 @@ impl ReinforcementConcreteGadget { let cnst = u64_to_ff::((DIGIT_SEP * idx) as u64); let signal = self.apply_table0(cs, &last_trn, &z, &first_trn, &cnst, true)?; signal_sequence.push(signal); - + let mut acc = in_elem.get_variable(); - let iter = itertools::multizip( - (&decomposed_num.in_chunks, &decomposed_num.out_chunks, &signal_sequence, &self.b_arr) - ).identify_first_last(); + let iter = itertools::multizip((&decomposed_num.in_chunks, &decomposed_num.out_chunks, &signal_sequence, &self.b_arr)).identify_first_last(); for (_is_first, is_last, (in_chunk, out_chunk, sig_seq, coef)) in iter { - self.apply_table1_acc( - cs, &in_chunk.get_variable(), &sig_seq, &out_chunk.get_variable(), - &mut acc, &coef, is_last - )?; + self.apply_table1_acc(cs, &in_chunk.get_variable(), &sig_seq, &out_chunk.get_variable(), &mut acc, &coef, is_last)?; } } - + *out_elem = Num::lc(cs, &self.b_arr[..], &decomposed_num.out_chunks[..])?; - } self.state = new_state; @@ -740,12 +664,11 @@ impl ReinforcementConcreteGadget { self.bars(cs)?; self.concrete(cs, RC_PRE_ROUNDS_COUNT + 1)?; // final rounds - for i in RC_PRE_ROUNDS_COUNT + 2..=RC_TOTAL_ROUNDS_COUNT - { + for i in RC_PRE_ROUNDS_COUNT + 2..=RC_TOTAL_ROUNDS_COUNT { self.bricks(cs)?; self.concrete(cs, i)?; } - + Ok(()) } @@ -764,8 +687,7 @@ impl ReinforcementConcreteGadget { Ok(res) } - pub fn absorb>(&mut self, cs: &mut CS, elems_to_absorb: &[Num]) -> Result<()> - { + pub fn absorb>(&mut self, cs: &mut CS, elems_to_absorb: &[Num]) -> Result<()> { assert!(elems_to_absorb.len() <= RC_RATE); for (state, elem_to_absorb) in self.state.0.iter_mut().zip(elems_to_absorb.iter()) { *state = state.add(cs, elem_to_absorb)?; @@ -776,4 +698,4 @@ impl ReinforcementConcreteGadget { pub fn get_cur_state(&self) -> [Num; RC_STATE_WIDTH] { self.state.0.clone() } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/hasher.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/hasher.rs index 3431b38..2d1e87d 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/hasher.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/hasher.rs @@ -1,13 +1,12 @@ -use std::sync::Arc; +use super::utils; +use crate::bellman::pairing::bls12_381::Bls12; +use crate::bellman::pairing::bn256::Bn256; use crate::bellman::pairing::ff::*; use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; use crate::bellman::Engine; -use crate::sha3::{digest::ExtendableOutput, digest::Update, Sha3XofReader, Shake128}; -use crate::bellman::pairing::bn256::Bn256; -use crate::bellman::pairing::bls12_381::Bls12; use crate::lazy_static::lazy_static; -use super::utils; - +use crate::sha3::{digest::ExtendableOutput, digest::Update, Sha3XofReader, Shake128}; +use std::sync::Arc; #[derive(Clone, Debug)] pub struct ReinforcedConcreteParams { @@ -61,7 +60,7 @@ impl ReinforcedConcreteParams { norm_shift_i, sbox: Self::pad_sbox(sbox, si), d, - p_prime + p_prime, } } @@ -89,13 +88,7 @@ impl ReinforcedConcreteParams { } fn instantiate_rc(shake: &mut Sha3XofReader) -> Vec> { - (0..=Self::TOTAL_ROUNDS) - .map(|_| { - (0..Self::T) - .map(|_| utils::field_element_from_shake(shake)) - .collect() - }) - .collect() + (0..=Self::TOTAL_ROUNDS).map(|_| (0..Self::T).map(|_| utils::field_element_from_shake(shake)).collect()).collect() } pub fn get_t(&self) -> usize { @@ -107,7 +100,6 @@ impl ReinforcedConcreteParams { } } - #[derive(Clone, Debug)] pub struct ReinforcedConcrete { pub(crate) params: Arc>, @@ -116,9 +108,7 @@ pub struct ReinforcedConcrete { impl ReinforcedConcrete { pub fn new(params: &Arc>) -> Self { debug_assert!(ReinforcedConcreteParams::::T == 3); - ReinforcedConcrete { - params: Arc::clone(params), - } + ReinforcedConcrete { params: Arc::clone(params) } } pub fn concrete(&self, state: &mut [F; 3], round: usize) { @@ -127,10 +117,7 @@ impl ReinforcedConcrete { let mut sum = state[0]; state.iter().skip(1).for_each(|el| sum.add_assign(el)); - for (el, rc) in state - .iter_mut() - .zip(self.params.round_constants[round].iter()) - { + for (el, rc) in state.iter_mut().zip(self.params.round_constants[round].iter()) { el.add_assign(&sum); el.add_assign(rc); // add round constant } @@ -180,12 +167,7 @@ impl ReinforcedConcrete { let mut repr = val.into_repr(); for i in (1..self.params.si.len()).rev() { - let (r, m) = utils::divide_long_using_recip::( - &repr, - self.params.divisor_i[i], - self.params.reciprokal_i[i], - self.params.norm_shift_i[i], - ); + let (r, m) = utils::divide_long_using_recip::(&repr, self.params.divisor_i[i], self.params.reciprokal_i[i], self.params.norm_shift_i[i]); repr = r; res[i] = m; } @@ -196,10 +178,7 @@ impl ReinforcedConcrete { if cfg!(debug_assertions) { let repr_ref = repr.as_ref(); debug_assert!(repr_ref[0] < self.params.si[0] as u64); - repr_ref - .iter() - .skip(1) - .for_each(|el| debug_assert!(*el == 0)); + repr_ref.iter().skip(1).for_each(|el| debug_assert!(*el == 0)); } res @@ -245,16 +224,11 @@ impl ReinforcedConcrete { } // bar round - current_state = self.bars(¤t_state); - self.concrete( - &mut current_state, - ReinforcedConcreteParams::::PRE_ROUNDS + 1, - ); + current_state = self.bars(¤t_state); + self.concrete(&mut current_state, ReinforcedConcreteParams::::PRE_ROUNDS + 1); // final rounds - for i in ReinforcedConcreteParams::::PRE_ROUNDS + 2 - ..=ReinforcedConcreteParams::::TOTAL_ROUNDS - { + for i in ReinforcedConcreteParams::::PRE_ROUNDS + 2..=ReinforcedConcreteParams::::TOTAL_ROUNDS { current_state = self.bricks(¤t_state); self.concrete(&mut current_state, i); } @@ -275,7 +249,6 @@ impl ReinforcedConcrete { } } - lazy_static! { // BLS12 pub static ref BLS12_SI: Vec = vec![ @@ -370,8 +343,7 @@ lazy_static! { Arc::new(ReinforcedConcreteParams::new(5, &BN256_SI, &BN256_SBOX, BN256_AB.as_ref())); } - -pub trait DefaultRcParams : Engine { +pub trait DefaultRcParams: Engine { fn get_default_rc_params() -> Arc::Fr>>; } @@ -386,4 +358,3 @@ impl DefaultRcParams for Bls12 { RC_BLS_PARAMS.clone() } } - diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/mod.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/mod.rs index 31a7c78..0a95cd2 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/mod.rs @@ -1,5 +1,5 @@ -pub mod tables; pub mod gadgets; -pub mod utils; pub mod hasher; -pub mod test; \ No newline at end of file +pub mod tables; +pub mod test; +pub mod utils; diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/tables.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/tables.rs index 4ded2a6..7ee5cc6 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/tables.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/tables.rs @@ -1,13 +1,12 @@ +use super::super::utils::*; +use crate::bellman::pairing::ff::*; use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::plonk::better_better_cs::lookup_tables::*; use crate::bellman::plonk::better_better_cs::utils; -use crate::bellman::pairing::ff::*; -use crate::bellman::SynthesisError; use crate::bellman::Engine; -use super::super::utils::*; -use std::iter::FromIterator; +use crate::bellman::SynthesisError; use itertools::Itertools; - +use std::iter::FromIterator; pub const DIGIT_SEP: usize = 3; @@ -18,7 +17,7 @@ pub const DIGIT_SEP: usize = 3; // // |<-----| |<-----| |<-------| // | | | | | | -// |--->[ 0 ]----|--->[ 1 ]<----|----->[ 2 ] +// |--->[ 0 ]----|--->[ 1 ]<----|----->[ 2 ] // // the only valid state transitions are: 0 -> 0, 0 -> 1, 1 -> 1, 1 -> 2, 2 -> 1, 2 -> 2 #[derive(Clone)] @@ -31,21 +30,18 @@ pub struct ReinforcementConcreterHelperTable0 { impl ReinforcementConcreterHelperTable0 { pub fn new(name: &'static str) -> Self { - let valid_state_transitions = std::collections::HashSet::<_>::from_iter(std::array::IntoIter::new( - [(0, 0), (0, 1), (1, 1), (1, 2), (2, 1), (2, 2)]).map( - |(x, y)| (u64_to_ff::(x), u64_to_ff::(y)) - ) - ); + let valid_state_transitions = + std::collections::HashSet::<_>::from_iter(std::array::IntoIter::new([(0, 0), (0, 1), (1, 1), (1, 2), (2, 1), (2, 2)]).map(|(x, y)| (u64_to_ff::(x), u64_to_ff::(y)))); let table_len = valid_state_transitions.len() * 2; let mut column0 = Vec::with_capacity(table_len); let mut column1 = Vec::with_capacity(table_len); let mut column2 = Vec::with_capacity(table_len); - let iter = valid_state_transitions.iter().cartesian_product(std::array::IntoIter::new([ - E::Fr::zero(), E::Fr::one() - ])); + let iter = valid_state_transitions.iter().cartesian_product(std::array::IntoIter::new([E::Fr::zero(), E::Fr::one()])); for ((s0, s1), z) in iter { - column0.push(s0.clone()); column1.push(s1.clone()); column2.push(z.clone()); + column0.push(s0.clone()); + column1.push(s1.clone()); + column2.push(z.clone()); } Self { @@ -101,7 +97,7 @@ impl LookupTableInternal for ReinforcementConcreterHelperTable0 let check_booleanity = |fr: &E::Fr| -> bool { (*fr == E::Fr::zero()) || (*fr == E::Fr::one()) }; let trns = (keys[0].clone(), keys[1].clone()); - self.valid_state_transitions.contains(&trns) && check_booleanity(&keys[2]) + self.valid_state_transitions.contains(&trns) && check_booleanity(&keys[2]) } fn query(&self, _keys: &[E::Fr]) -> Result, SynthesisError> { @@ -109,12 +105,11 @@ impl LookupTableInternal for ReinforcementConcreterHelperTable0 } } - // Special ReinForcement Concrete table has the following column structure: | x | sig_seq | f(x) | // where x is, roughly speaking, is the input of S_box (for Bars round), f(x) is the result of S box -// and signal sequence is auxiliary number which indicates both the index of the current S_box and +// and signal sequence is auxiliary number which indicates both the index of the current S_box and // tracks the elements of x, s.t. x < p -// each S_box S_i is associated with unique modulus s_i, s.t. p < s_i, +// each S_box S_i is associated with unique modulus s_i, s.t. p < s_i, // and S_i(x) = f(x), if x < p, and x othersiwe // these means that all S boxes operate identiacally on the subset of x < p, a // the actual tables for the table are the following: @@ -133,10 +128,7 @@ pub struct ReinforcementConcreterHelperTable1 { } impl ReinforcementConcreterHelperTable1 { - pub fn new u16>( - p: u16, perm_f: F, s_arr: &[u16], u_arr: &[u16], name: &'static str - ) -> Self - { + pub fn new u16>(p: u16, perm_f: F, s_arr: &[u16], u_arr: &[u16], name: &'static str) -> Self { let mut table_len = (p + s_arr.iter().map(|s| *s - p).sum::()) as usize; table_len -= (s_arr[0] - u_arr[0]) as usize; @@ -149,8 +141,10 @@ impl ReinforcementConcreterHelperTable1 { let x_fr = u64_to_ff::(x as u64); let y_fr = E::Fr::one(); let z_fr = u64_to_ff::(perm_f(x) as u64); - - column0.push(x_fr); column1.push(y_fr); column2.push(z_fr); + + column0.push(x_fr); + column1.push(y_fr); + column2.push(z_fr); map.insert((x_fr, y_fr), z_fr); } @@ -163,30 +157,36 @@ impl ReinforcementConcreterHelperTable1 { // (x_i | i * DIGIT_SEP + 2 | x_i) for x in p..*u_i { let x = u64_to_ff::(x as u64); - let y = u64_to_ff::(((i+1) * DIGIT_SEP + 1) as u64); + let y = u64_to_ff::(((i + 1) * DIGIT_SEP + 1) as u64); let z = x.clone(); - column0.push(x); column1.push(y); column2.push(z); + column0.push(x); + column1.push(y); + column2.push(z); map.insert((x, y), z); } let x = u64_to_ff::(*u_i as u64); - let y = u64_to_ff::(((i+1) * DIGIT_SEP + 0) as u64); + let y = u64_to_ff::(((i + 1) * DIGIT_SEP + 0) as u64); let z = x.clone(); - column0.push(x); column1.push(y); column2.push(z); + column0.push(x); + column1.push(y); + column2.push(z); map.insert((x, y), z); if i == 0 { - continue + continue; } for x in *u_i..*s_i { let x = u64_to_ff::(x as u64); - let y = u64_to_ff::(((i+1) * DIGIT_SEP + 2) as u64); + let y = u64_to_ff::(((i + 1) * DIGIT_SEP + 2) as u64); let z = x.clone(); - column0.push(x); column1.push(y); column2.push(z); + column0.push(x); + column1.push(y); + column2.push(z); map.insert((x, y), z); } } @@ -252,9 +252,9 @@ impl LookupTableInternal for ReinforcementConcreterHelperTable1 assert!(keys.len() == self.num_keys()); if let Some(entry) = self.table_lookup_map.get(&(keys[0], keys[1])) { - return Ok(vec![*entry]) + return Ok(vec![*entry]); } Err(SynthesisError::Unsatisfiable) } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/test.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/test.rs index 2c970c6..a7701ac 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/test.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/test.rs @@ -1,30 +1,24 @@ #[cfg(test)] mod test { - use std::sync::Arc; - use crate::bellman::plonk::better_better_cs::cs::*; + use crate::bellman::pairing::bls12_381::Bls12; + use crate::bellman::pairing::bn256::Bn256; use crate::bellman::pairing::ff::*; - use crate::bellman::SynthesisError; + use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::Engine; - use crate::plonk::circuit::allocated_num::{ - AllocatedNum, - Num, - }; - use crate::plonk::circuit::byte::{ - Byte, - }; - use crate::bellman::pairing::bn256::Bn256; - use crate::bellman::pairing::bls12_381::Bls12; + use crate::bellman::SynthesisError; + use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; + use crate::plonk::circuit::byte::Byte; + use std::sync::Arc; use super::super::gadgets::*; - use super::super::utils::*; use super::super::hasher::*; + use super::super::utils::*; use crate::plonk::circuit::custom_rescue_gate::Rescue5CustomGate; use rand::{Rng, SeedableRng, StdRng}; - use std::time::SystemTime; use std::convert::TryInto; + use std::time::SystemTime; - - struct TestReinforcementConcreteCircuit{ + struct TestReinforcementConcreteCircuit { input: [E::Fr; RC_STATE_WIDTH], output: [E::Fr; RC_STATE_WIDTH], elems_to_absorb: [E::Fr; RC_RATE], @@ -32,55 +26,39 @@ mod test { is_const_test: bool, } - impl Circuit for TestReinforcementConcreteCircuit - { + impl Circuit for TestReinforcementConcreteCircuit { type MainGate = Width4MainGateWithDNext; - fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Width4MainGateWithDNext::default().into_internal(), - Rescue5CustomGate::default().into_internal(), - ] - ) + fn declare_used_gates() -> Result>>, SynthesisError> { + Ok(vec![Width4MainGateWithDNext::default().into_internal(), Rescue5CustomGate::default().into_internal()]) } fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let mut actual_output_vars = Vec::with_capacity(RC_STATE_WIDTH); for value in self.output.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc_input(cs, || Ok(value.clone()))?; actual_output_vars.push(Num::Variable(new_var)); - } - else { + } else { actual_output_vars.push(Num::Constant(value.clone())); } } - let alphas : [E::Fr; 2] = { - self.params.alphas.iter().map(|x| from_u64::(*x as u64)) - .collect::>().try_into().unwrap() - }; + let alphas: [E::Fr; 2] = { self.params.alphas.iter().map(|x| from_u64::(*x as u64)).collect::>().try_into().unwrap() }; let betas = self.params.betas.clone(); let s_arr = self.params.si.clone(); let p_prime = self.params.p_prime; - let perm_f = |x: u16| -> u16 { - self.params.sbox[x as usize] - }; + let perm_f = |x: u16| -> u16 { self.params.sbox[x as usize] }; - let mut rc_gadget = ReinforcementConcreteGadget::new( - cs, alphas, betas, p_prime, s_arr, perm_f, false - )?; + let mut rc_gadget = ReinforcementConcreteGadget::new(cs, alphas, betas, p_prime, s_arr, perm_f, false)?; - let supposed_output_vars = { + let supposed_output_vars = { let mut input_vars = Vec::with_capacity(self.input.len()); for value in self.input.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc(cs, || Ok(value.clone()))?; input_vars.push(Num::Variable(new_var)); - } - else { + } else { input_vars.push(Num::Constant(value.clone())); } } @@ -90,8 +68,7 @@ mod test { if !self.is_const_test { let new_var = AllocatedNum::alloc(cs, || Ok(value.clone()))?; values_to_absorb.push(Num::Variable(new_var)); - } - else { + } else { values_to_absorb.push(Num::Constant(value.clone())); } } @@ -100,7 +77,7 @@ mod test { rc_gadget.absorb(cs, &values_to_absorb[..])?; rc_gadget.get_cur_state() }; - + for (a, b) in supposed_output_vars.iter().zip(actual_output_vars.into_iter()) { a.enforce_equal(cs, &b)?; } @@ -109,12 +86,11 @@ mod test { } } - fn rc_gadget_test_template(is_const_test: bool) - { + fn rc_gadget_test_template(is_const_test: bool) { // let seed: &[_] = &[1, 2, 3, 4, 5]; // let mut rng: StdRng = SeedableRng::from_seed(seed); let seed = [SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as usize]; - let mut rng : StdRng = SeedableRng::from_seed(&seed[..]); + let mut rng: StdRng = SeedableRng::from_seed(&seed[..]); let mut input = [E::Fr::zero(); RC_STATE_WIDTH]; input.iter_mut().for_each(|x| *x = rng.gen()); @@ -127,39 +103,37 @@ mod test { let output = hasher.tester(&input, &elems_to_absorb); let circuit = TestReinforcementConcreteCircuit:: { - input, output, elems_to_absorb, params, is_const_test + input, + output, + elems_to_absorb, + params, + is_const_test, }; - let mut assembly = TrivialAssembly::< - E, PlonkCsWidth4WithNextStepParams, Width4MainGateWithDNext - >::new(); + let mut assembly = TrivialAssembly::::new(); circuit.synthesize(&mut assembly).expect("must work"); - + println!("Assembly contains {} gates", assembly.n()); println!("Total length of all tables: {}", assembly.total_length_of_all_tables); assert!(assembly.is_satisfied()); } #[test] - fn rc_bn256_gadget_test() - { - rc_gadget_test_template::(false) + fn rc_bn256_gadget_test() { + rc_gadget_test_template::(false) } #[test] - fn rc_bn256_cnst_propagation_test() - { - rc_gadget_test_template::(true) + fn rc_bn256_cnst_propagation_test() { + rc_gadget_test_template::(true) } #[test] - fn rc_bls12_gadget_test() - { - rc_gadget_test_template::(false) + fn rc_bls12_gadget_test() { + rc_gadget_test_template::(false) } #[test] - fn rc_bls12_cnst_propagation_test() - { - rc_gadget_test_template::(true) + fn rc_bls12_cnst_propagation_test() { + rc_gadget_test_template::(true) } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/utils.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/utils.rs index adac14f..2fa9d04 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/utils.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/reinforcement_concrete/utils.rs @@ -1,7 +1,6 @@ use crate::bellman::pairing::ff::*; use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; -use sha3::{digest::ExtendableOutput, digest::Update, Sha3XofReader, Shake128, digest::XofReader}; - +use sha3::{digest::ExtendableOutput, digest::Update, digest::XofReader, Sha3XofReader, Shake128}; pub fn from_u64(val: u64) -> F { F::from_repr(F::Repr::from(val)).unwrap() @@ -50,11 +49,7 @@ fn div_mod_word_by_short(hi: u64, lo: u64, y: u16) -> (u64, u64) { } #[inline(always)] -pub fn divide_long_decomp( - a: &F::Repr, - divisor: u16, - offset: &mut usize, -) -> (F::Repr, u16) { +pub fn divide_long_decomp(a: &F::Repr, divisor: u16, offset: &mut usize) -> (F::Repr, u16) { let mut result = F::Repr::default(); let a_ref = a.as_ref(); @@ -72,16 +67,11 @@ pub fn divide_long_decomp( result_mut[start_index] = a_ref[start_index] / (divisor as u64); let mut r = a_ref[start_index] % (divisor as u64); - result_mut - .iter_mut() - .zip(a_ref.iter()) - .rev() - .skip(*offset + 1) - .for_each(|(res, a_)| { - let (q, m) = div_mod_word_by_short(r, *a_, divisor); - *res = q; - r = m; - }); + result_mut.iter_mut().zip(a_ref.iter()).rev().skip(*offset + 1).for_each(|(res, a_)| { + let (q, m) = div_mod_word_by_short(r, *a_, divisor); + *res = q; + r = m; + }); (result, r as u16) } @@ -98,16 +88,11 @@ pub fn divide_long(a: &F::Repr, divisor: u16) -> (F::Repr, u16) { result_mut[len - 1] = a_ref[len - 1] / (divisor as u64); let mut r = a.as_ref()[len - 1] % (divisor as u64); - result_mut - .iter_mut() - .zip(a_ref.iter()) - .rev() - .skip(1) - .for_each(|(res, a_)| { - let (q, m) = div_mod_word_by_short(r, *a_, divisor); - *res = q; - r = m; - }); + result_mut.iter_mut().zip(a_ref.iter()).rev().skip(1).for_each(|(res, a_)| { + let (q, m) = div_mod_word_by_short(r, *a_, divisor); + *res = q; + r = m; + }); (result, r as u16) } @@ -130,12 +115,7 @@ const fn split(a: u128) -> (u64, u64) { } #[inline(always)] -const fn div_mod_word_by_short_normalized( - u1: u64, - u0: u64, - divisor: u64, - recip: u64, -) -> (u64, u64) { +const fn div_mod_word_by_short_normalized(u1: u64, u0: u64, divisor: u64, recip: u64) -> (u64, u64) { let qq = (u1 as u128) * (recip as u128); let qq = qq + ((u1 as u128) << 64) + (u0 as u128); let (q1, q0) = split(qq); @@ -154,25 +134,15 @@ const fn div_mod_word_by_short_normalized( } #[inline(always)] -pub fn divide_long_using_recip( - a: &F::Repr, - divisor: u64, - recip: u64, - norm_shift: u32, -) -> (F::Repr, u16) { +pub fn divide_long_using_recip(a: &F::Repr, divisor: u64, recip: u64, norm_shift: u32) -> (F::Repr, u16) { let mut result = F::Repr::default(); let (repr, mut limb) = full_shl::(&a, norm_shift); - result - .as_mut() - .iter_mut() - .zip(repr.as_ref().iter()) - .rev() - .for_each(|(r, rep)| { - let (q, m) = div_mod_word_by_short_normalized(limb, *rep, divisor, recip); - *r = q; - limb = m; - }); + result.as_mut().iter_mut().zip(repr.as_ref().iter()).rev().for_each(|(r, rep)| { + let (q, m) = div_mod_word_by_short_normalized(limb, *rep, divisor, recip); + *r = q; + limb = m; + }); (result, (limb >> norm_shift) as u16) } @@ -212,14 +182,10 @@ pub fn mul_by_single_word(u: &F::Repr, w: u64) -> F::Repr { let mut tmp = (u_ref[0] as u128) * w_; res_mut[0] = tmp as u64; - res_mut - .iter_mut() - .zip(u_ref.iter()) - .skip(1) - .for_each(|(r, u_)| { - tmp = (*u_ as u128) * w_ + (tmp >> 64); - *r = tmp as u64; - }); + res_mut.iter_mut().zip(u_ref.iter()).skip(1).for_each(|(r, u_)| { + tmp = (*u_ as u128) * w_ + (tmp >> 64); + *r = tmp as u64; + }); res } @@ -235,10 +201,7 @@ pub fn full_shr(u: &F::Repr, shift: u32) -> F::Repr { let len = res_mut.len(); - res_mut - .iter_mut() - .zip(u_ref.iter()) - .for_each(|(r, u_)| *r = *u_ >> shift); + res_mut.iter_mut().zip(u_ref.iter()).for_each(|(r, u_)| *r = *u_ >> shift); for index in 0..len - 1 { res_mut[index] |= u_ref[index + 1] << (64u32 - shift); @@ -282,9 +245,6 @@ pub fn partial_shl(u: &F::Repr, shift: u32) -> F::Repr { res_mut[index + 1] = u_ref[index] >> (64u32 - shift); } - res_mut - .iter_mut() - .zip(u_ref.iter()) - .for_each(|(r, u_)| *r |= *u_ << shift); + res_mut.iter_mut().zip(u_ref.iter()).for_each(|(r, u_)| *r |= *u_ << shift); res } diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/gadgets.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/gadgets.rs index e8b021f..56d1b0e 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/gadgets.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/gadgets.rs @@ -1,48 +1,39 @@ +use crate::bellman::pairing::ff::*; +use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::plonk::better_better_cs::lookup_tables::*; use crate::bellman::plonk::better_better_cs::utils; -use crate::bellman::pairing::ff::*; -use crate::bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; -use crate::bellman::SynthesisError; use crate::bellman::Engine; -use crate::plonk::circuit::allocated_num::{ - AllocatedNum, - Num, -}; -use crate::plonk::circuit::byte::{ - Byte, -}; -use crate::plonk::circuit::assignment::{ - Assignment -}; +use crate::bellman::SynthesisError; +use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; +use crate::plonk::circuit::assignment::Assignment; +use crate::plonk::circuit::byte::Byte; +use super::super::tables::*; +use super::super::utils::*; +use super::super::{AllocatedNumExtension, NumExtension}; use super::tables::*; use super::utils::*; -use super::super::utils::*; -use super::super::tables::*; -use super::super::{NumExtension, AllocatedNumExtension}; -use std::sync::Arc; -use std::ops::Add; -use std::iter; -use std::cmp::Ordering; use std::cmp; +use std::cmp::Ordering; +use std::iter; +use std::ops::Add; +use std::sync::Arc; +use crate::itertools::Itertools; use crate::num_bigint::BigUint; use crate::num_traits::cast::ToPrimitive; -use crate::num_traits::{ Zero, One }; -use crate::itertools::Itertools; +use crate::num_traits::{One, Zero}; type Result = std::result::Result; - -const SHA256_GADGET_CHUNK_SIZE : usize = 11; -const SHA256_REG_WIDTH : usize = 32; -const CH_DEFAULT_NUM_OF_CHUNKS : usize = 5; // 7^4 is fine -const MAJ_AND_SHEDULER_DEFAULT_NUM_OF_CHUNKS : usize = 8; // 4^6 is fine -const BINARY_BASE : u64 = 2; -const DEFAULT_RANGE_TABLE_WIDTH : usize = 16; - +const SHA256_GADGET_CHUNK_SIZE: usize = 11; +const SHA256_REG_WIDTH: usize = 32; +const CH_DEFAULT_NUM_OF_CHUNKS: usize = 5; // 7^4 is fine +const MAJ_AND_SHEDULER_DEFAULT_NUM_OF_CHUNKS: usize = 8; // 4^6 is fine +const BINARY_BASE: u64 = 2; +const DEFAULT_RANGE_TABLE_WIDTH: usize = 16; // helper struct for tracking how far current value from being in 32-bit range // our gadget is suited to handle at most 4-bit overflows itself @@ -50,7 +41,7 @@ const DEFAULT_RANGE_TABLE_WIDTH : usize = 16; pub enum OverflowTracker { NoOverflow, OneBitOverflow, - SignificantOverflow(u64), //overflowed by 2 or more bits + SignificantOverflow(u64), //overflowed by 2 or more bits } impl OverflowTracker { @@ -68,7 +59,7 @@ impl OverflowTracker { OverflowTracker::OneBitOverflow => 1 + SHA256_REG_WIDTH as u64, OverflowTracker::SignificantOverflow(n) => *n + (SHA256_REG_WIDTH as u64), }; - let res : u64 = (1u64 << offset) - 1; + let res: u64 = (1u64 << offset) - 1; res } @@ -90,8 +81,8 @@ impl OverflowTracker { impl Ord for OverflowTracker { fn cmp(&self, other: &Self) -> Ordering { - let a : u64 = self.clone().into(); - let b : u64 = other.clone().into(); + let a: u64 = self.clone().into(); + let b: u64 = other.clone().into(); a.cmp(&b) } } @@ -104,8 +95,8 @@ impl PartialOrd for OverflowTracker { impl PartialEq for OverflowTracker { fn eq(&self, other: &Self) -> bool { - let a : u64 = self.clone().into(); - let b : u64 = other.clone().into(); + let a: u64 = self.clone().into(); + let b: u64 = other.clone().into(); a == b } } @@ -134,32 +125,29 @@ impl Add for OverflowTracker { type Output = Self; fn add(self, other: Self) -> Self { - let a : u64 = self.into(); - let b : u64 = other.into(); - let new_of_tracker : OverflowTracker = (a + b).into(); + let a: u64 = self.into(); + let b: u64 = other.into(); + let new_of_tracker: OverflowTracker = (a + b).into(); new_of_tracker } } - #[derive(Clone, Copy)] pub struct NumWithTracker { num: Num, overflow_tracker: OverflowTracker, } -impl From> for NumWithTracker -{ +impl From> for NumWithTracker { fn from(num: Num) -> Self { NumWithTracker { num, - overflow_tracker: OverflowTracker::NoOverflow + overflow_tracker: OverflowTracker::NoOverflow, } } } -impl Default for NumWithTracker -{ +impl Default for NumWithTracker { fn default() -> Self { NumWithTracker { num: Num::default(), @@ -168,7 +156,6 @@ impl Default for NumWithTracker } } - #[derive(Clone)] pub struct SparseChValue { normal: NumWithTracker, @@ -191,33 +178,33 @@ pub struct SparseMajValue { #[derive(Clone, Copy)] pub struct Sha256Registers { - a : NumWithTracker, - b : NumWithTracker, - c : NumWithTracker, - d : NumWithTracker, - e : NumWithTracker, - f : NumWithTracker, - g : NumWithTracker, - h : NumWithTracker, + a: NumWithTracker, + b: NumWithTracker, + c: NumWithTracker, + d: NumWithTracker, + e: NumWithTracker, + f: NumWithTracker, + g: NumWithTracker, + h: NumWithTracker, } #[derive(Clone, Debug)] pub struct Sha256Gadget { // is is possible to reduce the number of constraints even more by exploiting not only d_next, // but also c_prev - use_c_prev : bool, + use_c_prev: bool, // the purpose of these parameters is discussed before the "normalize" function ch_num_of_chunks: usize, // NOTE : actually the majority vand sheduler bases are the same (4), so there is no reason for their corresponding // number of chunks to be different maj_and_sheduler_num_of_chunks: usize, - - // tables used for chooser (ch) implementation + + // tables used for chooser (ch) implementation sha256_base7_rot6_table: Arc>, sha256_base7_rot3_extr10_table: Arc>, sha256_ch_normalization_table: Arc>, - + // tables used for majority (maj) implementation sha256_base4_rot2_table: Arc>, // the special property of this table is that it operates on 10-but chunks @@ -229,7 +216,7 @@ pub struct Sha256Gadget { // for normalization we are going to use the same table as in majority function - as their bases (4) are the same! // we also implement R_3 and S_19 (see below) with the help of specially crafted addtional tables, // namely: Sha256ShedulerHelperTable - sha256_sheduler_helper_table : Arc>, + sha256_sheduler_helper_table: Arc>, // there is an option to handle of range checks via globally defined range table // if there is no such table available, we are not going to create such a range table ourselves @@ -241,16 +228,22 @@ pub struct Sha256Gadget { global_range_table: Option>>, max_of_width: usize, - // constants + // constants iv: [E::Fr; 8], round_constants: [E::Fr; 64], } impl Sha256Gadget { pub fn iv() -> [E::Fr; 8] { - [ - u64_to_ff(0x6a09e667), u64_to_ff(0xbb67ae85), u64_to_ff(0x3c6ef372), u64_to_ff(0xa54ff53a), - u64_to_ff(0x510e527f), u64_to_ff(0x9b05688c), u64_to_ff(0x1f83d9ab), u64_to_ff(0x5be0cd19), + [ + u64_to_ff(0x6a09e667), + u64_to_ff(0xbb67ae85), + u64_to_ff(0x3c6ef372), + u64_to_ff(0xa54ff53a), + u64_to_ff(0x510e527f), + u64_to_ff(0x9b05688c), + u64_to_ff(0x1f83d9ab), + u64_to_ff(0x5be0cd19), ] } @@ -262,178 +255,179 @@ impl Sha256Gadget { } pub fn new>( - cs: &mut CS, + cs: &mut CS, ch_base_num_of_chunks: Option, maj_sheduler_base_num_of_chunks: Option, - use_c_prev : bool, + use_c_prev: bool, use_global_range_table: bool, - global_range_table_width : usize, + global_range_table_width: usize, global_range_table_name: &str, ) -> Result { - let ch_num_of_chunks = ch_base_num_of_chunks.unwrap_or(CH_DEFAULT_NUM_OF_CHUNKS); let maj_and_sheduler_num_of_chunks = maj_sheduler_base_num_of_chunks.unwrap_or(MAJ_AND_SHEDULER_DEFAULT_NUM_OF_CHUNKS); - let columns3 = vec![ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2) - ]; + let columns3 = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; use plonk::circuit::hashes_with_tables::get_or_create_table; let name1: &'static str = "sha256_base7_rot6_table"; - let sha256_base7_rot6_table = get_or_create_table( - cs, - name1, - || { - LookupTableApplication::new( - name1, - SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE, 6, 0, SHA256_CHOOSE_BASE, name1), - columns3.clone(), - None, - true - ) - } - )?; - - let name2 : &'static str = "sha256_base7_rot3_extr10_table"; - let sha256_base7_rot3_extr10_table = get_or_create_table( - cs, - name2, - || { - LookupTableApplication::new( - name2, - SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE, 3, SHA256_GADGET_CHUNK_SIZE-1, SHA256_CHOOSE_BASE, name2), - columns3.clone(), - None, - true - ) - } - )?; - - let name3 : &'static str = "sha256_base4_rot2_table"; - let sha256_base4_rot2_table = get_or_create_table( - cs, - name3, - || { - LookupTableApplication::new( - name3, - SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE, 2, 0, SHA256_MAJORITY_SHEDULER_BASE, name3), - columns3.clone(), - None, - true - ) - } - )?; - - let name4 : &'static str = "sha256_base4_rot2_width10_table"; - let sha256_base4_rot2_width10_table = get_or_create_table( - cs, - name4, - || { - LookupTableApplication::new( - name4, - SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE - 1, 2, 0, SHA256_MAJORITY_SHEDULER_BASE, name4), - columns3.clone(), - None, - true, - ) - } - )?; - - let xor_f = | x | { x & 1}; - let ch_f = | x | { ch_u64_normalizer(x) }; - let maj_f = | x | { maj_u64_normalizer(x) }; - - let name5 : &'static str = "sha256_ch_normalization_table"; - let sha256_ch_normalization_table = get_or_create_table( - cs, - name5, - || { - LookupTableApplication::new( - name5, - MultiBaseNormalizationTable::new(ch_num_of_chunks, SHA256_CHOOSE_BASE, BINARY_BASE, BINARY_BASE, ch_f, xor_f, name5), - columns3.clone(), - None, - true - ) - } - )?; - - let name6 : &'static str = "sha256_maj_normalization_table"; - let sha256_maj_sheduler_normalization_table = get_or_create_table( - cs, - name6, - || { - LookupTableApplication::new( - name6, - MultiBaseNormalizationTable::new( - maj_and_sheduler_num_of_chunks, SHA256_MAJORITY_SHEDULER_BASE, BINARY_BASE, BINARY_BASE, maj_f, xor_f, name6 - ), - columns3.clone(), - None, - true - ) - } - )?; + let sha256_base7_rot6_table = get_or_create_table(cs, name1, || { + LookupTableApplication::new(name1, SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE, 6, 0, SHA256_CHOOSE_BASE, name1), columns3.clone(), None, true) + })?; + + let name2: &'static str = "sha256_base7_rot3_extr10_table"; + let sha256_base7_rot3_extr10_table = get_or_create_table(cs, name2, || { + LookupTableApplication::new( + name2, + SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE, 3, SHA256_GADGET_CHUNK_SIZE - 1, SHA256_CHOOSE_BASE, name2), + columns3.clone(), + None, + true, + ) + })?; + + let name3: &'static str = "sha256_base4_rot2_table"; + let sha256_base4_rot2_table = get_or_create_table(cs, name3, || { + LookupTableApplication::new( + name3, + SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE, 2, 0, SHA256_MAJORITY_SHEDULER_BASE, name3), + columns3.clone(), + None, + true, + ) + })?; + + let name4: &'static str = "sha256_base4_rot2_width10_table"; + let sha256_base4_rot2_width10_table = get_or_create_table(cs, name4, || { + LookupTableApplication::new( + name4, + SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE - 1, 2, 0, SHA256_MAJORITY_SHEDULER_BASE, name4), + columns3.clone(), + None, + true, + ) + })?; + + let xor_f = |x| x & 1; + let ch_f = |x| ch_u64_normalizer(x); + let maj_f = |x| maj_u64_normalizer(x); + + let name5: &'static str = "sha256_ch_normalization_table"; + let sha256_ch_normalization_table = get_or_create_table(cs, name5, || { + LookupTableApplication::new( + name5, + MultiBaseNormalizationTable::new(ch_num_of_chunks, SHA256_CHOOSE_BASE, BINARY_BASE, BINARY_BASE, ch_f, xor_f, name5), + columns3.clone(), + None, + true, + ) + })?; + + let name6: &'static str = "sha256_maj_normalization_table"; + let sha256_maj_sheduler_normalization_table = get_or_create_table(cs, name6, || { + LookupTableApplication::new( + name6, + MultiBaseNormalizationTable::new(maj_and_sheduler_num_of_chunks, SHA256_MAJORITY_SHEDULER_BASE, BINARY_BASE, BINARY_BASE, maj_f, xor_f, name6), + columns3.clone(), + None, + true, + ) + })?; + + let name7: &'static str = "sha256_base4_rot7_table"; + let sha256_base4_rot7_table = get_or_create_table(cs, name7, || { + LookupTableApplication::new( + name7, + SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE, 7, 0, SHA256_MAJORITY_SHEDULER_BASE, name7), + columns3.clone(), + None, + true, + ) + })?; + + let name8: &'static str = "sha256_sheduler_helper_table"; + let sha256_sheduler_helper_table = get_or_create_table(cs, name8, || LookupTableApplication::new(name8, Sha256ShedulerHelperTable::new(name8), columns3.clone(), None, true))?; - let name7 : &'static str = "sha256_base4_rot7_table"; - let sha256_base4_rot7_table = get_or_create_table( - cs, - name7, - || { - LookupTableApplication::new( - name7, - SparseRotateTable::new(SHA256_GADGET_CHUNK_SIZE, 7, 0, SHA256_MAJORITY_SHEDULER_BASE, name7), - columns3.clone(), - None, - true - ) - } - )?; - - let name8 : &'static str = "sha256_sheduler_helper_table"; - let sha256_sheduler_helper_table = get_or_create_table( - cs, - name8, - || { - LookupTableApplication::new( - name8, - Sha256ShedulerHelperTable::new(name8), - columns3.clone(), - None, - true - ) - } - )?; - // Initialize IV values: // (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19): - let iv = [ - u64_to_ff(0x6a09e667), u64_to_ff(0xbb67ae85), u64_to_ff(0x3c6ef372), u64_to_ff(0xa54ff53a), - u64_to_ff(0x510e527f), u64_to_ff(0x9b05688c), u64_to_ff(0x1f83d9ab), u64_to_ff(0x5be0cd19), + let iv = [ + u64_to_ff(0x6a09e667), + u64_to_ff(0xbb67ae85), + u64_to_ff(0x3c6ef372), + u64_to_ff(0xa54ff53a), + u64_to_ff(0x510e527f), + u64_to_ff(0x9b05688c), + u64_to_ff(0x1f83d9ab), + u64_to_ff(0x5be0cd19), ]; // Initialize array of round constants: // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311): let round_constants = [ - u64_to_ff(0x428a2f98), u64_to_ff(0x71374491), u64_to_ff(0xb5c0fbcf), u64_to_ff(0xe9b5dba5), - u64_to_ff(0x3956c25b), u64_to_ff(0x59f111f1), u64_to_ff(0x923f82a4), u64_to_ff(0xab1c5ed5), - u64_to_ff(0xd807aa98), u64_to_ff(0x12835b01), u64_to_ff(0x243185be), u64_to_ff(0x550c7dc3), - u64_to_ff(0x72be5d74), u64_to_ff(0x80deb1fe), u64_to_ff(0x9bdc06a7), u64_to_ff(0xc19bf174), - u64_to_ff(0xe49b69c1), u64_to_ff(0xefbe4786), u64_to_ff(0x0fc19dc6), u64_to_ff(0x240ca1cc), - u64_to_ff(0x2de92c6f), u64_to_ff(0x4a7484aa), u64_to_ff(0x5cb0a9dc), u64_to_ff(0x76f988da), - u64_to_ff(0x983e5152), u64_to_ff(0xa831c66d), u64_to_ff(0xb00327c8), u64_to_ff(0xbf597fc7), - u64_to_ff(0xc6e00bf3), u64_to_ff(0xd5a79147), u64_to_ff(0x06ca6351), u64_to_ff(0x14292967), - u64_to_ff(0x27b70a85), u64_to_ff(0x2e1b2138), u64_to_ff(0x4d2c6dfc), u64_to_ff(0x53380d13), - u64_to_ff(0x650a7354), u64_to_ff(0x766a0abb), u64_to_ff(0x81c2c92e), u64_to_ff(0x92722c85), - u64_to_ff(0xa2bfe8a1), u64_to_ff(0xa81a664b), u64_to_ff(0xc24b8b70), u64_to_ff(0xc76c51a3), - u64_to_ff(0xd192e819), u64_to_ff(0xd6990624), u64_to_ff(0xf40e3585), u64_to_ff(0x106aa070), - u64_to_ff(0x19a4c116), u64_to_ff(0x1e376c08), u64_to_ff(0x2748774c), u64_to_ff(0x34b0bcb5), - u64_to_ff(0x391c0cb3), u64_to_ff(0x4ed8aa4a), u64_to_ff(0x5b9cca4f), u64_to_ff(0x682e6ff3), - u64_to_ff(0x748f82ee), u64_to_ff(0x78a5636f), u64_to_ff(0x84c87814), u64_to_ff(0x8cc70208), - u64_to_ff(0x90befffa), u64_to_ff(0xa4506ceb), u64_to_ff(0xbef9a3f7), u64_to_ff(0xc67178f2), + u64_to_ff(0x428a2f98), + u64_to_ff(0x71374491), + u64_to_ff(0xb5c0fbcf), + u64_to_ff(0xe9b5dba5), + u64_to_ff(0x3956c25b), + u64_to_ff(0x59f111f1), + u64_to_ff(0x923f82a4), + u64_to_ff(0xab1c5ed5), + u64_to_ff(0xd807aa98), + u64_to_ff(0x12835b01), + u64_to_ff(0x243185be), + u64_to_ff(0x550c7dc3), + u64_to_ff(0x72be5d74), + u64_to_ff(0x80deb1fe), + u64_to_ff(0x9bdc06a7), + u64_to_ff(0xc19bf174), + u64_to_ff(0xe49b69c1), + u64_to_ff(0xefbe4786), + u64_to_ff(0x0fc19dc6), + u64_to_ff(0x240ca1cc), + u64_to_ff(0x2de92c6f), + u64_to_ff(0x4a7484aa), + u64_to_ff(0x5cb0a9dc), + u64_to_ff(0x76f988da), + u64_to_ff(0x983e5152), + u64_to_ff(0xa831c66d), + u64_to_ff(0xb00327c8), + u64_to_ff(0xbf597fc7), + u64_to_ff(0xc6e00bf3), + u64_to_ff(0xd5a79147), + u64_to_ff(0x06ca6351), + u64_to_ff(0x14292967), + u64_to_ff(0x27b70a85), + u64_to_ff(0x2e1b2138), + u64_to_ff(0x4d2c6dfc), + u64_to_ff(0x53380d13), + u64_to_ff(0x650a7354), + u64_to_ff(0x766a0abb), + u64_to_ff(0x81c2c92e), + u64_to_ff(0x92722c85), + u64_to_ff(0xa2bfe8a1), + u64_to_ff(0xa81a664b), + u64_to_ff(0xc24b8b70), + u64_to_ff(0xc76c51a3), + u64_to_ff(0xd192e819), + u64_to_ff(0xd6990624), + u64_to_ff(0xf40e3585), + u64_to_ff(0x106aa070), + u64_to_ff(0x19a4c116), + u64_to_ff(0x1e376c08), + u64_to_ff(0x2748774c), + u64_to_ff(0x34b0bcb5), + u64_to_ff(0x391c0cb3), + u64_to_ff(0x4ed8aa4a), + u64_to_ff(0x5b9cca4f), + u64_to_ff(0x682e6ff3), + u64_to_ff(0x748f82ee), + u64_to_ff(0x78a5636f), + u64_to_ff(0x84c87814), + u64_to_ff(0x8cc70208), + u64_to_ff(0x90befffa), + u64_to_ff(0xa4506ceb), + u64_to_ff(0xbef9a3f7), + u64_to_ff(0xc67178f2), ]; let (global_range_table, max_of_width) = match use_global_range_table { @@ -443,7 +437,7 @@ impl Sha256Gadget { // for now only range table of width 16 is supported assert_eq!(global_range_table_width, DEFAULT_RANGE_TABLE_WIDTH); (Some(cs.get_table(global_range_table_name)?), global_range_table_width) - }, + } false => (None, SHA256_GADGET_CHUNK_SIZE), }; @@ -455,11 +449,11 @@ impl Sha256Gadget { sha256_base7_rot6_table, sha256_base7_rot3_extr10_table, sha256_ch_normalization_table, - + sha256_base4_rot2_table, sha256_base4_rot2_width10_table, sha256_maj_sheduler_normalization_table, - + sha256_base4_rot7_table, sha256_sheduler_helper_table, @@ -480,11 +474,10 @@ impl Sha256Gadget { // ------------------------------------------------------------------------------------------------------------------------ // for list of overflowed numbers, deduce the maximal possible overflow of their sum - fn deduce_of(&self, of_trackers: Vec) -> OverflowTracker - { + fn deduce_of(&self, of_trackers: Vec) -> OverflowTracker { assert!(!of_trackers.is_empty()); - let mut total : u64 = 0; + let mut total: u64 = 0; for of in of_trackers { total += of.get_template(); } @@ -493,15 +486,12 @@ impl Sha256Gadget { // the most general form of linear sum: // a = b + c + d + cnst, where (a, b, c, d) - our current row in the trace - // the function consumes b, c, d as output and produce a + // the function consumes b, c, d as output and produce a // every register among of a, b, c, d is put in the corresponding position (if nonconstant) // // NB: we calculate separately all constant registers and of for them (just a usuful trick) // so that we may reduce all constants mod 2^32 ahead of time - fn tracked_positioned_sum_general>( - &self, cs: &mut CS, b: NumWithTracker, c: NumWithTracker, d: NumWithTracker, input_cnst: E::Fr, - ) -> Result> - { + fn tracked_positioned_sum_general>(&self, cs: &mut CS, b: NumWithTracker, c: NumWithTracker, d: NumWithTracker, input_cnst: E::Fr) -> Result> { // special case - all of b, c, d are actually constants // there value would be there sum modulo 2^32 if b.num.is_constant() && c.num.is_constant() && d.num.is_constant() { @@ -552,18 +542,18 @@ impl Sha256Gadget { let repr = cnst.into_repr(); let n = repr.as_ref()[0] & ((1 << SHA256_REG_WIDTH) - 1); cnst = u64_to_ff(n); - + // calculation of the overflow let mut of_vec = Vec::with_capacity(4); for elem in [&b, &c, &d].iter() { - if !elem.num.is_constant() { - of_vec.push(elem.overflow_tracker) + if !elem.num.is_constant() { + of_vec.push(elem.overflow_tracker) } } if !cnst.is_zero() { of_vec.push(OverflowTracker::NoOverflow) } - let res_of = self.deduce_of(of_vec); + let res_of = self.deduce_of(of_vec); // construct the result - a // it will always be an allocated num @@ -578,19 +568,12 @@ impl Sha256Gadget { let tmp = d_var.get_value().grab()?; sum.add_assign(&tmp); - + Ok(sum) - })?; + })?; // definitely, num module should be refactored! - AllocatedNum::general_lc_gate( - cs, - &[minus_one, one.clone(), one.clone(), one], - &[a_var.clone(), b_var, c_var, d_var], - &cnst, - &zero, - &dummy, - )?; + AllocatedNum::general_lc_gate(cs, &[minus_one, one.clone(), one.clone(), one], &[a_var.clone(), b_var, c_var, d_var], &cnst, &zero, &dummy)?; let res = NumWithTracker { num: Num::Variable(a_var), @@ -599,27 +582,25 @@ impl Sha256Gadget { Ok(res) } - fn tracked_positioned_sum2_mod32>( - &self, cs: &mut CS, c: NumWithTracker, d: NumWithTracker, - ) -> Result> - { + fn tracked_positioned_sum2_mod32>(&self, cs: &mut CS, c: NumWithTracker, d: NumWithTracker) -> Result> { self.tracked_positioned_sum_general(cs, NumWithTracker::default(), c, d, E::Fr::zero()) } - fn tracked_positioned_sum3_mod32>( - &self, cs: &mut CS, b: NumWithTracker, c: NumWithTracker, d: NumWithTracker, - ) -> Result> - { + fn tracked_positioned_sum3_mod32>(&self, cs: &mut CS, b: NumWithTracker, c: NumWithTracker, d: NumWithTracker) -> Result> { self.tracked_positioned_sum_general(cs, b, c, d, E::Fr::zero()) } fn tracked_positioned_sum3_with_cnst_mod32>( - &self, cs: &mut CS, b: NumWithTracker, c: NumWithTracker, d: NumWithTracker, cnst: E::Fr, - ) -> Result> - { + &self, + cs: &mut CS, + b: NumWithTracker, + c: NumWithTracker, + d: NumWithTracker, + cnst: E::Fr, + ) -> Result> { self.tracked_positioned_sum_general(cs, b, c, d, cnst) } - + fn converter_helper(&self, n: u64, sparse_base: u64, rotation: usize, extraction: usize) -> E::Fr { let t = map_into_sparse_form(rotate_extract(n as usize, rotation, extraction), sparse_base as usize); E::Fr::from_str(&t.to_string()).unwrap() @@ -628,15 +609,14 @@ impl Sha256Gadget { fn allocate_converted_num>( &self, cs: &mut CS, - var: &AllocatedNum, - chunk_bitlen: usize, - chunk_offset: usize, + var: &AllocatedNum, + chunk_bitlen: usize, + chunk_offset: usize, sparse_base: u64, - rotation: usize, - extraction: usize - ) -> Result> - { - let new_val = var.get_value().map( |fr| { + rotation: usize, + extraction: usize, + ) -> Result> { + let new_val = var.get_value().map(|fr| { let repr = fr.into_repr(); let n = (repr.as_ref()[0] >> chunk_offset) & ((1 << chunk_bitlen) - 1); self.converter_helper(n, sparse_base, rotation, extraction) @@ -652,7 +632,7 @@ impl Sha256Gadget { // we can conbine transformation of each chunk x_i and accumulation of resulting y_i via f on the same row: // start with acc = 0 // for the row [x_i, f(x_i), acc_prev, acc_new], let acc_new = acc_prev * b^i + f(x_i) - + // actual implementation is the following: // for row of the form [x, f(x), g(x), acc] do: // table query x => f(x), g(x) @@ -660,26 +640,23 @@ impl Sha256Gadget { // if is_final is set, simply check: acc = coef * x // returns (f(x), g(x)) and updates acc fn query_table_acc>( - &self, - cs: &mut CS, - table: &Arc>, + &self, + cs: &mut CS, + table: &Arc>, key: &AllocatedNum, acc: &mut AllocatedNum, coef: &E::Fr, is_final: bool, - ) -> Result<(AllocatedNum, AllocatedNum)> - { + ) -> Result<(AllocatedNum, AllocatedNum)> { let (f_key, g_key) = match key.get_value() { - None => { - ( - AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?, - AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?, - ) - }, + None => ( + AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?, + AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?, + ), Some(val) => { let vals = table.query(&[val])?; (AllocatedNum::alloc(cs, || Ok(vals[0]))?, AllocatedNum::alloc(cs, || Ok(vals[1]))?) - }, + } }; let new_acc = if !is_final { @@ -690,8 +667,7 @@ impl Sha256Gadget { res.sub_assign(&tmp); Ok(res) })? - } - else { + } else { AllocatedNum::zero(cs) }; @@ -711,7 +687,7 @@ impl Sha256Gadget { cs.begin_gates_batch_for_step()?; cs.apply_single_lookup_gate(&vars[..table.width()], table.clone())?; - + let gate_term = MainGateTerm::new(); let (_, mut gate_coefs) = CS::MainGate::format_term(gate_term, dummy)?; @@ -724,12 +700,7 @@ impl Sha256Gadget { } let mg = CS::MainGate::default(); - cs.new_gate_in_batch( - &mg, - &gate_coefs, - &vars, - &[] - )?; + cs.new_gate_in_batch(&mg, &gate_coefs, &vars, &[])?; cs.end_gates_batch_for_step()?; @@ -741,66 +712,50 @@ impl Sha256Gadget { // we accomplish range check exploting sha-specific sparse-rotations tables // the row has the form: [of, sparse(of), sparse_rotate(of), acc] // updates acc: new_acc = acc - of * coef; - fn of_range_check>( - &self, cs: &mut CS, of: &AllocatedNum, acc: &mut AllocatedNum, coef: &E::Fr, - ) -> Result<()> - { + fn of_range_check>(&self, cs: &mut CS, of: &AllocatedNum, acc: &mut AllocatedNum, coef: &E::Fr) -> Result<()> { let table = match self.use_global_range_table { false => &self.sha256_base4_rot2_table, true => self.global_range_table.as_ref().unwrap(), }; - self.query_table_acc(cs, table, of, acc, coef, false)?; + self.query_table_acc(cs, table, of, acc, coef, false)?; Ok(()) } - fn query_table>( - &self, - cs: &mut CS, - table: &Arc>, - key: &AllocatedNum - ) -> Result<(AllocatedNum, AllocatedNum)> - { + fn query_table>(&self, cs: &mut CS, table: &Arc>, key: &AllocatedNum) -> Result<(AllocatedNum, AllocatedNum)> { let res = match key.get_value() { None => ( - AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?, - AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))? + AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?, + AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?, ), Some(val) => { let new_vals = table.query(&[val])?; - ( - AllocatedNum::alloc(cs, || Ok(new_vals[0]))?, - AllocatedNum::alloc(cs, || Ok(new_vals[1]))? - ) - }, + (AllocatedNum::alloc(cs, || Ok(new_vals[0]))?, AllocatedNum::alloc(cs, || Ok(new_vals[1]))?) + } }; cs.begin_gates_batch_for_step()?; //let dummy = AllocatedNum::alloc_zero(cs)?.get_variable(); let vars = [key.get_variable(), res.0.get_variable(), res.1.get_variable(), key.get_variable()]; - cs.allocate_variables_without_gate( - &vars, - &[] - )?; + cs.allocate_variables_without_gate(&vars, &[])?; cs.apply_single_lookup_gate(&vars[..table.width()], table.clone())?; cs.end_gates_batch_for_step()?; Ok(res) } - fn extact_32_bits_from_tracked_num>(&self, cs: &mut CS, input: NumWithTracker) -> Result> - { + fn extact_32_bits_from_tracked_num>(&self, cs: &mut CS, input: NumWithTracker) -> Result> { if let Num::Constant(fr) = input.num { let repr = fr.into_repr(); - let n = repr.as_ref()[0] & ((1 << SHA256_REG_WIDTH) - 1); + let n = repr.as_ref()[0] & ((1 << SHA256_REG_WIDTH) - 1); return Ok(Num::Constant(u64_to_ff(n))); } if let OverflowTracker::NoOverflow = input.overflow_tracker { return Ok(input.num); } - + let var = input.num.get_variable(); let res = if self.use_global_range_table { // NB: the only supported value for range table width is 16! @@ -809,9 +764,7 @@ impl Sha256Gadget { let high = self.allocate_converted_num(cs, &var, range_table_width, range_table_width, 0, 0, 0)?; let of = self.allocate_converted_num(cs, &var, range_table_width, range_table_width * 2, 0, 0, 0)?; - let cf = [ - E::Fr::one(), u64_to_ff(1 << range_table_width), u64_to_ff(1 << (2 * range_table_width)), - ]; + let cf = [E::Fr::one(), u64_to_ff(1 << range_table_width), u64_to_ff(1 << (2 * range_table_width))]; let table = &self.global_range_table.as_ref().unwrap(); let mut acc = var.clone(); @@ -821,26 +774,20 @@ impl Sha256Gadget { let extracted = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, 0, 0, 0)?; let dummy = AllocatedNum::zero(cs); - - AllocatedNum::ternary_lc_eq( - cs, - &[cf[0].clone(), cf[1].clone(), E::Fr::zero()], - &[low, high, dummy], - &extracted, - )?; + + AllocatedNum::ternary_lc_eq(cs, &[cf[0].clone(), cf[1].clone(), E::Fr::zero()], &[low, high, dummy], &extracted)?; Num::Variable(extracted) - } - else { + } else { let low = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, 0, 0, 0, 0)?; let mid = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, SHA256_GADGET_CHUNK_SIZE, 0, 0, 0)?; - let high = self.allocate_converted_num( - cs, &var, SHA256_GADGET_CHUNK_SIZE - 1, SHA256_GADGET_CHUNK_SIZE * 2, 0, 0, 0 - )?; + let high = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE - 1, SHA256_GADGET_CHUNK_SIZE * 2, 0, 0, 0)?; let of = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, SHA256_REG_WIDTH, 0, 0, 0)?; let cf = [ - E::Fr::one(), u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE), - u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE)), u64_to_ff(1 << SHA256_REG_WIDTH), + E::Fr::one(), + u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE), + u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE)), + u64_to_ff(1 << SHA256_REG_WIDTH), ]; let mut acc = var.clone(); @@ -851,39 +798,29 @@ impl Sha256Gadget { self.query_table_acc(cs, &self.sha256_base4_rot2_table, &of, &mut acc, &cf[3], true)?; let extracted = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, 0, 0, 0)?; - - AllocatedNum::ternary_lc_eq( - cs, - &[cf[0].clone(), cf[1].clone(), cf[2].clone()], - &[low, mid, high], - &extracted, - )?; + + AllocatedNum::ternary_lc_eq(cs, &[cf[0].clone(), cf[1].clone(), cf[2].clone()], &[low, mid, high], &extracted)?; Num::Variable(extracted) }; - + Ok(res) } // -------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------- - // convertion and normalization routines used inside hash + // convertion and normalization routines used inside hash // --------------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------------- - fn convert_into_sparse_chooser_form>( - &self, - cs: &mut CS, - input: NumWithTracker, - ) -> Result> - { + fn convert_into_sparse_chooser_form>(&self, cs: &mut CS, input: NumWithTracker) -> Result> { if let OverflowTracker::SignificantOverflow(n) = input.overflow_tracker { assert!(n <= (self.max_of_width as u64) + 1); }; - + if let Num::Constant(x) = input.num { let repr = x.into_repr(); - let n = repr.as_ref()[0] & ((1 << 32) - 1); - + let n = repr.as_ref()[0] & ((1 << 32) - 1); + let res = SparseChValue { normal: (Num::Constant(x)).into(), sparse: Num::Constant(self.converter_helper(n, SHA256_CHOOSE_BASE, 0, 0)), @@ -892,24 +829,26 @@ impl Sha256Gadget { rot25: Num::Constant(self.converter_helper(n, SHA256_CHOOSE_BASE, 25, 0)), }; - return Ok(res) + return Ok(res); } - let var = input.num.get_variable(); + let var = input.num.get_variable(); // split our 32bit variable into 11-bit chunks: // there will be three chunks (low, mid, high) for 32bit number // note that, we can deal here with possible 1-bit overflow: (as 3 * 11 = 33) // in order to do this we allow extraction set to 10 for the table working with highest chunk - + let low = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, 0, 0, 0, 0)?; let mid = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, SHA256_GADGET_CHUNK_SIZE, 0, 0, 0)?; let high = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, 2 * SHA256_GADGET_CHUNK_SIZE, 0, 0, 0)?; let mut acc = var.clone(); let cf = [ - E::Fr::one(), u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE), - u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE)), u64_to_ff(1 << (3 * SHA256_GADGET_CHUNK_SIZE)), + E::Fr::one(), + u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE), + u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE)), + u64_to_ff(1 << (3 * SHA256_GADGET_CHUNK_SIZE)), ]; if let OverflowTracker::SignificantOverflow(_n) = input.overflow_tracker { @@ -920,21 +859,17 @@ impl Sha256Gadget { let (sparse_low, sparse_low_rot6) = self.query_table_acc(cs, &self.sha256_base7_rot6_table, &low, &mut acc, &cf[0], false)?; let (sparse_mid, _sparse_mid_rot6) = self.query_table_acc(cs, &self.sha256_base7_rot6_table, &mid, &mut acc, &cf[1], false)?; - let (sparse_high, sparse_high_rot3) = self.query_table_acc( - cs, &self.sha256_base7_rot3_extr10_table, &high, &mut acc, &cf[2], true - )?; + let (sparse_high, sparse_high_rot3) = self.query_table_acc(cs, &self.sha256_base7_rot3_extr10_table, &high, &mut acc, &cf[2], true)?; let full_sparse = { // full_sparse = low_sparse + 7^11 * mid_sparse + 7^22 * high_sparse - let sparse_full = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH + 1, 0, SHA256_CHOOSE_BASE, 0, SHA256_REG_WIDTH - )?; + let sparse_full = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH + 1, 0, SHA256_CHOOSE_BASE, 0, SHA256_REG_WIDTH)?; let limb_1_shift = u64_exp_to_ff(7, 11); let limb_2_shift = u64_exp_to_ff(7, 22); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), limb_1_shift, limb_2_shift], &[sparse_low.clone(), sparse_mid.clone(), sparse_high.clone()], &sparse_full, @@ -945,15 +880,13 @@ impl Sha256Gadget { let full_sparse_rot6 = { // full_sparse_rot6 = low_sparse_rot6 + 7^(11-6) * sparse_mid + 7^(22-6) * sparse_high - let full_sparse_rot6 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH + 1, 0, SHA256_CHOOSE_BASE, 6, SHA256_REG_WIDTH - )?; + let full_sparse_rot6 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH + 1, 0, SHA256_CHOOSE_BASE, 6, SHA256_REG_WIDTH)?; - let rot6_limb_1_shift = u64_exp_to_ff(7, 11-6); + let rot6_limb_1_shift = u64_exp_to_ff(7, 11 - 6); let rot6_limb_2_shift = u64_exp_to_ff(7, 22 - 6); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), rot6_limb_1_shift, rot6_limb_2_shift], &[sparse_low_rot6, sparse_mid.clone(), sparse_high.clone()], &full_sparse_rot6, @@ -964,15 +897,13 @@ impl Sha256Gadget { let full_sparse_rot11 = { // full_sparse_rot11 = sparse_mid + 7^(22-11) * sparse_high + 7^(32-11) * sparse_low - let full_sparse_rot11 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH + 1, 0, SHA256_CHOOSE_BASE, 11, SHA256_REG_WIDTH - )?; + let full_sparse_rot11 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH + 1, 0, SHA256_CHOOSE_BASE, 11, SHA256_REG_WIDTH)?; let rot11_limb_0_shift = u64_exp_to_ff(7, 32 - 11); let rot11_limb_2_shift = u64_exp_to_ff(7, 22 - 11); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), rot11_limb_0_shift, rot11_limb_2_shift], &[sparse_mid.clone(), sparse_low.clone(), sparse_high], &full_sparse_rot11, @@ -983,15 +914,13 @@ impl Sha256Gadget { let full_sparse_rot_25 = { // full_sparse_rot25 = sparse_high_rot3 + 7^(11-3) * sparse_low + 7^(22-3) * sparse_mid - let full_sparse_rot25 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH + 1, 0, SHA256_CHOOSE_BASE, 25, SHA256_REG_WIDTH - )?; + let full_sparse_rot25 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH + 1, 0, SHA256_CHOOSE_BASE, 25, SHA256_REG_WIDTH)?; let rot25_limb_0_shift = u64_exp_to_ff(7, 10 - 3); let rot25_limb_1_shift = u64_exp_to_ff(7, 21 - 3); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), rot25_limb_0_shift, rot25_limb_1_shift], &[sparse_high_rot3, sparse_low, sparse_mid], &full_sparse_rot25, @@ -1005,10 +934,10 @@ impl Sha256Gadget { _ => OverflowTracker::OneBitOverflow, }; - let res = SparseChValue{ - normal: NumWithTracker { - num: Num::Variable(full_normal), - overflow_tracker: new_tracker, + let res = SparseChValue { + normal: NumWithTracker { + num: Num::Variable(full_normal), + overflow_tracker: new_tracker, }, sparse: Num::Variable(full_sparse), rot6: Num::Variable(full_sparse_rot6), @@ -1019,29 +948,24 @@ impl Sha256Gadget { } // IMPORTANT NOTE: - // there is a small difference between conversion into sparse chooser form and majority form functions + // there is a small difference between conversion into sparse chooser form and majority form functions // more precisely, we are using 2 different tables in the first case: rot6 table for low and mid chunks and rot3 - for upper one // this allows to embed handling of 1-bit overflow into the table itself without additional overflow check (as called above) // this works as following: we split our number into 3 11-bit chunks, hence there 33 bits overall - // however, our upper table for chooser has nontrivial extraction: we forget about the top-most bit of highest chunk, + // however, our upper table for chooser has nontrivial extraction: we forget about the top-most bit of highest chunk, // so our ombined full result will be of length 11 + 11 + 10 = 32, as required // NB: - // 1) this way, we may handle only potential one-bit overflows, for the case of 2-bit overflows and more traditional + // 1) this way, we may handle only potential one-bit overflows, for the case of 2-bit overflows and more traditional // approaches are required (as used inside extract_32_from_overflowed_num function) - // 2) we can use the same approach inside the "conversion into sparse majority form" function - or. in other words, - // create two tables instead of one: both will be base4_rot2, but the second one will also containt non-trivial extraction - // which forgets about the highest bit of 11-bit chunks. Sometimes, creation of additional goes for free (e.g. in current - // implementation, we do not have any penalty in prover's\verifier's workload with the introduction of new table as long as + // 2) we can use the same approach inside the "conversion into sparse majority form" function - or. in other words, + // create two tables instead of one: both will be base4_rot2, but the second one will also containt non-trivial extraction + // which forgets about the highest bit of 11-bit chunks. Sometimes, creation of additional goes for free (e.g. in current + // implementation, we do not have any penalty in prover's\verifier's workload with the introduction of new table as long as // there total number is less than closest power of 2). The choice of strategy: either work with two tables or work only with // base4_rot_2 and ALWAYS do overflow_check (even if we are sure, that we have only one bit of overflow) is handled // by MAJORITY_CONVERSION_STRATEGY flag - fn convert_into_sparse_majority_form>( - &self, - cs: &mut CS, - input: NumWithTracker, - ) -> Result> - { + fn convert_into_sparse_majority_form>(&self, cs: &mut CS, input: NumWithTracker) -> Result> { if let OverflowTracker::SignificantOverflow(n) = input.overflow_tracker { assert!(n <= self.max_of_width as u64); }; @@ -1049,8 +973,8 @@ impl Sha256Gadget { if let Num::Constant(x) = input.num { let repr = x.into_repr(); // NOTE : think, if it is safe for n to be overflowed - let n = repr.as_ref()[0] & ((1 << 32) - 1); - + let n = repr.as_ref()[0] & ((1 << 32) - 1); + let res = SparseMajValue { normal: (Num::Constant(x)).into(), sparse: Num::Constant(self.converter_helper(n, SHA256_MAJORITY_SHEDULER_BASE, 0, 0)), @@ -1058,14 +982,16 @@ impl Sha256Gadget { rot13: Num::Constant(self.converter_helper(n, SHA256_MAJORITY_SHEDULER_BASE, 13, 0)), rot22: Num::Constant(self.converter_helper(n, SHA256_MAJORITY_SHEDULER_BASE, 22, 0)), }; - return Ok(res) + return Ok(res); }; - let var = input.num.get_variable(); - let mut acc = var.clone(); + let var = input.num.get_variable(); + let mut acc = var.clone(); let cf = [ - E::Fr::one(), u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE), - u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE)), u64_to_ff(1 << SHA256_REG_WIDTH), + E::Fr::one(), + u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE), + u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE)), + u64_to_ff(1 << SHA256_REG_WIDTH), ]; match input.overflow_tracker { @@ -1073,20 +999,18 @@ impl Sha256Gadget { let of = self.allocate_converted_num(cs, &var, self.max_of_width, SHA256_REG_WIDTH, 0, 0, 0)?; self.of_range_check(cs, &of, &mut acc, &cf[3])?; } - _ => {}, + _ => {} } let full_normal = acc.clone(); - + // split our 32bit variable into 11-bit chunks: // there will be three chunks (low, mid, high) for 32bit number // note that, we can deal here with possible 1-bit overflow: (as 3 * 11 = 33) // in order to do this we allow extraction set to 10 for the table working with highest chunk - + let low = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, 0, 0, 0, 0)?; let mid = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, SHA256_GADGET_CHUNK_SIZE, 0, 0, 0)?; - let high = self.allocate_converted_num( - cs, &var, SHA256_GADGET_CHUNK_SIZE - 1, 2 * SHA256_GADGET_CHUNK_SIZE, 0, 0, SHA256_GADGET_CHUNK_SIZE - )?; + let high = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE - 1, 2 * SHA256_GADGET_CHUNK_SIZE, 0, 0, SHA256_GADGET_CHUNK_SIZE)?; let (sparse_low, sparse_low_rot2) = self.query_table_acc(cs, &self.sha256_base4_rot2_table, &low, &mut acc, &cf[0], false)?; let (sparse_mid, sparse_mid_rot2) = self.query_table_acc(cs, &self.sha256_base4_rot2_table, &mid, &mut acc, &cf[1], false)?; @@ -1094,15 +1018,13 @@ impl Sha256Gadget { let full_sparse = { // full_sparse = low_sparse + 4^11 * mid_sparse + 4^22 * high_sparse - let sparse_full = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 0, SHA256_REG_WIDTH - )?; + let sparse_full = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 0, SHA256_REG_WIDTH)?; let limb_1_shift = u64_exp_to_ff(4, 11); let limb_2_shift = u64_exp_to_ff(4, 22); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), limb_1_shift, limb_2_shift], &[sparse_low.clone(), sparse_mid.clone(), sparse_high.clone()], &sparse_full, @@ -1112,15 +1034,13 @@ impl Sha256Gadget { let full_sparse_rot2 = { // full_sparse_rot2 = low_sparse_rot2 + 4^(11-2) * sparse_mid + 4^(22-2) * sparse_high - let full_sparse_rot2 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 2, SHA256_REG_WIDTH - )?; + let full_sparse_rot2 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 2, SHA256_REG_WIDTH)?; let rot2_limb_1_shift = u64_exp_to_ff(4, 11 - 2); let rot2_limb_2_shift = u64_exp_to_ff(4, 22 - 2); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), rot2_limb_1_shift, rot2_limb_2_shift], &[sparse_low_rot2, sparse_mid.clone(), sparse_high.clone()], &full_sparse_rot2, @@ -1130,15 +1050,13 @@ impl Sha256Gadget { let full_sparse_rot13 = { // full_sparse_rot13 = sparse_mid_rot2 + 4^(22-11-2) * sparse_high + 4^(32-11-2) * sparse_low - let full_sparse_rot13 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 13, SHA256_REG_WIDTH - )?; + let full_sparse_rot13 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 13, SHA256_REG_WIDTH)?; let rot13_limb_0_shift = u64_exp_to_ff(4, 32 - 2 - 11); let rot13_limb_2_shift = u64_exp_to_ff(4, 22 - 2 - 11); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), rot13_limb_0_shift, rot13_limb_2_shift], &[sparse_mid_rot2, sparse_low.clone(), sparse_high.clone()], &full_sparse_rot13, @@ -1148,26 +1066,19 @@ impl Sha256Gadget { let full_sparse_rot_22 = { // full_sparse_rot22 = sparse_high + 4^(32 - 22) * sparse_low + 4^(32 - 22 + 11) * sparse_mid - let full_sparse_rot22 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 22, SHA256_REG_WIDTH - )?; + let full_sparse_rot22 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 22, SHA256_REG_WIDTH)?; let rot22_limb_0_shift = u64_exp_to_ff(4, 32 - 22); let rot22_limb_1_shift = u64_exp_to_ff(4, 32 - 22 + 11); - AllocatedNum::ternary_lc_eq( - cs, - &[E::Fr::one(), rot22_limb_0_shift, rot22_limb_1_shift], - &[sparse_high, sparse_low, sparse_mid], - &full_sparse_rot22, - )?; + AllocatedNum::ternary_lc_eq(cs, &[E::Fr::one(), rot22_limb_0_shift, rot22_limb_1_shift], &[sparse_high, sparse_low, sparse_mid], &full_sparse_rot22)?; full_sparse_rot22 }; - let res = SparseMajValue{ + let res = SparseMajValue { normal: NumWithTracker { - num: Num::Variable(full_normal), - overflow_tracker: OverflowTracker::NoOverflow, + num: Num::Variable(full_normal), + overflow_tracker: OverflowTracker::NoOverflow, }, sparse: Num::Variable(full_sparse), rot2: Num::Variable(full_sparse_rot2), @@ -1177,7 +1088,7 @@ impl Sha256Gadget { return Ok(res); } - // this function does the following: + // this function does the following: // given any x = \sum_{i=0}^{n} x_i * base^i and well-defined mapping f: [0; base-1] -> [0; 1] // (among possible variants for f are "parity": f(k) = k mod 2, choose_function or majority_function: // for the description of the latter two refer to "tables" module) @@ -1195,12 +1106,12 @@ impl Sha256Gadget { // each such y_j is in smaller range [0; base^NUM_CHUNKS-1] // and for each such y_j we may apply the corresponding (and realtively small) normalization table and get // z_j = \sum_{i=0}^{NUM_CHUNKS} f(x_{j * NUM_OF_CHUNKS + x_i}) 2^j - // the final z is then constructed as a linear conbination of {z_j} with simple weigt coefficients + // the final z is then constructed as a linear conbination of {z_j} with simple weigt coefficients // (in order for each z_j to be placed in an appropriate position in the bit representation of final result z) // // note, that for each possible pair of normalization transformation f(x) and base, // the parameter NUM_OF_CHUNKS may be determined separately - // + // // e.g. in reference implementation Barretenberg a = NUM_OF_CHUNKS = 4 for base = 7 and b = NUM_OF_CHUNKS = 6 for base = 4 // IMHO, the motivation for such choice of parameters is the following: // in any case we would use sparse_rotate_extract tables with 11-bit chunks (and hence of size c = 2^11) @@ -1211,43 +1122,42 @@ impl Sha256Gadget { // in any case we do not want to be two strict here, and allow NUM_OF_CHUNKS for bases 7 and 4 // to be specified as constructor parameters for Sha256Gadget gadget // - // NB1: we pack two different convertions x -> f(x), x -> g(x) in the same normalization table - // i.e. our column structure is: [x, f(x), g(x)], hence we need additional parameter "sel_flag", + // NB1: we pack two different convertions x -> f(x), x -> g(x) in the same normalization table + // i.e. our column structure is: [x, f(x), g(x)], hence we need additional parameter "sel_flag", // which chooses particular transform among the two (sel_flag is 0 for f(x), and 1 for g(x)) // // NB2: the final step of normalizer is the long weighted linear combination of chunks: // res = c0 * res0 + c1 * res1 + ... + cn * resn - // in our default setting the number of chunks is 4 or 7, so the corresponding lc + // in our default setting the number of chunks is 4 or 7, so the corresponding lc // can oocupy 1(2) gate(s) when we allow the result to be puton the next row // the possibility for such a trick in every concrete situation is determined by "use_d_next" flag // // NB3: the problem concerned in NB2 may be used solved by the following tactics: // instead of using d_next we may enlarge our MainGate type to allow using b_prev // (this is what the global flag with the same name in Sha256Gadget is linked to) - // this tactics is yet unused, and postponed for future releases + // this tactics is yet unused, and postponed for future releases fn normalize, F: Fn(E::Fr) -> E::Fr>( &self, - cs: &mut CS, - input: &Num, + cs: &mut CS, + input: &Num, table: &Arc>, - sel_flag: bool, + sel_flag: bool, converter_func: F, - base: usize, + base: usize, num_chunks: usize, use_d_next: bool, - ) -> Result<(Num, bool)> - { + ) -> Result<(Num, bool)> { if let Num::Constant(x) = input { let output = converter_func(x.clone()); return Ok((Num::Constant(output), false)); } let x = input.get_variable(); - + // split and slice! let num_slices = round_up(SHA256_REG_WIDTH, num_chunks); - let mut input_slices : Vec> = Vec::with_capacity(num_slices); - let mut output_slices : Vec> = Vec::with_capacity(num_slices); + let mut input_slices: Vec> = Vec::with_capacity(num_slices); + let mut output_slices: Vec> = Vec::with_capacity(num_slices); let input_slice_modulus = pow(base, num_chunks); let output_slice_modulus = pow(BINARY_BASE as usize, num_chunks); @@ -1257,7 +1167,7 @@ impl Sha256Gadget { let tmp = AllocatedNum::alloc(cs, || Err(SynthesisError::AssignmentMissing))?; input_slices.push(tmp); } - }, + } Some(f) => { // here we have to operate on row biguint number let mut big_f = BigUint::default(); @@ -1265,7 +1175,7 @@ impl Sha256Gadget { for n in f_repr.as_ref().iter().rev() { big_f <<= 64; big_f += *n; - } + } for _i in 0..num_slices { let remainder = (big_f.clone() % BigUint::from(input_slice_modulus)).to_u64().unwrap(); @@ -1289,85 +1199,91 @@ impl Sha256Gadget { let out_chunk = if !sel_flag { f_out_chunk } else { g_out_chunk }; output_slices.push(out_chunk); } - - let output = AllocatedNum::alloc(cs, || x.get_value().map(| fr | converter_func(fr)).grab())?; + + let output = AllocatedNum::alloc(cs, || x.get_value().map(|fr| converter_func(fr)).grab())?; let output_base = u64_to_ff(output_slice_modulus as u64); // TODO: use negative dialation for b_prev! - let d_next_actually_used = AllocatedNum::long_weighted_sum_eq(cs, &output_slices, &output_base, &output, use_d_next)?; + let d_next_actually_used = AllocatedNum::long_weighted_sum_eq(cs, &output_slices, &output_base, &output, use_d_next)?; Ok((Num::Variable(output), d_next_actually_used)) } fn choose(&self, cs: &mut CS, e: SparseChValue, f: SparseChValue, g: SparseChValue) -> Result> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { let mut two = E::Fr::one(); two.double(); let mut three = two.clone(); three.add_assign(&E::Fr::one()); - - let t0 = Num::lc(cs, &[E::Fr::one(), two, three], &[e.sparse, f.sparse, g.sparse])?; + + let t0 = Num::lc(cs, &[E::Fr::one(), two, three], &[e.sparse, f.sparse, g.sparse])?; let t1 = Num::lc(cs, &[E::Fr::one(), E::Fr::one(), E::Fr::one()], &[e.rot6, e.rot11, e.rot25])?; let (r0, _) = self.normalize( - cs, &t0, + cs, + &t0, &self.sha256_ch_normalization_table, false, - ch_ff_normalizer, - SHA256_CHOOSE_BASE as usize, + ch_ff_normalizer, + SHA256_CHOOSE_BASE as usize, self.ch_num_of_chunks, false, )?; let (r1, _) = self.normalize( - cs, &t1, + cs, + &t1, &self.sha256_ch_normalization_table, - true, + true, ch_xor_ff_normalizer, - SHA256_CHOOSE_BASE as usize, + SHA256_CHOOSE_BASE as usize, self.ch_num_of_chunks, true, )?; - let r0 : NumWithTracker = r0.into(); - let r1 : NumWithTracker = r1.into(); + let r0: NumWithTracker = r0.into(); + let r1: NumWithTracker = r1.into(); Ok(self.tracked_positioned_sum2_mod32(cs, r0, r1)?) } fn majority(&self, cs: &mut CS, a: SparseMajValue, b: SparseMajValue, c: SparseMajValue) -> Result> - where CS: ConstraintSystem - { - let t0 = Num::lc(cs, &[E::Fr::one(), E::Fr::one(), E::Fr::one()], &[a.sparse, b.sparse, c.sparse])?; + where + CS: ConstraintSystem, + { + let t0 = Num::lc(cs, &[E::Fr::one(), E::Fr::one(), E::Fr::one()], &[a.sparse, b.sparse, c.sparse])?; let t1 = Num::lc(cs, &[E::Fr::one(), E::Fr::one(), E::Fr::one()], &[a.rot2, a.rot13, a.rot22])?; let (r0, _) = self.normalize( - cs, &t0, + cs, + &t0, &self.sha256_maj_sheduler_normalization_table, false, - maj_ff_normalizer, - SHA256_MAJORITY_SHEDULER_BASE as usize, + maj_ff_normalizer, + SHA256_MAJORITY_SHEDULER_BASE as usize, self.maj_and_sheduler_num_of_chunks, false, )?; let (r1, _) = self.normalize( - cs, &t1, + cs, + &t1, &self.sha256_maj_sheduler_normalization_table, - true, + true, maj_and_sheduler_xor_ff_normalizer, - SHA256_MAJORITY_SHEDULER_BASE as usize, + SHA256_MAJORITY_SHEDULER_BASE as usize, self.maj_and_sheduler_num_of_chunks, true, )?; - let r0 : NumWithTracker = r0.into(); - let r1 : NumWithTracker = r1.into(); + let r0: NumWithTracker = r0.into(); + let r1: NumWithTracker = r1.into(); Ok(self.tracked_positioned_sum2_mod32(cs, r0, r1)?) } // -------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------- - // convertion and normalization routines for message expansion (sheduling) + // convertion and normalization routines for message expansion (sheduling) // --------------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------------- @@ -1377,12 +1293,13 @@ impl Sha256Gadget { // input is mutable as we are going to rewrite it with the same value but with of_extracted // returns (output, is_d_next_actually_used) fn sigma_0(&self, cs: &mut CS, input: &mut NumWithTracker, use_d_next: bool) -> Result<(Num, bool)> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { if let OverflowTracker::SignificantOverflow(n) = input.overflow_tracker { assert!(n <= self.max_of_width as u64); }; - + if let Num::Constant(x) = input.num { let repr = x.into_repr(); // NOTE : think, if it is safe for n to be overflowed @@ -1398,8 +1315,10 @@ impl Sha256Gadget { let var = input.num.get_variable(); let mut acc = var.clone(); let cf = [ - E::Fr::one(), u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE), - u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE)), u64_to_ff(1 << SHA256_REG_WIDTH), + E::Fr::one(), + u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE), + u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE)), + u64_to_ff(1 << SHA256_REG_WIDTH), ]; match input.overflow_tracker { @@ -1408,34 +1327,32 @@ impl Sha256Gadget { self.of_range_check(cs, &of, &mut acc, &cf[3])?; *input = NumWithTracker { num: Num::Variable(acc.clone()), - overflow_tracker: OverflowTracker::NoOverflow, + overflow_tracker: OverflowTracker::NoOverflow, }; } - _ => {}, + _ => {} } // split our 32bit variable into 11-bit chunks: // there will be three chunks (low, mid, high) for 32bit number let low = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, 0, 0, 0, 0)?; let mid = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, SHA256_GADGET_CHUNK_SIZE, 0, 0, 0)?; - let high = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE-1, 2 * SHA256_GADGET_CHUNK_SIZE, 0, 0, 0)?; + let high = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE - 1, 2 * SHA256_GADGET_CHUNK_SIZE, 0, 0, 0)?; let (sparse_low, sparse_low_rot7) = self.query_table_acc(cs, &self.sha256_base4_rot7_table, &low, &mut acc, &cf[0], false)?; - + let (sparse_mid, sparse_mid_rot7) = self.query_table_acc(cs, &self.sha256_base4_rot7_table, &mid, &mut acc, &cf[1], false)?; let (sparse_high, _) = self.query_table_acc(cs, &self.sha256_base4_rot2_width10_table, &high, &mut acc, &cf[2], true)?; let full_sparse_rot7 = { // full_sparse_rot7 = low_sparse_rot7 + 4^(11-7) * sparse_mid + 4^(22-7) * sparse_high - let full_sparse_rot7 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 7, 0 - )?; + let full_sparse_rot7 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 7, 0)?; let rot7_limb_1_shift = u64_exp_to_ff(4, 11 - 7); let rot7_limb_2_shift = u64_exp_to_ff(4, 22 - 7); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), rot7_limb_1_shift, rot7_limb_2_shift], &[sparse_low_rot7, sparse_mid.clone(), sparse_high.clone()], &full_sparse_rot7, @@ -1445,15 +1362,13 @@ impl Sha256Gadget { let full_sparse_rot18 = { // full_sparse_rot18 = sparse_mid_rot7 + 4^(22-11-7) * sparse_high + 4^(32-11-7) * sparse_low - let full_sparse_rot18 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 18, 0 - )?; + let full_sparse_rot18 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 18, 0)?; let rot18_limb_0_shift = u64_exp_to_ff(4, 32 - 7 - 11); let rot18_limb_2_shift = u64_exp_to_ff(4, 22 - 7 - 11); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), rot18_limb_0_shift, rot18_limb_2_shift], &[sparse_mid_rot7, sparse_low.clone(), sparse_high.clone()], &full_sparse_rot18, @@ -1463,11 +1378,11 @@ impl Sha256Gadget { let full_sparse_shift_3 = { let (r3, _) = self.query_table(cs, &self.sha256_sheduler_helper_table, &low)?; - - let new_val = var.get_value().map( |fr| { + + let new_val = var.get_value().map(|fr| { let input_repr = fr.into_repr(); let n = input_repr.as_ref()[0] & ((1 << SHA256_REG_WIDTH) - 1); - + let m = map_into_sparse_form(shift_right(n as usize, 3), SHA256_MAJORITY_SHEDULER_BASE as usize); E::Fr::from_str(&m.to_string()).unwrap() }); @@ -1476,25 +1391,21 @@ impl Sha256Gadget { // full_sparse_shift3 = sparse_low_shift3 + 4^(11 - 3) * sparse_mid + 4^(22 - 3) * sparse_high let shift3_limb_1_shift = u64_exp_to_ff(4, 11 - 3); let shift3_limb_2_shift = u64_exp_to_ff(4, 22 - 3); - - AllocatedNum::ternary_lc_eq( - cs, - &[E::Fr::one(), shift3_limb_1_shift, shift3_limb_2_shift], - &[r3, sparse_mid, sparse_high], - &full_sparse_shift3, - )?; + + AllocatedNum::ternary_lc_eq(cs, &[E::Fr::one(), shift3_limb_1_shift, shift3_limb_2_shift], &[r3, sparse_mid, sparse_high], &full_sparse_shift3)?; full_sparse_shift3 }; - // now we have all the components: + // now we have all the components: // S7 = full_sparse_rot7, S18 = full_sparse_rot18, R3 = full_sparse_shift3 - let t = Num::Variable(full_sparse_rot7.add_two(cs, full_sparse_rot18, full_sparse_shift_3)?); + let t = Num::Variable(full_sparse_rot7.add_two(cs, full_sparse_rot18, full_sparse_shift_3)?); let (r, d_next_flag) = self.normalize( - cs, &t, + cs, + &t, &self.sha256_maj_sheduler_normalization_table, true, - maj_and_sheduler_xor_ff_normalizer, - SHA256_MAJORITY_SHEDULER_BASE as usize, + maj_and_sheduler_xor_ff_normalizer, + SHA256_MAJORITY_SHEDULER_BASE as usize, self.maj_and_sheduler_num_of_chunks, use_d_next, )?; @@ -1508,12 +1419,13 @@ impl Sha256Gadget { // 10 bits, so x = | 11 | 11 | 10 | is still 32 bits-length in total // such an unusual split will simplify R_10 in an obvious way fn sigma_1(&self, cs: &mut CS, input: &mut NumWithTracker, use_d_next: bool) -> Result<(Num, bool)> - where CS: ConstraintSystem + where + CS: ConstraintSystem, { if let OverflowTracker::SignificantOverflow(n) = input.overflow_tracker { assert!(n <= self.max_of_width as u64); }; - + if let Num::Constant(x) = input.num { let repr = x.into_repr(); // NOTE : think, if it is safe for n to be overflowed @@ -1522,16 +1434,18 @@ impl Sha256Gadget { let s17 = rotate_extract(n, 17, 0); let s19 = rotate_extract(n, 19, 0); let r10 = shift_right(n, 10); - let res = u64_to_ff((s17 ^ s19 ^ r10) as u64); - + let res = u64_to_ff((s17 ^ s19 ^ r10) as u64); + return Ok((Num::Constant(res), false)); } let var = input.num.get_variable(); let mut acc = var.clone(); let cf = [ - E::Fr::one(), u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE - 1), - u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE) - 1), u64_to_ff(1 << SHA256_REG_WIDTH), + E::Fr::one(), + u64_to_ff(1 << SHA256_GADGET_CHUNK_SIZE - 1), + u64_to_ff(1 << (2 * SHA256_GADGET_CHUNK_SIZE) - 1), + u64_to_ff(1 << SHA256_REG_WIDTH), ]; match input.overflow_tracker { @@ -1540,17 +1454,17 @@ impl Sha256Gadget { self.of_range_check(cs, &of, &mut acc, &cf[3])?; *input = NumWithTracker { num: Num::Variable(acc.clone()), - overflow_tracker: OverflowTracker::NoOverflow, + overflow_tracker: OverflowTracker::NoOverflow, }; } - _ => {}, + _ => {} } - + // split our 32bit variable into one 10-bit chunk (lowest one) and two 11-bit chunks: // there will be three chunks (low, mid, high) for 32bit number - let low = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE-1, 0, 0, 0, 0)?; - let mid = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, SHA256_GADGET_CHUNK_SIZE-1, 0, 0, 0)?; - let high = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, 2*SHA256_GADGET_CHUNK_SIZE-1, 0, 0, 0)?; + let low = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE - 1, 0, 0, 0, 0)?; + let mid = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, SHA256_GADGET_CHUNK_SIZE - 1, 0, 0, 0)?; + let high = self.allocate_converted_num(cs, &var, SHA256_GADGET_CHUNK_SIZE, 2 * SHA256_GADGET_CHUNK_SIZE - 1, 0, 0, 0)?; let (sparse_low, _) = self.query_table_acc(cs, &self.sha256_base4_rot2_width10_table, &low, &mut acc, &cf[0], false)?; let (sparse_mid, sparse_mid_rot7) = self.query_table_acc(cs, &self.sha256_base4_rot7_table, &mid, &mut acc, &cf[1], false)?; @@ -1558,15 +1472,13 @@ impl Sha256Gadget { let full_sparse_rot17 = { // full_sparse_rot17 = mid_sparse_rot7 + 4^(11-7) * sparse_high + 4^(22-7) * sparse_low - let full_sparse_rot17 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 17, 0 - )?; + let full_sparse_rot17 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 17, 0)?; let rot17_limb_2_shift = u64_exp_to_ff(4, 11 - 7); let rot17_limb_0_shift = u64_exp_to_ff(4, 22 - 7); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), rot17_limb_0_shift, rot17_limb_2_shift], &[sparse_mid_rot7, sparse_low.clone(), sparse_high.clone()], &full_sparse_rot17, @@ -1577,14 +1489,12 @@ impl Sha256Gadget { let full_sparse_shift10 = { // full_sparse_shift10 = mid_sparse + 4^(11) * sparse_high - let full_sparse_shift10 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH - 10, 10, SHA256_MAJORITY_SHEDULER_BASE, 0, 0, - )?; + let full_sparse_shift10 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH - 10, 10, SHA256_MAJORITY_SHEDULER_BASE, 0, 0)?; let dummy = AllocatedNum::zero(cs); let shift10_limb_2_shift = u64_exp_to_ff(4, 11); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), shift10_limb_2_shift, E::Fr::zero()], &[sparse_mid.clone(), sparse_high.clone(), dummy], &full_sparse_shift10, @@ -1593,18 +1503,16 @@ impl Sha256Gadget { }; let full_sparse_rot19 = { - let (_, sparse_mid_rot9) = self.query_table(cs, &self.sha256_sheduler_helper_table, &mid)?; - + let (_, sparse_mid_rot9) = self.query_table(cs, &self.sha256_sheduler_helper_table, &mid)?; + // full_sparse_rot19 = mid_sparse_rot9 + 4^(11-9) * sparse_high + 4^(22-9) * sparse_low - let full_sparse_rot19 = self.allocate_converted_num( - cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 19, 0 - )?; - + let full_sparse_rot19 = self.allocate_converted_num(cs, &var, SHA256_REG_WIDTH, 0, SHA256_MAJORITY_SHEDULER_BASE, 19, 0)?; + let rot19_limb_0_shift = u64_exp_to_ff(4, 22 - 9); let rot19_limb_2_shift = u64_exp_to_ff(4, 11 - 9); AllocatedNum::ternary_lc_eq( - cs, + cs, &[E::Fr::one(), rot19_limb_0_shift, rot19_limb_2_shift], &[sparse_mid_rot9, sparse_low, sparse_high], &full_sparse_rot19, @@ -1612,17 +1520,18 @@ impl Sha256Gadget { full_sparse_rot19 }; - let t = Num::Variable(full_sparse_rot17.add_two(cs, full_sparse_rot19, full_sparse_shift10)?); + let t = Num::Variable(full_sparse_rot17.add_two(cs, full_sparse_rot19, full_sparse_shift10)?); let (r, d_next_flag) = self.normalize( - cs, &t, + cs, + &t, &self.sha256_maj_sheduler_normalization_table, true, - maj_and_sheduler_xor_ff_normalizer, - SHA256_MAJORITY_SHEDULER_BASE as usize, + maj_and_sheduler_xor_ff_normalizer, + SHA256_MAJORITY_SHEDULER_BASE as usize, self.maj_and_sheduler_num_of_chunks, use_d_next, )?; - + return Ok((r, d_next_flag)); } @@ -1631,23 +1540,22 @@ impl Sha256Gadget { // Wj = Mj for j = [0; 15] // For j = 16 to 63: // Wj = sigma_1(W_{j-2}) + W_{j-7} + sigma_0(W_{j-15}) + W_{j-16} - // where + // where // sigma_0(x) = S_7(x) ^ S_18(x) ^ R_3(x) // sigma_1(x) = S_17(x) ^ S_19(x) ^ R_10(x) // here S_n - is right circular n-bit rotation // and R_n - right n-nit shift - fn message_expansion>(&self, cs: &mut CS, message: &[Num]) -> Result>> - { + fn message_expansion>(&self, cs: &mut CS, message: &[Num]) -> Result>> { assert_eq!(message.len(), 16); - let mut res : Vec> = Vec::with_capacity(64); + let mut res: Vec> = Vec::with_capacity(64); for i in 0..16 { res.push(message[i].clone().into()); - } + } for j in 16..64 { let (tmp1, _) = self.sigma_1(cs, &mut res[j - 2], true)?; - let mut sum = self.tracked_positioned_sum3_mod32(cs, res[j-7].clone(), res[j-16].clone(), tmp1.into())?; + let mut sum = self.tracked_positioned_sum3_mod32(cs, res[j - 7].clone(), res[j - 16].clone(), tmp1.into())?; let (tmp2, _) = self.sigma_0(cs, &mut res[j - 15], true)?; sum = self.tracked_positioned_sum2_mod32(cs, sum, tmp2.into())?; @@ -1661,21 +1569,14 @@ impl Sha256Gadget { // Sha256 single block processor // ------------------------------------------------------------------------------------------------------------------------- - // one round of inner SHA256 cycle + // one round of inner SHA256 cycle // the hash for single block of 512 chunks requires 64 such cycles - fn sha256_inner_block>( - &self, - cs: &mut CS, - regs: Sha256Registers, - inputs: &[NumWithTracker], - round_constants: &[E::Fr], - ) -> Result> - { + fn sha256_inner_block>(&self, cs: &mut CS, regs: Sha256Registers, inputs: &[NumWithTracker], round_constants: &[E::Fr]) -> Result> { let mut a = self.convert_into_sparse_majority_form(cs, regs.a.clone())?; let mut b = self.convert_into_sparse_majority_form(cs, regs.b.clone())?; let mut c = self.convert_into_sparse_majority_form(cs, regs.c.clone())?; let mut d = self.convert_into_sparse_majority_form(cs, regs.d.clone())?; - + let mut e = self.convert_into_sparse_chooser_form(cs, regs.e.clone())?; let mut f = self.convert_into_sparse_chooser_form(cs, regs.f.clone())?; let mut g = self.convert_into_sparse_chooser_form(cs, regs.g.clone())?; @@ -1693,10 +1594,10 @@ impl Sha256Gadget { for i in 0..64 { let ch = self.choose(cs, e.clone(), f.clone(), g.clone())?; let maj = self.majority(cs, a.clone(), b.clone(), c.clone())?; - + let rc = round_constants[i].clone(); let temp1 = self.tracked_positioned_sum3_with_cnst_mod32(cs, h.normal, ch, inputs[i].clone(), rc)?; - + h = g; g = f; f = e; @@ -1709,7 +1610,7 @@ impl Sha256Gadget { b = a; let temp3 = self.tracked_positioned_sum2_mod32(cs, maj, temp1)?; - a =self.convert_into_sparse_majority_form(cs, temp3)?; + a = self.convert_into_sparse_majority_form(cs, temp3)?; } let regs = Sha256Registers { @@ -1722,18 +1623,17 @@ impl Sha256Gadget { g: self.tracked_positioned_sum2_mod32(cs, reduced_old_g, g.normal)?, h: self.tracked_positioned_sum2_mod32(cs, reduced_old_h, h.normal)?, }; - + Ok(regs) } /// expects well formed and padded input, outputs 32 bit words /// Can be used when we perform something like sha256(truncate(sha256(a)), truncate(sha256(b))) /// to fit hashing of truncated outputs into the single round - pub fn sha256>(&self, cs: &mut CS, message: &[Num]) -> Result<[Num; 8]> - { + pub fn sha256>(&self, cs: &mut CS, message: &[Num]) -> Result<[Num; 8]> { // we assume that input is already well-padded assert!(message.len() % 16 == 0); - + let mut regs = Sha256Registers { a: Num::Constant(self.iv[0].clone()).into(), b: Num::Constant(self.iv[1].clone()).into(), @@ -1785,9 +1685,7 @@ impl Sha256Gadget { } /// expects inner state as 8 32-bit words and input as 16 32-bit words, and outputs and updated state - pub fn sha256_round_function>(&self, cs: &mut CS, inner_state: [Num; 8], round_input: &[Num; 16]) -> Result<[Num; 8]> - { - + pub fn sha256_round_function>(&self, cs: &mut CS, inner_state: [Num; 8], round_input: &[Num; 16]) -> Result<[Num; 8]> { let state = Sha256Registers { a: inner_state[0].into(), b: inner_state[1].into(), @@ -1798,7 +1696,7 @@ impl Sha256Gadget { g: inner_state[6].into(), h: inner_state[7].into(), }; - + let expanded_block = self.message_expansion(cs, round_input)?; let state = self.sha256_inner_block(cs, state, &expanded_block[..], &self.round_constants)?; @@ -1819,10 +1717,9 @@ impl Sha256Gadget { // --------------------------------------------------------------------------------------------------------------------------- // public interface: exported functions // --------------------------------------------------------------------------------------------------------------------------- - + /// take bytes as input and return Num as output, where each Num is 32 bit integer - pub fn sha256_from_bytes>(&self, cs: &mut CS, bytes: &[Byte]) -> Result<[Num; 8]> - { + pub fn sha256_from_bytes>(&self, cs: &mut CS, bytes: &[Byte]) -> Result<[Num; 8]> { // first apply the right padding: // begin with the original message of length L bits // append a single '1' bit @@ -1832,11 +1729,10 @@ impl Sha256Gadget { let last_block_size = bytes.len() % 64; let (num_of_zero_bytes, _pad_overflowed) = if last_block_size <= (64 - 1 - 8) { (64 - 1 - 8 - last_block_size, false) - } - else { + } else { (128 - 1 - 8 - last_block_size, true) }; - + let mut padded = vec![]; padded.extend(bytes.iter().cloned()); padded.push(Byte::from_cnst(u64_to_ff(1 << 7))); @@ -1844,7 +1740,7 @@ impl Sha256Gadget { // represent L as big integer number: let repr = message_bitlen.to_be_bytes(); - padded.extend(repr.iter().map(|num| { Byte::from_cnst(u64_to_ff(*num as u64)) })); + padded.extend(repr.iter().map(|num| Byte::from_cnst(u64_to_ff(*num as u64)))); assert_eq!(padded.len() % 64, 0); @@ -1852,20 +1748,15 @@ impl Sha256Gadget { let mut words32 = Vec::with_capacity(padded.len() % 4); let cfs = [u64_to_ff(1 << 24), u64_to_ff(1 << 16), u64_to_ff(1 << 8), E::Fr::one()]; for chunk in padded.chunks(4) { - let tmp = Num::lc( - cs, - &cfs, - &[chunk[0].into_num(), chunk[1].into_num(), chunk[2].into_num(), chunk[3].into_num()], - )?; + let tmp = Num::lc(cs, &cfs, &[chunk[0].into_num(), chunk[1].into_num(), chunk[2].into_num(), chunk[3].into_num()])?; words32.push(tmp); } - self.sha256(cs, &words32[..]) + self.sha256(cs, &words32[..]) } /// take bytes as input and return bytes as output - pub fn sha256_from_bytes_to_bytes>(&self, cs: &mut CS, bytes: &[Byte]) -> Result<[Byte; 32]> - { + pub fn sha256_from_bytes_to_bytes>(&self, cs: &mut CS, bytes: &[Byte]) -> Result<[Byte; 32]> { use plonk::circuit::byte::num_into_bytes_be; let as_nums = self.sha256_from_bytes(cs, bytes)?; @@ -1880,4 +1771,3 @@ impl Sha256Gadget { Ok(gadget_output) } } - diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/mod.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/mod.rs index ac66f6f..4a3989e 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/mod.rs @@ -1,4 +1,4 @@ -pub mod utils; -pub mod tables; pub mod gadgets; -pub mod test; \ No newline at end of file +pub mod tables; +pub mod test; +pub mod utils; diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/tables.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/tables.rs index d362b95..3037340 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/tables.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/tables.rs @@ -1,13 +1,12 @@ +use crate::bellman::pairing::ff::*; use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::plonk::better_better_cs::lookup_tables::*; use crate::bellman::plonk::better_better_cs::utils; -use crate::bellman::pairing::ff::*; -use crate::bellman::SynthesisError; use crate::bellman::Engine; +use crate::bellman::SynthesisError; -use super::utils::*; use super::super::utils::*; - +use super::utils::*; // SHA256 SPECIFIC TABLES (so to say) // ---------------------------------------------------------------------------------------------------------------------------- @@ -38,7 +37,7 @@ impl Sha256ShedulerHelperTable { for x in 0..(1 << bits) { let y = map_into_sparse_form(shift_right(x, shift), base); let z = map_into_sparse_form(rotate_extract(x, rot, 0), base); - + let x = E::Fr::from_str(&x.to_string()).unwrap(); let y = E::Fr::from_str(&y.to_string()).unwrap(); let z = E::Fr::from_str(&z.to_string()).unwrap(); @@ -60,8 +59,7 @@ impl Sha256ShedulerHelperTable { impl std::fmt::Debug for Sha256ShedulerHelperTable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Sha256ExtensionHelperTable") - .finish() + f.debug_struct("Sha256ExtensionHelperTable").finish() } } @@ -112,10 +110,9 @@ impl LookupTableInternal for Sha256ShedulerHelperTable { assert!(keys.len() == self.num_keys()); if let Some(entry) = self.table_lookup_map.get(&keys[0]) { - return Ok(vec![entry.0, entry.1]) + return Ok(vec![entry.0, entry.1]); } Err(SynthesisError::Unsatisfiable) } } - diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/test.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/test.rs index e35526e..902ea78 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/test.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/test.rs @@ -1,27 +1,21 @@ #[cfg(test)] mod test { - use crate::bellman::plonk::better_better_cs::cs::*; + use crate::bellman::pairing::bn256::{Bn256, Fr}; use crate::bellman::pairing::ff::*; - use crate::bellman::SynthesisError; + use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::Engine; - use crate::sha2::{Sha256, Digest}; - use crate::plonk::circuit::allocated_num::{ - AllocatedNum, - Num, - }; - use crate::plonk::circuit::byte::{ - Byte, - }; - use crate::bellman::pairing::bn256::{Bn256, Fr}; + use crate::bellman::SynthesisError; + use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; + use crate::plonk::circuit::byte::Byte; + use crate::sha2::{Digest, Sha256}; + use super::super::super::utils::*; use super::super::gadgets::*; use super::super::utils::*; - use super::super::super::utils::*; use rand::{Rng, SeedableRng, StdRng}; - - struct TestSha256Circuit{ + struct TestSha256Circuit { input: Vec, output: [E::Fr; 8], ch_base_num_of_chunks: Option, @@ -30,57 +24,45 @@ mod test { is_byte_test: bool, } - impl Circuit for TestSha256Circuit - { + impl Circuit for TestSha256Circuit { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Width4MainGateWithDNext::default().into_internal(), - ] - ) + Ok(vec![Width4MainGateWithDNext::default().into_internal()]) } fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - let mut actual_output_vars = Vec::with_capacity(16); for value in self.output.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc_input(cs, || Ok(value.clone()))?; actual_output_vars.push(Num::Variable(new_var)); - } - else { + } else { actual_output_vars.push(Num::Constant(value.clone())); } } - let sha256_gadget = Sha256Gadget::new( - cs, self.ch_base_num_of_chunks, self.maj_sheduler_base_num_of_chunks, false, false, 0, "", - )?; + let sha256_gadget = Sha256Gadget::new(cs, self.ch_base_num_of_chunks, self.maj_sheduler_base_num_of_chunks, false, false, 0, "")?; - let supposed_output_vars = if !self.is_byte_test { + let supposed_output_vars = if !self.is_byte_test { let mut input_vars = Vec::with_capacity(self.input.len()); for value in self.input.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc(cs, || Ok(value.clone()))?; input_vars.push(Num::Variable(new_var)); - } - else { + } else { input_vars.push(Num::Constant(value.clone())); } } sha256_gadget.sha256(cs, &input_vars[..])? - } - else { + } else { let mut input_vars = Vec::with_capacity(self.input.len()); for value in self.input.iter() { if !self.is_const_test { let new_var = AllocatedNum::alloc(cs, || Ok(value.clone()))?; let byte = Byte::from_num_unconstrained(cs, Num::Variable(new_var)); input_vars.push(byte); - } - else { + } else { let byte = Byte::from_cnst(value.clone()); input_vars.push(byte); } @@ -98,14 +80,13 @@ mod test { fn slice_to_ff(slice: &[u8]) -> Fr { assert_eq!(slice.len(), 4); - let mut repr : ::Repr = Fr::zero().into_repr(); + let mut repr: ::Repr = Fr::zero().into_repr(); repr.as_mut()[0] = slice[3] as u64 + ((slice[2] as u64) << 8) + ((slice[1] as u64) << 16) + ((slice[0] as u64) << 24); Fr::from_repr(repr).expect("should parse") } #[test] - fn polished_sha256_gadget_single_block_test() - { + fn polished_sha256_gadget_single_block_test() { // SHA256 Pre-processing (Padding): // begin with the original message of length L bits // append a single '1' bit @@ -139,8 +120,8 @@ mod test { for (i, block) in output.chunks(4).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestSha256Circuit::{ + + let circuit = TestSha256Circuit:: { input: input_fr_arr, output: output_fr_arr, ch_base_num_of_chunks: None, @@ -158,27 +139,26 @@ mod test { } #[test] - fn polished_sha256_gadget_multiple_blocks_test() - { + fn polished_sha256_gadget_multiple_blocks_test() { const NUM_OF_BLOCKS: usize = 2; let mut rng = rand::thread_rng(); let mut input = [0u8; 64 * NUM_OF_BLOCKS]; - for i in 0..(64 * (NUM_OF_BLOCKS-1) + 55) { + for i in 0..(64 * (NUM_OF_BLOCKS - 1) + 55) { input[i] = rng.gen(); } - input[64 * (NUM_OF_BLOCKS-1) + 55] = 0b10000000; - - let total_number_of_bits = (64 * (NUM_OF_BLOCKS-1) + 55) * 8; - input[64 * (NUM_OF_BLOCKS-1) + 60] = (total_number_of_bits >> 24) as u8; - input[64 * (NUM_OF_BLOCKS-1) + 61] = (total_number_of_bits >> 16) as u8; - input[64 * (NUM_OF_BLOCKS-1) + 62] = (total_number_of_bits >> 8) as u8; - input[64 * (NUM_OF_BLOCKS-1) + 63] = total_number_of_bits as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 55] = 0b10000000; + + let total_number_of_bits = (64 * (NUM_OF_BLOCKS - 1) + 55) * 8; + input[64 * (NUM_OF_BLOCKS - 1) + 60] = (total_number_of_bits >> 24) as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 61] = (total_number_of_bits >> 16) as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 62] = (total_number_of_bits >> 8) as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 63] = total_number_of_bits as u8; // create a Sha256 object let mut hasher = Sha256::new(); // write input message - hasher.update(&input[0..(64 * (NUM_OF_BLOCKS-1) + 55)]); + hasher.update(&input[0..(64 * (NUM_OF_BLOCKS - 1) + 55)]); // read hash digest and consume hasher let output = hasher.finalize(); @@ -192,8 +172,8 @@ mod test { for (i, block) in output.chunks(4).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestSha256Circuit::{ + + let circuit = TestSha256Circuit:: { input: input_fr_arr, output: output_fr_arr, ch_base_num_of_chunks: None, @@ -211,27 +191,26 @@ mod test { } #[test] - fn polished_sha256_gadget_const_propagation_test() - { + fn polished_sha256_gadget_const_propagation_test() { const NUM_OF_BLOCKS: usize = 3; let mut rng = rand::thread_rng(); let mut input = [0u8; 64 * NUM_OF_BLOCKS]; - for i in 0..(64 * (NUM_OF_BLOCKS-1) + 55) { + for i in 0..(64 * (NUM_OF_BLOCKS - 1) + 55) { input[i] = rng.gen(); } - input[64 * (NUM_OF_BLOCKS-1) + 55] = 0b10000000; - - let total_number_of_bits = (64 * (NUM_OF_BLOCKS-1) + 55) * 8; - input[64 * (NUM_OF_BLOCKS-1) + 60] = (total_number_of_bits >> 24) as u8; - input[64 * (NUM_OF_BLOCKS-1) + 61] = (total_number_of_bits >> 16) as u8; - input[64 * (NUM_OF_BLOCKS-1) + 62] = (total_number_of_bits >> 8) as u8; - input[64 * (NUM_OF_BLOCKS-1) + 63] = total_number_of_bits as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 55] = 0b10000000; + + let total_number_of_bits = (64 * (NUM_OF_BLOCKS - 1) + 55) * 8; + input[64 * (NUM_OF_BLOCKS - 1) + 60] = (total_number_of_bits >> 24) as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 61] = (total_number_of_bits >> 16) as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 62] = (total_number_of_bits >> 8) as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 63] = total_number_of_bits as u8; // create a Sha256 object let mut hasher = Sha256::new(); // write input message - hasher.update(&input[0..(64 * (NUM_OF_BLOCKS-1) + 55)]); + hasher.update(&input[0..(64 * (NUM_OF_BLOCKS - 1) + 55)]); // read hash digest and consume hasher let output = hasher.finalize(); @@ -245,8 +224,8 @@ mod test { for (i, block) in output.chunks(4).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestSha256Circuit::{ + + let circuit = TestSha256Circuit:: { input: input_fr_arr, output: output_fr_arr, ch_base_num_of_chunks: None, @@ -264,8 +243,7 @@ mod test { } #[test] - fn polished_sha256_gadget_bytes_test() - { + fn polished_sha256_gadget_bytes_test() { const NUM_OF_BYTES: usize = 22560; const IS_CONST_TEST: bool = false; @@ -275,7 +253,7 @@ mod test { for i in 0..NUM_OF_BYTES { input[i] = rng.gen(); } - + // create a Sha256 object let mut hasher = Sha256::new(); // write input message @@ -283,16 +261,16 @@ mod test { // read hash digest and consume hasher let output = hasher.finalize(); - let mut input_fr_arr : Vec<::Fr> = Vec::with_capacity(NUM_OF_BYTES); + let mut input_fr_arr: Vec<::Fr> = Vec::with_capacity(NUM_OF_BYTES); let mut output_fr_arr = [Fr::zero(); 8]; input_fr_arr.extend(input.iter().map(|byte| u64_to_ff::<::Fr>(*byte as u64))); - + for (i, block) in output.chunks(4).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestSha256Circuit::{ + + let circuit = TestSha256Circuit:: { input: input_fr_arr, output: output_fr_arr, ch_base_num_of_chunks: None, @@ -315,21 +293,21 @@ mod test { let mut rng = rand::thread_rng(); let mut input = [0u8; 64 * NUM_OF_BLOCKS]; - for i in 0..(64 * (NUM_OF_BLOCKS-1) + 55) { + for i in 0..(64 * (NUM_OF_BLOCKS - 1) + 55) { input[i] = rng.gen(); } - input[64 * (NUM_OF_BLOCKS-1) + 55] = 0b10000000; - - let total_number_of_bits = (64 * (NUM_OF_BLOCKS-1) + 55) * 8; - input[64 * (NUM_OF_BLOCKS-1) + 60] = (total_number_of_bits >> 24) as u8; - input[64 * (NUM_OF_BLOCKS-1) + 61] = (total_number_of_bits >> 16) as u8; - input[64 * (NUM_OF_BLOCKS-1) + 62] = (total_number_of_bits >> 8) as u8; - input[64 * (NUM_OF_BLOCKS-1) + 63] = total_number_of_bits as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 55] = 0b10000000; + + let total_number_of_bits = (64 * (NUM_OF_BLOCKS - 1) + 55) * 8; + input[64 * (NUM_OF_BLOCKS - 1) + 60] = (total_number_of_bits >> 24) as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 61] = (total_number_of_bits >> 16) as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 62] = (total_number_of_bits >> 8) as u8; + input[64 * (NUM_OF_BLOCKS - 1) + 63] = total_number_of_bits as u8; // create a Sha256 object let mut hasher = Sha256::new(); // write input message - hasher.update(&input[0..(64 * (NUM_OF_BLOCKS-1) + 55)]); + hasher.update(&input[0..(64 * (NUM_OF_BLOCKS - 1) + 55)]); // read hash digest and consume hasher let output = hasher.finalize(); @@ -343,8 +321,8 @@ mod test { for (i, block) in output.chunks(4).enumerate() { output_fr_arr[i] = slice_to_ff::(block); } - - let circuit = TestSha256Circuit::{ + + let circuit = TestSha256Circuit:: { input: input_fr_arr, output: output_fr_arr, ch_base_num_of_chunks: None, @@ -359,21 +337,19 @@ mod test { assert!(assembly.is_satisfied()); use crate::bellman::kate_commitment::{Crs, CrsForMonomialForm}; - use crate::bellman::worker::Worker; - use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; use crate::bellman::plonk::better_better_cs::setup::VerificationKey; use crate::bellman::plonk::better_better_cs::verifier::verify; + use crate::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; + use crate::bellman::worker::Worker; let worker = Worker::new(); let setup_size = assembly.n().next_power_of_two(); let crs = Crs::::dummy_crs(setup_size); - let setup = assembly.create_setup::>(&worker).unwrap(); + let setup = assembly.create_setup::>(&worker).unwrap(); let vk = VerificationKey::from_setup(&setup, &worker, &crs).unwrap(); - - let proof = assembly - .create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs, None) - .unwrap(); + + let proof = assembly.create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs, None).unwrap(); let valid = verify::<_, _, RollingKeccakTranscript>(&vk, &proof, None).unwrap(); assert!(valid); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/utils.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/utils.rs index 10644e5..9830adf 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/utils.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/sha256/utils.rs @@ -1,19 +1,18 @@ -use crate::bellman::pairing::ff::*; use super::super::utils::*; +use crate::bellman::pairing::ff::*; pub const SHA256_CHOOSE_BASE: u64 = 7; pub const SHA256_MAJORITY_SHEDULER_BASE: u64 = 4; - // Sha256 choose (ch) transform: -// one of major components of Sha256 hash is bitwise application for a choose function +// one of major components of Sha256 hash is bitwise application for a choose function // choose(e, f, g) = (e & f) ^ (~e & g), where e, f, g - bits for current 32bit-words E, F, G -// in order to do it effectively we take the following approach: -// convert all of E, F, G into sparse form with base 7 with the help od Sha256SparseRotateTable -// now for a given bits (e, f, g) and t = (e & f) ^ (~e & g) we apply Daira's trick: want to create a unique encoding of 't', +// in order to do it effectively we take the following approach: +// convert all of E, F, G into sparse form with base 7 with the help od Sha256SparseRotateTable +// now for a given bits (e, f, g) and t = (e & f) ^ (~e & g) we apply Daira's trick: want to create a unique encoding of 't', // using some arithmetic relationship between e, f and g. // one of such possible algebraic mappings is between t and e + 2f + 3g: -// +// // | e | f | g | t | e + 2f + 3g | // ------------------------------- // | 0 | 0 | 0 | 0 | 0 | @@ -27,7 +26,7 @@ pub const SHA256_MAJORITY_SHEDULER_BASE: u64 = 4; // -------------------------------- // // so there is a well defined algebraic encoding for ch: t = f(x) from x = e + 2f + 3g \in [0, 6] to t \in [0, 1]. -pub const CH_BIT_TABLE : [u64; SHA256_CHOOSE_BASE as usize] = [ +pub const CH_BIT_TABLE: [u64; SHA256_CHOOSE_BASE as usize] = [ 0, // e + 2f + 3g = 0 => e = 0, f = 0, g = 0 => t = 0 0, // e + 2f + 3g = 1 => e = 1, f = 0, g = 0 => t = 0 0, // e + 2f + 3g = 2 => e = 0, f = 1, g = 0 => t = 0 @@ -41,9 +40,8 @@ pub fn ch_u64_normalizer(n: u64) -> u64 { CH_BIT_TABLE[n as usize] } -pub fn ch_ff_normalizer(fr: Fr) -> Fr -{ - let bit_table : [u64; SHA256_CHOOSE_BASE as usize] = [ 0, 0, 0, 1, 0, 1, 1 ]; +pub fn ch_ff_normalizer(fr: Fr) -> Fr { + let bit_table: [u64; SHA256_CHOOSE_BASE as usize] = [0, 0, 0, 1, 0, 1, 1]; let base = SHA256_CHOOSE_BASE; general_normalizer(fr, &bit_table[..], base) } @@ -65,7 +63,7 @@ pub fn ch_ff_normalizer(fr: Fr) -> Fr // | 1 | 1 | 1 | 0 | 3 | // // this well-formed function f(x): [0; 3] -> [0;1] is called majority -pub const MAJ_BIT_TABLE : [u64; SHA256_MAJORITY_SHEDULER_BASE as usize] = [ +pub const MAJ_BIT_TABLE: [u64; SHA256_MAJORITY_SHEDULER_BASE as usize] = [ 0, // a + b + c = 0 => (a & b) ^ (a & c) ^ (b & c) = 0 0, // a + b + c = 1 => (a & b) ^ (a & c) ^ (b & c) = 0 1, // a + b + c = 2 => (a & b) ^ (a & c) ^ (b & c) = 1 @@ -76,24 +74,20 @@ pub fn maj_u64_normalizer(n: u64) -> u64 { MAJ_BIT_TABLE[n as usize] } -pub fn maj_ff_normalizer(fr: Fr) -> Fr -{ - let bit_table : [u64; SHA256_MAJORITY_SHEDULER_BASE as usize] = [ 0, 0, 1, 1 ]; +pub fn maj_ff_normalizer(fr: Fr) -> Fr { + let bit_table: [u64; SHA256_MAJORITY_SHEDULER_BASE as usize] = [0, 0, 1, 1]; let base = SHA256_MAJORITY_SHEDULER_BASE; general_normalizer(fr, &bit_table[..], base) } -pub fn ch_xor_ff_normalizer(fr: Fr) -> Fr -{ - let bit_table : [u64; SHA256_CHOOSE_BASE as usize] = [ 0, 1, 0, 1, 0, 1, 0 ]; +pub fn ch_xor_ff_normalizer(fr: Fr) -> Fr { + let bit_table: [u64; SHA256_CHOOSE_BASE as usize] = [0, 1, 0, 1, 0, 1, 0]; let base = SHA256_CHOOSE_BASE; general_normalizer(fr, &bit_table[..], base) } -pub fn maj_and_sheduler_xor_ff_normalizer(fr: Fr) -> Fr -{ - let bit_table : [u64; SHA256_MAJORITY_SHEDULER_BASE as usize] = [ 0, 1, 0, 1 ]; +pub fn maj_and_sheduler_xor_ff_normalizer(fr: Fr) -> Fr { + let bit_table: [u64; SHA256_MAJORITY_SHEDULER_BASE as usize] = [0, 1, 0, 1]; let base = SHA256_MAJORITY_SHEDULER_BASE; general_normalizer(fr, &bit_table[..], base) } - diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/tables.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/tables.rs index a7974a1..e3da2a5 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/tables.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/tables.rs @@ -1,37 +1,30 @@ +use crate::bellman::pairing::ff::*; use crate::bellman::plonk::better_better_cs::cs::*; use crate::bellman::plonk::better_better_cs::lookup_tables::*; use crate::bellman::plonk::better_better_cs::utils; -use crate::bellman::pairing::ff::*; -use crate::bellman::SynthesisError; use crate::bellman::Engine; +use crate::bellman::SynthesisError; use super::utils::*; use itertools::Itertools; use std::sync::Arc; - -pub fn add_table_once>( - cs: &mut CS, table: LookupTableApplication -) -> Result>, SynthesisError> -{ +pub fn add_table_once>(cs: &mut CS, table: LookupTableApplication) -> Result>, SynthesisError> { let existing_table_or_err = cs.get_table(&table.functional_name()); if existing_table_or_err.is_ok() { existing_table_or_err - } - else { + } else { cs.add_table(table) } } - // GENERAL PURPOSE TABLES (so to say) // ---------------------------------------------------------------------------------------------------------------------------- - // for given bit_width, rotation parameter, extraction parameter and base construct the following table: // first column containts all values of x in the range [0, 2^bits - 1] -// the corresponding value in the second column is sparse representation of x (with extraction) -// while the value in the thrid column is sparse representation of shifted and extracted value of x +// the corresponding value in the second column is sparse representation of x (with extraction) +// while the value in the thrid column is sparse representation of shifted and extracted value of x // (if shift = 0) then the third column is simpy zero // see utils file for more details #[derive(Clone)] @@ -46,7 +39,6 @@ pub struct SparseRotateTable { } impl SparseRotateTable { - pub fn new(bits: usize, rotation: usize, extraction: usize, base: u64, name: &'static str) -> Self { let mut key = Vec::with_capacity(1 << bits); let mut value_0 = Vec::with_capacity(1 << bits); @@ -59,8 +51,7 @@ impl SparseRotateTable { for x in 0..(1 << bits) { let y = if extraction > 0 { map_into_sparse_form(rotate_extract(x, 0, extraction), base as usize) - } - else { + } else { map_into_sparse_form(x, base as usize) }; let z = map_into_sparse_form(rotate_extract(x, rotation, extraction), base as usize); @@ -146,15 +137,14 @@ impl LookupTableInternal for SparseRotateTable { assert!(keys.len() == self.num_keys()); if let Some(entry) = self.table_lookup_map.get(&keys[0]) { - return Ok(vec![entry.0, entry.1]) + return Ok(vec![entry.0, entry.1]); } Err(SynthesisError::Unsatisfiable) } } - -// Sha256 normalization table is parametrized by the following parameters: +// Sha256 normalization table is parametrized by the following parameters: // sparse representation INPUT base inp_base, num of input chunks, two OUTPUT bases out_base0, out_base1, // and corresponding transformation functions: // f0: [0, inp_base) -> [0, out_base0); f1: [0, inp_base) -> [0, out_base1). @@ -176,8 +166,10 @@ pub struct MultiBaseNormalizationTable { } impl MultiBaseNormalizationTable { - pub fn new(num_chunks: usize, inp_base: u64, out_base0: u64, out_base1: u64, f0: F0, f1: F1, name: &'static str) -> Self - where F0 : Fn(u64) -> u64, F1 : Fn(u64) -> u64 + pub fn new(num_chunks: usize, inp_base: u64, out_base0: u64, out_base1: u64, f0: F0, f1: F1, name: &'static str) -> Self + where + F0: Fn(u64) -> u64, + F1: Fn(u64) -> u64, { let table_size = pow(inp_base as usize, num_chunks); let mut keys_vec = Vec::with_capacity(table_size); @@ -221,10 +213,10 @@ impl MultiBaseNormalizationTable { Self { table_entries: [keys_vec, values0_vec, values1_vec], table_lookup_map: map, - num_chunks : num_chunks, + num_chunks: num_chunks, input_base: inp_base, - first_output_base : out_base0, - second_output_base : out_base1, + first_output_base: out_base0, + second_output_base: out_base1, name, } } @@ -288,14 +280,13 @@ impl LookupTableInternal for MultiBaseNormalizationTable { assert!(keys.len() == self.num_keys()); if let Some(entry) = self.table_lookup_map.get(&keys[0]) { - return Ok(vec![entry.0, entry.1]) + return Ok(vec![entry.0, entry.1]); } Err(SynthesisError::Unsatisfiable) } } - // for columns (a, b, c) this table asserts that c = (a ^ b) >>> shift (cyclic shift of 32 bit values) // if shift is zero, than it is simple xor table: c = a ^ b; #[derive(Clone)] @@ -307,7 +298,6 @@ pub struct XorRotateTable { name: &'static str, } - impl XorRotateTable { pub fn new(bits: usize, shift: u32, name: &'static str) -> Self { let mut keys1 = Vec::with_capacity(1 << bits); @@ -318,12 +308,7 @@ impl XorRotateTable { for x in 0..(1 << bits) { for y in 0..(1 << bits) { let tmp: u32 = x ^ y; - let z : u32 = if shift > 0 { - tmp.rotate_right(shift) - } - else { - tmp - }; + let z: u32 = if shift > 0 { tmp.rotate_right(shift) } else { tmp }; let x = u64_to_ff(x as u64); let y = u64_to_ff(y as u64); @@ -334,7 +319,7 @@ impl XorRotateTable { values.push(z); map.insert((x, y), z); - } + } } Self { @@ -347,17 +332,12 @@ impl XorRotateTable { } } - impl std::fmt::Debug for XorRotateTable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("XorRotateTable") - .field("bits", &self.bits) - .field("shift", &self.shift) - .finish() + f.debug_struct("XorRotateTable").field("bits", &self.bits).field("shift", &self.shift).finish() } } - impl LookupTableInternal for XorRotateTable { fn name(&self) -> &'static str { self.name @@ -405,14 +385,13 @@ impl LookupTableInternal for XorRotateTable { assert!(keys.len() == self.num_keys()); if let Some(entry) = self.table_lookup_map.get(&(keys[0], keys[1])) { - return Ok(vec![*entry]) + return Ok(vec![*entry]); } Err(SynthesisError::Unsatisfiable) } } - // The following tables check booleanity of three elemets at once: // it contains all possible triples [a0, a1, a2] where each a_i \in {0, 1} #[derive(Clone)] @@ -421,7 +400,6 @@ pub struct BooleanityTable { name: &'static str, } - impl BooleanityTable { pub fn new(name: &'static str) -> Self { let entries = vec![ @@ -435,21 +413,16 @@ impl BooleanityTable { [E::Fr::one(), E::Fr::one(), E::Fr::one()], ]; - Self { - table_entries: entries, - name, - } + Self { table_entries: entries, name } } } - impl std::fmt::Debug for BooleanityTable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("BooleanityTable").finish() } } - impl LookupTableInternal for BooleanityTable { fn name(&self) -> &'static str { self.name @@ -467,7 +440,7 @@ impl LookupTableInternal for BooleanityTable { true } fn get_table_values_for_polys(&self) -> Vec> { - let mut result = vec![vec![]; 3]; + let mut result = vec![vec![]; 3]; for [e0, e1, e2] in self.table_entries.iter() { result[0].push(*e0); result[1].push(*e1); @@ -502,7 +475,7 @@ impl LookupTableInternal for BooleanityTable { for set in self.table_entries.iter() { if &set[..] == keys { - return Ok(vec![]) + return Ok(vec![]); } } @@ -510,4 +483,3 @@ impl LookupTableInternal for BooleanityTable { // Err(SynthesisError::Unsatisfiable) } } - diff --git a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/utils.rs b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/utils.rs index 749db90..d4ca2fb 100644 --- a/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/utils.rs +++ b/crates/franklin-crypto/src/plonk/circuit/hashes_with_tables/utils.rs @@ -2,29 +2,28 @@ use crate::bellman::pairing::ff::*; use crate::bellman::SynthesisError; use crate::num_bigint::BigUint; use crate::num_traits::cast::ToPrimitive; -use crate::num_traits::{ Zero, One, PrimInt }; -use std::{ iter, mem }; - +use crate::num_traits::{One, PrimInt, Zero}; +use std::{iter, mem}; // for given x=(x_0, x_1, ..., x_n) extract the k lower bits: y = (x_0, x_1, ..., x_{k-1}, 0, ..., 0) // and then rotate // NOTE: by rotate we always mean right rotate of 32-bit numbers! -pub fn rotate_extract(value: usize, rotation: usize, extraction: usize) -> usize -{ - let temp = if extraction > 0 {value & ((1 << extraction) - 1)} else {value}; - let res = if rotation > 0 {(temp >> rotation) + ((temp << (32 - rotation)) & 0xffffffff) } else {temp}; +pub fn rotate_extract(value: usize, rotation: usize, extraction: usize) -> usize { + let temp = if extraction > 0 { value & ((1 << extraction) - 1) } else { value }; + let res = if rotation > 0 { (temp >> rotation) + ((temp << (32 - rotation)) & 0xffffffff) } else { temp }; res } -pub fn shift_right(value: usize, shift: usize) -> usize -{ - if shift > 0 {value >> shift} else {value} +pub fn shift_right(value: usize, shift: usize) -> usize { + if shift > 0 { + value >> shift + } else { + value + } } - pub fn pow(base: usize, exp: usize) -> usize { - let mut res = 1; for _i in 0..exp { res *= base; @@ -43,7 +42,7 @@ pub fn biguint_pow(base: usize, exp: usize) -> BigUint { } pub fn u64_to_ff(n: u64) -> Fr { - let mut repr : ::Repr = Fr::zero().into_repr(); + let mut repr: ::Repr = Fr::zero().into_repr(); repr.as_mut()[0] = n; let res = Fr::from_repr(repr).expect("should parse"); res @@ -54,7 +53,7 @@ pub fn u64_exp_to_ff(n: u64, exp: u64) -> Fr { return Fr::one(); } - let mut repr : ::Repr = Fr::zero().into_repr(); + let mut repr: ::Repr = Fr::zero().into_repr(); repr.as_mut()[0] = n; let res = Fr::from_repr(repr).expect("should parse"); res.pow(&[exp]) @@ -72,15 +71,13 @@ fn biguint_to_ff(value: &BigUint) -> Fr { Fr::from_str(&value.to_str_radix(10)).unwrap() } - // converts x = (x_0, x_1, ..., x_n) - bit decomposition of x into y = \sum_{i=1}^{n} x_i * base^i -pub fn map_into_sparse_form(input: usize, base: usize) -> BigUint -{ +pub fn map_into_sparse_form(input: usize, base: usize) -> BigUint { // if base is zero, than no convertion is actually needed if base == 0 { return BigUint::from(input); } - + let mut out = BigUint::zero(); let mut base_accumulator = BigUint::one(); let mut converted = input; @@ -93,15 +90,14 @@ pub fn map_into_sparse_form(input: usize, base: usize) -> BigUint } base_accumulator *= base; } - + out } -pub fn map_from_sparse_form(input: usize, base: usize) -> usize -{ - let mut target : usize = input; - let mut output : usize = 0; - let mut count : usize = 0; +pub fn map_from_sparse_form(input: usize, base: usize) -> usize { + let mut target: usize = input; + let mut output: usize = 0; + let mut count: usize = 0; while target > 0 { let slice = target % base; @@ -115,16 +111,14 @@ pub fn map_from_sparse_form(input: usize, base: usize) -> usize output } - // in general all bit-friendly transformations (such as xor or SHA256 majority and choose operations) // are hadled by the gadget library itself with the use of tables // however, in some our wires are actually constants and not allocated variables -// for them we do not want apply the common strategy +// for them we do not want apply the common strategy // ( split in chunks -- chunk-by-chunk transform via tables -- compose chunks back ) // but want to do all the bitwise transformations on the whole constant number in one turn // this is done by the corresponding "normalizer" mappings, contained in this module -pub fn general_normalizer(fr : Fr, bit_table: &[u64], base: u64) -> Fr -{ +pub fn general_normalizer(fr: Fr, bit_table: &[u64], base: u64) -> Fr { let mut input = BigUint::default(); let fr_repr = fr.into_repr(); for n in fr_repr.as_ref().iter().rev() { @@ -132,9 +126,9 @@ pub fn general_normalizer(fr : Fr, bit_table: &[u64], base: u64) input += *n; } - let mut acc : u64 = 0; + let mut acc: u64 = 0; let mut count = 0; - + while !input.is_zero() { let remainder = (input.clone() % BigUint::from(base)).to_u64().unwrap(); let bit = bit_table[remainder as usize]; @@ -143,7 +137,7 @@ pub fn general_normalizer(fr : Fr, bit_table: &[u64], base: u64) count += 1; } - let mut repr : ::Repr = Fr::zero().into_repr(); + let mut repr: ::Repr = Fr::zero().into_repr(); repr.as_mut()[0] = acc; let res = Fr::from_repr(repr).expect("should parse"); @@ -152,9 +146,8 @@ pub fn general_normalizer(fr : Fr, bit_table: &[u64], base: u64) /// Normalizes an input value by taking `digits` in the `input_base`, /// then transforming this "digits" with transformation function, -/// and finally treating transformation results as digits into `output_base` -pub fn func_normalizer u64>(fr : Fr, input_base: u64, output_base: u64, transform_f: T) -> Fr -{ +/// and finally treating transformation results as digits into `output_base` +pub fn func_normalizer u64>(fr: Fr, input_base: u64, output_base: u64, transform_f: T) -> Fr { let mut input = BigUint::default(); let fr_repr = fr.into_repr(); for n in fr_repr.as_ref().iter().rev() { @@ -162,9 +155,9 @@ pub fn func_normalizer u64>(fr : Fr, input_base: u input += *n; } - let mut acc = BigUint::default(); + let mut acc = BigUint::default(); let mut base = BigUint::one(); - + while !input.is_zero() { let remainder = (input.clone() % BigUint::from(input_base)).to_u64().unwrap(); let output_chunk = transform_f(remainder); @@ -177,33 +170,38 @@ pub fn func_normalizer u64>(fr : Fr, input_base: u res } - // returns closets upper integer to a / b -pub fn round_up(a: usize, b : usize) -> usize { - let additional_chunks : usize = if a % b > 0 {1} else {0}; - a/b + additional_chunks +pub fn round_up(a: usize, b: usize) -> usize { + let additional_chunks: usize = if a % b > 0 { 1 } else { 0 }; + a / b + additional_chunks } - pub fn num_bits(x: T) -> usize { const BITS_PER_BYTE: usize = 8; BITS_PER_BYTE * std::mem::size_of::() - (x.leading_zeros() as usize) } - pub trait IdentifyFirstLast: Iterator + Sized { fn identify_first_last(self) -> Iter; } -impl IdentifyFirstLast for I where I: Iterator { +impl IdentifyFirstLast for I +where + I: Iterator, +{ fn identify_first_last(self) -> Iter { Iter(true, self.peekable()) } } -pub struct Iter(bool, iter::Peekable) where I: Iterator; +pub struct Iter(bool, iter::Peekable) +where + I: Iterator; -impl Iterator for Iter where I: Iterator { +impl Iterator for Iter +where + I: Iterator, +{ type Item = (bool, bool, I::Item); fn next(&mut self) -> Option { diff --git a/crates/franklin-crypto/src/plonk/circuit/linear_combination.rs b/crates/franklin-crypto/src/plonk/circuit/linear_combination.rs index c7f9e42..6569a4f 100644 --- a/crates/franklin-crypto/src/plonk/circuit/linear_combination.rs +++ b/crates/franklin-crypto/src/plonk/circuit/linear_combination.rs @@ -1,36 +1,16 @@ -use crate::bellman::pairing::{ - Engine, -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; - -use crate::bellman::{ - SynthesisError, -}; - -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm -}; +use crate::bellman::pairing::Engine; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; + +use crate::bellman::SynthesisError; + +use crate::bellman::plonk::better_better_cs::cs::{ArithmeticTerm, ConstraintSystem, MainGateTerm, Variable}; use crate::plonk::circuit::Assignment; -use super::allocated_num::{ - AllocatedNum, - Num -}; +use super::allocated_num::{AllocatedNum, Num}; -use super::boolean::{ - AllocatedBit, - Boolean -}; +use super::boolean::{AllocatedBit, Boolean}; use super::simple_term::Term; @@ -39,7 +19,7 @@ const DEFAULT_SMALLVEC_CAPACITY: usize = 9; pub struct LinearCombination { pub(crate) value: Option, pub(crate) terms: smallvec::SmallVec<[(E::Fr, Variable); DEFAULT_SMALLVEC_CAPACITY]>, - pub(crate) constant: E::Fr + pub(crate) constant: E::Fr, } impl std::fmt::Debug for LinearCombination { @@ -58,7 +38,7 @@ impl From> for LinearCombination { Self { value: num.value, terms: smallvec::smallvec![(E::Fr::one(), num.variable)], - constant: E::Fr::zero() + constant: E::Fr::zero(), } } } @@ -66,16 +46,12 @@ impl From> for LinearCombination { impl From> for LinearCombination { fn from(num: Num) -> LinearCombination { match num { - Num::Variable(allocated) => { - Self::from(allocated) + Num::Variable(allocated) => Self::from(allocated), + Num::Constant(constant) => Self { + value: Some(constant), + terms: smallvec::smallvec![], + constant: constant, }, - Num::Constant(constant) => { - Self { - value: Some(constant), - terms: smallvec::smallvec![], - constant: constant - } - } } } } @@ -111,10 +87,7 @@ impl LinearCombination { self.value } - pub fn scale( - &mut self, - coeff: &E::Fr - ) { + pub fn scale(&mut self, coeff: &E::Fr) { if coeff.is_zero() { self.terms.truncate(0); self.constant = E::Fr::zero(); @@ -133,18 +106,15 @@ impl LinearCombination { self.constant.mul_assign(&coeff); } - pub fn add_assign( - &mut self, - other: &Self, - ) { + pub fn add_assign(&mut self, other: &Self) { let new_value = match (self.value, other.value) { (Some(this), Some(other)) => { let mut tmp = this; tmp.add_assign(&other); Some(tmp) - }, - _ => None + } + _ => None, }; self.value = new_value; @@ -157,41 +127,28 @@ impl LinearCombination { self.constant.add_assign(&other.constant); } - pub fn add_assign_scaled( - &mut self, - other: &Self, - scale: E::Fr - ) { + pub fn add_assign_scaled(&mut self, other: &Self, scale: E::Fr) { let mut other_scaled = other.clone(); other_scaled.scale(&scale); self.add_assign(&other_scaled); } - pub fn add_assign_number_with_coeff( - &mut self, - number: &Num, - coeff: E::Fr - ) { + pub fn add_assign_number_with_coeff(&mut self, number: &Num, coeff: E::Fr) { match number { Num::Variable(ref allocated_number) => { self.add_assign_variable_with_coeff(allocated_number, coeff); - }, + } Num::Constant(constant) => { let mut res = coeff; res.mul_assign(&constant); self.add_assign_constant(res); - } + } } } - pub fn add_assign_variable_with_coeff( - &mut self, - variable: &AllocatedNum, - coeff: E::Fr - ) - { + pub fn add_assign_variable_with_coeff(&mut self, variable: &AllocatedNum, coeff: E::Fr) { if coeff.is_zero() { return; } @@ -204,19 +161,15 @@ impl LinearCombination { curval.add_assign(&tmp); Some(curval) - }, - _ => None + } + _ => None, }; self.value = newval; self.terms.push((coeff, variable.variable)); } - pub fn add_assign_term( - &mut self, - term: &Term - ) - { + pub fn add_assign_term(&mut self, term: &Term) { if term.is_constant() { self.add_assign_constant(term.get_constant_value()); return; @@ -227,19 +180,13 @@ impl LinearCombination { self.add_assign_number_with_coeff(&term.num, term.coeff); } - pub fn add_assign_term_with_coeff(&mut self, term: &Term, coeff: E::Fr) - { + pub fn add_assign_term_with_coeff(&mut self, term: &Term, coeff: E::Fr) { let mut scaled_term = term.clone(); scaled_term.scale(&coeff); self.add_assign_term(&scaled_term) } - - pub fn add_assign_boolean_with_coeff( - &mut self, - bit: &Boolean, - coeff: E::Fr - ) - { + + pub fn add_assign_boolean_with_coeff(&mut self, bit: &Boolean, coeff: E::Fr) { if coeff.is_zero() { return; } @@ -251,8 +198,8 @@ impl LinearCombination { } Some(val) - }, - _ => None + } + _ => None, }; self.value = new_value; @@ -261,10 +208,10 @@ impl LinearCombination { if c { self.constant.add_assign(&coeff); } - }, + } &Boolean::Is(ref v) => { self.terms.push((coeff, v.get_variable())); - }, + } &Boolean::Not(ref v) => { let mut coeff_negated = coeff; coeff_negated.negate(); @@ -275,12 +222,7 @@ impl LinearCombination { } } - pub fn add_assign_bit_with_coeff( - &mut self, - bit: &AllocatedBit, - coeff: E::Fr - ) - { + pub fn add_assign_bit_with_coeff(&mut self, bit: &AllocatedBit, coeff: E::Fr) { if coeff.is_zero() { return; } @@ -292,19 +234,15 @@ impl LinearCombination { } Some(val) - }, - _ => None + } + _ => None, }; self.value = new_value; self.terms.push((coeff, bit.get_variable())) } - pub fn add_assign_constant( - &mut self, - coeff: E::Fr - ) - { + pub fn add_assign_constant(&mut self, coeff: E::Fr) { if coeff.is_zero() { return; } @@ -314,31 +252,22 @@ impl LinearCombination { curval.add_assign(&coeff); Some(curval) - }, - None => { - None } + None => None, }; self.value = newval; self.constant.add_assign(&coeff); } - pub fn sub_assign_constant( - &mut self, - coeff: E::Fr - ) - { + pub fn sub_assign_constant(&mut self, coeff: E::Fr) { let mut c = coeff; c.negate(); self.add_assign_constant(c); } - pub fn into_num>( - self, - cs: &mut CS - ) -> Result, SynthesisError> { + pub fn into_num>(self, cs: &mut CS) -> Result, SynthesisError> { if self.terms.len() == 0 { return Ok(Num::Constant(self.constant)); } @@ -349,30 +278,20 @@ impl LinearCombination { } #[track_caller] - pub fn enforce_zero>( - self, - cs: &mut CS - ) -> Result<(), SynthesisError> { + pub fn enforce_zero>(self, cs: &mut CS) -> Result<(), SynthesisError> { if let Some(value) = self.get_value() { assert!(value.is_zero(), "LC is not actually zero with value {}", value); } use crate::bellman::plonk::better_better_cs::cs::PlonkConstraintSystemParams; if CS::Params::CAN_ACCESS_NEXT_TRACE_STEP { - Self::enforce_zero_using_next_step( - cs, - self.terms, - self.constant - ) + Self::enforce_zero_using_next_step(cs, self.terms, self.constant) } else { unimplemented!() } } - pub fn into_allocated_num>( - self, - cs: &mut CS - ) -> Result, SynthesisError> { + pub fn into_allocated_num>(self, cs: &mut CS) -> Result, SynthesisError> { let may_be_trivial = self.unwrap_as_allocated_num(); if may_be_trivial.is_ok() { return may_be_trivial; @@ -380,12 +299,7 @@ impl LinearCombination { // manually transpile into chain of gates - let final_var = AllocatedNum::alloc( - cs, - || { - Ok(*self.value.get()?) - } - )?; + let final_var = AllocatedNum::alloc(cs, || Ok(*self.value.get()?))?; let mut minus_one = E::Fr::one(); minus_one.negate(); @@ -393,7 +307,7 @@ impl LinearCombination { let mut terms = self.terms; terms.push((minus_one, final_var.variable)); - // we do this to + // we do this to let terms = Self::deduplicate_stable(terms); // do the chunking @@ -401,11 +315,7 @@ impl LinearCombination { use crate::bellman::plonk::better_better_cs::cs::PlonkConstraintSystemParams; if CS::Params::CAN_ACCESS_NEXT_TRACE_STEP { - Self::enforce_zero_using_next_step( - cs, - terms, - self.constant - )?; + Self::enforce_zero_using_next_step(cs, terms, self.constant)?; } else { unimplemented!() } @@ -413,9 +323,7 @@ impl LinearCombination { Ok(final_var) } - fn deduplicate_stable( - terms: smallvec::SmallVec<[(E::Fr, Variable); DEFAULT_SMALLVEC_CAPACITY]>, - ) -> smallvec::SmallVec<[(E::Fr, Variable); DEFAULT_SMALLVEC_CAPACITY]> { + fn deduplicate_stable(terms: smallvec::SmallVec<[(E::Fr, Variable); DEFAULT_SMALLVEC_CAPACITY]>) -> smallvec::SmallVec<[(E::Fr, Variable); DEFAULT_SMALLVEC_CAPACITY]> { use std::collections::HashMap; if terms.len() <= 1 { @@ -423,9 +331,9 @@ impl LinearCombination { } let mut scratch: HashMap = HashMap::with_capacity(terms.len()); - + let mut deduped_vec = smallvec::SmallVec::<[(E::Fr, Variable); DEFAULT_SMALLVEC_CAPACITY]>::new(); - + for (coeff, var) in terms.into_iter() { if let Some(existing_index) = scratch.get(&var) { let (c, _) = &mut deduped_vec[*existing_index]; @@ -436,17 +344,13 @@ impl LinearCombination { scratch.insert(var, new_idx); } } - + deduped_vec = deduped_vec.into_iter().filter(|(coeff, _)| !coeff.is_zero()).collect(); - + deduped_vec } - fn evaluate_term_value>( - cs: &CS, - terms: &[(E::Fr, Variable)], - constant: E::Fr, - ) -> Result { + fn evaluate_term_value>(cs: &CS, terms: &[(E::Fr, Variable)], constant: E::Fr) -> Result { let mut result = constant; for (c, v) in terms.iter() { let mut tmp = cs.get_value(*v)?; @@ -460,7 +364,7 @@ impl LinearCombination { fn enforce_zero_using_next_step>( cs: &mut CS, terms: smallvec::SmallVec<[(E::Fr, Variable); DEFAULT_SMALLVEC_CAPACITY]>, - constant_term: E::Fr + constant_term: E::Fr, ) -> Result<(), SynthesisError> { // we assume that terms are deduplicated @@ -478,13 +382,13 @@ impl LinearCombination { let mg = CS::MainGate::default(); - // we have two options: + // we have two options: // - fit everything into a single gate (in case of number terms in the linear combination // smaller than a width of the state) // - make a required number of extra variables and chain it use crate::bellman::plonk::better_better_cs::cs::PlonkConstraintSystemParams; - + if num_terms <= CS::Params::STATE_WIDTH { // we can just make a single gate @@ -505,7 +409,7 @@ impl LinearCombination { // - every time take STATE_WIDTH-1 variables and place their sum + last wire into the next gate last wire // we have also made a final variable already, so there is NO difference - let cycles = ((terms.len() - CS::Params::STATE_WIDTH) + (CS::Params::STATE_WIDTH - 2)) / (CS::Params::STATE_WIDTH - 1); // ceil + let cycles = ((terms.len() - CS::Params::STATE_WIDTH) + (CS::Params::STATE_WIDTH - 2)) / (CS::Params::STATE_WIDTH - 1); // ceil let mut it = terms.into_iter(); use crate::bellman::plonk::better_better_cs::cs::{Gate, MainGate}; @@ -514,25 +418,19 @@ impl LinearCombination { assert_eq!(next_term_range.len(), 1, "for now works only if only one variable is accessible on the next step"); let next_step_coeff_idx = next_term_range.next().expect("must give at least one index"); - // this is a placeholder variable that must go into the - // corresponding trace polynomial at the NEXT time step + // this is a placeholder variable that must go into the + // corresponding trace polynomial at the NEXT time step let (mut next_step_var_in_chain, mut next_step_var_in_chain_value) = { let chunk: Vec<_> = (&mut it).take(CS::Params::STATE_WIDTH).collect(); - let may_be_new_intermediate_value = Self::evaluate_term_value( - &*cs, - &chunk, - constant_term - ); + let may_be_new_intermediate_value = Self::evaluate_term_value(&*cs, &chunk, constant_term); let some_value = match &may_be_new_intermediate_value { Ok(val) => Some(*val), - Err(_) => None + Err(_) => None, }; // we manually allocate the new variable - let new_intermediate_var = cs.alloc(|| { - may_be_new_intermediate_value - })?; + let new_intermediate_var = cs.alloc(|| may_be_new_intermediate_value)?; let mut gate_term = MainGateTerm::::new(); @@ -549,34 +447,25 @@ impl LinearCombination { let (vars, mut coeffs) = CS::MainGate::format_term(gate_term, dummy)?; coeffs[next_step_coeff_idx] = minus_one_fr; - cs.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - )?; + cs.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[])?; (new_intermediate_var, some_value) }; // run over the rest - // we can only take one less cause + // we can only take one less cause // we've already used one of the variable - let consume_from_lc = CS::Params::STATE_WIDTH - 1; - for _ in 0..(cycles-1) { + let consume_from_lc = CS::Params::STATE_WIDTH - 1; + for _ in 0..(cycles - 1) { // we need to keep in mind that last term of the linear combination is taken - // so we have to fill only CS::Params::STATE_WIDTH - 1 and then manually - // place the next_step_var_in_chain + // so we have to fill only CS::Params::STATE_WIDTH - 1 and then manually + // place the next_step_var_in_chain let chunk: Vec<_> = (&mut it).take(consume_from_lc).collect(); - + // this is a sum of new terms - let may_be_new_intermediate_value = Self::evaluate_term_value( - &*cs, - &chunk, - E::Fr::zero() - ).map(|val| { - // and + let may_be_new_intermediate_value = Self::evaluate_term_value(&*cs, &chunk, E::Fr::zero()).map(|val| { + // and let mut tmp = val; tmp.add_assign(next_step_var_in_chain_value.as_ref().expect("value must be known")); @@ -585,14 +474,12 @@ impl LinearCombination { let some_value = match &may_be_new_intermediate_value { Ok(val) => Some(*val), - Err(_) => None + Err(_) => None, }; // we manually allocate the new variable // and also add value of one in a chain - let new_intermediate_var = cs.alloc(|| { - may_be_new_intermediate_value - })?; + let new_intermediate_var = cs.alloc(|| may_be_new_intermediate_value)?; let mut gate_term = MainGateTerm::::new(); @@ -609,12 +496,7 @@ impl LinearCombination { let (vars, mut coeffs) = CS::MainGate::format_term(gate_term, dummy)?; coeffs[next_step_coeff_idx] = minus_one_fr; - cs.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - )?; + cs.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[])?; next_step_var_in_chain = new_intermediate_var; next_step_var_in_chain_value = some_value; @@ -643,12 +525,7 @@ impl LinearCombination { *vars.last_mut().unwrap() = next_step_var_in_chain; coeffs[idx_of_last_linear_term] = one_fr; - cs.new_single_gate_for_trace_step( - &mg, - &coeffs, - &vars, - &[] - )?; + cs.new_single_gate_for_trace_step(&mg, &coeffs, &vars, &[])?; } assert!(it.next().is_none()); } @@ -656,18 +533,13 @@ impl LinearCombination { Ok(()) } - pub fn unwrap_as_allocated_num( - &self, - ) -> Result, SynthesisError> { + pub fn unwrap_as_allocated_num(&self) -> Result, SynthesisError> { if self.constant.is_zero() == false { return Err(SynthesisError::Unsatisfiable); } if self.terms.len() == 1 && self.terms[0].0 == E::Fr::one() { let var = (&self.terms[0].1).clone(); - let var = AllocatedNum { - value: self.value, - variable: var - }; + let var = AllocatedNum { value: self.value, variable: var }; return Ok(var); } @@ -675,17 +547,11 @@ impl LinearCombination { return Err(SynthesisError::Unsatisfiable); } - pub fn uniquely_pack_le_booleans_into_single_num>( - cs: &mut CS, - bools: &[Boolean], - ) -> Result, SynthesisError> { + pub fn uniquely_pack_le_booleans_into_single_num>(cs: &mut CS, bools: &[Boolean]) -> Result, SynthesisError> { Self::uniquely_pack_booleans_into_single_num(cs, bools) } - pub fn uniquely_pack_booleans_into_single_num>( - cs: &mut CS, - bools: &[Boolean], - ) -> Result, SynthesisError> { + pub fn uniquely_pack_booleans_into_single_num>(cs: &mut CS, bools: &[Boolean]) -> Result, SynthesisError> { assert!(bools.len() <= E::Fr::CAPACITY as usize); let mut lc = Self::zero(); @@ -700,10 +566,7 @@ impl LinearCombination { Ok(num) } - pub fn uniquely_pack_booleans_into_nums>( - cs: &mut CS, - bools: &[Boolean], - ) -> Result>, SynthesisError> { + pub fn uniquely_pack_booleans_into_nums>(cs: &mut CS, bools: &[Boolean]) -> Result>, SynthesisError> { let mut result = vec![]; let chunk_size = E::Fr::CAPACITY as usize; @@ -728,12 +591,7 @@ mod test { let mut assembly = TrivialAssembly::::new(); let _before = assembly.n(); - let variables: Vec<_> = (0..9).map(|_| AllocatedNum::alloc( - &mut assembly, - || { - Ok(Fr::one()) - } - ).unwrap()).collect(); + let variables: Vec<_> = (0..9).map(|_| AllocatedNum::alloc(&mut assembly, || Ok(Fr::one())).unwrap()).collect(); let mut lc = LinearCombination::::zero(); lc.add_assign_constant(Fr::one()); @@ -765,12 +623,7 @@ mod test { let mut assembly = TrivialAssembly::::new(); let _before = assembly.n(); - let variables: Vec<_> = (0..5).map(|_| AllocatedNum::alloc( - &mut assembly, - || { - Ok(Fr::one()) - } - ).unwrap()).collect(); + let variables: Vec<_> = (0..5).map(|_| AllocatedNum::alloc(&mut assembly, || Ok(Fr::one())).unwrap()).collect(); let mut lc = LinearCombination::::zero(); lc.add_assign_constant(Fr::one()); @@ -793,8 +646,8 @@ mod test { fn check_terms_summing() { use crate::bellman::pairing::bn256::{Bn256, Fr}; use crate::bellman::plonk::better_better_cs::cs::*; - use crate::plonk::circuit::linear_combination::*; use crate::plonk::circuit::allocated_num::*; + use crate::plonk::circuit::linear_combination::*; use crate::plonk::circuit::simple_term::*; struct Tester; @@ -803,25 +656,16 @@ mod test { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { - Ok( - vec![ - Self::MainGate::default().into_internal(), - ] - ) + Ok(vec![Self::MainGate::default().into_internal()]) } fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { - for len in vec![3,4,5] { + for len in vec![3, 4, 5] { let mut terms = vec![]; for i in 1..=len { let coeff = Fr::from_str(&i.to_string()).unwrap(); let value = Fr::from_str(&i.to_string()).unwrap(); - let var = AllocatedNum::alloc( - cs, - || { - Ok(value) - } - )?; + let var = AllocatedNum::alloc(cs, || Ok(value))?; let mut term = Term::::from_allocated_num(var); term.scale(&coeff); @@ -829,12 +673,12 @@ mod test { terms.push(term); } - + let (first, other) = terms.split_first().unwrap(); let _ = first.add_multiple(cs, &other)?; } - + Ok(()) } } @@ -854,16 +698,10 @@ mod test { let setup = assembly.create_setup::(&worker).unwrap(); use crate::bellman::kate_commitment::*; - use crate::bellman::plonk::commitments::transcript::{*, keccak_transcript::RollingKeccakTranscript}; + use crate::bellman::plonk::commitments::transcript::{keccak_transcript::RollingKeccakTranscript, *}; - let crs_mons = - Crs::::crs_42(setup.permutation_monomials[0].size(), &worker); + let crs_mons = Crs::::crs_42(setup.permutation_monomials[0].size(), &worker); - let _proof = assembly.create_proof::<_, RollingKeccakTranscript>( - &worker, - &setup, - &crs_mons, - None - ).unwrap(); + let _proof = assembly.create_proof::<_, RollingKeccakTranscript>(&worker, &setup, &crs_mons, None).unwrap(); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/mod.rs b/crates/franklin-crypto/src/plonk/circuit/mod.rs index 524615f..670bb58 100644 --- a/crates/franklin-crypto/src/plonk/circuit/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/mod.rs @@ -1,27 +1,27 @@ pub mod allocated_num; +pub mod blake2s; +pub mod boolean; pub mod custom_rescue_gate; -pub mod rescue; pub mod linear_combination; -pub mod boolean; -pub mod uint32; pub mod multieq; +pub mod rescue; pub mod sha256; -pub mod blake2s; +pub mod uint32; //pub mod poseidon; pub mod bigint; pub mod bigint_new; -pub mod simple_term; +pub mod byte; +pub mod counter; pub mod curve; pub mod curve_new; +pub mod custom_5th_degree_gate_optimized; +pub mod edwards; pub mod goldilocks; -pub mod verifier_circuit; +pub mod permutation_network; +pub mod simple_term; pub mod tables; -pub mod counter; -pub mod byte; pub mod utils; -pub mod permutation_network; -pub mod edwards; -pub mod custom_5th_degree_gate_optimized; +pub mod verifier_circuit; pub mod assignment; pub mod hashes_with_tables; @@ -54,8 +54,8 @@ impl SomeArithmetizable for Option { tmp.add_assign(&o); Some(tmp) - }, - _ => None + } + _ => None, } } fn sub(&self, other: &Self) -> Self { @@ -65,8 +65,8 @@ impl SomeArithmetizable for Option { tmp.sub_assign(&o); Some(tmp) - }, - _ => None + } + _ => None, } } fn mul(&self, other: &Self) -> Self { @@ -76,8 +76,8 @@ impl SomeArithmetizable for Option { tmp.mul_assign(&o); Some(tmp) - }, - _ => None + } + _ => None, } } fn fma(&self, to_mul: &Self, to_add: &Self) -> Self { @@ -88,8 +88,8 @@ impl SomeArithmetizable for Option { tmp.add_assign(&a); Some(tmp) - }, - _ => None + } + _ => None, } } fn negate(&self) -> Self { @@ -99,9 +99,8 @@ impl SomeArithmetizable for Option { tmp.negate(); Some(tmp) - }, - _ => None + } + _ => None, } } } - diff --git a/crates/franklin-crypto/src/plonk/circuit/multieq.rs b/crates/franklin-crypto/src/plonk/circuit/multieq.rs index bb1496a..85e34e1 100644 --- a/crates/franklin-crypto/src/plonk/circuit/multieq.rs +++ b/crates/franklin-crypto/src/plonk/circuit/multieq.rs @@ -1,46 +1,21 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, Variable, Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, }; - use crate::plonk::circuit::Assignment; -use super::allocated_num::{ - AllocatedNum -}; +use super::allocated_num::AllocatedNum; -use super::linear_combination::{ - LinearCombination -}; +use super::linear_combination::LinearCombination; -pub struct MultiEq<'a, E: Engine, CS: ConstraintSystem + 'a>{ +pub struct MultiEq<'a, E: Engine, CS: ConstraintSystem + 'a> { cs: &'a mut CS, ops: usize, bits_used: usize, @@ -55,7 +30,7 @@ impl<'a, E: Engine, CS: ConstraintSystem + 'a> MultiEq<'a, E, CS> { ops: 0, bits_used: 0, lhs: LinearCombination::::zero(), - rhs: LinearCombination::::zero() + rhs: LinearCombination::::zero(), } } @@ -63,8 +38,7 @@ impl<'a, E: Engine, CS: ConstraintSystem + 'a> MultiEq<'a, E, CS> { &mut self.cs } - fn accumulate(&mut self) - { + fn accumulate(&mut self) { let mut lhs = self.lhs.clone(); let mut rhs = self.rhs.clone(); let mut minus_one = E::Fr::one(); @@ -81,13 +55,7 @@ impl<'a, E: Engine, CS: ConstraintSystem + 'a> MultiEq<'a, E, CS> { self.ops += 1; } - pub fn enforce_equal( - &mut self, - num_bits: usize, - lhs: &LinearCombination, - rhs: &LinearCombination - ) - { + pub fn enforce_equal(&mut self, num_bits: usize, lhs: &LinearCombination, rhs: &LinearCombination) { // Check if we will exceed the capacity if (E::Fr::CAPACITY as usize) <= (self.bits_used + num_bits) { self.accumulate(); @@ -112,33 +80,23 @@ impl<'a, E: Engine, CS: ConstraintSystem + 'a> MultiEq<'a, E, CS> { impl<'a, E: Engine, CS: ConstraintSystem + 'a> Drop for MultiEq<'a, E, CS> { fn drop(&mut self) { if self.bits_used > 0 { - self.accumulate(); + self.accumulate(); } } } -pub fn bytes_to_bits(bytes: &[u8]) -> Vec -{ - bytes.iter() - .flat_map(|&v| (0..8).rev().map(move |i| (v >> i) & 1 == 1)) - .collect() +pub fn bytes_to_bits(bytes: &[u8]) -> Vec { + bytes.iter().flat_map(|&v| (0..8).rev().map(move |i| (v >> i) & 1 == 1)).collect() } -pub fn bytes_to_bits_le(bytes: &[u8]) -> Vec -{ - bytes.iter() - .flat_map(|&v| (0..8).map(move |i| (v >> i) & 1 == 1)) - .collect() +pub fn bytes_to_bits_le(bytes: &[u8]) -> Vec { + bytes.iter().flat_map(|&v| (0..8).map(move |i| (v >> i) & 1 == 1)).collect() } -pub fn compute_multipacking( - bits: &[bool] -) -> Vec -{ +pub fn compute_multipacking(bits: &[bool]) -> Vec { let mut result = vec![]; - for bits in bits.chunks(E::Fr::CAPACITY as usize) - { + for bits in bits.chunks(E::Fr::CAPACITY as usize) { let mut cur = E::Fr::zero(); let mut coeff = E::Fr::one(); @@ -154,4 +112,4 @@ pub fn compute_multipacking( } result -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/permutation_network/circuit.rs b/crates/franklin-crypto/src/plonk/circuit/permutation_network/circuit.rs index 3d5b11b..3ee8d95 100644 --- a/crates/franklin-crypto/src/plonk/circuit/permutation_network/circuit.rs +++ b/crates/franklin-crypto/src/plonk/circuit/permutation_network/circuit.rs @@ -1,15 +1,8 @@ use super::*; -use super::witness::{ - IntegerPermutation, - AsWaksmanTopology, - AsWaksmanRoute -}; - -pub fn order_into_switches_set>( - cs: &mut CS, - permutation: &IntegerPermutation -) -> Result>, SynthesisError> { +use super::witness::{AsWaksmanRoute, AsWaksmanTopology, IntegerPermutation}; + +pub fn order_into_switches_set>(cs: &mut CS, permutation: &IntegerPermutation) -> Result>, SynthesisError> { let mut layers = vec![]; let size = permutation.size(); @@ -36,11 +29,7 @@ pub fn order_into_switches_set>( } else { // validity check let a = router.switches[column_idx].get(&packet_idx); - let b = if packet_idx > 0 { - router.switches[column_idx].get(&(packet_idx - 1)) - } else { - None - }; + let b = if packet_idx > 0 { router.switches[column_idx].get(&(packet_idx - 1)) } else { None }; // get value to make a witness let switch_value = if a.is_some() { @@ -74,13 +63,10 @@ pub fn order_into_switches_set>( another_idx = Some(idx); break; } - } + } assert!(another_idx.is_some()); - let boolean_switch = Boolean::from(AllocatedBit::alloc( - cs, - switch_value - )?); + let boolean_switch = Boolean::from(AllocatedBit::alloc(cs, switch_value)?); routed_packages.insert(routed_into_straght); routed_packages.insert(routed_into_cross); @@ -102,25 +88,20 @@ pub fn order_into_switches_set>( let max = prev; assert_eq!(min, 0, "permutation should start with 0"); - assert_eq!(max, size-1, "permutation should not contain spaces"); + assert_eq!(max, size - 1, "permutation should not contain spaces"); } Ok(layers) } - /// prove permutation by routing elements through the permutation network -/// Topology is calculated exclusively based on the size on the network, +/// Topology is calculated exclusively based on the size on the network, /// and permuted elements can be anything. Caller be responsible for validity /// if elements are unique or not -pub fn prove_permutation_using_switches_witness( - cs: &mut CS, - original: &[AllocatedNum], - permuted: &[AllocatedNum], - switches_layes: &Vec>, -) -> Result<(), SynthesisError> - where CS: ConstraintSystem, - E: Engine +pub fn prove_permutation_using_switches_witness(cs: &mut CS, original: &[AllocatedNum], permuted: &[AllocatedNum], switches_layes: &Vec>) -> Result<(), SynthesisError> +where + CS: ConstraintSystem, + E: Engine, { assert_eq!(original.len(), permuted.len()); // First make a topology @@ -170,8 +151,7 @@ pub fn prove_permutation_using_switches_witness( let routed_into_cross = topology.topology[column_idx][packet_idx].1; // this is a cross index // may be we have already routed a pair, so quickly check - if result_of_this_column[routed_into_straght].is_some() || result_of_this_column[routed_into_cross].is_some() - { + if result_of_this_column[routed_into_straght].is_some() || result_of_this_column[routed_into_cross].is_some() { assert!(result_of_this_column[routed_into_straght].is_some() && result_of_this_column[routed_into_cross].is_some()); continue; } @@ -187,7 +167,7 @@ pub fn prove_permutation_using_switches_witness( another_idx = Some(idx); break; } - } + } assert!(another_idx.is_some()); let another_idx = another_idx.unwrap(); @@ -196,13 +176,8 @@ pub fn prove_permutation_using_switches_witness( let boolean_switch = switches_it.next().expect("must contain a switch value"); - // perform an actual switching - let (next_level_straight, next_level_cross) = AllocatedNum::conditionally_reverse( - cs, - &previous_level_variable, - &previous_level_pair, - &boolean_switch - )?; + // perform an actual switching + let (next_level_straight, next_level_cross) = AllocatedNum::conditionally_reverse(cs, &previous_level_variable, &previous_level_pair, &boolean_switch)?; switch_count += 1; result_of_this_column[routed_into_straght] = Some(next_level_straight); @@ -215,7 +190,7 @@ pub fn prove_permutation_using_switches_witness( } // we have routed the "original" into some "permutation", so we check that - // "permutation" is equal to the claimed "permuted" value + // "permutation" is equal to the claimed "permuted" value for (claimed, routed) in permuted.iter().zip(permutation.into_iter()) { let routed = routed.expect("must be some"); routed.enforce_equal(cs, &claimed)?; @@ -223,24 +198,17 @@ pub fn prove_permutation_using_switches_witness( println!("switch count: {}", switch_count); - Ok(()) } - - /// prove permutation by routing elements through the permutation network -/// Topology is calculated exclusively based on the size on the network, +/// Topology is calculated exclusively based on the size on the network, /// and permuted elements can be anything. Caller be responsible for validity /// if elements are unique or not -pub fn prove_permutation_of_nums_using_switches_witness( - cs: &mut CS, - original: &[Num], - permuted: &[Num], - switches_layes: &Vec>, -) -> Result<(), SynthesisError> - where CS: ConstraintSystem, - E: Engine +pub fn prove_permutation_of_nums_using_switches_witness(cs: &mut CS, original: &[Num], permuted: &[Num], switches_layes: &Vec>) -> Result<(), SynthesisError> +where + CS: ConstraintSystem, + E: Engine, { // it's a code dumplication until we introduce traits and reworks assert_eq!(original.len(), permuted.len()); @@ -278,8 +246,7 @@ pub fn prove_permutation_of_nums_using_switches_witness( let routed_into_cross = topology.topology[column_idx][packet_idx].1; // this is a cross index // may be we have already routed a pair, so quickly check - if result_of_this_column[routed_into_straght].is_some() || result_of_this_column[routed_into_cross].is_some() - { + if result_of_this_column[routed_into_straght].is_some() || result_of_this_column[routed_into_cross].is_some() { assert!(result_of_this_column[routed_into_straght].is_some() && result_of_this_column[routed_into_cross].is_some()); continue; } @@ -295,7 +262,7 @@ pub fn prove_permutation_of_nums_using_switches_witness( another_idx = Some(idx); break; } - } + } assert!(another_idx.is_some()); let another_idx = another_idx.unwrap(); @@ -304,13 +271,8 @@ pub fn prove_permutation_of_nums_using_switches_witness( let boolean_switch = switches_it.next().expect("must contain a switch value"); - // perform an actual switching - let (next_level_straight, next_level_cross) = Num::conditionally_reverse( - cs, - &previous_level_variable, - &previous_level_pair, - &boolean_switch - )?; + // perform an actual switching + let (next_level_straight, next_level_cross) = Num::conditionally_reverse(cs, &previous_level_variable, &previous_level_pair, &boolean_switch)?; result_of_this_column[routed_into_straght] = Some(next_level_straight); result_of_this_column[routed_into_cross] = Some(next_level_cross); @@ -322,28 +284,23 @@ pub fn prove_permutation_of_nums_using_switches_witness( } // we have routed the "original" into some "permutation", so we check that - // "permutation" is equal to the claimed "permuted" value + // "permutation" is equal to the claimed "permuted" value for (claimed, routed) in permuted.iter().zip(permutation.into_iter()) { let routed = routed.expect("must be some"); routed.enforce_equal(cs, &claimed)?; } - Ok(()) } /// prove permutation by routing elements through the permutation network -/// Topology is calculated exclusively based on the size on the network, +/// Topology is calculated exclusively based on the size on the network, /// and permuted elements can be anything. Caller be responsible for validity /// if elements are unique or not -pub fn prove_shuffle( - cs: &mut CS, - original: &[AllocatedNum], - permuted: &[AllocatedNum], - permuted_order: &IntegerPermutation, -) -> Result<(), SynthesisError> - where CS: ConstraintSystem, - E: Engine +pub fn prove_shuffle(cs: &mut CS, original: &[AllocatedNum], permuted: &[AllocatedNum], permuted_order: &IntegerPermutation) -> Result<(), SynthesisError> +where + CS: ConstraintSystem, + E: Engine, { assert_eq!(original.len(), permuted.len()); assert_eq!(original.len(), permuted_order.size()); @@ -431,7 +388,7 @@ pub fn prove_shuffle( // another_idx = Some(idx); // break; // } - // } + // } // assert!(another_idx.is_some()); // let another_idx = another_idx.unwrap(); @@ -441,7 +398,7 @@ pub fn prove_shuffle( // let boolean_switch = Boolean::from(AllocatedBit::alloc( // cs, // switch_value - // )?); + // )?); // let cross_value = AllocatedNum::alloc( // cs, @@ -459,7 +416,7 @@ pub fn prove_shuffle( // Ok(value) // })?; - // // perform an actual switching + // // perform an actual switching // let (next_level_straight, next_level_cross) = AllocatedNum::conditionally_reverse( // cs, // &straight_value, @@ -483,7 +440,6 @@ pub fn prove_shuffle( // variable.enforce_equal(cs, &permuted)?; // } - // Ok(()) } @@ -491,11 +447,11 @@ pub fn prove_shuffle( mod test { use super::*; use crate::bellman::plonk::better_better_cs::cs::*; - use rand::{XorShiftRng, SeedableRng, Rand, Rng}; use bellman::pairing::bn256::{Bn256, Fr}; use bellman::pairing::ff::{BitIterator, Field, PrimeField}; + use rand::{Rand, Rng, SeedableRng, XorShiftRng}; - use super::{AsWaksmanRoute, AsWaksmanTopology, IntegerPermutation, prove_shuffle}; + use super::{prove_shuffle, AsWaksmanRoute, AsWaksmanTopology, IntegerPermutation}; #[test] fn test_permutation_positive() { @@ -519,23 +475,15 @@ mod test { let mut original = vec![]; let mut permuted = vec![]; - for(_i, (o, p)) in original_vector.into_iter().zip(permuted_vector.into_iter()).enumerate() { - let o = AllocatedNum::alloc(&mut cs, - || Ok(o) - ).unwrap(); - let p = AllocatedNum::alloc(&mut cs, - || Ok(p) - ).unwrap(); + for (_i, (o, p)) in original_vector.into_iter().zip(permuted_vector.into_iter()).enumerate() { + let o = AllocatedNum::alloc(&mut cs, || Ok(o)).unwrap(); + let p = AllocatedNum::alloc(&mut cs, || Ok(p)).unwrap(); original.push(o); permuted.push(p); } - prove_shuffle(&mut cs, - &original, - &permuted, - &permutation - ).unwrap(); + prove_shuffle(&mut cs, &original, &permuted, &permutation).unwrap(); assert!(cs.is_satisfied()); } @@ -550,7 +498,7 @@ mod test { println!("Size = {}", size); for _ in 0..10 { let mut cs = TrivialAssembly::::new(); - + let mut permutation = IntegerPermutation::new(size); permutation.make_permutation(rng); @@ -571,26 +519,18 @@ mod test { let mut original = vec![]; let mut permuted = vec![]; - for(_i, (o, p)) in original_vector.into_iter().zip(permuted_vector.into_iter()).enumerate() { - let o = AllocatedNum::alloc(&mut cs, - || Ok(o) - ).unwrap(); - let p = AllocatedNum::alloc(&mut cs, - || Ok(p) - ).unwrap(); + for (_i, (o, p)) in original_vector.into_iter().zip(permuted_vector.into_iter()).enumerate() { + let o = AllocatedNum::alloc(&mut cs, || Ok(o)).unwrap(); + let p = AllocatedNum::alloc(&mut cs, || Ok(p)).unwrap(); original.push(o); permuted.push(p); } - prove_shuffle(&mut cs, - &original, - &permuted, - &another_permutation - ).unwrap(); + prove_shuffle(&mut cs, &original, &permuted, &another_permutation).unwrap(); assert!(!cs.is_satisfied()); } } } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/permutation_network/mod.rs b/crates/franklin-crypto/src/plonk/circuit/permutation_network/mod.rs index d046eb8..8fd0a2e 100644 --- a/crates/franklin-crypto/src/plonk/circuit/permutation_network/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/permutation_network/mod.rs @@ -1,39 +1,19 @@ -use crate::bellman::pairing::{ - Engine, -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; - -use crate::bellman::{ - SynthesisError, -}; - -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm -}; +use crate::bellman::pairing::Engine; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; + +use crate::bellman::SynthesisError; + +use crate::bellman::plonk::better_better_cs::cs::{ArithmeticTerm, ConstraintSystem, MainGateTerm, Variable}; use crate::plonk::circuit::Assignment; -use super::allocated_num::{ - AllocatedNum, - Num -}; +use super::allocated_num::{AllocatedNum, Num}; -use super::boolean::{ - AllocatedBit, - Boolean -}; +use super::boolean::{AllocatedBit, Boolean}; -mod witness; mod circuit; +mod witness; +pub use self::circuit::*; pub use self::witness::*; -pub use self::circuit::*; \ No newline at end of file diff --git a/crates/franklin-crypto/src/plonk/circuit/permutation_network/witness.rs b/crates/franklin-crypto/src/plonk/circuit/permutation_network/witness.rs index 0eff0e9..d63e5a2 100644 --- a/crates/franklin-crypto/src/plonk/circuit/permutation_network/witness.rs +++ b/crates/franklin-crypto/src/plonk/circuit/permutation_network/witness.rs @@ -6,7 +6,7 @@ const EMPTY_STATE: usize = std::usize::MAX; #[derive(Clone, Debug)] pub struct AsWaksmanTopology { pub topology: Vec>, - pub size: usize + pub size: usize, } impl AsWaksmanTopology { @@ -21,23 +21,16 @@ impl AsWaksmanTopology { let destinations: Vec = (0..size).collect(); // recursively iterate and construct the topology - Self::construct_inner(0, num_columns-1, 0, size-1, &destinations, &mut topology); + Self::construct_inner(0, num_columns - 1, 0, size - 1, &destinations, &mut topology); - Self { - topology, - size - } + Self { topology, size } } fn calculate_top_height(size: usize) -> usize { size / 2 } - fn construct_inner(left: usize, right: usize, - low: usize, high: usize, - destinations: &[usize], - topology: &mut [Vec<(usize, usize)>]) - { + fn construct_inner(left: usize, right: usize, low: usize, high: usize, destinations: &[usize], topology: &mut [Vec<(usize, usize)>]) { if left > right { return; } @@ -50,9 +43,8 @@ impl AsWaksmanTopology { let num_columns = right - left + 1; assert!(num_columns >= columns_to_generate); - if num_columns > columns_to_generate - { - // + if num_columns > columns_to_generate { + // // If there is more space for the routing network than needed, // just add straight edges. This also handles the size-1 base case. // @@ -66,10 +58,10 @@ impl AsWaksmanTopology { let mut subdestinations = vec![EMPTY_STATE; rows_to_generate]; for idx in low..=high { - subdestinations[idx-low] = idx; + subdestinations[idx - low] = idx; } - Self::construct_inner(left+1, right-1, low, high, &subdestinations, topology); + Self::construct_inner(left + 1, right - 1, low, high, &subdestinations, topology); } else if rows_to_generate == 2 { topology[left][low].0 = destinations[0]; topology[left][high].1 = destinations[0]; @@ -80,33 +72,28 @@ impl AsWaksmanTopology { // recursion step let mut subdestinations = vec![EMPTY_STATE; rows_to_generate]; - let limit = if rows_to_generate % 2 == 1 { - high - } else { - high + 1 - }; + let limit = if rows_to_generate % 2 == 1 { high } else { high + 1 }; for idx in (low..limit).step_by(2) { let top_idx = Self::calculate_in_out_index(rows_to_generate, low, idx, true); topology[left][idx].0 = top_idx; - topology[left][idx+1].1 = top_idx; + topology[left][idx + 1].1 = top_idx; let bottom_idx = Self::calculate_in_out_index(rows_to_generate, low, idx, false); topology[left][idx].1 = bottom_idx; - topology[left][idx+1].0 = bottom_idx; + topology[left][idx + 1].0 = bottom_idx; subdestinations[(top_idx as usize) - low] = idx; subdestinations[(bottom_idx as usize) - low] = idx + 1; topology[right][idx].0 = destinations[idx - low]; - topology[right][idx+1].1 = destinations[idx - low]; + topology[right][idx + 1].1 = destinations[idx - low]; topology[right][idx].1 = destinations[idx + 1 - low]; - topology[right][idx+1].0 = destinations[idx + 1 - low]; + topology[right][idx + 1].0 = destinations[idx + 1 - low]; } - if rows_to_generate % 2 == 1 - { + if rows_to_generate % 2 == 1 { topology[left][high].0 = high; topology[left][high].1 = high; @@ -114,10 +101,8 @@ impl AsWaksmanTopology { topology[right][high].1 = destinations[high - low]; subdestinations[high - low] = high; - } - else - { - topology[left][high-1].1 = topology[left][high-1].0; + } else { + topology[left][high - 1].1 = topology[left][high - 1].0; topology[left][high].1 = topology[left][high].0; } @@ -125,8 +110,8 @@ impl AsWaksmanTopology { let top_subnet_destinations = &subdestinations[..d]; let bottom_subnet_destinations = &subdestinations[d..]; - Self::construct_inner(left+1, right-1, low, low + d - 1, top_subnet_destinations, topology); - Self::construct_inner(left+1, right-1, low + d, high, bottom_subnet_destinations, topology); + Self::construct_inner(left + 1, right - 1, low, low + d - 1, top_subnet_destinations, topology); + Self::construct_inner(left + 1, right - 1, low + d, high, bottom_subnet_destinations, topology); } } @@ -139,15 +124,10 @@ impl AsWaksmanTopology { let log_2 = next_power_of_two.trailing_zeros(); let num_columns = log_2 as usize; - 2*num_columns - 1 + 2 * num_columns - 1 } - fn calculate_in_out_index( - size: usize, - offset: usize, - index: usize, - is_top: bool - ) -> usize { + fn calculate_in_out_index(size: usize, offset: usize, index: usize, is_top: bool) -> usize { let mut relative_position = index - offset; assert!(relative_position % 2 == 0 && relative_position + 1 < size); relative_position >>= 1; @@ -167,7 +147,7 @@ impl AsWaksmanTopology { pub struct IntegerPermutation { pub elements: Vec, pub min: usize, - pub max: usize + pub max: usize, } impl IntegerPermutation { @@ -189,23 +169,19 @@ impl IntegerPermutation { } assert_eq!(min, 0, "permutation should start with 0"); - assert_eq!(max, permutation.len()-1, "permutation should not contain spaces"); + assert_eq!(max, permutation.len() - 1, "permutation should not contain spaces"); Self { elements: permutation, min: min, - max: max + max: max, } } pub(crate) fn new_for_max_and_min(min: usize, max: usize) -> Self { let elements: Vec = (min..=max).collect(); - Self { - elements, - min: min, - max: max - } + Self { elements, min: min, max: max } } pub fn size(&self) -> usize { @@ -235,7 +211,7 @@ impl IntegerPermutation { let result = Self { elements: self.elements[(min - self.min)..(max - self.min + 1)].to_vec(), min: min, - max: max + max: max, }; assert!(result.size() == result.elements.len()); @@ -257,7 +233,7 @@ impl IntegerPermutation { return true; } - let mut set: std::collections::HashSet = std::collections::HashSet::with_capacity(self.elements.len()); + let mut set: std::collections::HashSet = std::collections::HashSet::with_capacity(self.elements.len()); for element in self.elements.iter() { if *element < self.min || *element > self.max { return false; @@ -269,14 +245,14 @@ impl IntegerPermutation { } true - } + } } // this is basically a grid of size x columns #[derive(Clone, Debug)] pub struct AsWaksmanRoute { pub switches: Vec>, - pub size: usize + pub size: usize, } impl AsWaksmanRoute { @@ -288,12 +264,9 @@ impl AsWaksmanRoute { let inversed_permutation = permutation.inverse(); assert!(inversed_permutation.inverse().elements == permutation.elements); - Self::construct_inner(0, num_columns-1, 0, size-1, permutation, &inversed_permutation, &mut assignments); + Self::construct_inner(0, num_columns - 1, 0, size - 1, permutation, &inversed_permutation, &mut assignments); - Self { - switches: assignments, - size - } + Self { switches: assignments, size } } fn get_canonical_row_index(offset: usize, row_index: usize) -> usize { @@ -322,14 +295,15 @@ impl AsWaksmanRoute { } fn construct_inner( - left: usize, right: usize, - low: usize, high: usize, + left: usize, + right: usize, + low: usize, + high: usize, permutation: &IntegerPermutation, permutation_inversed: &IntegerPermutation, - switches: &mut [std::collections::HashMap] + switches: &mut [std::collections::HashMap], ) { - if left > right - { + if left > right { return; } @@ -345,20 +319,15 @@ impl AsWaksmanRoute { assert!(permutation.inverse().elements == permutation_inversed.elements); assert!(permutation_inversed.inverse().elements == permutation.elements); - if num_columns > columns_to_generate - { - Self::construct_inner(left+1, right - 1, low, high, permutation, permutation_inversed, switches); - } - else if rows_to_generate == 2 - { - assert!(permutation.get(low) == low || permutation.get(low) == low+1); - assert!(permutation.get(low+1) == low || permutation.get(low+1) == low+1); - assert!(permutation.get(low) != permutation.get(low+1)); + if num_columns > columns_to_generate { + Self::construct_inner(left + 1, right - 1, low, high, permutation, permutation_inversed, switches); + } else if rows_to_generate == 2 { + assert!(permutation.get(low) == low || permutation.get(low) == low + 1); + assert!(permutation.get(low + 1) == low || permutation.get(low + 1) == low + 1); + assert!(permutation.get(low) != permutation.get(low + 1)); switches[left].insert(low, permutation.get(low) != low); - } - else - { + } else { // // The algorithm first assigns a setting to a LHS switch, // route its target to RHS, which will enforce a RHS switch setting. @@ -375,15 +344,13 @@ impl AsWaksmanRoute { let mut should_route_left; - if rows_to_generate % 2 == 1 - { + if rows_to_generate % 2 == 1 { // // ODD CASE: we first deal with the bottom-most straight wire, // which is not connected to any of the switches at this level // of recursion and just passed into the lower subnetwork. // - if permutation.get(high) == high - { + if permutation.get(high) == high { // // Easy sub-case: it is routed directly to the bottom-most // wire on RHS, so no switches need to be touched. @@ -392,9 +359,7 @@ impl AsWaksmanRoute { new_permutation_inversed.set(high, high); to_route = high - 1; should_route_left = true; - } - else - { + } else { // // Other sub-case: the straight wire is routed to a switch // on RHS, so route the other value from that switch @@ -415,9 +380,7 @@ impl AsWaksmanRoute { lhs_is_routed[high - low] = true; max_unrouted = high - 1; - } - else - { + } else { // // EVEN CASE: the bottom-most switch is fixed to a constant // straight setting. So we route wire hi accordingly. @@ -428,25 +391,21 @@ impl AsWaksmanRoute { max_unrouted = high; } - loop - { + loop { // // INVARIANT: the wire `to_route' on LHS (if route_left = true), // resp., RHS (if route_left = false) can be routed. // - if should_route_left - { + if should_route_left { // If switch value has not been assigned, assign it arbitrarily. let lhs_switch = Self::get_canonical_row_index(low, to_route); - if switches[left].get(&lhs_switch).is_none() - { + if switches[left].get(&lhs_switch).is_none() { switches[left].insert(lhs_switch, false); } let lhs_switch_setting = *switches[left].get(&lhs_switch).unwrap(); let should_use_top = Self::get_top_bottom_decision_from_switch_setting(low, to_route, lhs_switch_setting); let t = AsWaksmanTopology::calculate_in_out_index(rows_to_generate, low, lhs_switch, should_use_top); - if permutation.get(to_route) == high - { + if permutation.get(to_route) == high { // // We have routed to the straight wire for the odd case, // so now we back-route from it. @@ -456,9 +415,7 @@ impl AsWaksmanRoute { lhs_is_routed[to_route - low] = true; to_route = max_unrouted; should_route_left = true; - } - else - { + } else { let rhs_switch = Self::get_canonical_row_index(low, permutation.get(to_route)); // // We know that the corresponding switch on the right-hand side @@ -476,9 +433,7 @@ impl AsWaksmanRoute { to_route = Self::calculate_other_position(low, permutation.get(to_route)); should_route_left = false; } - } - else - { + } else { // // We have arrived on the right-hand side, so the switch setting is fixed. // Next, we back route from here. @@ -508,31 +463,25 @@ impl AsWaksmanRoute { } /* If the next packet to be routed hasn't been routed before, then try routing it. */ - if !should_route_left || !lhs_is_routed[to_route-low] - { + if !should_route_left || !lhs_is_routed[to_route - low] { continue; } /* Otherwise just find the next unrouted packet. */ - while max_unrouted > low && lhs_is_routed[max_unrouted-low] - { + while max_unrouted > low && lhs_is_routed[max_unrouted - low] { max_unrouted -= 1; } - if max_unrouted < low || (max_unrouted == low && lhs_is_routed[0]) - { + if max_unrouted < low || (max_unrouted == low && lhs_is_routed[0]) { /* All routed! */ break; - } - else - { + } else { to_route = max_unrouted; should_route_left = true; } } - if rows_to_generate % 2 == 0 - { + if rows_to_generate % 2 == 0 { /* Remove the AS-Waksman switch with the fixed value. */ switches[left].remove(&(high - 1)); } @@ -547,14 +496,12 @@ impl AsWaksmanRoute { let new_permutation_inversed_upper = new_permutation_inversed.slice(low, low + d - 1); let new_permutation_inversed_lower = new_permutation_inversed.slice(low + d, high); - Self::construct_inner(left+1, right-1, low, low + d - 1, &new_permutation_upper, &new_permutation_inversed_upper, switches); - Self::construct_inner(left+1, right-1, low + d, high, &new_permutation_lower, &new_permutation_inversed_lower, switches); + Self::construct_inner(left + 1, right - 1, low, low + d - 1, &new_permutation_upper, &new_permutation_inversed_upper, switches); + Self::construct_inner(left + 1, right - 1, low + d, high, &new_permutation_lower, &new_permutation_inversed_lower, switches); } } - fn validate_routing_for_permutation(permutation: &IntegerPermutation, - routing: &Self) -> bool - { + fn validate_routing_for_permutation(permutation: &IntegerPermutation, routing: &Self) -> bool { let size = permutation.size(); let num_columns = AsWaksmanTopology::num_columns(size); let topology = AsWaksmanTopology::new(size); @@ -568,22 +515,12 @@ impl AsWaksmanRoute { if topology.topology[column_idx][packet_idx].0 == topology.topology[column_idx][packet_idx].1 { // straight switch routed_index = topology.topology[column_idx][packet_idx].0; - } - else - { + } else { let a = routing.switches[column_idx].get(&packet_idx); - let b = if packet_idx > 0 { - routing.switches[column_idx].get(&(packet_idx - 1)) - } else { - None - }; + let b = if packet_idx > 0 { routing.switches[column_idx].get(&(packet_idx - 1)) } else { None }; assert!(a.is_some() ^ b.is_some()); - let switch_setting = if a.is_some() { - *a.unwrap() - } else { - *b.unwrap() - }; - + let switch_setting = if a.is_some() { *a.unwrap() } else { *b.unwrap() }; + routed_index = if switch_setting { topology.topology[column_idx][packet_idx].1 } else { @@ -641,11 +578,9 @@ impl AsWaksmanRoute { result } - // this function forwards newly created ordered set [0, n) into the permutation by switches // that were supplied to the router - fn calculate_permutation(&self) -> IntegerPermutation - { + fn calculate_permutation(&self) -> IntegerPermutation { let num_columns = AsWaksmanTopology::num_columns(self.size); let topology = AsWaksmanTopology::new(self.size); @@ -658,22 +593,12 @@ impl AsWaksmanRoute { if topology.topology[column_idx][packet_idx].0 == topology.topology[column_idx][packet_idx].1 { // straight switch routed_into = topology.topology[column_idx][packet_idx].0; - } - else - { + } else { let a = self.switches[column_idx].get(&packet_idx); - let b = if packet_idx > 0 { - self.switches[column_idx].get(&(packet_idx - 1)) - } else { - None - }; + let b = if packet_idx > 0 { self.switches[column_idx].get(&(packet_idx - 1)) } else { None }; assert!(a.is_some() ^ b.is_some()); - let switch_setting = if a.is_some() { - *a.unwrap() - } else { - *b.unwrap() - }; - + let switch_setting = if a.is_some() { *a.unwrap() } else { *b.unwrap() }; + routed_into = if switch_setting { topology.topology[column_idx][packet_idx].1 } else { @@ -684,7 +609,7 @@ impl AsWaksmanRoute { let value_at_this_level = permutation.get(packet_idx); permutation_by_this_column.set(routed_into, value_at_this_level); } - + // permutation that we keep a track on is now replaced by result of permutation by this column permutation = permutation_by_this_column; } @@ -695,7 +620,7 @@ impl AsWaksmanRoute { #[test] fn test_aswaksman() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let size = 3; let mut permutation = IntegerPermutation::new(size); @@ -711,7 +636,7 @@ fn test_aswaksman() { #[test] fn test_back_and_forward_pass() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); for size in 3..4 { let mut permutation = IntegerPermutation::new(size); @@ -731,7 +656,7 @@ fn test_back_and_forward_pass() { #[test] fn test_forward_pass() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); for size in 3..9 { let mut permutation = IntegerPermutation::new(size); @@ -754,7 +679,7 @@ fn test_forward_pass() { #[test] fn test_trivial_permutations() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); for _ in 0..100 { for size in 2..128 { @@ -767,7 +692,7 @@ fn test_trivial_permutations() { #[test] fn test_routing_for_permutation() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); for size in 2..128 { println!("size = {}", size); @@ -788,7 +713,7 @@ fn test_routing_for_permutation() { #[test] fn test_uniformity() { - use rand::{Rand, thread_rng}; + use rand::{thread_rng, Rand}; let rng = &mut thread_rng(); let size = 64; let mut hists: Vec> = vec![std::collections::HashMap::new(); size]; @@ -823,7 +748,7 @@ fn test_uniformity() { let mut xi_squared = 0.0f64; let expected = (num_trials as f64) / (size as f64); for (_, v) in subhist.iter() { - xi_squared += (v - expected)*(v - expected)/expected; + xi_squared += (v - expected) * (v - expected) / expected; } if xi_squared > max_xi_squared { @@ -858,7 +783,7 @@ fn test_uniformity() { // let mut cdf = vec![0.0f64; size]; // cdf[0] = normalized[0]; // for k in 1..size { - // cdf[k] = normalized[k] + cdf[k-1]; + // cdf[k] = normalized[k] + cdf[k-1]; // } // assert!(cdf[size-1] >= 0.99999); // let mut max = 0.0f64; @@ -879,4 +804,4 @@ fn test_uniformity() { // // and P = 0.99 // let alpha = 0.0015f64; // assert!(global_max < alpha); -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/rescue.rs b/crates/franklin-crypto/src/plonk/circuit/rescue.rs index a50af90..efea8c8 100644 --- a/crates/franklin-crypto/src/plonk/circuit/rescue.rs +++ b/crates/franklin-crypto/src/plonk/circuit/rescue.rs @@ -1,42 +1,20 @@ -use crate::bellman::pairing::{ - Engine, -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; - -use crate::bellman::{ - SynthesisError, -}; - -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - PlonkConstraintSystemParams -}; +use crate::bellman::pairing::Engine; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; + +use crate::bellman::SynthesisError; + +use crate::bellman::plonk::better_better_cs::cs::{ArithmeticTerm, ConstraintSystem, MainGateTerm, PlonkConstraintSystemParams, Variable}; use crate::plonk::circuit::Assignment; -use super::boolean::{ - Boolean -}; +use super::boolean::Boolean; -use super::allocated_num::{ - AllocatedNum, - Num -}; +use super::allocated_num::{AllocatedNum, Num}; -use super::linear_combination::{ - LinearCombination -}; +use super::linear_combination::LinearCombination; -use crate::rescue::{RescueEngine, RescueHashParams, RescueParamsInternal, SBox, QuinticSBox, PowerSBox}; +use crate::rescue::{PowerSBox, QuinticSBox, RescueEngine, RescueHashParams, RescueParamsInternal, SBox}; use super::custom_rescue_gate::*; @@ -70,12 +48,7 @@ pub trait PlonkCsSBox: SBox { impl PlonkCsSBox for QuinticSBox { const SHOULD_APPLY_FORWARD: bool = true; - fn apply_constraints>( - &self, - cs: &mut CS, - el: &Num, - force_no_custom_gates: bool - ) -> Result, SynthesisError> { + fn apply_constraints>(&self, cs: &mut CS, el: &Num, force_no_custom_gates: bool) -> Result, SynthesisError> { // we need state width of 4 to make custom gate if force_no_custom_gates == false && CS::Params::HAS_CUSTOM_GATES == true && CS::Params::STATE_WIDTH >= 4 { return self.apply_custom_gate(cs, el); @@ -89,7 +62,7 @@ impl PlonkCsSBox for QuinticSBox { result.mul_assign(constant); Ok(Num::Constant(result)) - }, + } Num::Variable(el) => { // we take a value and make 5th power from it let square = el.square(cs)?; @@ -103,22 +76,13 @@ impl PlonkCsSBox for QuinticSBox { ret } - fn apply_constraints_in_reverse>( - &self, - _cs: &mut CS, - _el: &Num, - _force_no_custom_gates: bool - ) -> Result, SynthesisError> { + fn apply_constraints_in_reverse>(&self, _cs: &mut CS, _el: &Num, _force_no_custom_gates: bool) -> Result, SynthesisError> { unimplemented!("Making 5th power can only be used in straight order") } } impl QuinticSBox { - fn apply_custom_gate>( - &self, - cs: &mut CS, - el: &Num, - ) -> Result, SynthesisError> { + fn apply_custom_gate>(&self, cs: &mut CS, el: &Num) -> Result, SynthesisError> { match el { Num::Constant(constant) => { let mut result = *constant; @@ -127,7 +91,7 @@ impl QuinticSBox { result.mul_assign(constant); Ok(Num::Constant(result)) - }, + } Num::Variable(el) => { // we take a value and make 5th power from it let out = apply_5th_power(cs, el, None)?; @@ -141,12 +105,7 @@ impl QuinticSBox { impl PlonkCsSBox for PowerSBox { const SHOULD_APPLY_FORWARD: bool = false; - fn apply_constraints_in_reverse>( - &self, - cs: &mut CS, - el: &Num, - force_no_custom_gates: bool - ) -> Result, SynthesisError> { + fn apply_constraints_in_reverse>(&self, cs: &mut CS, el: &Num, force_no_custom_gates: bool) -> Result, SynthesisError> { // we need state width of 4 to make custom gate if force_no_custom_gates == false && CS::Params::HAS_CUSTOM_GATES == true && CS::Params::STATE_WIDTH >= 4 { return self.apply_custom_gate(cs, el); @@ -157,17 +116,14 @@ impl PlonkCsSBox for PowerSBox { let result = constant.pow(&self.power); Ok(Num::Constant(result)) - }, + } Num::Variable(el) => { - let out = AllocatedNum::::alloc( - cs, - || { - let base = *el.get_value().get()?; - let result = base.pow(&self.power); + let out = AllocatedNum::::alloc(cs, || { + let base = *el.get_value().get()?; + let result = base.pow(&self.power); - Ok(result) - } - )?; + Ok(result) + })?; // we take a value and make 5th power from it let square = out.square(cs)?; @@ -187,41 +143,29 @@ impl PlonkCsSBox for PowerSBox { ret } - fn apply_constraints>( - &self, - _cs: &mut CS, - _el: &Num, - _force_no_custom_gates: bool - ) -> Result, SynthesisError> { + fn apply_constraints>(&self, _cs: &mut CS, _el: &Num, _force_no_custom_gates: bool) -> Result, SynthesisError> { unimplemented!("Making inverse of 5th power can only be used in backward mode") } } impl PowerSBox { - fn apply_custom_gate>( - &self, - cs: &mut CS, - el: &Num, - ) -> Result, SynthesisError> { + fn apply_custom_gate>(&self, cs: &mut CS, el: &Num) -> Result, SynthesisError> { match el { Num::Constant(constant) => { let result = constant.pow(&self.power); Ok(Num::Constant(result)) - }, + } Num::Variable(el) => { // manually make a large power - let out = AllocatedNum::::alloc( - cs, - || { - let base = *el.get_value().get()?; - let result = base.pow(&self.power); + let out = AllocatedNum::::alloc(cs, || { + let base = *el.get_value().get()?; + let result = base.pow(&self.power); - Ok(result) - } - )?; - - // now we need to make sure that 5th power of base is equal to + Ok(result) + })?; + + // now we need to make sure that 5th power of base is equal to // the original value let _ = apply_5th_power(cs, &out, Some(el.clone()))?; @@ -234,40 +178,32 @@ impl PowerSBox { #[derive(Clone, Debug)] enum RescueOpMode { AccumulatingToAbsorb(Vec>), - SqueezedInto(Vec>) + SqueezedInto(Vec>), } #[derive(Clone, Debug)] pub struct StatefulRescueGadget { internal_state: Vec>, - mode: RescueOpMode + mode: RescueOpMode, } -pub fn rescue_hash>(cs: &mut CS, params: &E::Params, input: &[Num]) -> Result>, SynthesisError> - where <::Params as RescueHashParams>::SBox0: PlonkCsSBox, - <::Params as RescueHashParams>::SBox1: PlonkCsSBox +pub fn rescue_hash>(cs: &mut CS, params: &E::Params, input: &[Num]) -> Result>, SynthesisError> +where + <::Params as RescueHashParams>::SBox0: PlonkCsSBox, + <::Params as RescueHashParams>::SBox1: PlonkCsSBox, { let before = cs.get_current_step_number(); - let mut rescue_gadget = StatefulRescueGadget::::new( - ¶ms - ); + let mut rescue_gadget = StatefulRescueGadget::::new(¶ms); rescue_gadget.specizalize(input.len() as u8); - rescue_gadget.absorb_nums( - cs, - &input, - ¶ms - )?; + rescue_gadget.absorb_nums(cs, &input, ¶ms)?; rescue_gadget.pad_if_necessary(¶ms)?; let mut result = vec![]; for _ in 0..params.rate() { - let res_lc = rescue_gadget.squeeze_out_single( - cs, - ¶ms - )?; + let res_lc = rescue_gadget.squeeze_out_single(cs, ¶ms)?; let res = res_lc.into_num(cs)?; @@ -279,18 +215,17 @@ pub fn rescue_hash>(cs: &mut CS, params Ok(result) } -impl StatefulRescueGadget - where <::Params as RescueHashParams>::SBox0: PlonkCsSBox, - <::Params as RescueHashParams>::SBox1: PlonkCsSBox +impl StatefulRescueGadget +where + <::Params as RescueHashParams>::SBox0: PlonkCsSBox, + <::Params as RescueHashParams>::SBox1: PlonkCsSBox, { - pub fn new( - params: &E::Params - ) -> Self { + pub fn new(params: &E::Params) -> Self { let op = RescueOpMode::AccumulatingToAbsorb(Vec::with_capacity(params.rate() as usize)); Self { internal_state: vec![LinearCombination::::zero(); params.state_width() as usize], - mode: op + mode: op, } } @@ -343,18 +278,9 @@ impl StatefulRescueGadget // } // } - - pub fn rescue_mimc_over_nums>( - cs: &mut CS, - state: &[Num], - params: &E::Params - ) -> Result>, SynthesisError> { + pub fn rescue_mimc_over_nums>(cs: &mut CS, state: &[Num], params: &E::Params) -> Result>, SynthesisError> { let state: Vec<_> = state.iter().map(|el| LinearCombination::from(*el)).collect(); - let out_lcs = Self::rescue_mimc_over_lcs( - cs, - &state, - ¶ms - )?; + let out_lcs = Self::rescue_mimc_over_lcs(cs, &state, ¶ms)?; let mut out = vec![]; for lc in out_lcs.into_iter() { let as_num = lc.into_num(cs)?; @@ -364,11 +290,7 @@ impl StatefulRescueGadget Ok(out) } - pub fn rescue_mimc_over_lcs>( - cs: &mut CS, - state: &[LinearCombination], - params: &E::Params - ) -> Result>, SynthesisError> { + pub fn rescue_mimc_over_lcs>(cs: &mut CS, state: &[LinearCombination], params: &E::Params) -> Result>, SynthesisError> { let state_len = state.len(); assert_eq!(state_len, params.state_width() as usize); let mut state = Some(state.to_vec()); @@ -417,7 +339,7 @@ impl StatefulRescueGadget let mut lc = LinearCombination::::zero(); let mds_row = params.mds_matrix_row(i as u32); - for (s, coeff) in after_nonlin.iter().zip(mds_row.iter()){ + for (s, coeff) in after_nonlin.iter().zip(mds_row.iter()) { lc.add_assign_number_with_coeff(s, *coeff); } lc.add_assign_constant(round_constants[i]); @@ -432,15 +354,12 @@ impl StatefulRescueGadget } #[track_caller] - pub fn specizalize( - &mut self, - dst: u8 - ) { + pub fn specizalize(&mut self, dst: u8) { assert!(dst > 0); match self.mode { RescueOpMode::AccumulatingToAbsorb(ref into) => { assert_eq!(into.len(), 0, "can not specialize sponge that absorbed something") - }, + } _ => { panic!("can not specialized sponge in squeezing state"); } @@ -453,18 +372,13 @@ impl StatefulRescueGadget self.internal_state[last_state_elem_idx].add_assign_constant(as_fe) } - pub fn absorb_single_value>( - &mut self, - cs: &mut CS, - value: Num, - params: &E::Params - ) -> Result<(), SynthesisError> { + pub fn absorb_single_value>(&mut self, cs: &mut CS, value: Num, params: &E::Params) -> Result<(), SynthesisError> { let before = cs.get_current_step_number(); match self.mode { RescueOpMode::AccumulatingToAbsorb(ref mut into) => { // two cases - // either we have accumulated enough already and should to + // either we have accumulated enough already and should to // a mimc round before accumulating more, or just accumulate more let rate = params.rate() as usize; if into.len() < rate { @@ -474,16 +388,12 @@ impl StatefulRescueGadget self.internal_state[i].add_assign_number_with_coeff(&into[i], E::Fr::one()); } - self.internal_state = Self::rescue_mimc_over_lcs( - cs, - &self.internal_state, - ¶ms - )?; + self.internal_state = Self::rescue_mimc_over_lcs(cs, &self.internal_state, ¶ms)?; into.truncate(0); into.push(value.clone()); } - }, + } RescueOpMode::SqueezedInto(_) => { // we don't need anything from the output, so it's dropped @@ -500,16 +410,11 @@ impl StatefulRescueGadget Ok(()) } - pub fn absorb>( - &mut self, - cs: &mut CS, - input: &[AllocatedNum], - params: &E::Params - ) -> Result<(), SynthesisError>{ + pub fn absorb>(&mut self, cs: &mut CS, input: &[AllocatedNum], params: &E::Params) -> Result<(), SynthesisError> { let before = cs.get_current_step_number(); let absorbtion_len = params.rate() as usize; - + assert!(input.len() > 0); let mut absorbtion_cycles = input.len() / absorbtion_len; if input.len() % absorbtion_len != 0 { @@ -518,15 +423,11 @@ impl StatefulRescueGadget let mut input: Vec<_> = input.iter().map(|el| Num::Variable(el.clone())).collect(); input.resize(absorbtion_cycles * absorbtion_len, Num::Constant(E::Fr::one())); - + let it = input.into_iter(); - + for (_idx, val) in it.enumerate() { - self.absorb_single_value( - cs, - val, - ¶ms - )?; + self.absorb_single_value(cs, val, ¶ms)?; } increment_counter_by(cs.get_current_step_number() - before); @@ -534,16 +435,11 @@ impl StatefulRescueGadget Ok(()) } - pub fn absorb_nums>( - &mut self, - cs: &mut CS, - input: &[Num], - params: &E::Params - ) -> Result<(), SynthesisError>{ + pub fn absorb_nums>(&mut self, cs: &mut CS, input: &[Num], params: &E::Params) -> Result<(), SynthesisError> { let before = cs.get_current_step_number(); let absorbtion_len = params.rate() as usize; - + assert!(input.len() > 0); let mut absorbtion_cycles = input.len() / absorbtion_len; if input.len() % absorbtion_len != 0 { @@ -552,15 +448,11 @@ impl StatefulRescueGadget let mut input: Vec<_> = input.to_vec(); input.resize(absorbtion_cycles * absorbtion_len, Num::Constant(E::Fr::one())); - + let it = input.into_iter(); - + for (_idx, val) in it.enumerate() { - self.absorb_single_value( - cs, - val, - ¶ms - )?; + self.absorb_single_value(cs, val, ¶ms)?; } increment_counter_by(cs.get_current_step_number() - before); @@ -568,29 +460,21 @@ impl StatefulRescueGadget Ok(()) } - pub fn squeeze_out_single>( - &mut self, - cs: &mut CS, - params: &E::Params - ) -> Result, SynthesisError> { + pub fn squeeze_out_single>(&mut self, cs: &mut CS, params: &E::Params) -> Result, SynthesisError> { let before = cs.get_current_step_number(); - + match self.mode { RescueOpMode::AccumulatingToAbsorb(ref mut into) => { let rate = params.rate() as usize; assert_eq!(into.len(), rate, "padding was necessary!"); // two cases - // either we have accumulated enough already and should to + // either we have accumulated enough already and should to // a mimc round before accumulating more, or just accumulate more for i in 0..rate { self.internal_state[i].add_assign_number_with_coeff(&into[i], E::Fr::one()); } - self.internal_state = Self::rescue_mimc_over_lcs( - cs, - &self.internal_state, - ¶ms - )?; + self.internal_state = Self::rescue_mimc_over_lcs(cs, &self.internal_state, ¶ms)?; // we don't take full internal state, but only the rate let mut sponge_output = self.internal_state[0..rate].to_vec(); @@ -602,29 +486,26 @@ impl StatefulRescueGadget increment_counter_by(cs.get_current_step_number() - before); return Ok(output); - }, + } RescueOpMode::SqueezedInto(ref mut into) => { assert!(into.len() > 0, "squeezed state is depleted!"); let output = into.drain(0..1).next().expect("squeezed sponge must contain some data left"); increment_counter_by(cs.get_current_step_number() - before); - + return Ok(output); } } } - pub fn pad_if_necessary( - &mut self, - params: &E::Params - ) -> Result<(), SynthesisError> { + pub fn pad_if_necessary(&mut self, params: &E::Params) -> Result<(), SynthesisError> { match self.mode { RescueOpMode::AccumulatingToAbsorb(ref mut into) => { let rate = params.rate() as usize; if into.len() != rate { into.resize(rate, Num::Constant(E::Fr::one())); }; - }, + } RescueOpMode::SqueezedInto(..) => { // do nothing // panic!("Can not call padding on a squeezed sponge"); @@ -638,16 +519,12 @@ impl StatefulRescueGadget #[cfg(test)] mod test { use super::*; - use rand::{SeedableRng, Rng, XorShiftRng}; use super::*; + use crate::bellman::plonk::better_better_cs::cs::{PlonkCsWidth4WithNextStepParams, TrivialAssembly, Width4MainGateWithDNext}; + use crate::rescue; use bellman::pairing::bn256::{Bn256, Fr}; use bellman::pairing::ff::PrimeField; - use crate::rescue; - use crate::bellman::plonk::better_better_cs::cs::{ - TrivialAssembly, - PlonkCsWidth4WithNextStepParams, - Width4MainGateWithDNext - }; + use rand::{Rng, SeedableRng, XorShiftRng}; use crate::plonk::circuit::Width4WithCustomGates; @@ -661,47 +538,24 @@ mod test { let expected = rescue::rescue_hash::(¶ms, &input[..]); { - let mut cs = TrivialAssembly::::new(); - - let input_words: Vec> = input.iter().enumerate().map(|(_i, b)| { - AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - }).unwrap() - }).collect(); - - let mut rescue_gadget = StatefulRescueGadget::::new( - ¶ms - ); + let mut cs = TrivialAssembly::::new(); + + let input_words: Vec> = input.iter().enumerate().map(|(_i, b)| AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap()).collect(); + + let mut rescue_gadget = StatefulRescueGadget::::new(¶ms); rescue_gadget.specizalize(input_words.len() as u8); - rescue_gadget.absorb( - &mut cs, - &input_words, - ¶ms - ).unwrap(); + rescue_gadget.absorb(&mut cs, &input_words, ¶ms).unwrap(); - let res_0 = rescue_gadget.squeeze_out_single( - &mut cs, - ¶ms - ).unwrap(); + let res_0 = rescue_gadget.squeeze_out_single(&mut cs, ¶ms).unwrap(); assert_eq!(res_0.get_value().unwrap(), expected[0]); println!("Rescue stateful hash of {} elements taken {} constraints", input.len(), cs.n()); - let res_1 = rescue_gadget.squeeze_out_single( - &mut cs, - ¶ms - ).unwrap(); + let res_1 = rescue_gadget.squeeze_out_single(&mut cs, ¶ms).unwrap(); - let mut stateful_hasher = rescue::StatefulRescue::::new( - ¶ms - ); + let mut stateful_hasher = rescue::StatefulRescue::::new(¶ms); stateful_hasher.specialize(input.len() as u8); @@ -728,47 +582,24 @@ mod test { let expected = rescue::rescue_hash::(¶ms, &input[..]); { - let mut cs = TrivialAssembly::::new(); - - let input_words: Vec> = input.iter().enumerate().map(|(_i, b)| { - AllocatedNum::alloc( - &mut cs, - || { - Ok(*b) - }).unwrap() - }).collect(); - - let mut rescue_gadget = StatefulRescueGadget::::new( - ¶ms - ); + let mut cs = TrivialAssembly::::new(); + + let input_words: Vec> = input.iter().enumerate().map(|(_i, b)| AllocatedNum::alloc(&mut cs, || Ok(*b)).unwrap()).collect(); + + let mut rescue_gadget = StatefulRescueGadget::::new(¶ms); rescue_gadget.specizalize(input_words.len() as u8); - rescue_gadget.absorb( - &mut cs, - &input_words, - ¶ms - ).unwrap(); + rescue_gadget.absorb(&mut cs, &input_words, ¶ms).unwrap(); - let res_0 = rescue_gadget.squeeze_out_single( - &mut cs, - ¶ms - ).unwrap(); + let res_0 = rescue_gadget.squeeze_out_single(&mut cs, ¶ms).unwrap(); assert_eq!(res_0.get_value().unwrap(), expected[0]); println!("Rescue stateful hash of {} elements taken {} constraints", input.len(), cs.n()); - let res_1 = rescue_gadget.squeeze_out_single( - &mut cs, - ¶ms - ).unwrap(); + let res_1 = rescue_gadget.squeeze_out_single(&mut cs, ¶ms).unwrap(); - let mut stateful_hasher = rescue::StatefulRescue::::new( - ¶ms - ); + let mut stateful_hasher = rescue::StatefulRescue::::new(¶ms); stateful_hasher.specialize(input.len() as u8); @@ -809,17 +640,17 @@ mod test { // Ok(*b) // }).unwrap() // }).collect(); - + // let mut rescue_gadget = StatefulRescueGadget::::new( // ¶ms // ); - + // rescue_gadget.absorb( // cs, - // &input_words, + // &input_words, // ¶ms // )?; - + // let res_0 = rescue_gadget.squeeze_out_single( // cs, // ¶ms @@ -843,4 +674,4 @@ mod test { // _ // >(&TestCircuit).unwrap(); // } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/sha256.rs b/crates/franklin-crypto/src/plonk/circuit/sha256.rs index 8963168..27a7a62 100644 --- a/crates/franklin-crypto/src/plonk/circuit/sha256.rs +++ b/crates/franklin-crypto/src/plonk/circuit/sha256.rs @@ -1,92 +1,48 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, Variable, Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, }; - use crate::plonk::circuit::Assignment; -use super::allocated_num::{ - AllocatedNum -}; +use super::allocated_num::AllocatedNum; -use super::linear_combination::{ - LinearCombination -}; +use super::linear_combination::LinearCombination; -use super::boolean::{ - AllocatedBit, - Boolean -}; +use super::boolean::{AllocatedBit, Boolean}; use super::multieq::MultiEq; use super::uint32::UInt32; const ROUND_CONSTANTS: [u32; 64] = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, ]; -const IV: [u32; 8] = [ - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 -]; +const IV: [u32; 8] = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]; -pub fn sha256_block_no_padding( - cs: &mut CS, - input: &[Boolean] -) -> Result, SynthesisError> - where E: Engine, CS: ConstraintSystem +pub fn sha256_block_no_padding(cs: &mut CS, input: &[Boolean]) -> Result, SynthesisError> +where + E: Engine, + CS: ConstraintSystem, { assert_eq!(input.len(), 512); - Ok(sha256_compression_function( - cs, - &input, - &get_sha256_iv() - )? - .into_iter() - .flat_map(|e| e.into_bits_be()) - .collect()) + Ok(sha256_compression_function(cs, &input, &get_sha256_iv())?.into_iter().flat_map(|e| e.into_bits_be()).collect()) } -pub fn sha256( - cs: &mut CS, - input: &[Boolean] -) -> Result, SynthesisError> - where E: Engine, CS: ConstraintSystem +pub fn sha256(cs: &mut CS, input: &[Boolean]) -> Result, SynthesisError> +where + E: Engine, + CS: ConstraintSystem, { assert!(input.len() % 8 == 0); @@ -106,35 +62,25 @@ pub fn sha256( let mut cur = get_sha256_iv(); for (_i, block) in padded.chunks(512).enumerate() { - cur = sha256_compression_function( - cs, - block, - &cur - )?; + cur = sha256_compression_function(cs, block, &cur)?; } - Ok(cur.into_iter() - .flat_map(|e| e.into_bits_be()) - .collect()) + Ok(cur.into_iter().flat_map(|e| e.into_bits_be()).collect()) } pub fn get_sha256_iv() -> Vec { IV.iter().map(|&v| UInt32::constant(v)).collect() } -pub fn sha256_compression_function( - cs: &mut CS, - input: &[Boolean], - current_hash_value: &[UInt32] -) -> Result, SynthesisError> - where E: Engine, CS: ConstraintSystem +pub fn sha256_compression_function(cs: &mut CS, input: &[Boolean], current_hash_value: &[UInt32]) -> Result, SynthesisError> +where + E: Engine, + CS: ConstraintSystem, { assert_eq!(input.len(), 512); assert_eq!(current_hash_value.len(), 8); - let mut w = input.chunks(32) - .map(|e| UInt32::from_bits_be(e)) - .collect::>(); + let mut w = input.chunks(32).map(|e| UInt32::from_bits_be(e)).collect::>(); // We can save some constraints by combining some of // the constraints in different u32 additions @@ -144,31 +90,16 @@ pub fn sha256_compression_function( let cs = cs.as_cs(); // s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3) - let mut s0 = w[i-15].rotr(7); - s0 = s0.xor( - cs, - &w[i-15].rotr(18) - )?; - s0 = s0.xor( - cs, - &w[i-15].shr(3) - )?; + let mut s0 = w[i - 15].rotr(7); + s0 = s0.xor(cs, &w[i - 15].rotr(18))?; + s0 = s0.xor(cs, &w[i - 15].shr(3))?; // s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift 10) - let mut s1 = w[i-2].rotr(17); - s1 = s1.xor( - cs, - &w[i-2].rotr(19) - )?; - s1 = s1.xor( - cs, - &w[i-2].shr(10) - )?; - - let tmp = UInt32::addmany( - cs, - &[w[i-16].clone(), s0, w[i-7].clone(), s1] - )?; + let mut s1 = w[i - 2].rotr(17); + s1 = s1.xor(cs, &w[i - 2].rotr(19))?; + s1 = s1.xor(cs, &w[i - 2].shr(10))?; + + let tmp = UInt32::addmany(cs, &[w[i - 16].clone(), s0, w[i - 7].clone(), s1])?; // w[i] := w[i-16] + s0 + w[i-7] + s1 w.push(tmp); @@ -178,28 +109,20 @@ pub fn sha256_compression_function( enum Maybe { Deferred(Vec), - Concrete(UInt32) + Concrete(UInt32), } impl Maybe { - fn compute( - self, - cs: &mut CS, - others: &[UInt32] - ) -> Result - where E: Engine, - CS: ConstraintSystem + fn compute(self, cs: &mut CS, others: &[UInt32]) -> Result + where + E: Engine, + CS: ConstraintSystem, { Ok(match self { - Maybe::Concrete(ref v) => { - return Ok(v.clone()) - }, + Maybe::Concrete(ref v) => return Ok(v.clone()), Maybe::Deferred(mut v) => { v.extend(others.into_iter().cloned()); - UInt32::addmany( - cs, - &v - )? + UInt32::addmany(cs, &v)? } }) } @@ -219,51 +142,23 @@ pub fn sha256_compression_function( // S1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25) let new_e = e.compute(cs, &[])?; let mut s1 = new_e.rotr(6); - s1 = s1.xor( - cs, - &new_e.rotr(11) - )?; - s1 = s1.xor( - cs, - &new_e.rotr(25) - )?; + s1 = s1.xor(cs, &new_e.rotr(11))?; + s1 = s1.xor(cs, &new_e.rotr(25))?; // ch := (e and f) xor ((not e) and g) - let ch = UInt32::sha256_ch( - cs, - &new_e, - &f, - &g - )?; + let ch = UInt32::sha256_ch(cs, &new_e, &f, &g)?; // temp1 := h + S1 + ch + k[i] + w[i] - let temp1 = vec![ - h.clone(), - s1, - ch, - UInt32::constant(ROUND_CONSTANTS[i]), - w[i].clone() - ]; + let temp1 = vec![h.clone(), s1, ch, UInt32::constant(ROUND_CONSTANTS[i]), w[i].clone()]; // S0 := (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22) let new_a = a.compute(cs, &[])?; let mut s0 = new_a.rotr(2); - s0 = s0.xor( - cs, - &new_a.rotr(13) - )?; - s0 = s0.xor( - cs, - &new_a.rotr(22) - )?; + s0 = s0.xor(cs, &new_a.rotr(13))?; + s0 = s0.xor(cs, &new_a.rotr(22))?; // maj := (a and b) xor (a and c) xor (b and c) - let maj = UInt32::sha256_maj( - cs, - &new_a, - &b, - &c - )?; + let maj = UInt32::sha256_maj(cs, &new_a, &b, &c)?; // temp2 := S0 + maj let temp2 = vec![s0, maj]; @@ -303,45 +198,21 @@ pub fn sha256_compression_function( let cs = cs.as_cs(); - let h0 = a.compute( - cs, - &[current_hash_value[0].clone()] - )?; - - let h1 = UInt32::addmany( - cs, - &[current_hash_value[1].clone(), b] - )?; - - let h2 = UInt32::addmany( - cs, - &[current_hash_value[2].clone(), c] - )?; - - let h3 = UInt32::addmany( - cs, - &[current_hash_value[3].clone(), d] - )?; - - let h4 = e.compute( - cs, - &[current_hash_value[4].clone()] - )?; - - let h5 = UInt32::addmany( - cs, - &[current_hash_value[5].clone(), f] - )?; - - let h6 = UInt32::addmany( - cs, - &[current_hash_value[6].clone(), g] - )?; - - let h7 = UInt32::addmany( - cs, - &[current_hash_value[7].clone(), h] - )?; + let h0 = a.compute(cs, &[current_hash_value[0].clone()])?; + + let h1 = UInt32::addmany(cs, &[current_hash_value[1].clone(), b])?; + + let h2 = UInt32::addmany(cs, &[current_hash_value[2].clone(), c])?; + + let h3 = UInt32::addmany(cs, &[current_hash_value[3].clone(), d])?; + + let h4 = e.compute(cs, &[current_hash_value[4].clone()])?; + + let h5 = UInt32::addmany(cs, &[current_hash_value[5].clone(), f])?; + + let h6 = UInt32::addmany(cs, &[current_hash_value[6].clone(), g])?; + + let h7 = UInt32::addmany(cs, &[current_hash_value[7].clone(), h])?; Ok(vec![h0, h1, h2, h3, h4, h5, h6, h7]) } @@ -349,7 +220,7 @@ pub fn sha256_compression_function( #[cfg(test)] mod test { use super::*; - use rand::{XorShiftRng, SeedableRng, Rng}; + use rand::{Rng, SeedableRng, XorShiftRng}; use bellman::pairing::bn256::{Bn256, Fr}; use bellman::pairing::ff::{Field, PrimeField}; @@ -364,11 +235,7 @@ mod test { let mut cs = TrivialAssembly::::new(); let mut input_bits: Vec<_> = (0..512).map(|_| Boolean::Constant(false)).collect(); input_bits[0] = Boolean::Constant(true); - let out = sha256_compression_function( - &mut cs, - &input_bits, - &iv - ).unwrap(); + let out = sha256_compression_function(&mut cs, &input_bits, &iv).unwrap(); let out_bits: Vec<_> = out.into_iter().flat_map(|e| e.into_bits_be()).collect(); assert!(cs.is_satisfied()); @@ -393,20 +260,9 @@ mod test { let iv = get_sha256_iv(); let mut cs = TrivialAssembly::::new(); - let input_bits: Vec<_> = (0..512).map(|_i| { - Boolean::from( - AllocatedBit::alloc( - &mut cs, - Some(rng.gen()) - ).unwrap() - ) - }).collect(); - - sha256_compression_function( - &mut cs, - &input_bits, - &iv - ).unwrap(); + let input_bits: Vec<_> = (0..512).map(|_i| Boolean::from(AllocatedBit::alloc(&mut cs, Some(rng.gen())).unwrap())).collect(); + + sha256_compression_function(&mut cs, &input_bits, &iv).unwrap(); assert!(cs.is_satisfied()); assert_eq!(cs.n() - 512, 25840); @@ -414,12 +270,11 @@ mod test { #[test] fn test_against_vectors() { - use sha2::{Sha256, Digest}; + use sha2::{Digest, Sha256}; let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - for input_len in (0..32).chain((32..256).filter(|a| a % 8 == 0)) - { + for input_len in (0..32).chain((32..256).filter(|a| a % 8 == 0)) { let mut h = Sha256::new(); let data: Vec = (0..input_len).map(|_| rng.gen()).collect(); h.update(&data); @@ -441,17 +296,16 @@ mod test { assert!(cs.is_satisfied()); - let mut s = hash_result.as_ref().iter() - .flat_map(|&byte| (0..8).rev().map(move |i| (byte >> i) & 1u8 == 1u8)); + let mut s = hash_result.as_ref().iter().flat_map(|&byte| (0..8).rev().map(move |i| (byte >> i) & 1u8 == 1u8)); for b in r { match b { Boolean::Is(b) => { assert!(s.next().unwrap() == b.get_value().unwrap()); - }, + } Boolean::Not(b) => { assert!(s.next().unwrap() != b.get_value().unwrap()); - }, + } Boolean::Constant(b) => { assert!(input_len == 0); assert!(s.next().unwrap() == b); diff --git a/crates/franklin-crypto/src/plonk/circuit/simple_term.rs b/crates/franklin-crypto/src/plonk/circuit/simple_term.rs index b713e2c..b410b2b 100644 --- a/crates/franklin-crypto/src/plonk/circuit/simple_term.rs +++ b/crates/franklin-crypto/src/plonk/circuit/simple_term.rs @@ -1,30 +1,16 @@ -use crate::bellman::pairing::{ - Engine, -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; - -use crate::bellman::{ - SynthesisError, -}; - -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm -}; +use crate::bellman::pairing::Engine; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; + +use crate::bellman::SynthesisError; + +use crate::bellman::plonk::better_better_cs::cs::{ArithmeticTerm, ConstraintSystem, MainGateTerm, Variable}; use crate::plonk::circuit::Assignment; use super::allocated_num::*; -use super::linear_combination::*; use super::boolean::Boolean; +use super::linear_combination::*; // a*X + b that is more lightweight than linear // combination but allows to better work with constants and scaling @@ -35,7 +21,6 @@ pub struct Term { pub constant_term: E::Fr, } - impl std::fmt::Display for Term { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Term {{ ")?; @@ -50,13 +35,13 @@ impl Term { pub fn enforce_equal>(&self, cs: &mut CS, other: &Self) -> Result<(), SynthesisError> { if self.is_constant() || other.is_constant() { assert_eq!(self.get_constant_value(), other.get_constant_value()); - return Ok(()) + return Ok(()); } let mut lc = LinearCombination::zero(); lc.add_assign_number_with_coeff(&self.num, self.coeff); lc.add_assign_constant(self.constant_term); - + let mut coeff = other.coeff; coeff.negate(); lc.add_assign_number_with_coeff(&other.num, coeff); @@ -69,30 +54,27 @@ impl Term { match (self.is_constant(), other.is_constant()) { (true, true) => self.get_value() == other.get_value(), (true, false) | (false, true) => false, - (false, false) => { - self.get_variable().get_variable() == other.get_variable().get_variable() && - self.coeff == other.coeff && self.constant_term == other.constant_term - }, + (false, false) => self.get_variable().get_variable() == other.get_variable().get_variable() && self.coeff == other.coeff && self.constant_term == other.constant_term, } } pub fn is_constant(&self) -> bool { match self.num { Num::Constant(..) => true, - _ => false + _ => false, } } pub fn unpack(&self) -> (Variable, E::Fr, E::Fr) { let var = self.num.get_variable().get_variable(); (var, self.coeff, self.constant_term) - } + } pub fn from_constant(val: E::Fr) -> Self { Self { num: Num::Constant(val), coeff: E::Fr::one(), - constant_term: E::Fr::zero() + constant_term: E::Fr::zero(), } } @@ -100,7 +82,7 @@ impl Term { Self { num: Num::Variable(n), coeff: E::Fr::one(), - constant_term: E::Fr::zero() + constant_term: E::Fr::zero(), } } @@ -108,7 +90,7 @@ impl Term { Self { num: n, coeff: E::Fr::one(), - constant_term: E::Fr::zero() + constant_term: E::Fr::zero(), } } @@ -130,34 +112,27 @@ impl Term { } else { Self::from_constant(E::Fr::zero()) } - }, + } Boolean::Is(bit) => { let var = bit.get_variable(); let val = bit.get_value_as_field_element::(); - let allocated = AllocatedNum:: { - variable: var, - value: val - }; + let allocated = AllocatedNum:: { variable: var, value: val }; Self::from_allocated_num(allocated) - }, + } Boolean::Not(bit) => { let var = bit.get_variable(); let val = bit.get_value_as_field_element::(); - let allocated = AllocatedNum:: { - variable: var, - value: val - }; + let allocated = AllocatedNum:: { variable: var, value: val }; let mut tmp = Self::from_allocated_num(allocated); tmp.negate(); tmp.add_constant(&E::Fr::one()); tmp - }, - + } } } @@ -169,8 +144,10 @@ impl Term { tmp.add_assign(&self.constant_term); tmp - }, - _ => {panic!("variable")} + } + _ => { + panic!("variable") + } } } @@ -181,7 +158,7 @@ impl Term { tmp.mul_assign(&c); tmp.add_assign(&self.constant_term); Some(tmp) - }, + } _ => None, } } @@ -204,10 +181,8 @@ impl Term { match &self.num { Num::Constant(..) => { panic!("this term is constant") - }, - Num::Variable(v) => { - v.clone() } + Num::Variable(v) => v.clone(), } } @@ -216,7 +191,7 @@ impl Term { match &self.num { Num::Constant(..) => { panic!("this term is constant") - }, + } Num::Variable(v) => { assert_eq!(E::Fr::one(), self.coeff); assert!(self.constant_term.is_zero()); @@ -241,9 +216,7 @@ impl Term { pub fn get_value(&self) -> Option { match &self.num { - Num::Constant(..) => { - Some(self.get_constant_value()) - }, + Num::Constant(..) => Some(self.get_constant_value()), Num::Variable(v) => { if let Some(v) = v.get_value() { let mut tmp = self.coeff; @@ -258,10 +231,7 @@ impl Term { } } - pub fn collapse_into_num>( - &self, - cs: &mut CS - ) -> Result, SynthesisError> { + pub fn collapse_into_num>(&self, cs: &mut CS) -> Result, SynthesisError> { if self.is_constant() { return Ok(Num::Constant(self.get_constant_value())); } @@ -292,17 +262,13 @@ impl Term { let allocated = AllocatedNum:: { variable: result_var, - value: new_value + value: new_value, }; Ok(Num::Variable(allocated)) } - pub fn add>( - &self, - cs: &mut CS, - other: &Self - ) -> Result { + pub fn add>(&self, cs: &mut CS, other: &Self) -> Result { let this_is_constant = self.is_constant(); let other_is_constant = other.is_constant(); @@ -311,27 +277,19 @@ impl Term { let mut v = self.get_constant_value(); v.add_assign(&other.get_constant_value()); - return Ok(Self::from_constant(v)) - }, + return Ok(Self::from_constant(v)); + } (true, false) | (false, true) => { - let c = if this_is_constant { - self.get_constant_value() - } else { - other.get_constant_value() - }; + let c = if this_is_constant { self.get_constant_value() } else { other.get_constant_value() }; - let mut non_constant = if this_is_constant { - other.clone() - } else { - self.clone() - }; + let mut non_constant = if this_is_constant { other.clone() } else { self.clone() }; non_constant.add_constant(&c); let num = non_constant.collapse_into_num(cs)?; return Ok(Self::from_num(num)); - }, + } (false, false) => { let mut lc = LinearCombination::::zero(); lc.add_assign_number_with_coeff(&self.num, self.coeff); @@ -346,22 +304,14 @@ impl Term { } } - pub fn sub>( - &self, - cs: &mut CS, - other: &Self - ) -> Result { + pub fn sub>(&self, cs: &mut CS, other: &Self) -> Result { let mut other = other.clone(); other.negate(); self.add(cs, &other) } - pub fn add_multiple>( - &self, - cs: &mut CS, - other: &[Self] - ) -> Result { + pub fn add_multiple>(&self, cs: &mut CS, other: &[Self]) -> Result { if other.len() == 0 { return Ok(self.clone()); } @@ -382,20 +332,11 @@ impl Term { return Ok(Self::from_num(num)); } - pub fn mul>( - &self, - cs: &mut CS, - other: &Self - ) -> Result { + pub fn mul>(&self, cs: &mut CS, other: &Self) -> Result { Self::fma(cs, self, other, &Self::zero()) } - pub fn fma>( - cs: &mut CS, - mul_x: &Self, - mul_y: &Self, - add_z: &Self - ) -> Result { + pub fn fma>(cs: &mut CS, mul_x: &Self, mul_y: &Self, add_z: &Self) -> Result { let x_is_constant = mul_x.is_constant(); let y_is_constant = mul_y.is_constant(); let z_is_constant = add_z.is_constant(); @@ -409,7 +350,7 @@ impl Term { let n = Self::from_constant(result); return Ok(n); - }, + } (true, true, false) => { let mut value = mul_x.get_constant_value(); value.mul_assign(&mul_y.get_constant_value()); @@ -418,45 +359,29 @@ impl Term { result.add_constant(&value); return Ok(result); - }, - (true, false, true) | (false, true, true)=> { + } + (true, false, true) | (false, true, true) => { let additive_constant = add_z.get_constant_value(); - let multiplicative_constant = if x_is_constant { - mul_x.get_constant_value() - } else { - mul_y.get_constant_value() - }; + let multiplicative_constant = if x_is_constant { mul_x.get_constant_value() } else { mul_y.get_constant_value() }; - let mut result = if x_is_constant { - mul_y.clone() - } else { - mul_x.clone() - }; + let mut result = if x_is_constant { mul_y.clone() } else { mul_x.clone() }; result.scale(&multiplicative_constant); result.add_constant(&additive_constant); return Ok(result); - }, + } (true, false, false) | (false, true, false) => { - let multiplicative_constant = if x_is_constant { - mul_x.get_constant_value() - } else { - mul_y.get_constant_value() - }; + let multiplicative_constant = if x_is_constant { mul_x.get_constant_value() } else { mul_y.get_constant_value() }; - let mut tmp = if x_is_constant { - mul_y.clone() - } else { - mul_x.clone() - }; + let mut tmp = if x_is_constant { mul_y.clone() } else { mul_x.clone() }; tmp.scale(&multiplicative_constant); let tmp = tmp.add(cs, &add_z)?; return Ok(tmp); - }, + } (false, false, true) => { let mut mul_coeff = mul_x.coeff; mul_coeff.mul_assign(&mul_y.coeff); @@ -481,16 +406,11 @@ impl Term { new_value.add_assign(&z); Some(new_value) - }, - _ => {None} + } + _ => None, }; - let allocated_num = AllocatedNum::alloc( - cs, - || { - Ok(*new_value.get()?) - } - )?; + let allocated_num = AllocatedNum::alloc(cs, || Ok(*new_value.get()?))?; let mut term = MainGateTerm::::new(); let mul_term = ArithmeticTerm::::from_variable_and_coeff(x_var, mul_coeff).mul_by_variable(y_var); @@ -510,12 +430,12 @@ impl Term { let new = Self::from_allocated_num(allocated_num); return Ok(new); - }, + } (false, false, false) => { // each term is something like a*X + b // in this case we have do manually unroll it - // (a_0 * X + b_0) * (a_1 * Y + b_1) + (a_2 * Z + b_2) = + // (a_0 * X + b_0) * (a_1 * Y + b_1) + (a_2 * Z + b_2) = // a_0 * X * a_1 * Y + (a_0 * X * b_1 + a_1 * Y * b_0 + a_2 * Z) + (b_0 * b_1 + b_2) @@ -543,16 +463,11 @@ impl Term { new_value.add_assign(&z); Some(new_value) - }, - _ => {None} + } + _ => None, }; - let allocated_num = AllocatedNum::alloc( - cs, - || { - Ok(*new_value.get()?) - } - )?; + let allocated_num = AllocatedNum::alloc(cs, || Ok(*new_value.get()?))?; let mut term = MainGateTerm::::new(); let mul_term = ArithmeticTerm::::from_variable_and_coeff(x_var, mul_coeff).mul_by_variable(y_var); @@ -578,12 +493,7 @@ impl Term { } } - pub(crate) fn square_with_factor_and_add>( - cs: &mut CS, - x: &Self, - z: &Self, - factor: &E::Fr - ) -> Result { + pub(crate) fn square_with_factor_and_add>(cs: &mut CS, x: &Self, z: &Self, factor: &E::Fr) -> Result { let x_is_constant = x.is_constant(); let z_is_constant = z.is_constant(); @@ -597,7 +507,7 @@ impl Term { let n = Self::from_constant(result); return Ok(n); - }, + } (true, false) => { let mut value = x.get_constant_value(); value.square(); @@ -607,7 +517,7 @@ impl Term { result.add_constant(&value); return Ok(result); - }, + } (false, true) => { let mut mul_coeff = x.coeff; mul_coeff.square(); @@ -633,16 +543,11 @@ impl Term { new_value.add_assign(&z); Some(new_value) - }, - _ => {None} + } + _ => None, }; - let allocated_num = AllocatedNum::alloc( - cs, - || { - Ok(*new_value.get()?) - } - )?; + let allocated_num = AllocatedNum::alloc(cs, || Ok(*new_value.get()?))?; let mut term = MainGateTerm::::new(); let mul_term = ArithmeticTerm::::from_variable_and_coeff(x_var, mul_coeff).mul_by_variable(x_var); @@ -660,7 +565,7 @@ impl Term { let new = Self::from_allocated_num(allocated_num); return Ok(new); - }, + } (false, false) => { let mut mul_coeff = x.coeff; mul_coeff.square(); @@ -687,16 +592,11 @@ impl Term { new_value.add_assign(&z); Some(new_value) - }, - _ => {None} + } + _ => None, }; - let allocated_num = AllocatedNum::alloc( - cs, - || { - Ok(*new_value.get()?) - } - )?; + let allocated_num = AllocatedNum::alloc(cs, || Ok(*new_value.get()?))?; let mut term = MainGateTerm::::new(); let mul_term = ArithmeticTerm::::from_variable_and_coeff(x_var, mul_coeff).mul_by_variable(x_var); @@ -716,17 +616,12 @@ impl Term { let new = Self::from_allocated_num(allocated_num); return Ok(new); - }, + } } } // returns first if true and second if false - pub fn select>( - cs: &mut CS, - flag: &Boolean, - first: &Self, - second: &Self - ) -> Result { + pub fn select>(cs: &mut CS, flag: &Boolean, first: &Self, second: &Self) -> Result { match flag { Boolean::Constant(c) => { if *c { @@ -734,7 +629,7 @@ impl Term { } else { return Ok(second.clone()); } - }, + } _ => {} } @@ -751,16 +646,13 @@ impl Term { Ok(new) } - pub fn inverse>( - &self, - cs: &mut CS, - ) -> Result { + pub fn inverse>(&self, cs: &mut CS) -> Result { if self.is_constant() { let new_value = self.into_constant_value().inverse().expect("inverse must exist"); - + let new = Self::from_constant(new_value); - return Ok(new) + return Ok(new); } let new_value = self.get_value().map(|el| el.inverse().expect("inverse must exist")); @@ -778,23 +670,19 @@ impl Term { term.sub_assign(const_term); cs.allocate_main_gate(term)?; - + Ok(new) } - pub fn div>( - &self, - cs: &mut CS, - other: &Self - ) -> Result { + pub fn div>(&self, cs: &mut CS, other: &Self) -> Result { match (self.is_constant(), other.is_constant()) { (true, true) => { let mut new_value = other.into_constant_value().inverse().expect("inverse must exist"); new_value.mul_assign(&self.into_constant_value()); let new = Self::from_constant(new_value); - - return Ok(new) - }, + + return Ok(new); + } (false, false) => { let new_value = match (self.get_value(), other.get_value()) { (Some(this), Some(other)) => { @@ -803,7 +691,7 @@ impl Term { Some(new_value) } - _ => None + _ => None, }; // (a * X + b) / (c * Y + d) = Z @@ -815,16 +703,16 @@ impl Term { let yz_term = ArithmeticTerm::::from_variable_and_coeff(other.num.get_variable().get_variable(), other.coeff).mul_by_variable(z.num.get_variable().get_variable()); let z_term = ArithmeticTerm::::from_variable_and_coeff(z.num.get_variable().get_variable(), other.constant_term); let b_term = ArithmeticTerm::constant(self.constant_term); - + term.add_assign(x_term); term.add_assign(b_term); term.sub_assign(yz_term); term.sub_assign(z_term); - + cs.allocate_main_gate(term)?; - return Ok(z) - }, + return Ok(z); + } _ => { unimplemented!() } @@ -837,29 +725,15 @@ mod test { use super::*; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - TrivialAssembly, - PlonkCsWidth4WithNextStepParams, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; - use crate::bellman::pairing::bn256::{Fq, Bn256, Fr}; + use crate::bellman::pairing::bn256::{Bn256, Fq, Fr}; #[test] - fn test_add_on_random_witness(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_add_on_random_witness() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _ in 0..100 { @@ -874,19 +748,9 @@ mod test { let c0 = rng.gen(); let c1 = rng.gen(); - let a = AllocatedNum::alloc( - &mut cs, - || { - Ok(a0) - } - ).unwrap(); + let a = AllocatedNum::alloc(&mut cs, || Ok(a0)).unwrap(); - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(a1) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(a1)).unwrap(); let mut a_term = Term::::from_allocated_num(a); a_term.scale(&v0); @@ -912,12 +776,11 @@ mod test { assert!(cs.is_satisfied()); assert!(a_b_term.get_value().unwrap() == res); } - } #[test] - fn test_square_on_random_witness(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_square_on_random_witness() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _ in 0..100 { @@ -932,19 +795,9 @@ mod test { let c0 = rng.gen(); let c1 = rng.gen(); - let a = AllocatedNum::alloc( - &mut cs, - || { - Ok(a0) - } - ).unwrap(); + let a = AllocatedNum::alloc(&mut cs, || Ok(a0)).unwrap(); - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(a1) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(a1)).unwrap(); let mut a_term = Term::::from_allocated_num(a); a_term.scale(&v0); @@ -974,13 +827,11 @@ mod test { assert!(cs.is_satisfied()); assert!(a_b_term.get_value().unwrap() == res); } - } - #[test] - fn test_fma_on_random_witness(){ - use rand::{XorShiftRng, SeedableRng, Rng}; + fn test_fma_on_random_witness() { + use rand::{Rng, SeedableRng, XorShiftRng}; let rng = &mut XorShiftRng::from_seed([0x3dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _ in 0..100 { @@ -998,26 +849,11 @@ mod test { let c1 = rng.gen(); let c2 = rng.gen(); - let a = AllocatedNum::alloc( - &mut cs, - || { - Ok(a0) - } - ).unwrap(); + let a = AllocatedNum::alloc(&mut cs, || Ok(a0)).unwrap(); - let b = AllocatedNum::alloc( - &mut cs, - || { - Ok(a1) - } - ).unwrap(); + let b = AllocatedNum::alloc(&mut cs, || Ok(a1)).unwrap(); - let c = AllocatedNum::alloc( - &mut cs, - || { - Ok(a2) - } - ).unwrap(); + let c = AllocatedNum::alloc(&mut cs, || Ok(a2)).unwrap(); let mut a_term = Term::::from_allocated_num(a); a_term.scale(&v0); @@ -1052,6 +888,5 @@ mod test { assert!(cs.is_satisfied()); assert!(a_b_term.get_value().unwrap() == res); } - } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/tables.rs b/crates/franklin-crypto/src/plonk/circuit/tables.rs index 014816e..cfe860f 100644 --- a/crates/franklin-crypto/src/plonk/circuit/tables.rs +++ b/crates/franklin-crypto/src/plonk/circuit/tables.rs @@ -1,57 +1,30 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, - Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, - PlonkConstraintSystemParams, - PlonkCsWidth4WithNextStepParams, - TrivialAssembly + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PlonkConstraintSystemParams, PlonkCsWidth4WithNextStepParams, + PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, TrivialAssembly, Variable, Width4MainGateWithDNext, }; use crate::bellman::plonk::better_better_cs::data_structures::PolyIdentifier; use crate::bellman::plonk::better_better_cs::lookup_tables::*; -use crate::plonk::circuit::Assignment; -use super::*; use super::bigint_new::*; +use super::*; +use crate::plonk::circuit::Assignment; use crate::plonk::circuit::allocated_num::{AllocatedNum, Num}; -use crate::plonk::circuit::simple_term::{Term}; use crate::plonk::circuit::linear_combination::LinearCombination; +use crate::plonk::circuit::simple_term::Term; pub use crate::bellman::plonk::better_better_cs::lookup_tables::RANGE_CHECK_SINGLE_APPLICATION_TABLE_NAME; const DEFAULT_RANGE_TABLE_NAME_PREFIX: &'static str = "Range check table over 3 columns for"; - -pub fn inscribe_default_range_table_for_bit_width_over_first_three_columns>( - cs: &mut CS, - width: usize -) -> Result<(), SynthesisError> { +pub fn inscribe_default_range_table_for_bit_width_over_first_three_columns>(cs: &mut CS, width: usize) -> Result<(), SynthesisError> { // inscribe_range_table_for_bit_width_over_first_three_columns(cs, width).map(|_| ()) let over = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; let table = LookupTableApplication::new_range_table_of_width_3(width, over)?; @@ -60,32 +33,23 @@ pub fn inscribe_default_range_table_for_bit_width_over_first_three_columns(cs: &mut CS, width: usize) -> Result<(), SynthesisError> -where E: Engine, CS: ConstraintSystem +pub fn inscribe_combined_bitwise_ops_and_range_table(cs: &mut CS, width: usize) -> Result<(), SynthesisError> +where + E: Engine, + CS: ConstraintSystem, { - let over = vec![ - PolyIdentifier::VariablesPolynomial(0), - PolyIdentifier::VariablesPolynomial(1), - PolyIdentifier::VariablesPolynomial(2) - ]; + let over = vec![PolyIdentifier::VariablesPolynomial(0), PolyIdentifier::VariablesPolynomial(1), PolyIdentifier::VariablesPolynomial(2)]; use crate::plonk::circuit::bigint_new::*; let name = BITWISE_LOGICAL_OPS_TABLE_NAME; - let table = LookupTableApplication::new( - name, CombinedBitwiseLogicRangeTable::new(&name, width), over.clone(), None, true - ); + let table = LookupTableApplication::new(name, CombinedBitwiseLogicRangeTable::new(&name, width), over.clone(), None, true); cs.add_table(table)?; Ok(()) } -pub fn inscribe_range_table_for_bit_width_over_first_three_columns>( - cs: &mut CS, - width: usize -) -> Result { +pub fn inscribe_range_table_for_bit_width_over_first_three_columns>(cs: &mut CS, width: usize) -> Result { assert!(width > 0); - let generator = move || { - format!("{} {} bits over A/B/C", DEFAULT_RANGE_TABLE_NAME_PREFIX, width) - }; + let generator = move || format!("{} {} bits over A/B/C", DEFAULT_RANGE_TABLE_NAME_PREFIX, width); let name = (&generator)(); if let Ok(..) = cs.get_table(&name) { return Ok(name); @@ -95,23 +59,14 @@ pub fn inscribe_range_table_for_bit_width_over_first_three_columns String + Send + Sync>; - let application = LookupTableApplication::new( - "Range check table", - table_internal, - over, - Some(name_generator), - true - ); + let application = LookupTableApplication::new("Range check table", table_internal, over, Some(name_generator), true); cs.add_table(application)?; Ok(name) } -pub fn get_name_for_range_table_for_bit_width_over_first_three_columns( - width: usize -) -> String { +pub fn get_name_for_range_table_for_bit_width_over_first_three_columns(width: usize) -> String { assert!(width > 0); format!("{} {} bits over A/B/C", DEFAULT_RANGE_TABLE_NAME_PREFIX, width) } - diff --git a/crates/franklin-crypto/src/plonk/circuit/uint32.rs b/crates/franklin-crypto/src/plonk/circuit/uint32.rs index 575a2c9..bb88195 100644 --- a/crates/franklin-crypto/src/plonk/circuit/uint32.rs +++ b/crates/franklin-crypto/src/plonk/circuit/uint32.rs @@ -1,49 +1,21 @@ -use crate::bellman::pairing::{ - Engine, -}; +use crate::bellman::pairing::Engine; -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; -use crate::bellman::{ - SynthesisError, -}; +use crate::bellman::SynthesisError; use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - ArithmeticTerm, - MainGateTerm, + ArithmeticTerm, Coefficient, ConstraintSystem, Gate, GateInternal, LinearCombinationOfTerms, MainGate, MainGateTerm, PolynomialInConstraint, PolynomialMultiplicativeTerm, TimeDilation, Variable, Width4MainGateWithDNext, - MainGate, - GateInternal, - Gate, - LinearCombinationOfTerms, - PolynomialMultiplicativeTerm, - PolynomialInConstraint, - TimeDilation, - Coefficient, }; - use crate::plonk::circuit::Assignment; -use super::allocated_num::{ - AllocatedNum -}; +use super::allocated_num::AllocatedNum; -use super::linear_combination::{ - LinearCombination -}; +use super::linear_combination::LinearCombination; -use super::boolean::{ - AllocatedBit, - Boolean -}; +use super::boolean::{AllocatedBit, Boolean}; use super::multieq::MultiEq; @@ -53,13 +25,12 @@ use super::multieq::MultiEq; pub struct UInt32 { // Least significant bit first bits: Vec, - value: Option + value: Option, } impl UInt32 { /// Construct a constant `UInt32` from a `u32` - pub fn constant(value: u32) -> Self - { + pub fn constant(value: u32) -> Self { let mut bits = Vec::with_capacity(32); let mut tmp = value; @@ -73,18 +44,11 @@ impl UInt32 { tmp >>= 1; } - UInt32 { - bits: bits, - value: Some(value) - } + UInt32 { bits: bits, value: Some(value) } } /// Allocate a `UInt32` in the constraint system - pub fn alloc>( - cs: &mut CS, - value: Option - ) -> Result - { + pub fn alloc>(cs: &mut CS, value: Option) -> Result { let values = match value { Some(mut val) => { let mut v = Vec::with_capacity(32); @@ -95,24 +59,17 @@ impl UInt32 { } v - }, - None => vec![None; 32] + } + None => vec![None; 32], }; - let bits = values.into_iter() - .enumerate() - .map(|(_i, v)| { - Ok(Boolean::from(AllocatedBit::alloc( - cs, - v - )?)) - }) - .collect::, SynthesisError>>()?; + let bits = values + .into_iter() + .enumerate() + .map(|(_i, v)| Ok(Boolean::from(AllocatedBit::alloc(cs, v)?))) + .collect::, SynthesisError>>()?; - Ok(UInt32 { - bits: bits, - value: value - }) + Ok(UInt32 { bits: bits, value: value }) } pub fn into_bits_be(&self) -> Vec { @@ -127,19 +84,22 @@ impl UInt32 { value.as_mut().map(|v| *v <<= 1); match b.get_value() { - Some(true) => { value.as_mut().map(|v| *v |= 1); }, - Some(false) => {}, - None => { value = None; } + Some(true) => { + value.as_mut().map(|v| *v |= 1); + } + Some(false) => {} + None => { + value = None; + } } } UInt32 { value: value, - bits: bits.iter().rev().cloned().collect() + bits: bits.iter().rev().cloned().collect(), } } - /// Turns this `UInt32` into its little-endian byte order representation. pub fn into_bits(&self) -> Vec { self.bits.clone() @@ -147,8 +107,7 @@ impl UInt32 { /// Converts a little-endian byte order representation of bits into a /// `UInt32`. - pub fn from_bits(bits: &[Boolean]) -> Self - { + pub fn from_bits(bits: &[Boolean]) -> Self { assert_eq!(bits.len(), 32); let new_bits = bits.to_vec(); @@ -162,43 +121,35 @@ impl UInt32 { if b { value.as_mut().map(|v| *v |= 1); } - }, - &Boolean::Is(ref b) => { - match b.get_value() { - Some(true) => { value.as_mut().map(|v| *v |= 1); }, - Some(false) => {}, - None => { value = None } + } + &Boolean::Is(ref b) => match b.get_value() { + Some(true) => { + value.as_mut().map(|v| *v |= 1); } + Some(false) => {} + None => value = None, }, - &Boolean::Not(ref b) => { - match b.get_value() { - Some(false) => { value.as_mut().map(|v| *v |= 1); }, - Some(true) => {}, - None => { value = None } + &Boolean::Not(ref b) => match b.get_value() { + Some(false) => { + value.as_mut().map(|v| *v |= 1); } - } + Some(true) => {} + None => value = None, + }, } } - UInt32 { - value: value, - bits: new_bits - } + UInt32 { value: value, bits: new_bits } } pub fn rotr(&self, by: usize) -> Self { let by = by % 32; - let new_bits = self.bits.iter() - .skip(by) - .chain(self.bits.iter()) - .take(32) - .cloned() - .collect(); + let new_bits = self.bits.iter().skip(by).chain(self.bits.iter()).take(32).cloned().collect(); UInt32 { bits: new_bits, - value: self.value.map(|v| v.rotate_right(by as u32)) + value: self.value.map(|v| v.rotate_right(by as u32)), } } @@ -207,138 +158,88 @@ impl UInt32 { let fill = Boolean::constant(false); - let new_bits = self.bits - .iter() // The bits are least significant first - .skip(by) // Skip the bits that will be lost during the shift - .chain(Some(&fill).into_iter().cycle()) // Rest will be zeros - .take(32) // Only 32 bits needed! - .cloned() - .collect(); + let new_bits = self + .bits + .iter() // The bits are least significant first + .skip(by) // Skip the bits that will be lost during the shift + .chain(Some(&fill).into_iter().cycle()) // Rest will be zeros + .take(32) // Only 32 bits needed! + .cloned() + .collect(); UInt32 { bits: new_bits, - value: self.value.map(|v| v >> by as u32) + value: self.value.map(|v| v >> by as u32), } } - fn triop( - cs: &mut CS, - a: &Self, - b: &Self, - c: &Self, - tri_fn: F, - circuit_fn: U - ) -> Result - where E: Engine, - CS: ConstraintSystem, - F: Fn(u32, u32, u32) -> u32, - U: Fn(&mut CS, usize, &Boolean, &Boolean, &Boolean) -> Result + fn triop(cs: &mut CS, a: &Self, b: &Self, c: &Self, tri_fn: F, circuit_fn: U) -> Result + where + E: Engine, + CS: ConstraintSystem, + F: Fn(u32, u32, u32) -> u32, + U: Fn(&mut CS, usize, &Boolean, &Boolean, &Boolean) -> Result, { let new_value = match (a.value, b.value, c.value) { - (Some(a), Some(b), Some(c)) => { - Some(tri_fn(a, b, c)) - }, - _ => None + (Some(a), Some(b), Some(c)) => Some(tri_fn(a, b, c)), + _ => None, }; - let bits = a.bits.iter() - .zip(b.bits.iter()) - .zip(c.bits.iter()) - .enumerate() - .map(|(i, ((a, b), c))| circuit_fn(cs, i, a, b, c)) - .collect::>()?; + let bits = a + .bits + .iter() + .zip(b.bits.iter()) + .zip(c.bits.iter()) + .enumerate() + .map(|(i, ((a, b), c))| circuit_fn(cs, i, a, b, c)) + .collect::>()?; - Ok(UInt32 { - bits: bits, - value: new_value - }) + Ok(UInt32 { bits: bits, value: new_value }) } /// Compute the `maj` value (a and b) xor (a and c) xor (b and c) /// during SHA256. - pub fn sha256_maj( - cs: &mut CS, - a: &Self, - b: &Self, - c: &Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn sha256_maj(cs: &mut CS, a: &Self, b: &Self, c: &Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { - Self::triop(cs, a, b, c, |a, b, c| (a & b) ^ (a & c) ^ (b & c), - |cs, _i, a, b, c| { - Boolean::sha256_maj( - cs, - a, - b, - c - ) - } - ) + Self::triop(cs, a, b, c, |a, b, c| (a & b) ^ (a & c) ^ (b & c), |cs, _i, a, b, c| Boolean::sha256_maj(cs, a, b, c)) } /// Compute the `ch` value `(a and b) xor ((not a) and c)` /// during SHA256. - pub fn sha256_ch( - cs: &mut CS, - a: &Self, - b: &Self, - c: &Self - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn sha256_ch(cs: &mut CS, a: &Self, b: &Self, c: &Self) -> Result + where + E: Engine, + CS: ConstraintSystem, { - Self::triop(cs, a, b, c, |a, b, c| (a & b) ^ ((!a) & c), - |cs, _i, a, b, c| { - Boolean::sha256_ch( - cs, - a, - b, - c - ) - } - ) + Self::triop(cs, a, b, c, |a, b, c| (a & b) ^ ((!a) & c), |cs, _i, a, b, c| Boolean::sha256_ch(cs, a, b, c)) } /// XOR this `UInt32` with another `UInt32` - pub fn xor>( - &self, - cs: &mut CS, - other: &Self - ) -> Result - { + pub fn xor>(&self, cs: &mut CS, other: &Self) -> Result { let new_value = match (self.value, other.value) { - (Some(a), Some(b)) => { - Some(a ^ b) - }, - _ => None + (Some(a), Some(b)) => Some(a ^ b), + _ => None, }; - let bits = self.bits.iter() - .zip(other.bits.iter()) - .enumerate() - .map(|(_i, (a, b))| { - Boolean::xor( - cs, - a, - b - ) - }) - .collect::>()?; + let bits = self + .bits + .iter() + .zip(other.bits.iter()) + .enumerate() + .map(|(_i, (a, b))| Boolean::xor(cs, a, b)) + .collect::>()?; - Ok(UInt32 { - bits: bits, - value: new_value - }) + Ok(UInt32 { bits: bits, value: new_value }) } /// Perform modular addition of several `UInt32` objects. - pub fn addmany( - cs: &mut CS, - operands: &[Self] - ) -> Result - where E: Engine, - CS: ConstraintSystem + pub fn addmany(cs: &mut CS, operands: &[Self]) -> Result + where + E: Engine, + CS: ConstraintSystem, { // Make some arbitrary bounds for ourselves to avoid overflows // in the scalar field @@ -367,7 +268,7 @@ impl UInt32 { match op.value { Some(val) => { result_value.as_mut().map(|v| *v += val as u64); - }, + } None => { // If any of our operands have unknown value, we won't // know the value of the result @@ -409,12 +310,9 @@ impl UInt32 { let mut i = 0; while max_value != 0 { // Allocate the bit - let b = AllocatedBit::alloc( - multieq_gadget.as_cs(), - result_value.map(|v| (v >> i) & 1 == 1) - )?; + let b = AllocatedBit::alloc(multieq_gadget.as_cs(), result_value.map(|v| (v >> i) & 1 == 1))?; - // Add this bit to the result combination + // Add this bit to the result combination result_lc.add_assign_bit_with_coeff(&b, coeff); result_bits.push(b.into()); @@ -434,7 +332,7 @@ impl UInt32 { Ok(UInt32 { bits: result_bits, - value: modular_value + value: modular_value, }) } } @@ -442,7 +340,7 @@ impl UInt32 { #[cfg(test)] mod test { use super::*; - use rand::{XorShiftRng, SeedableRng, Rng}; + use rand::{Rng, SeedableRng, XorShiftRng}; use bellman::pairing::bn256::{Bn256, Fr}; use bellman::pairing::ff::{Field, PrimeField}; @@ -471,19 +369,18 @@ mod test { match bit { &Boolean::Constant(bit) => { assert!(bit == ((b.value.unwrap() >> i) & 1 == 1)); - }, - _ => unreachable!() + } + _ => unreachable!(), } } let expected_to_be_same = b.into_bits_be(); - for x in v.iter().zip(expected_to_be_same.iter()) - { + for x in v.iter().zip(expected_to_be_same.iter()) { match x { - (&Boolean::Constant(true), &Boolean::Constant(true)) => {}, - (&Boolean::Constant(false), &Boolean::Constant(false)) => {}, - _ => unreachable!() + (&Boolean::Constant(true), &Boolean::Constant(true)) => {} + (&Boolean::Constant(false), &Boolean::Constant(false)) => {} + _ => unreachable!(), } } } @@ -502,19 +399,18 @@ mod test { match bit { &Boolean::Constant(bit) => { assert!(bit == ((b.value.unwrap() >> i) & 1 == 1)); - }, - _ => unreachable!() + } + _ => unreachable!(), } } let expected_to_be_same = b.into_bits(); - for x in v.iter().zip(expected_to_be_same.iter()) - { + for x in v.iter().zip(expected_to_be_same.iter()) { match x { - (&Boolean::Constant(true), &Boolean::Constant(true)) => {}, - (&Boolean::Constant(false), &Boolean::Constant(false)) => {}, - _ => unreachable!() + (&Boolean::Constant(true), &Boolean::Constant(true)) => {} + (&Boolean::Constant(false), &Boolean::Constant(false)) => {} + _ => unreachable!(), } } } @@ -548,10 +444,10 @@ mod test { match b { &Boolean::Is(ref b) => { assert!(b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Not(ref b) => { assert!(!b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Constant(b) => { assert!(b == (expected & 1 == 1)); } @@ -635,10 +531,10 @@ mod test { match b { &Boolean::Is(ref b) => { assert!(b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Not(ref b) => { assert!(!b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Constant(_) => { unreachable!() } @@ -668,8 +564,8 @@ mod test { match b { &Boolean::Constant(b) => { assert_eq!(b, tmp & 1 == 1); - }, - _ => unreachable!() + } + _ => unreachable!(), } tmp >>= 1; @@ -726,10 +622,10 @@ mod test { match b { &Boolean::Is(ref b) => { assert!(b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Not(ref b) => { assert!(!b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Constant(b) => { assert!(b == (expected & 1 == 1)); } @@ -767,10 +663,10 @@ mod test { match b { &Boolean::Is(ref b) => { assert!(b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Not(ref b) => { assert!(!b.get_value().unwrap() == (expected & 1 == 1)); - }, + } &Boolean::Constant(b) => { assert!(b == (expected & 1 == 1)); } diff --git a/crates/franklin-crypto/src/plonk/circuit/utils.rs b/crates/franklin-crypto/src/plonk/circuit/utils.rs index 4cc3415..ce97fce 100644 --- a/crates/franklin-crypto/src/plonk/circuit/utils.rs +++ b/crates/franklin-crypto/src/plonk/circuit/utils.rs @@ -25,11 +25,7 @@ pub fn u128_to_fe(value: u128) -> F { } pub fn u64_to_le_bits(value: u64, limit: Option) -> Vec { - let limit = if let Some(limit) = limit { - limit - } else { - 64 - }; + let limit = if let Some(limit) = limit { limit } else { 64 }; let mut bits: Vec = BitIterator::new(&[value]).collect(); bits.reverse(); @@ -39,11 +35,7 @@ pub fn u64_to_le_bits(value: u64, limit: Option) -> Vec { } pub fn fe_to_le_bits(value: F, limit: Option) -> Vec { - let limit = if let Some(limit) = limit { - limit - } else { - F::NUM_BITS as usize - }; + let limit = if let Some(limit) = limit { limit } else { F::NUM_BITS as usize }; let mut bits: Vec = BitIterator::new(&value.into_repr()).collect(); bits.reverse(); @@ -55,10 +47,18 @@ pub fn fe_to_le_bits(value: F, limit: Option) -> Vec struct ZeroPaddingBuffer<'a>(&'a [u8]); impl<'a> std::io::Read for ZeroPaddingBuffer<'a> { - fn read(&mut self, _buf: &mut [u8]) -> std::io::Result { unimplemented!() } - fn read_vectored(&mut self, _bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result { unimplemented!( )} - fn read_to_end(&mut self, _buf: &mut Vec) -> std::io::Result { unimplemented!() } - fn read_to_string(&mut self, _buf: &mut String) -> std::io::Result { unimplemented!() } + fn read(&mut self, _buf: &mut [u8]) -> std::io::Result { + unimplemented!() + } + fn read_vectored(&mut self, _bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result { + unimplemented!() + } + fn read_to_end(&mut self, _buf: &mut Vec) -> std::io::Result { + unimplemented!() + } + fn read_to_string(&mut self, _buf: &mut String) -> std::io::Result { + unimplemented!() + } fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> { let bytes_available = self.0.len(); let len = buf.len(); @@ -76,20 +76,48 @@ impl<'a> std::io::Read for ZeroPaddingBuffer<'a> { } Ok(()) } - fn by_ref(&mut self) -> &mut Self where Self: Sized, { self } - fn bytes(self) -> std::io::Bytes where Self: Sized { unimplemented!() } - fn chain(self, _next: R) -> std::io::Chain where Self: Sized { unimplemented!() } - fn take(self, _limit: u64) -> std::io::Take where Self: Sized { unimplemented!() } + fn by_ref(&mut self) -> &mut Self + where + Self: Sized, + { + self + } + fn bytes(self) -> std::io::Bytes + where + Self: Sized, + { + unimplemented!() + } + fn chain(self, _next: R) -> std::io::Chain + where + Self: Sized, + { + unimplemented!() + } + fn take(self, _limit: u64) -> std::io::Take + where + Self: Sized, + { + unimplemented!() + } } #[derive(Clone, Copy)] struct ZeroPrePaddingBuffer<'a>(&'a [u8], usize); impl<'a> std::io::Read for ZeroPrePaddingBuffer<'a> { - fn read(&mut self, _buf: &mut [u8]) -> std::io::Result { unimplemented!() } - fn read_vectored(&mut self, _bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result { unimplemented!( )} - fn read_to_end(&mut self, _buf: &mut Vec) -> std::io::Result { unimplemented!() } - fn read_to_string(&mut self, _buf: &mut String) -> std::io::Result { unimplemented!() } + fn read(&mut self, _buf: &mut [u8]) -> std::io::Result { + unimplemented!() + } + fn read_vectored(&mut self, _bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result { + unimplemented!() + } + fn read_to_end(&mut self, _buf: &mut Vec) -> std::io::Result { + unimplemented!() + } + fn read_to_string(&mut self, _buf: &mut String) -> std::io::Result { + unimplemented!() + } fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> { let bytes_available = self.0.len(); let padding_available = self.1; @@ -119,17 +147,37 @@ impl<'a> std::io::Read for ZeroPrePaddingBuffer<'a> { self.0 = &[]; } } - + Ok(()) } - fn by_ref(&mut self) -> &mut Self where Self: Sized, { self } - fn bytes(self) -> std::io::Bytes where Self: Sized { unimplemented!() } - fn chain(self, _next: R) -> std::io::Chain where Self: Sized { unimplemented!() } - fn take(self, _limit: u64) -> std::io::Take where Self: Sized { unimplemented!() } + fn by_ref(&mut self) -> &mut Self + where + Self: Sized, + { + self + } + fn bytes(self) -> std::io::Bytes + where + Self: Sized, + { + unimplemented!() + } + fn chain(self, _next: R) -> std::io::Chain + where + Self: Sized, + { + unimplemented!() + } + fn take(self, _limit: u64) -> std::io::Take + where + Self: Sized, + { + unimplemented!() + } } #[track_caller] -pub fn pack_be_bytes_to_fe(bytes: &[u8]) -> Result{ +pub fn pack_be_bytes_to_fe(bytes: &[u8]) -> Result { let mut repr = F::zero().into_repr(); let expected_len = repr.as_ref().len() * 8; assert!(bytes.len() <= expected_len); @@ -218,4 +266,4 @@ pub fn is_selector_specialized_gate>() -> boo use std::any::Any; Any::type_id(&CS::MainGate::default()) == Any::type_id(&SelectorOptimizedWidth4MainGateWithDNext) -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/aux_data.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/aux_data.rs index 13faa95..b2ad9dd 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/aux_data.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/aux_data.rs @@ -1,18 +1,10 @@ -use crate::bellman::pairing::{ - Engine, - CurveAffine, - CurveProjective, -}; +use crate::bellman::pairing::{CurveAffine, CurveProjective, Engine}; -use crate::bellman::pairing::ff::{ - PrimeField, -}; +use crate::bellman::pairing::ff::PrimeField; -use crate::bellman::pairing::bn256::{Bn256}; +use crate::bellman::pairing::bn256::Bn256; - -pub trait AuxData: Clone + std::fmt::Debug -{ +pub trait AuxData: Clone + std::fmt::Debug { fn new() -> Self; fn get_b(&self) -> ::Base; fn get_group_order(&self) -> &[u64]; @@ -29,18 +21,14 @@ pub struct BN256AuxData { } impl AuxData for BN256AuxData { - fn new() -> Self { // curve equation: y^2 = x^3 + 3, a = 0, b = 3 // r = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 - + let b = ::Fq::from_str("3").expect("should convert"); - let r : [u64; 4] = [0x43e1f593f0000001, 0x2833e84879b97091, 0xb85045b68181585d, 0x30644e72e131a029]; + let r: [u64; 4] = [0x43e1f593f0000001, 0x2833e84879b97091, 0xb85045b68181585d, 0x30644e72e131a029]; - BN256AuxData { - b: b, - group_order: r, - } + BN256AuxData { b: b, group_order: r } } fn get_b(&self) -> ::Fq { @@ -60,4 +48,4 @@ impl AuxData for BN256AuxData { } } -// TODO: implement AuxData for BLS12-381 \ No newline at end of file +// TODO: implement AuxData for BLS12-381 diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/mod.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/mod.rs index 1a21aa8..6fe6299 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/mod.rs @@ -1,37 +1,22 @@ pub mod aux_data; -use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, - CurveProjective, -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - BitIterator, -}; - -use crate::bellman::{ - SynthesisError, -}; - -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - PlonkConstraintSystemParams, -}; +use crate::bellman::pairing::{CurveProjective, Engine, GenericCurveAffine}; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField}; + +use crate::bellman::SynthesisError; + +use crate::bellman::plonk::better_better_cs::cs::{ConstraintSystem, PlonkConstraintSystemParams, Variable}; -use crate::plonk::circuit::curve::sw_affine::*; -use crate::plonk::circuit::bigint::field::*; use crate::plonk::circuit::allocated_num::*; +use crate::plonk::circuit::bigint::field::*; use crate::plonk::circuit::boolean::*; +use crate::plonk::circuit::curve::sw_affine::*; pub trait WrappedAffinePoint<'a, E: Engine>: Sized + Clone + std::fmt::Debug { - fn get_point(&self) -> &AffinePoint; fn get_zero_flag(&self) -> Boolean; - + fn alloc, AD: aux_data::AuxData>( cs: &mut CS, value: Option, @@ -39,11 +24,7 @@ pub trait WrappedAffinePoint<'a, E: Engine>: Sized + Clone + std::fmt::Debug { aux_data: &AD, ) -> Result; - fn alloc_unchecked>( - cs: &mut CS, - value: Option, - params: &'a RnsParameters::Base>, - ) -> Result; + fn alloc_unchecked>(cs: &mut CS, value: Option, params: &'a RnsParameters::Base>) -> Result; fn from_allocated_limb_witness<'b, CS: ConstraintSystem, AD: aux_data::AuxData>( _cs: &mut CS, @@ -55,70 +36,39 @@ pub trait WrappedAffinePoint<'a, E: Engine>: Sized + Clone + std::fmt::Debug { } fn zero(params: &'a RnsParameters::Base>) -> Self; - - fn constant( - value: E::G1Affine, - params: &'a RnsParameters::Base> - ) -> Self; - fn equals>( - &self, - cs: &mut CS, - other: &Self, - _params: &'a RnsParameters::Base>, - ) -> Result; + fn constant(value: E::G1Affine, params: &'a RnsParameters::Base>) -> Self; - fn add>( - &mut self, - cs: &mut CS, - other: &mut Self, - params: &'a RnsParameters::Base>, - ) -> Result; + fn equals>(&self, cs: &mut CS, other: &Self, _params: &'a RnsParameters::Base>) -> Result; - fn sub>( - &mut self, - cs: &mut CS, - other: &mut Self, - params: &'a RnsParameters::Base>, - ) -> Result; + fn add>(&mut self, cs: &mut CS, other: &mut Self, params: &'a RnsParameters::Base>) -> Result; - fn double>( - &mut self, - cs: &mut CS, - _params: &'a RnsParameters::Base>, - ) -> Result; + fn sub>(&mut self, cs: &mut CS, other: &mut Self, params: &'a RnsParameters::Base>) -> Result; - fn negate>( - &mut self, - cs: &mut CS, - _params: &'a RnsParameters::Base>, - ) -> Result; + fn double>(&mut self, cs: &mut CS, _params: &'a RnsParameters::Base>) -> Result; + + fn negate>(&mut self, cs: &mut CS, _params: &'a RnsParameters::Base>) -> Result; + + fn select>(cs: &mut CS, flag: &Boolean, first: Self, second: Self) -> Result; - fn select>( - cs: &mut CS, - flag: &Boolean, - first: Self, - second: Self - ) -> Result; - fn is_on_curve, AD: aux_data::AuxData>( &self, cs: &mut CS, params: &RnsParameters::Base>, aux_data: &AD, - ) -> Result; + ) -> Result; fn subgroup_check, AD: aux_data::AuxData>( &self, cs: &mut CS, params: &RnsParameters::Base>, aux_data: &AD, - ) -> Result; + ) -> Result; fn mul, AD: aux_data::AuxData>( &mut self, cs: &mut CS, - scalar: &AllocatedNum::, + scalar: &AllocatedNum, bit_limit: Option, params: &'a RnsParameters::Base>, aux_data: &AD, @@ -126,7 +76,7 @@ pub trait WrappedAffinePoint<'a, E: Engine>: Sized + Clone + std::fmt::Debug { fn multiexp, AD: aux_data::AuxData>( cs: &mut CS, - scalars: &[AllocatedNum::], + scalars: &[AllocatedNum], points: &[Self], bit_limit: Option, params: &'a RnsParameters::Base>, @@ -134,7 +84,6 @@ pub trait WrappedAffinePoint<'a, E: Engine>: Sized + Clone + std::fmt::Debug { ) -> Result; } - // pub mod with_zero_flag; +pub mod without_flag_checked; pub mod without_flag_unchecked; -pub mod without_flag_checked; \ No newline at end of file diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/without_flag_checked.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/without_flag_checked.rs index f3c6876..9d794c8 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/without_flag_checked.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/without_flag_checked.rs @@ -6,7 +6,6 @@ pub struct WrapperChecked<'a, E: Engine> { } impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperChecked<'a, E> { - fn get_point(&self) -> &AffinePoint { &self.point } @@ -14,165 +13,112 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperChecked<'a, E> { fn get_zero_flag(&self) -> Boolean { Boolean::constant(false) } - + fn alloc, AD: aux_data::AuxData>( cs: &mut CS, value: Option, params: &'a RnsParameters::Base>, aux_data: &AD, - ) -> Result - { + ) -> Result { let point = AffinePoint::alloc(cs, value, params)?; - let res = WrapperChecked { - point, - }; + let res = WrapperChecked { point }; let is_on_curve = res.is_on_curve(cs, params, aux_data)?; let subgroup_check = if aux_data.requires_subgroup_check() { res.subgroup_check(cs, params, aux_data)? - } - else { + } else { Boolean::constant(true) }; - + let is_valid_point = Boolean::and(cs, &is_on_curve, &subgroup_check)?; Boolean::enforce_equal(cs, &is_valid_point, &Boolean::constant(true))?; Ok(res) } - fn alloc_unchecked>( - cs: &mut CS, - value: Option, - params: &'a RnsParameters::Base>, - ) -> Result - { - let res = WrapperChecked { - point: AffinePoint::alloc(cs, value, params)? + fn alloc_unchecked>(cs: &mut CS, value: Option, params: &'a RnsParameters::Base>) -> Result { + let res = WrapperChecked { + point: AffinePoint::alloc(cs, value, params)?, }; Ok(res) } - fn zero(_params: &'a RnsParameters::Base>) -> Self - { + fn zero(_params: &'a RnsParameters::Base>) -> Self { unimplemented!(); } - - fn constant( - value: E::G1Affine, - params: &'a RnsParameters::Base> - ) -> Self - { - let res = WrapperChecked { + + fn constant(value: E::G1Affine, params: &'a RnsParameters::Base>) -> Self { + let res = WrapperChecked { point: AffinePoint::constant(value, params), }; res } - fn equals>( - &self, - cs: &mut CS, - other: &Self, - _params: &'a RnsParameters::Base>, - ) -> Result - { + fn equals>(&self, cs: &mut CS, other: &Self, _params: &'a RnsParameters::Base>) -> Result { let (eq, _) = AffinePoint::equals(cs, self.point.clone(), other.point.clone())?; Ok(eq) } - fn add>( - &mut self, - cs: &mut CS, - other: &mut Self, - _params: &'a RnsParameters::Base>, - ) -> Result - { + fn add>(&mut self, cs: &mut CS, other: &mut Self, _params: &'a RnsParameters::Base>) -> Result { let (check, _) = FieldElement::equals(cs, self.point.x.clone(), other.point.x.clone())?; Boolean::enforce_equal(cs, &check, &Boolean::constant(false))?; - - let res = WrapperChecked { + + let res = WrapperChecked { point: self.point.clone().add_unequal(cs, other.point.clone())?.0, }; Ok(res) - } + } - fn sub>( - &mut self, - cs: &mut CS, - other: &mut Self, - _params: &'a RnsParameters::Base>, - ) -> Result - { + fn sub>(&mut self, cs: &mut CS, other: &mut Self, _params: &'a RnsParameters::Base>) -> Result { let (check, _) = FieldElement::equals(cs, self.point.x.clone(), other.point.x.clone())?; Boolean::enforce_equal(cs, &check, &Boolean::constant(false))?; - - let res = WrapperChecked { + + let res = WrapperChecked { point: self.point.clone().sub_unequal(cs, other.point.clone())?.0, }; Ok(res) } - fn double>( - &mut self, - cs: &mut CS, - _params: &'a RnsParameters::Base>, - ) -> Result - { - let res = WrapperChecked { + fn double>(&mut self, cs: &mut CS, _params: &'a RnsParameters::Base>) -> Result { + let res = WrapperChecked { point: self.point.clone().double(cs)?.0, }; Ok(res) } - fn negate>( - &mut self, - cs: &mut CS, - _params: &'a RnsParameters::Base>, - ) -> Result - { + fn negate>(&mut self, cs: &mut CS, _params: &'a RnsParameters::Base>) -> Result { let (negated, _) = self.point.clone().negate(cs)?; - let res = WrapperChecked { - point: negated, - }; + let res = WrapperChecked { point: negated }; Ok(res) } - fn select>( - cs: &mut CS, - flag: &Boolean, - first: Self, - second: Self - ) -> Result - { + fn select>(cs: &mut CS, flag: &Boolean, first: Self, second: Self) -> Result { let (selected, _) = AffinePoint::select(cs, flag, first.point, second.point)?; - let res = WrapperChecked { - point: selected - }; + let res = WrapperChecked { point: selected }; Ok(res) } - + fn is_on_curve, AD: aux_data::AuxData>( &self, cs: &mut CS, params: &RnsParameters::Base>, aux_data: &AD, - ) -> Result - { + ) -> Result { let lhs = self.point.y.clone().square(cs)?.0; - + let (mut rhs, reduced_x) = self.point.x.clone().square(cs)?; - + rhs = rhs.mul(cs, reduced_x)?.0; - + let b = FieldElement::new_constant(aux_data.get_b(), params); rhs = rhs.add(cs, b)?.0; let (check, _) = FieldElement::equals(cs, lhs, rhs)?; - + Ok(check) } @@ -181,8 +127,7 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperChecked<'a, E> { _cs: &mut CS, _params: &RnsParameters::Base>, _aux_data: &AD, - ) -> Result - { + ) -> Result { // we check that (n-1)x = -x //let mut exp = aux_data.get_group_order().clone(); //exp[0] -= 1; @@ -198,14 +143,13 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperChecked<'a, E> { fn mul, AD: aux_data::AuxData>( &mut self, cs: &mut CS, - scalar: &AllocatedNum::, + scalar: &AllocatedNum, bit_limit: Option, _params: &'a RnsParameters::Base>, _aux_data: &AD, - ) -> Result - { + ) -> Result { let d = Num::Variable(scalar.clone()); - let res = WrapperChecked { + let res = WrapperChecked { point: self.point.clone().mul(cs, &d, bit_limit)?.0, }; Ok(res) @@ -215,18 +159,17 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperChecked<'a, E> { fn multiexp, AD: aux_data::AuxData>( cs: &mut CS, - scalars: &[AllocatedNum::], + scalars: &[AllocatedNum], points: &[Self], bit_limit: Option, _params: &'a RnsParameters::Base>, _aux_data: &AD, - ) -> Result - { - let d_arr : Vec> = scalars.iter().map(|x| Num::Variable(x.clone())).collect(); - let aff_points : Vec<_> = points.into_iter().map(|x| x.point.clone()).collect(); - let res = WrapperChecked { + ) -> Result { + let d_arr: Vec> = scalars.iter().map(|x| Num::Variable(x.clone())).collect(); + let aff_points: Vec<_> = points.into_iter().map(|x| x.point.clone()).collect(); + let res = WrapperChecked { point: AffinePoint::multiexp(cs, &d_arr[..], &aff_points[..], bit_limit)?, }; Ok(res) } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/without_flag_unchecked.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/without_flag_unchecked.rs index f94b83e..d8388a2 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/without_flag_unchecked.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/affine_point_wrapper/without_flag_unchecked.rs @@ -13,20 +13,17 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperUnchecked<'a, E> { fn get_zero_flag(&self) -> Boolean { Boolean::constant(false) } - + #[track_caller] fn alloc, AD: aux_data::AuxData>( cs: &mut CS, value: Option, params: &'a RnsParameters::Base>, aux_data: &AD, - ) -> Result - { + ) -> Result { let point = AffinePoint::alloc(cs, value, params)?; - let res = WrapperUnchecked { - point, - }; + let res = WrapperUnchecked { point }; let is_on_curve = res.is_on_curve(cs, params, aux_data)?; @@ -35,7 +32,7 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperUnchecked<'a, E> { } else { Boolean::constant(true) }; - + let is_valid_point = Boolean::and(cs, &is_on_curve, &subgroup_check)?; Boolean::enforce_equal(cs, &is_valid_point, &Boolean::constant(true))?; @@ -43,14 +40,9 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperUnchecked<'a, E> { } #[track_caller] - fn alloc_unchecked>( - cs: &mut CS, - value: Option, - params: &'a RnsParameters::Base>, - ) -> Result - { - let res = WrapperUnchecked { - point: AffinePoint::alloc(cs, value, params)? + fn alloc_unchecked>(cs: &mut CS, value: Option, params: &'a RnsParameters::Base>) -> Result { + let res = WrapperUnchecked { + point: AffinePoint::alloc(cs, value, params)?, }; Ok(res) } @@ -70,20 +62,12 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperUnchecked<'a, E> { let point = E::G1Affine::from_xy_unchecked(x_val, y_val); Some(point) - }, - _ => { - None } + _ => None, }; - let p = AffinePoint { - value, - x, - y - }; + let p = AffinePoint { value, x, y }; - let res = WrapperUnchecked { - point: p - }; + let res = WrapperUnchecked { point: p }; let is_on_curve = res.is_on_curve(cs, params, aux_data)?; @@ -92,129 +76,85 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperUnchecked<'a, E> { } else { Boolean::constant(true) }; - + let is_valid_point = Boolean::and(cs, &is_on_curve, &subgroup_check)?; Boolean::enforce_equal(cs, &is_valid_point, &Boolean::constant(true))?; Ok((res, rest)) } - fn zero(_params: &'a RnsParameters::Base>) -> Self - { + fn zero(_params: &'a RnsParameters::Base>) -> Self { unimplemented!(); } - + #[track_caller] - fn constant( - value: E::G1Affine, - params: &'a RnsParameters::Base> - ) -> Self - { - let res = WrapperUnchecked { + fn constant(value: E::G1Affine, params: &'a RnsParameters::Base>) -> Self { + let res = WrapperUnchecked { point: AffinePoint::constant(value, params), }; res } #[track_caller] - fn equals>( - &self, - cs: &mut CS, - other: &Self, - _params: &'a RnsParameters::Base>, - ) -> Result - { + fn equals>(&self, cs: &mut CS, other: &Self, _params: &'a RnsParameters::Base>) -> Result { let (eq, _) = AffinePoint::equals(cs, self.point.clone(), other.point.clone())?; - + Ok(eq) } #[track_caller] - fn add>( - &mut self, - cs: &mut CS, - other: &mut Self, - _params: &'a RnsParameters::Base>, - ) -> Result - { - let res = WrapperUnchecked { + fn add>(&mut self, cs: &mut CS, other: &mut Self, _params: &'a RnsParameters::Base>) -> Result { + let res = WrapperUnchecked { point: self.point.clone().add_unequal(cs, other.point.clone())?.0, }; Ok(res) - } + } #[track_caller] - fn sub>( - &mut self, - cs: &mut CS, - other: &mut Self, - _params: &'a RnsParameters::Base>, - ) -> Result - { - let res = WrapperUnchecked { + fn sub>(&mut self, cs: &mut CS, other: &mut Self, _params: &'a RnsParameters::Base>) -> Result { + let res = WrapperUnchecked { point: self.point.clone().sub_unequal(cs, other.point.clone())?.0, }; Ok(res) } #[track_caller] - fn double>( - &mut self, - cs: &mut CS, - _params: &'a RnsParameters::Base>, - ) -> Result - { - let res = WrapperUnchecked { + fn double>(&mut self, cs: &mut CS, _params: &'a RnsParameters::Base>) -> Result { + let res = WrapperUnchecked { point: self.point.clone().double(cs)?.0, }; Ok(res) } #[track_caller] - fn negate>( - &mut self, - cs: &mut CS, - _params: &'a RnsParameters::Base>, - ) -> Result - { + fn negate>(&mut self, cs: &mut CS, _params: &'a RnsParameters::Base>) -> Result { let (negated, _) = self.point.clone().negate(cs)?; - let res = WrapperUnchecked { - point: negated, - }; + let res = WrapperUnchecked { point: negated }; Ok(res) } #[track_caller] - fn select>( - cs: &mut CS, - flag: &Boolean, - first: Self, - second: Self - ) -> Result - { + fn select>(cs: &mut CS, flag: &Boolean, first: Self, second: Self) -> Result { let (selected, _) = AffinePoint::select(cs, flag, first.point, second.point)?; - let res = WrapperUnchecked { - point: selected - }; + let res = WrapperUnchecked { point: selected }; Ok(res) } - + #[track_caller] fn is_on_curve, AD: aux_data::AuxData>( &self, cs: &mut CS, params: &RnsParameters::Base>, aux_data: &AD, - ) -> Result - { + ) -> Result { let lhs = self.point.y.clone().square(cs)?.0; - + let (mut rhs, reduced_x) = self.point.x.clone().square(cs)?; - + rhs = rhs.mul(cs, reduced_x)?.0; - + let b = FieldElement::new_constant(aux_data.get_b(), params); rhs = rhs.add(cs, b)?.0; @@ -228,8 +168,7 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperUnchecked<'a, E> { _cs: &mut CS, _params: &RnsParameters::Base>, _aux_data: &AD, - ) -> Result - { + ) -> Result { // we check that (n-1)x = -x //let mut exp = aux_data.get_group_order().clone(); //exp[0] -= 1; @@ -246,14 +185,13 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperUnchecked<'a, E> { fn mul, AD: aux_data::AuxData>( &mut self, cs: &mut CS, - scalar: &AllocatedNum::, + scalar: &AllocatedNum, bit_limit: Option, _params: &'a RnsParameters::Base>, _aux_data: &AD, - ) -> Result - { + ) -> Result { let d = Num::Variable(scalar.clone()); - let res = WrapperUnchecked { + let res = WrapperUnchecked { point: self.point.clone().mul(cs, &d, bit_limit)?.0, }; Ok(res) @@ -262,16 +200,15 @@ impl<'a, E: Engine> WrappedAffinePoint<'a, E> for WrapperUnchecked<'a, E> { #[track_caller] fn multiexp, AD: aux_data::AuxData>( cs: &mut CS, - scalars: &[AllocatedNum::], + scalars: &[AllocatedNum], points: &[Self], bit_limit: Option, _params: &'a RnsParameters::Base>, _aux_data: &AD, - ) -> Result - { - let d_arr : Vec> = scalars.iter().map(|x| Num::Variable(x.clone())).collect(); - let aff_points : Vec<_> = points.into_iter().map(|x| x.point.clone()).collect(); - let res = WrapperUnchecked { + ) -> Result { + let d_arr: Vec> = scalars.iter().map(|x| Num::Variable(x.clone())).collect(); + let aff_points: Vec<_> = points.into_iter().map(|x| x.point.clone()).collect(); + let res = WrapperUnchecked { point: AffinePoint::multiexp(cs, &d_arr[..], &aff_points[..], bit_limit)?, }; Ok(res) @@ -303,4 +240,4 @@ fn allocate_coordinate_from_limb_witness<'a, 'b, E: Engine, CS: ConstraintSystem return Ok((fe, rest)); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/channel.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/channel.rs index 2d2f486..e50a128 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/channel.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/channel.rs @@ -3,27 +3,18 @@ use crate::plonk::circuit::linear_combination::*; use crate::plonk::circuit::rescue::*; use crate::rescue::*; -use crate::plonk::circuit::curve::sw_affine::AffinePoint; -use crate::plonk::circuit::bigint::field::*; use crate::plonk::circuit::bigint::bigint::*; +use crate::plonk::circuit::bigint::field::*; +use crate::plonk::circuit::curve::sw_affine::AffinePoint; use crate::plonk::circuit::verifier_circuit::affine_point_wrapper::WrappedAffinePoint; -use bellman::pairing::ff::{ - Field, -}; - -use bellman::pairing::{ - Engine, -}; +use bellman::pairing::ff::Field; -use crate::bellman::{ - SynthesisError, -}; +use bellman::pairing::Engine; -use crate::bellman::plonk::better_better_cs::cs::{ - ConstraintSystem, -}; +use crate::bellman::SynthesisError; +use crate::bellman::plonk::better_better_cs::cs::ConstraintSystem; pub trait ChannelGadget { type Params; @@ -32,25 +23,20 @@ pub trait ChannelGadget { fn consume>(&mut self, data: AllocatedNum, cs: &mut CS) -> Result<(), SynthesisError>; - fn consume_point<'a, CS: ConstraintSystem, WP: WrappedAffinePoint<'a, E>>( - &mut self, - cs: &mut CS, - data: WP, - ) -> Result<(), SynthesisError>; - + fn consume_point<'a, CS: ConstraintSystem, WP: WrappedAffinePoint<'a, E>>(&mut self, cs: &mut CS, data: WP) -> Result<(), SynthesisError>; + fn produce_challenge>(&mut self, cs: &mut CS) -> Result, SynthesisError>; } - pub struct RescueChannelGadget { state: StatefulRescueGadget, params: E::Params, } - impl ChannelGadget for RescueChannelGadget -where <::Params as RescueHashParams>::SBox0: PlonkCsSBox, - <::Params as RescueHashParams>::SBox1: PlonkCsSBox +where + <::Params as RescueHashParams>::SBox0: PlonkCsSBox, + <::Params as RescueHashParams>::SBox1: PlonkCsSBox, { type Params = E::Params; @@ -61,19 +47,14 @@ where <::Params as RescueHashParams>::SBox0: PlonkCsSBox>(&mut self, data: AllocatedNum, cs: &mut CS) -> Result<(), SynthesisError> { + fn consume>(&mut self, data: AllocatedNum, cs: &mut CS) -> Result<(), SynthesisError> { self.state.absorb_single_value(cs, Num::Variable(data), &self.params)?; - // self.state.absorb(cs, &[data], &self.params) + // self.state.absorb(cs, &[data], &self.params) Ok(()) } - fn consume_point<'a, CS: ConstraintSystem, WP: WrappedAffinePoint<'a, E>>( - &mut self, - cs: &mut CS, - data: WP, - ) -> Result<(), SynthesisError> { - + fn consume_point<'a, CS: ConstraintSystem, WP: WrappedAffinePoint<'a, E>>(&mut self, cs: &mut CS, data: WP) -> Result<(), SynthesisError> { // // our strategy here is to consume x mod Pq and y mod Pq, // let x = data.get_point().x.base_field_limb.collapse_into_num(cs)?.get_variable(); // let y = data.get_point().y.base_field_limb.collapse_into_num(cs)?.get_variable(); @@ -81,8 +62,8 @@ where <::Params as RescueHashParams>::SBox0: PlonkCsSBox::Params as RescueHashParams>::SBox0: PlonkCsSBox::Params as RescueHashParams>::SBox0: PlonkCsSBox(&l); - // let w = AllocatedNum::alloc(cs, + // let w = AllocatedNum::alloc(cs, // || { // Ok(*v.get()?) // })?; - + // witnesses.push(w); // } @@ -175,4 +155,4 @@ where <::Params as RescueHashParams>::SBox0: PlonkCsSBox> { @@ -53,7 +38,6 @@ pub struct ProofGadget<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> { _m: &'a std::marker::PhantomData<()>, } - impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> ProofGadget<'a, E, WP> { pub fn alloc, P: OldCSParams, AD: AuxData>( cs: &mut CS, @@ -61,40 +45,35 @@ impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> ProofGadget<'a, E, WP> { params: &'a RnsParameters::Base>, aux_data: &AD, ) -> Result { - - let input_values = proof.input_values.iter().map(|x| { - AllocatedNum::alloc_input(cs, || Ok(*x)) - }).collect::, _>>()?; + let input_values = proof.input_values.iter().map(|x| AllocatedNum::alloc_input(cs, || Ok(*x))).collect::, _>>()?; - let wire_commitments = proof.wire_commitments.iter().map(|x| { - WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data) - }).collect::, _>>()?; + let wire_commitments = proof + .wire_commitments + .iter() + .map(|x| WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data)) + .collect::, _>>()?; let grand_product_commitment = WrappedAffinePoint::alloc(cs, Some(proof.grand_product_commitment), params, aux_data)?; - - let quotient_poly_commitments = proof.quotient_poly_commitments.iter().map(|x| { - WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data) - }).collect::, _>>()?; - let wire_values_at_z = proof.wire_values_at_z.iter().map(|x| { - AllocatedNum::alloc(cs, || Ok(*x)) - }).collect::, _>>()?; + let quotient_poly_commitments = proof + .quotient_poly_commitments + .iter() + .map(|x| WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data)) + .collect::, _>>()?; - let wire_values_at_z_omega = proof.wire_values_at_z_omega.iter().map(|x| { - AllocatedNum::alloc(cs, || Ok(*x)) - }).collect::, _>>()?; + let wire_values_at_z = proof.wire_values_at_z.iter().map(|x| AllocatedNum::alloc(cs, || Ok(*x))).collect::, _>>()?; - let grand_product_at_z_omega = AllocatedNum::alloc(cs, || Ok(proof.grand_product_at_z_omega))?; - let quotient_polynomial_at_z = AllocatedNum::alloc(cs, || Ok(proof.quotient_polynomial_at_z))?; - let linearization_polynomial_at_z = AllocatedNum::alloc(cs, || Ok(proof.linearization_polynomial_at_z))?; + let wire_values_at_z_omega = proof.wire_values_at_z_omega.iter().map(|x| AllocatedNum::alloc(cs, || Ok(*x))).collect::, _>>()?; - let permutation_polynomials_at_z = proof.permutation_polynomials_at_z.iter().map(|x| { - AllocatedNum::alloc(cs, || Ok(*x)) - }).collect::, _>>()?; + let grand_product_at_z_omega = AllocatedNum::alloc(cs, || Ok(proof.grand_product_at_z_omega))?; + let quotient_polynomial_at_z = AllocatedNum::alloc(cs, || Ok(proof.quotient_polynomial_at_z))?; + let linearization_polynomial_at_z = AllocatedNum::alloc(cs, || Ok(proof.linearization_polynomial_at_z))?; + + let permutation_polynomials_at_z = proof.permutation_polynomials_at_z.iter().map(|x| AllocatedNum::alloc(cs, || Ok(*x))).collect::, _>>()?; let opening_at_z_proof = WrappedAffinePoint::alloc(cs, Some(proof.opening_at_z_proof), params, aux_data)?; let opening_at_z_omega_proof = WrappedAffinePoint::alloc(cs, Some(proof.opening_at_z_omega_proof), params, aux_data)?; - + Ok(ProofGadget { num_inputs: proof.num_inputs, input_values, @@ -123,7 +102,6 @@ impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> ProofGadget<'a, E, WP> { params: &'a RnsParameters::Base>, aux_data: &AD, ) -> Result { - use crate::plonk::circuit::Assignment; let state_width = P::STATE_WIDTH; @@ -147,7 +125,7 @@ impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> ProofGadget<'a, E, WP> { wire_commitments.push(allocated); } - + let wit = proof.as_ref().and_then(|el| Some(el.grand_product_commitment)); let grand_product_commitment = WrappedAffinePoint::alloc(cs, wit, params, aux_data)?; @@ -176,16 +154,16 @@ impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> ProofGadget<'a, E, WP> { } let wit = proof.as_ref().and_then(|el| Some(el.grand_product_at_z_omega)); - let grand_product_at_z_omega = AllocatedNum::alloc(cs, || Ok(*wit.get()?))?; + let grand_product_at_z_omega = AllocatedNum::alloc(cs, || Ok(*wit.get()?))?; let wit = proof.as_ref().and_then(|el| Some(el.quotient_polynomial_at_z)); - let quotient_polynomial_at_z = AllocatedNum::alloc(cs, || Ok(*wit.get()?))?; + let quotient_polynomial_at_z = AllocatedNum::alloc(cs, || Ok(*wit.get()?))?; let wit = proof.as_ref().and_then(|el| Some(el.linearization_polynomial_at_z)); - let linearization_polynomial_at_z = AllocatedNum::alloc(cs, || Ok(*wit.get()?))?; + let linearization_polynomial_at_z = AllocatedNum::alloc(cs, || Ok(*wit.get()?))?; let mut permutation_polynomials_at_z = vec![]; - for idx in 0..(state_width-1) { + for idx in 0..(state_width - 1) { let wit = proof.as_ref().and_then(|el| Some(&el.permutation_polynomials_at_z)).and_then(|el| Some(el[idx])); let allocated = AllocatedNum::alloc(cs, || Ok(*wit.get()?))?; @@ -234,33 +212,36 @@ pub struct VerificationKeyGagdet<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> { _m: &'a std::marker::PhantomData<()>, } - impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> VerificationKeyGagdet<'a, E, WP> { - pub fn alloc, P: OldCSParams, AD: AuxData>( cs: &mut CS, - vk: VerificationKey, + vk: VerificationKey, params: &'a RnsParameters::Base>, aux_data: &AD, ) -> Result { - - let selector_commitments = vk.selector_commitments.iter().map(|x| { - WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data) - }).collect::, _>>()?; - - let next_step_selector_commitments = vk.next_step_selector_commitments.iter().map(|x| { - WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data) - }).collect::, _>>()?; - - let permutation_commitments = vk.permutation_commitments.iter().map(|x| { - WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data) - }).collect::, _>>()?; + let selector_commitments = vk + .selector_commitments + .iter() + .map(|x| WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data)) + .collect::, _>>()?; + + let next_step_selector_commitments = vk + .next_step_selector_commitments + .iter() + .map(|x| WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data)) + .collect::, _>>()?; + + let permutation_commitments = vk + .permutation_commitments + .iter() + .map(|x| WrappedAffinePoint::alloc(cs, Some(*x), params, aux_data)) + .collect::, _>>()?; Ok(VerificationKeyGagdet { - n : Some(vk.n), + n: Some(vk.n), domain_size_as_allocated_num: None, omega_as_allocated_num: None, - num_inputs : vk.num_inputs, + num_inputs: vk.num_inputs, selector_commitments, next_step_selector_commitments, permutation_commitments, @@ -280,8 +261,7 @@ impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> VerificationKeyGagdet<'a, E, non_residues: Vec, aux_data: &AD, ) -> Result { - - let num_selector_commitments = P::STATE_WIDTH + 2; + let num_selector_commitments = P::STATE_WIDTH + 2; let num_next_step_selector_commitments = 1; let num_permutation_commitments = P::STATE_WIDTH; @@ -321,10 +301,10 @@ impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> VerificationKeyGagdet<'a, E, assert_eq!(w.len(), 0, "must consume all the witness"); Ok(VerificationKeyGagdet { - n : None, + n: None, domain_size_as_allocated_num: Some(domain_size.clone()), omega_as_allocated_num: Some(omega.clone()), - num_inputs : num_inputs, + num_inputs: num_inputs, selector_commitments, next_step_selector_commitments, permutation_commitments, @@ -339,14 +319,14 @@ pub trait IntoLimbedWitness { fn into_witness(&self) -> Result, SynthesisError> { unimplemented!() } - fn witness_size_for_params(params: &RnsParameters::Base >) -> usize; - fn into_witness_for_params(&self, _params: &RnsParameters::Base >) -> Result, SynthesisError> { + fn witness_size_for_params(params: &RnsParameters::Base>) -> usize; + fn into_witness_for_params(&self, _params: &RnsParameters::Base>) -> Result, SynthesisError> { unimplemented!() } } impl> IntoLimbedWitness for VerificationKey { - fn witness_size_for_params(params: &RnsParameters::Base >) -> usize { + fn witness_size_for_params(params: &RnsParameters::Base>) -> usize { let mut base = 2; let per_coord = if params.can_allocate_from_double_limb_witness() { @@ -360,7 +340,7 @@ impl> IntoLimbedWitness for VerificationKey> IntoLimbedWitness for VerificationKey> IntoLimbedWitness for Proof { - fn witness_size_for_params(_params: &RnsParameters::Base >) -> usize { + fn witness_size_for_params(_params: &RnsParameters::Base>) -> usize { unimplemented!(); // let mut base = 2; @@ -401,7 +380,7 @@ impl> IntoLimbedWitness for Proof { // params.num_limbs_for_in_field_representation // }; - // let num_selector_commitments = P::STATE_WIDTH + 2; + // let num_selector_commitments = P::STATE_WIDTH + 2; // let num_next_step_selector_commitments = 1; // let num_permutation_commitments = P::STATE_WIDTH; @@ -458,7 +437,6 @@ impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> IntoLimbedCircuitWitness f } } - impl<'a, E: Engine, WP: WrappedAffinePoint<'a, E>> IntoLimbedCircuitWitness for VerificationKeyGagdet<'a, E, WP> { fn into_witness>(&self, _cs: &mut CS) -> Result>, SynthesisError> { assert!(self.domain_size_as_allocated_num.is_some(), "can only be called on a gadget with variable parameters"); @@ -489,7 +467,7 @@ fn add_prime_field_elements<'a, E: Engine, F: PrimeField>(src: &[FieldElement<'a for limb in el.binary_limbs.iter() { let as_num = limb.term.into_num(); dst.push(as_num); - } + } } } @@ -498,6 +476,6 @@ fn add_points<'a, E: Engine, WP: WrappedAffinePoint<'a, E>>(src: &[WP], dst: &mu let p = el.get_point(); let x = p.x.clone(); let y = p.y.clone(); - add_prime_field_elements(&[x, y], dst); + add_prime_field_elements(&[x, y], dst); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/helper_functions.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/helper_functions.rs index b2f244d..8fab824 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/helper_functions.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/helper_functions.rs @@ -1,82 +1,69 @@ -use crate::plonk::circuit::curve::sw_affine::AffinePoint; -use crate::plonk::circuit::bigint::field::*; use crate::plonk::circuit::allocated_num::*; +use crate::plonk::circuit::bigint::field::*; use crate::plonk::circuit::boolean::*; +use crate::plonk::circuit::curve::sw_affine::AffinePoint; use crate::plonk::circuit::linear_combination::*; use crate::plonk::circuit::simple_term::*; -use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - BitIterator, -}; - -use crate::bellman::{ - SynthesisError, -}; - -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, -}; - -pub fn evaluate_vanishing_poly( - cs: &mut CS, - point_in_pow_n : AllocatedNum, -) -> Result, SynthesisError> -where E: Engine, CS: ConstraintSystem +use crate::bellman::pairing::{Engine, GenericCurveAffine}; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField}; + +use crate::bellman::SynthesisError; + +use crate::bellman::plonk::better_better_cs::cs::{ConstraintSystem, Variable}; + +pub fn evaluate_vanishing_poly(cs: &mut CS, point_in_pow_n: AllocatedNum) -> Result, SynthesisError> +where + E: Engine, + CS: ConstraintSystem, { point_in_pow_n.sub_constant(cs, E::Fr::one()) } pub fn evaluate_vanishing_poly_without_last_point( - cs: &mut CS, + cs: &mut CS, vahisning_size: usize, - omega_inv : &E::Fr, + omega_inv: &E::Fr, point: AllocatedNum, - point_in_pow_n : AllocatedNum, -) -> Result, SynthesisError> -where E: Engine, CS: ConstraintSystem + point_in_pow_n: AllocatedNum, +) -> Result, SynthesisError> +where + E: Engine, + CS: ConstraintSystem, { assert!(vahisning_size.is_power_of_two()); // update from the paper - it should not hold for the last generator, omega^(n) in original notations - // Z(X) = (X^n - 1) / (X - omega^(n-1)) + // Z(X) = (X^n - 1) / (X - omega^(n-1)) // note that omega^(n-1) = omega^(-1) let numerator = point_in_pow_n.sub_constant(cs, E::Fr::one())?; let denominator = point.sub_constant(cs, *omega_inv)?; - + numerator.div(cs, &denominator) } - pub fn evaluate_lagrange_poly>( cs: &mut CS, - vahisning_size: usize, + vahisning_size: usize, poly_number: usize, - omega_inv : &E::Fr, + omega_inv: &E::Fr, point: AllocatedNum, // point raise to n-th power (n = vanishing size) - point_in_pow_n : AllocatedNum, -) -> Result, SynthesisError> -{ + point_in_pow_n: AllocatedNum, +) -> Result, SynthesisError> { assert!(vahisning_size.is_power_of_two()); // L_0(X) = (Z_H(X) / (X - 1)) * (1/n) and L_0(1) = 1 // L_k(omega) = 1 = L_0(omega * omega^-k) // L_k(z) = L_0(z * omega^-k) = (1/n-1) * (z^n - 1)/(z * omega^{-k} - 1) - let numerator = point_in_pow_n.sub_constant(cs, E::Fr::one())?; + let numerator = point_in_pow_n.sub_constant(cs, E::Fr::one())?; let omega_inv_pow = omega_inv.pow([poly_number as u64]); - let mut denominator_lc : LinearCombination = point.into(); + let mut denominator_lc: LinearCombination = point.into(); denominator_lc.scale(&omega_inv_pow); denominator_lc.sub_assign_constant(E::Fr::one()); @@ -89,22 +76,20 @@ pub fn evaluate_lagrange_poly>( numerator.div(cs, &denominator) } - pub fn evaluate_lagrange_poly_for_variable_domain_size>( cs: &mut CS, poly_number: usize, domain_size: AllocatedNum, - omega_inv : &AllocatedNum, + omega_inv: &AllocatedNum, point: AllocatedNum, // point raise to n-th power (n = vanishing size) - point_in_pow_n : AllocatedNum, -) -> Result, SynthesisError> -{ + point_in_pow_n: AllocatedNum, +) -> Result, SynthesisError> { // L_0(X) = (Z_H(X) / (X - 1)) * (1/n) and L_0(1) = 1 // L_k(omega) = 1 = L_0(omega * omega^-k) // L_k(z) = L_0(z * omega^-k) = (1/n-1) * (z^n - 1)/(z * omega^{-k} - 1) - let numerator = point_in_pow_n.sub_constant(cs, E::Fr::one())?; + let numerator = point_in_pow_n.sub_constant(cs, E::Fr::one())?; let omega_inv_pow = if poly_number == 0 { AllocatedNum::::one(cs) } else { @@ -113,7 +98,7 @@ pub fn evaluate_lagrange_poly_for_variable_domain_size::from_num(Num::Variable(point)); - let omega_inv_power_as_term = Term::::from_num(Num::Variable(omega_inv_pow)); + let omega_inv_power_as_term = Term::::from_num(Num::Variable(omega_inv_pow)); let mut minus_one = E::Fr::one(); minus_one.negate(); @@ -130,10 +115,7 @@ pub fn evaluate_lagrange_poly_for_variable_domain_size>( - n: F, -) -> Vec -{ +pub fn decompose_const_to_bits>(n: F) -> Vec { let mut res = Vec::with_capacity(::NUM_BITS as usize); let mut found_one = false; @@ -147,4 +129,4 @@ pub fn decompose_const_to_bits>( } res -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/mod.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/mod.rs index 1fe8eb9..f051160 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/mod.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/mod.rs @@ -1,7 +1,7 @@ pub mod affine_point_wrapper; -pub mod data_structs; pub mod channel; +pub mod data_structs; pub mod helper_functions; -pub mod verifying_circuit; pub mod test; -pub mod utils; \ No newline at end of file +pub mod utils; +pub mod verifying_circuit; diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/test.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/test.rs index 8f52ce5..8241d39 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/test.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/test.rs @@ -1,50 +1,31 @@ // new test paradigm: using better_cs for witness generation and better_better_cs for actual constraint system -use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, - GenericCurveProjective -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - BitIterator, - ScalarEngine, -}; - -use crate::bellman::{ - SynthesisError, -}; - -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, -}; - -use crate::bellman::plonk::better_cs::keys::{Proof, VerificationKey, SetupPolynomialsPrecomputations, SetupPolynomials}; -use crate::bellman::plonk::better_cs::cs::PlonkConstraintSystemParams as OldCSParams; +use crate::bellman::pairing::{Engine, GenericCurveAffine, GenericCurveProjective}; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, ScalarEngine}; + +use crate::bellman::SynthesisError; + +use crate::bellman::plonk::better_better_cs::cs::{ConstraintSystem, Variable}; + use crate::bellman::plonk::better_cs::cs::Circuit as OldCircuit; use crate::bellman::plonk::better_cs::cs::ConstraintSystem as OldConstraintSystem; +use crate::bellman::plonk::better_cs::cs::PlonkConstraintSystemParams as OldCSParams; use crate::bellman::plonk::better_cs::cs::PlonkCsWidth4WithNextStepParams as OldActualParams; +use crate::bellman::plonk::better_cs::keys::{Proof, SetupPolynomials, SetupPolynomialsPrecomputations, VerificationKey}; +use crate::bellman::kate_commitment::*; +use crate::bellman::plonk::better_better_cs::cs::{Circuit, PlonkCsWidth4WithNextStepParams, TrivialAssembly, Width4MainGateWithDNext}; use crate::bellman::plonk::better_cs::generator::GeneratorAssembly as OldAssembly; use crate::bellman::plonk::better_cs::generator::GeneratorAssembly4WithNextStep as OldActualAssembly; use crate::bellman::plonk::better_cs::prover::ProverAssembly as OldProver; use crate::bellman::plonk::better_cs::prover::ProverAssembly4WithNextStep as OldActualProver; use crate::bellman::plonk::better_cs::verifier::verify; -use crate::bellman::worker::*; use crate::bellman::plonk::commitments::transcript::*; -use crate::bellman::kate_commitment::*; use crate::bellman::plonk::fft::cooley_tukey_ntt::*; -use crate::bellman::plonk::better_better_cs::cs::{ - TrivialAssembly, - Circuit, - PlonkCsWidth4WithNextStepParams, - Width4MainGateWithDNext -}; +use crate::bellman::worker::*; #[derive(Clone)] -pub struct BenchmarkCircuit{ +pub struct BenchmarkCircuit { pub num_steps: usize, pub a: E::Fr, pub b: E::Fr, @@ -54,7 +35,6 @@ pub struct BenchmarkCircuit{ } pub fn fibbonacci(a: &F, b: &F, num_steps: usize) -> F { - let mut a = a.clone(); let mut b = b.clone(); @@ -74,25 +54,18 @@ impl OldCircuit for BenchmarkCircuit { let mut negative_one = one; negative_one.negate(); let zero = E::Fr::zero(); - - let mut a = cs.alloc_input(|| { - Ok(self.a.clone()) - })?; - let mut b = cs.alloc_input(|| { - Ok(self.b.clone()) - })?; + let mut a = cs.alloc_input(|| Ok(self.a.clone()))?; + + let mut b = cs.alloc_input(|| Ok(self.b.clone()))?; let mut a_value = self.a.clone(); let mut b_value = self.b.clone(); for _ in 0..self.num_steps { - b_value.add_assign(&a_value); - - let temp = cs.alloc(|| { - Ok(b_value.clone()) - })?; + + let temp = cs.alloc(|| Ok(b_value.clone()))?; // *q_a = gate.1[0]; // *q_b = gate.1[1]; @@ -113,9 +86,7 @@ impl OldCircuit for BenchmarkCircuit { a = temp; } - let output = cs.alloc_input(|| { - Ok(self.output.clone()) - })?; + let output = cs.alloc_input(|| Ok(self.output.clone()))?; let state_variables = [a, cs.get_dummy_variable(), cs.get_dummy_variable(), output]; let this_step_coeffs = [one.clone(), zero.clone(), zero.clone(), negative_one, zero.clone(), zero.clone()]; @@ -125,13 +96,9 @@ impl OldCircuit for BenchmarkCircuit { // fill in constant, c and d_next selectors - let zero_var = cs.alloc(|| { - Ok(E::Fr::zero()) - })?; + let zero_var = cs.alloc(|| Ok(E::Fr::zero()))?; - let one_var = cs.alloc(|| { - Ok(E::Fr::one()) - })?; + let one_var = cs.alloc(|| Ok(E::Fr::one()))?; let mut two = one; two.double(); @@ -162,9 +129,8 @@ impl OldCircuit for BenchmarkCircuit { } } - #[derive(Clone)] -pub struct BenchmarkCircuitWithOneInput{ +pub struct BenchmarkCircuitWithOneInput { pub num_steps: usize, pub a: E::Fr, pub b: E::Fr, @@ -181,25 +147,18 @@ impl OldCircuit for BenchmarkCircuitWithOneInput< let mut negative_one = one; negative_one.negate(); let zero = E::Fr::zero(); - - let mut a = cs.alloc_input(|| { - Ok(self.a.clone()) - })?; - let mut b = cs.alloc(|| { - Ok(self.b.clone()) - })?; + let mut a = cs.alloc_input(|| Ok(self.a.clone()))?; + + let mut b = cs.alloc(|| Ok(self.b.clone()))?; let mut a_value = self.a.clone(); let mut b_value = self.b.clone(); for _ in 0..self.num_steps { - b_value.add_assign(&a_value); - - let temp = cs.alloc(|| { - Ok(b_value.clone()) - })?; + + let temp = cs.alloc(|| Ok(b_value.clone()))?; // *q_a = gate.1[0]; // *q_b = gate.1[1]; @@ -220,9 +179,7 @@ impl OldCircuit for BenchmarkCircuitWithOneInput< a = temp; } - let output = cs.alloc(|| { - Ok(self.output.clone()) - })?; + let output = cs.alloc(|| Ok(self.output.clone()))?; let state_variables = [a, cs.get_dummy_variable(), cs.get_dummy_variable(), output]; let this_step_coeffs = [one.clone(), zero.clone(), zero.clone(), negative_one, zero.clone(), zero.clone()]; @@ -232,13 +189,9 @@ impl OldCircuit for BenchmarkCircuitWithOneInput< // fill in constant, c and d_next selectors - let zero_var = cs.alloc(|| { - Ok(E::Fr::zero()) - })?; + let zero_var = cs.alloc(|| Ok(E::Fr::zero()))?; - let one_var = cs.alloc(|| { - Ok(E::Fr::one()) - })?; + let one_var = cs.alloc(|| Ok(E::Fr::one()))?; let mut two = one; two.double(); @@ -273,81 +226,66 @@ impl OldCircuit for BenchmarkCircuitWithOneInput< mod test { use super::*; - use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, - GenericCurveProjective - }; - - use crate::bellman::pairing::ff::{ - Field, - PrimeField, - BitIterator, - ScalarEngine, - }; - - use crate::bellman::{ - SynthesisError, - }; - - use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, - }; - - use crate::bellman::plonk::better_cs::keys::{Proof, VerificationKey, SetupPolynomialsPrecomputations, SetupPolynomials}; - use crate::bellman::plonk::better_cs::cs::PlonkConstraintSystemParams as OldCSParams; + use crate::bellman::pairing::{Engine, GenericCurveAffine, GenericCurveProjective}; + + use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, ScalarEngine}; + + use crate::bellman::SynthesisError; + + use crate::bellman::plonk::better_better_cs::cs::{ConstraintSystem, Variable}; + use crate::bellman::plonk::better_cs::cs::Circuit as OldCircuit; use crate::bellman::plonk::better_cs::cs::ConstraintSystem as OldConstraintSystem; + use crate::bellman::plonk::better_cs::cs::PlonkConstraintSystemParams as OldCSParams; use crate::bellman::plonk::better_cs::cs::PlonkCsWidth4WithNextStepParams as OldActualParams; + use crate::bellman::plonk::better_cs::keys::{Proof, SetupPolynomials, SetupPolynomialsPrecomputations, VerificationKey}; + use crate::bellman::kate_commitment::*; + use crate::bellman::plonk::better_better_cs::cs::{Circuit, PlonkCsWidth4WithNextStepParams, TrivialAssembly, Width4MainGateWithDNext}; use crate::bellman::plonk::better_cs::generator::GeneratorAssembly as OldAssembly; use crate::bellman::plonk::better_cs::generator::GeneratorAssembly4WithNextStep as OldActualAssembly; use crate::bellman::plonk::better_cs::prover::ProverAssembly as OldProver; use crate::bellman::plonk::better_cs::prover::ProverAssembly4WithNextStep as OldActualProver; use crate::bellman::plonk::better_cs::verifier::verify; - use crate::bellman::worker::*; use crate::bellman::plonk::commitments::transcript::*; - use crate::bellman::kate_commitment::*; use crate::bellman::plonk::fft::cooley_tukey_ntt::*; - use crate::bellman::plonk::better_better_cs::cs::{ - TrivialAssembly, - Circuit, - PlonkCsWidth4WithNextStepParams, - Width4MainGateWithDNext - }; + use crate::bellman::worker::*; use super::super::affine_point_wrapper::aux_data::*; use super::super::affine_point_wrapper::*; + use super::super::channel::*; use super::super::data_structs::*; use super::super::verifying_circuit::*; - use super::super::channel::*; - use crate::plonk::circuit::curve::sw_affine::*; + use crate::bellman::pairing::bn256::Bn256; + use crate::bellman::plonk::commitments::transcript::Transcript; use crate::plonk::circuit::bigint::field::*; + use crate::plonk::circuit::curve::sw_affine::*; use crate::plonk::circuit::rescue::*; - use crate::rescue::RescueEngine; - use crate::bellman::pairing::bn256::{Bn256}; use crate::rescue::bn256::Bn256RescueParams; - use crate::bellman::plonk::commitments::transcript::Transcript; + use crate::rescue::RescueEngine; // use crate::plonk::circuit::verifier_circuit::affine_point_wrapper::with_zero_flag::WrapperWithFlag; use crate::plonk::circuit::verifier_circuit::affine_point_wrapper::without_flag_unchecked::WrapperUnchecked; pub fn recursion_test<'a, E, T, CG, AD, WP>( - a: E::Fr, - b: E::Fr, + a: E::Fr, + b: E::Fr, num_steps: usize, channel_params: &'a CG::Params, rns_params: &'a RnsParameters::Base>, transcript_params: >::InitializationParameters, - ) - where E: Engine, T: Transcript, CG: ChannelGadget, AD: AuxData, WP: WrappedAffinePoint<'a, E> + ) where + E: Engine, + T: Transcript, + CG: ChannelGadget, + AD: AuxData, + WP: WrappedAffinePoint<'a, E>, { use crate::plonk::circuit::*; let worker = Worker::new(); let output = fibbonacci(&a, &b, num_steps); - + let circuit = BenchmarkCircuit:: { num_steps, a, @@ -364,16 +302,9 @@ mod test { let crs_mons = Crs::::crs_42(setup.permutation_polynomials[0].size(), &worker); let crs_vals = Crs::::crs_42(setup.permutation_polynomials[0].size(), &worker); - let verification_key = VerificationKey::from_setup( - &setup, - &worker, - &crs_mons - ).expect("should create vk"); + let verification_key = VerificationKey::from_setup(&setup, &worker, &crs_mons).expect("should create vk"); - let precomputations = SetupPolynomialsPrecomputations::from_setup( - &setup, - &worker - ).expect("should create precomputations"); + let precomputations = SetupPolynomialsPrecomputations::from_setup(&setup, &worker).expect("should create precomputations"); let mut prover = OldActualProver::::new(); circuit.synthesize(&mut prover).expect("should synthesize"); @@ -382,21 +313,22 @@ mod test { let size = setup.permutation_polynomials[0].size(); let omegas_bitreversed = BitReversedOmegas::::new_for_domain_size(size.next_power_of_two()); - let omegas_inv_bitreversed = - as CTPrecomputations::>::new_for_domain_size(size.next_power_of_two()); + let omegas_inv_bitreversed = as CTPrecomputations>::new_for_domain_size(size.next_power_of_two()); println!("BEFORE PROVE"); - let proof = prover.prove::( - &worker, - &setup, - &precomputations, - &crs_vals, - &crs_mons, - &omegas_bitreversed, - &omegas_inv_bitreversed, - Some(transcript_params.clone()), - ).expect("should prove"); + let proof = prover + .prove::( + &worker, + &setup, + &precomputations, + &crs_vals, + &crs_mons, + &omegas_bitreversed, + &omegas_inv_bitreversed, + Some(transcript_params.clone()), + ) + .expect("should prove"); println!("DONE"); @@ -406,16 +338,8 @@ mod test { println!("PROOF IS VALID"); - let verifier_circuit = - PlonkVerifierCircuit::::new( - channel_params, - vec![a, b, output], - vec![], - proof, - verification_key, - AD::new(), - rns_params, - ); + let verifier_circuit = + PlonkVerifierCircuit::::new(channel_params, vec![a, b, output], vec![], proof, verification_key, AD::new(), rns_params); let mut cs = TrivialAssembly::::new(); verifier_circuit.synthesize(&mut cs).expect("should synthesize"); @@ -426,8 +350,7 @@ mod test { } #[test] - fn bn256_recursion_test() - { + fn bn256_recursion_test() { let a = ::Fr::one(); let b = ::Fr::one(); let num_steps = 100; @@ -436,11 +359,9 @@ mod test { let rescue_params = Bn256RescueParams::new_checked_2_into_1(); let transcript_params = (&rescue_params, &rns_params); - + // recursion_test::, RescueChannelGadget, BN256AuxData, WrapperUnchecked>( // a, b, num_steps, &rescue_params, &rns_params, transcript_params, // ); } } - - diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/utils.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/utils.rs index 1440580..9bad455 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/utils.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/utils.rs @@ -3,25 +3,23 @@ use crate::plonk::circuit::linear_combination::*; use crate::plonk::circuit::rescue::*; use crate::rescue::*; -use crate::plonk::circuit::bigint::field::*; use crate::plonk::circuit::bigint::bigint::*; +use crate::plonk::circuit::bigint::field::*; -use crate::bellman::pairing::{Engine, GenericCurveAffine}; use crate::bellman::pairing::ff::PrimeField; +use crate::bellman::pairing::{Engine, GenericCurveAffine}; -use crate::bellman::plonk::better_cs::keys::{Proof, VerificationKey}; -use crate::bellman::plonk::better_cs::cs::PlonkConstraintSystemParams as OldCSParams; use crate::bellman::plonk::better_cs::cs::Circuit as OldCircuit; use crate::bellman::plonk::better_cs::cs::ConstraintSystem as OldConstraintSystem; +use crate::bellman::plonk::better_cs::cs::PlonkConstraintSystemParams as OldCSParams; use crate::bellman::plonk::better_cs::cs::PlonkCsWidth4WithNextStepParams as OldActualParams; +use crate::bellman::plonk::better_cs::keys::{Proof, VerificationKey}; use crate::bellman::plonk::domains::*; -pub fn verification_key_into_allocated_limb_witnesses>( - vk: &VerificationKey, - params: &RnsParameters::Base>) -> Vec - // where ::Base: PrimeField - { +pub fn verification_key_into_allocated_limb_witnesses>(vk: &VerificationKey, params: &RnsParameters::Base>) -> Vec +// where ::Base: PrimeField +{ // we encode // domain size // domain generator @@ -75,10 +73,7 @@ pub fn verification_key_into_allocated_limb_witnesses>( - proof: &Proof, - params: &RnsParameters::Base>) -> Vec - { +pub fn proof_into_allocated_limb_witnesses>(proof: &Proof, params: &RnsParameters::Base>) -> Vec { // we encode // inputs // witness commitments @@ -114,10 +109,7 @@ pub fn proof_into_allocated_limb_witnesses>( encodings } -pub fn proof_into_single_limb_witness>( - proof: &Proof, - params: &RnsParameters::Base>) -> Vec -{ +pub fn proof_into_single_limb_witness>(proof: &Proof, params: &RnsParameters::Base>) -> Vec { // change the params let mut new_params = params.clone(); @@ -168,11 +160,7 @@ pub fn field_to_witness(element: &F, params: &RnsParam let coord_as_bigint = fe_to_biguint(element); - let witness_limbs = split_into_fixed_number_of_limbs( - coord_as_bigint, - params.binary_limbs_params.limb_size_bits * 2, - num_witness - ); + let witness_limbs = split_into_fixed_number_of_limbs(coord_as_bigint, params.binary_limbs_params.limb_size_bits * 2, num_witness); let witnesses: Vec<_> = witness_limbs.into_iter().map(|el| biguint_to_fe::(el)).collect(); @@ -182,11 +170,7 @@ pub fn field_to_witness(element: &F, params: &RnsParam let coord_as_bigint = fe_to_biguint(element); - let witness_limbs = split_into_fixed_number_of_limbs( - coord_as_bigint, - params.binary_limbs_params.limb_size_bits, - num_witness - ); + let witness_limbs = split_into_fixed_number_of_limbs(coord_as_bigint, params.binary_limbs_params.limb_size_bits, num_witness); let witnesses: Vec<_> = witness_limbs.into_iter().map(|el| biguint_to_fe::(el)).collect(); @@ -208,4 +192,4 @@ pub fn add_points(src: &[E::G1Affine], dst: &mut Vec, params: for s in src.iter() { add_point(s, dst, params); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/verifying_circuit.rs b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/verifying_circuit.rs index 173b2af..3079007 100644 --- a/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/verifying_circuit.rs +++ b/crates/franklin-crypto/src/plonk/circuit/verifier_circuit/verifying_circuit.rs @@ -1,40 +1,27 @@ -use crate::bellman::pairing::{ - Engine, - GenericCurveAffine, -}; - -use crate::bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr, - BitIterator -}; - -use crate::bellman::{ - SynthesisError, -}; - -use crate::bellman::plonk::better_better_cs::cs::{ - Variable, - ConstraintSystem, -}; +use crate::bellman::pairing::{Engine, GenericCurveAffine}; + +use crate::bellman::pairing::ff::{BitIterator, Field, PrimeField, PrimeFieldRepr}; + +use crate::bellman::SynthesisError; + +use crate::bellman::plonk::better_better_cs::cs::{ConstraintSystem, Variable}; use crate::bellman::plonk::better_better_cs::cs::*; -use crate::bellman::plonk::better_cs::keys::{Proof, VerificationKey}; use crate::bellman::plonk::better_cs::cs::PlonkConstraintSystemParams as OldCSParams; +use crate::bellman::plonk::better_cs::keys::{Proof, VerificationKey}; use crate::bellman::plonk::domains::*; +use crate::plonk::circuit::allocated_num::*; use crate::plonk::circuit::bigint::field::*; -use crate::plonk::circuit::curve::*; use crate::plonk::circuit::boolean::*; -use crate::plonk::circuit::allocated_num::*; +use crate::plonk::circuit::curve::*; use crate::plonk::circuit::simple_term::*; +use super::affine_point_wrapper::aux_data::AuxData; +use super::affine_point_wrapper::WrappedAffinePoint; use super::channel::*; use super::data_structs::*; use super::helper_functions::*; -use super::affine_point_wrapper::aux_data::AuxData; -use super::affine_point_wrapper::WrappedAffinePoint; use std::cell::Cell; @@ -48,9 +35,14 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( aux_data: &AD, params: &'a RnsParameters::Base>, ) -> Result<[WP; 2], SynthesisError> - where - E: Engine, CS: ConstraintSystem, T: ChannelGadget, AD: AuxData, OldP: OldCSParams, - P: PlonkConstraintSystemParams, WP: WrappedAffinePoint<'a, E> +where + E: Engine, + CS: ConstraintSystem, + T: ChannelGadget, + AD: AuxData, + OldP: OldCSParams, + P: PlonkConstraintSystemParams, + WP: WrappedAffinePoint<'a, E>, { assert!(P::CAN_ACCESS_NEXT_TRACE_STEP); @@ -173,16 +165,9 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( None }; - let l_0_at_z = if let Some(required_domain_size) = required_domain_size { + let l_0_at_z = if let Some(required_domain_size) = required_domain_size { let omega_inv = omega_inv_const.unwrap(); - let l_0_at_z = evaluate_lagrange_poly( - cs, - required_domain_size, - 0, - &omega_inv, - z.clone(), - z_in_pow_domain_size.clone() - )?; + let l_0_at_z = evaluate_lagrange_poly(cs, required_domain_size, 0, &omega_inv, z.clone(), z_in_pow_domain_size.clone())?; l_0_at_z } else { @@ -191,8 +176,8 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( 0, vk.domain_size_as_allocated_num.as_ref().unwrap().clone(), omega_inv_variable.as_ref().unwrap(), - z.clone(), - z_in_pow_domain_size.clone() + z.clone(), + z_in_pow_domain_size.clone(), )?; l_0_at_z @@ -212,7 +197,7 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( let tmp = if idx == 0 { l_0_at_z.mul(cs, &input)? } else { - let tmp = if let Some(required_domain_size) = required_domain_size { + let tmp = if let Some(required_domain_size) = required_domain_size { let omega_inv = omega_inv_const.unwrap(); let tmp = evaluate_lagrange_poly(cs, required_domain_size, idx, &omega_inv, z.clone(), z_in_pow_domain_size.clone())?; @@ -223,15 +208,15 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( idx, vk.domain_size_as_allocated_num.as_ref().unwrap().clone(), omega_inv_variable.as_ref().unwrap(), - z.clone(), - z_in_pow_domain_size.clone() + z.clone(), + z_in_pow_domain_size.clone(), )?; tmp }; tmp.mul(cs, &input)? - }; + }; rhs = rhs.add(cs, &tmp)?; } } @@ -247,7 +232,7 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( tmp = tmp.add(cs, &w)?; z_part = z_part.mul(cs, &tmp)?; - } + } // last poly value and gamma let mut tmp = gamma.clone(); @@ -255,10 +240,10 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( z_part = z_part.mul(cs, &tmp)?; z_part = z_part.mul(cs, &alpha)?; - rhs = rhs.sub(cs, &z_part)?; + rhs = rhs.sub(cs, &z_part)?; let quotient_linearization_challenge = alpha.mul(cs, &alpha)?; - + // - L_0(z) * \alpha^2 let tmp = l_0_at_z.mul(cs, "ient_linearization_challenge)?; rhs = rhs.sub(cs, &tmp)?; @@ -279,10 +264,9 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( // calculate the power to add z(X) commitment that is opened at x*omega // it's r(X) + witness + all permutations + 1 - let v_power_for_standalone_z_x_opening = 1 + 1 + P::STATE_WIDTH + (P::STATE_WIDTH-1); + let v_power_for_standalone_z_x_opening = 1 + 1 + P::STATE_WIDTH + (P::STATE_WIDTH - 1); let mut virtual_commitment_for_linearization_poly = { - let mut r = vk.selector_commitments[selector_q_const_index].clone(); let mut points: Vec = vec![]; let mut scalars: Vec> = vec![]; @@ -310,7 +294,7 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( // v * [alpha * (a + beta*z + gamma)(b + beta*k_1*z + gamma)()() * z(X) - // - \alpha * (a*perm_a(z)*beta + gamma)()()*beta*z(z*omega) * perm_d(X) + - // + alpha^2 * L_0(z) * z(X) ] + + // + alpha^2 * L_0(z) * z(X) ] + // + v^{P} * u * z(X) // and join alpha^2 * L_0(z) and v^{P} * u into the first term containing z(X) @@ -319,26 +303,21 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( let mut scalar: Option> = None; // permutation part - for (_i, (wire, non_res)) in proof.wire_values_at_z.iter() - .zip(Some(E::Fr::one()).iter().chain(&vk.non_residues)).enumerate() - { + for (_i, (wire, non_res)) in proof.wire_values_at_z.iter().zip(Some(E::Fr::one()).iter().chain(&vk.non_residues)).enumerate() { // tmp = non_res * z * beta + wire use crate::plonk::circuit::Assignment; - let mut tmp = AllocatedNum::alloc( - cs, - || { - // non_res * z * beta + wire + let mut tmp = AllocatedNum::alloc(cs, || { + // non_res * z * beta + wire - let mut result = *z.get_value().get()?; - result.mul_assign(beta.get_value().get()?); - result.mul_assign(&non_res); + let mut result = *z.get_value().get()?; + result.mul_assign(beta.get_value().get()?); + result.mul_assign(&non_res); - result.add_assign(wire.get_value().get()?); + result.add_assign(wire.get_value().get()?); - Ok(result) - } - )?; + Ok(result) + })?; // create arithmetic terms @@ -368,7 +347,7 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( let s = tmp.add(cs, &gamma)?; scalar = Some(s); - } + } assert!(scalar.is_some()); } @@ -395,25 +374,20 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( let mut scalar: Option> = None; // permutation part - for (_i, (wire, perm_at_z)) in proof.wire_values_at_z.iter() - .zip(&proof.permutation_polynomials_at_z).enumerate() - { + for (_i, (wire, perm_at_z)) in proof.wire_values_at_z.iter().zip(&proof.permutation_polynomials_at_z).enumerate() { // tmp = perm_at_z * beta + wire use crate::plonk::circuit::Assignment; - let mut tmp = AllocatedNum::alloc( - cs, - || { - // perm(z) * beta + wire + let mut tmp = AllocatedNum::alloc(cs, || { + // perm(z) * beta + wire - let mut result = *beta.get_value().get()?; - result.mul_assign(perm_at_z.get_value().get()?); + let mut result = *beta.get_value().get()?; + result.mul_assign(perm_at_z.get_value().get()?); - result.add_assign(wire.get_value().get()?); + result.add_assign(wire.get_value().get()?); - Ok(result) - } - )?; + Ok(result) + })?; // create arithmetic terms @@ -439,7 +413,7 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( scalar = Some(s); } else { let s = tmp.add(cs, &gamma)?; - + scalar = Some(s); } @@ -457,7 +431,7 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( // also add to multiexp points.push(proof.grand_product_commitment.clone()); scalars.push(grand_product_part_at_z); - + let mut last_permutation = vk.permutation_commitments.last().unwrap().clone(); points.push(last_permutation.negate(cs, params)?); scalars.push(last_permutation_part_at_z); @@ -479,7 +453,7 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( let mut commitments_aggregation = proof.quotient_poly_commitments[0].clone(); - let mut scalars : Vec> = vec![]; + let mut scalars: Vec> = vec![]; let mut points: Vec = vec![]; let mut current = z_in_pow_domain_size.clone(); @@ -497,29 +471,29 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( // do the same for wires for com in proof.wire_commitments.iter() { // add to second multiexp as well - multiopening_challenge = multiopening_challenge.mul(cs, &v)?; + multiopening_challenge = multiopening_challenge.mul(cs, &v)?; points.push(com.clone()); scalars.push(multiopening_challenge.clone()); } // and for all permutation polynomials except the last one assert_eq!(vk.permutation_commitments.len(), proof.permutation_polynomials_at_z.len() + 1); - + let arr_len = vk.permutation_commitments.len(); for com in vk.permutation_commitments[0..(arr_len - 1)].iter() { // v^{1+STATE_WIDTH + STATE_WIDTH - 1} // second multiexp - multiopening_challenge = multiopening_challenge.mul(cs, &v)?; + multiopening_challenge = multiopening_challenge.mul(cs, &v)?; points.push(com.clone()); scalars.push(multiopening_challenge.clone()); } - + // we skip z(X) at z - multiopening_challenge = multiopening_challenge.mul(cs, &v)?; + multiopening_challenge = multiopening_challenge.mul(cs, &v)?; // aggregate last wire commitment (that is opened at z*omega) // using multiopening challenge and u - multiopening_challenge = multiopening_challenge.mul(cs, &v)?; + multiopening_challenge = multiopening_challenge.mul(cs, &v)?; let scalar = multiopening_challenge.mul(cs, &u)?; // add to second multiexp points.push(proof.wire_commitments.last().unwrap().clone()); @@ -529,29 +503,30 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( let mut multiopening_challenge_for_values = v.clone(); let mut aggregated_value = proof.quotient_polynomial_at_z.clone(); - for (i, value_at_z) in Some(proof.linearization_polynomial_at_z.clone()).iter() - .chain(&proof.wire_values_at_z) - .chain(&proof.permutation_polynomials_at_z) - .enumerate() + for (i, value_at_z) in Some(proof.linearization_polynomial_at_z.clone()) + .iter() + .chain(&proof.wire_values_at_z) + .chain(&proof.permutation_polynomials_at_z) + .enumerate() { - if i != 0 { + if i != 0 { multiopening_challenge_for_values = multiopening_challenge_for_values.mul(cs, &v)?; }; - + let tmp = value_at_z.mul(cs, &multiopening_challenge_for_values)?; aggregated_value = aggregated_value.add(cs, &tmp)?; } // add parts that are opened at z*omega using `u` { - multiopening_challenge_for_values = multiopening_challenge_for_values.mul(cs, &v)?; + multiopening_challenge_for_values = multiopening_challenge_for_values.mul(cs, &v)?; let scalar = multiopening_challenge_for_values.mul(cs, &u)?; let tmp = proof.grand_product_at_z_omega.mul(cs, &scalar)?; aggregated_value = aggregated_value.add(cs, &tmp)?; } { - multiopening_challenge_for_values = multiopening_challenge_for_values.mul(cs, &v)?; + multiopening_challenge_for_values = multiopening_challenge_for_values.mul(cs, &v)?; let scalar = multiopening_challenge_for_values.mul(cs, &u)?; let tmp = proof.wire_values_at_z_omega[0].mul(cs, &scalar)?; aggregated_value = aggregated_value.add(cs, &tmp)?; @@ -565,8 +540,8 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( scalars.push(aggregated_value); // next, we need to check that - // e(proof_for_z + u*proof_for_z_omega, g2^x) = - // e(z*proof_for_z + z*omega*u*proof_for_z_omega + (aggregated_commitment - aggregated_opening), g2^1) + // e(proof_for_z + u*proof_for_z_omega, g2^x) = + // e(z*proof_for_z + z*omega*u*proof_for_z_omega + (aggregated_commitment - aggregated_opening), g2^1) // however, we are going to compute the pairing itself outside the circuit // here we only go to prepare the pairing argumets: // arg1 = proof_for_z + u*proof_for_z_omega @@ -576,16 +551,16 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( let mut opening_at_z_omega_proof = proof.opening_at_z_omega_proof.clone(); let mut pair_with_x_negated = opening_at_z_omega_proof.mul(cs, &u, None, params, aux_data)?; pair_with_x_negated = pair_with_x_negated.add(cs, &mut opening_at_z_proof, params)?; - + let pair_with_x = pair_with_x_negated.negate(cs, params)?; // to second multiexp points.push(proof.opening_at_z_proof.clone()); scalars.push(z.clone()); - let z_omega_term = if let Some(_required_domain_size) = required_domain_size { + let z_omega_term = if let Some(_required_domain_size) = required_domain_size { let omega = omega_const.unwrap(); - + let mut z_omega_term = Term::::from_allocated_num(z.clone()); z_omega_term.scale(&omega); @@ -615,20 +590,23 @@ pub fn aggregate_proof<'a, E, CS, T, P, OldP, AD, WP>( Ok([pair_with_generator, pair_with_x]) } - -pub struct PlonkVerifierCircuit<'a, E, T, P, OldP, AD, WP> -where -E: Engine, T: ChannelGadget, AD: AuxData, OldP: OldCSParams, -P: PlonkConstraintSystemParams, WP: WrappedAffinePoint<'a, E>, +pub struct PlonkVerifierCircuit<'a, E, T, P, OldP, AD, WP> +where + E: Engine, + T: ChannelGadget, + AD: AuxData, + OldP: OldCSParams, + P: PlonkConstraintSystemParams, + WP: WrappedAffinePoint<'a, E>, { - _engine_marker : std::marker::PhantomData, - _channel_marker : std::marker::PhantomData, + _engine_marker: std::marker::PhantomData, + _channel_marker: std::marker::PhantomData, _cs_params_marker: std::marker::PhantomData

, _point_wrapper_marker: std::marker::PhantomData, channel_params: &'a T::Params, - public_inputs : Vec, + public_inputs: Vec, supposed_outputs: Vec, proof: Cell>>, vk: Cell>>, @@ -636,27 +614,27 @@ P: PlonkConstraintSystemParams, WP: WrappedAffinePoint<'a, E>, params: &'a RnsParameters::Base>, } - -impl<'a, E, T, P, OldP, AD, WP> PlonkVerifierCircuit<'a, E, T, P, OldP, AD, WP> -where -E: Engine, T: ChannelGadget, AD: AuxData, P: PlonkConstraintSystemParams, -OldP: OldCSParams, WP: WrappedAffinePoint<'a, E>, +impl<'a, E, T, P, OldP, AD, WP> PlonkVerifierCircuit<'a, E, T, P, OldP, AD, WP> +where + E: Engine, + T: ChannelGadget, + AD: AuxData, + P: PlonkConstraintSystemParams, + OldP: OldCSParams, + WP: WrappedAffinePoint<'a, E>, { pub fn new( - channel_params: &'a T::Params, - public_inputs: Vec, + channel_params: &'a T::Params, + public_inputs: Vec, supposed_outputs: Vec, proof: Proof, vk: VerificationKey, aux_data: AD, params: &'a RnsParameters::Base>, - ) -> Self - { - + ) -> Self { PlonkVerifierCircuit { - - _engine_marker : std::marker::PhantomData::, - _channel_marker : std::marker::PhantomData::, + _engine_marker: std::marker::PhantomData::, + _channel_marker: std::marker::PhantomData::, _cs_params_marker: std::marker::PhantomData::

, _point_wrapper_marker: std::marker::PhantomData::, @@ -672,30 +650,24 @@ OldP: OldCSParams, WP: WrappedAffinePoint<'a, E>, } } -impl<'a, E, T, P, OldP, AD, WP> Circuit for PlonkVerifierCircuit<'a, E, T, P, OldP, AD, WP> - where - E: Engine, T: ChannelGadget, AD: AuxData, P: PlonkConstraintSystemParams, - OldP: OldCSParams, WP: WrappedAffinePoint<'a, E> +impl<'a, E, T, P, OldP, AD, WP> Circuit for PlonkVerifierCircuit<'a, E, T, P, OldP, AD, WP> +where + E: Engine, + T: ChannelGadget, + AD: AuxData, + P: PlonkConstraintSystemParams, + OldP: OldCSParams, + WP: WrappedAffinePoint<'a, E>, { type MainGate = Width4MainGateWithDNext; fn declare_used_gates() -> Result>>, SynthesisError> { use crate::plonk::circuit::bigint::range_constraint_gate::TwoBitDecompositionRangecheckCustomGate; - Ok( - vec![ - Self::MainGate::default().into_internal(), - TwoBitDecompositionRangecheckCustomGate::default().into_internal(), - - ] - ) + Ok(vec![Self::MainGate::default().into_internal(), TwoBitDecompositionRangecheckCustomGate::default().into_internal()]) } - fn synthesize>( - &self, - cs: &mut CS, - ) -> Result<(), SynthesisError> { - + fn synthesize>(&self, cs: &mut CS) -> Result<(), SynthesisError> { assert!(P::CAN_ACCESS_NEXT_TRACE_STEP); let actual_proof = self.proof.replace(None); @@ -704,16 +676,8 @@ impl<'a, E, T, P, OldP, AD, WP> Circuit for PlonkVerifierCircuit<'a, E, T, P, let proof = ProofGadget::::alloc(cs, actual_proof.unwrap(), self.params, &self.aux_data)?; let vk = VerificationKeyGagdet::::alloc(cs, actual_vk.unwrap(), self.params, &self.aux_data)?; - let _ = aggregate_proof::( - cs, - self.channel_params, - &proof.input_values, - &vk, - &proof, - &self.aux_data, - &self.params - )?; + let _ = aggregate_proof::(cs, self.channel_params, &proof.input_values, &vk, &proof, &self.aux_data, &self.params)?; Ok(()) } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/plonk/mod.rs b/crates/franklin-crypto/src/plonk/mod.rs index 0a3a8af..db89e61 100644 --- a/crates/franklin-crypto/src/plonk/mod.rs +++ b/crates/franklin-crypto/src/plonk/mod.rs @@ -1 +1 @@ -pub mod circuit; \ No newline at end of file +pub mod circuit; diff --git a/crates/franklin-crypto/src/primitives/mod.rs b/crates/franklin-crypto/src/primitives/mod.rs index ba5c45d..aa10def 100644 --- a/crates/franklin-crypto/src/primitives/mod.rs +++ b/crates/franklin-crypto/src/primitives/mod.rs @@ -1,87 +1,55 @@ -use bellman::pairing::ff::{ - Field, - PrimeField, - PrimeFieldRepr -}; +use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; use constants; use group_hash::group_hash; -use pedersen_hash::{ - pedersen_hash, - Personalization -}; +use pedersen_hash::{pedersen_hash, Personalization}; -use byteorder::{ - LittleEndian, - WriteBytesExt -}; +use byteorder::{LittleEndian, WriteBytesExt}; -use jubjub::{ - JubjubEngine, - JubjubParams, - edwards, - PrimeOrder, - FixedGenerators -}; +use jubjub::{edwards, FixedGenerators, JubjubEngine, JubjubParams, PrimeOrder}; use blake2_rfc::blake2s::Blake2s; #[derive(Clone)] pub struct ValueCommitment { pub value: u64, - pub randomness: E::Fs + pub randomness: E::Fs, } impl ValueCommitment { - pub fn cm( - &self, - params: &E::Params - ) -> edwards::Point - { - params.generator(FixedGenerators::ValueCommitmentValue) - .mul(self.value, params) - .add( - ¶ms.generator(FixedGenerators::ValueCommitmentRandomness) - .mul(self.randomness, params), - params - ) + pub fn cm(&self, params: &E::Params) -> edwards::Point { + params + .generator(FixedGenerators::ValueCommitmentValue) + .mul(self.value, params) + .add(¶ms.generator(FixedGenerators::ValueCommitmentRandomness).mul(self.randomness, params), params) } } #[derive(Clone)] pub struct ProofGenerationKey { pub ak: edwards::Point, - pub nsk: E::Fs + pub nsk: E::Fs, } impl ProofGenerationKey { pub fn into_viewing_key(&self, params: &E::Params) -> ViewingKey { ViewingKey { ak: self.ak.clone(), - nk: params.generator(FixedGenerators::ProofGenerationKey) - .mul(self.nsk, params) + nk: params.generator(FixedGenerators::ProofGenerationKey).mul(self.nsk, params), } } } pub struct ViewingKey { pub ak: edwards::Point, - pub nk: edwards::Point + pub nk: edwards::Point, } impl ViewingKey { - pub fn rk( - &self, - ar: E::Fs, - params: &E::Params - ) -> edwards::Point { - self.ak.add( - ¶ms.generator(FixedGenerators::SpendingKeyGenerator) - .mul(ar, params), - params - ) + pub fn rk(&self, ar: E::Fs, params: &E::Params) -> edwards::Point { + self.ak.add(¶ms.generator(FixedGenerators::SpendingKeyGenerator).mul(ar, params), params) } pub fn ivk(&self) -> E::Fs { @@ -103,19 +71,11 @@ impl ViewingKey { E::Fs::from_repr(e).expect("should be a valid scalar") } - pub fn into_payment_address( - &self, - diversifier: Diversifier, - params: &E::Params - ) -> Option> - { + pub fn into_payment_address(&self, diversifier: Diversifier, params: &E::Params) -> Option> { diversifier.g_d(params).map(|g_d| { let pk_d = g_d.mul(self.ivk(), params); - PaymentAddress { - pk_d: pk_d, - diversifier: diversifier - } + PaymentAddress { pk_d: pk_d, diversifier: diversifier } }) } } @@ -124,11 +84,7 @@ impl ViewingKey { pub struct Diversifier(pub [u8; 11]); impl Diversifier { - pub fn g_d( - &self, - params: &E::Params - ) -> Option> - { + pub fn g_d(&self, params: &E::Params) -> Option> { group_hash::(&self.0, constants::KEY_DIVERSIFICATION_PERSONALIZATION, params) } } @@ -136,32 +92,20 @@ impl Diversifier { #[derive(Clone)] pub struct PaymentAddress { pub pk_d: edwards::Point, - pub diversifier: Diversifier + pub diversifier: Diversifier, } impl PaymentAddress { - pub fn g_d( - &self, - params: &E::Params - ) -> Option> - { + pub fn g_d(&self, params: &E::Params) -> Option> { self.diversifier.g_d(params) } - pub fn create_note( - &self, - value: u64, - randomness: E::Fs, - params: &E::Params - ) -> Option> - { - self.g_d(params).map(|g_d| { - Note { - value: value, - r: randomness, - g_d: g_d, - pk_d: self.pk_d.clone() - } + pub fn create_note(&self, value: u64, randomness: E::Fs, params: &E::Params) -> Option> { + self.g_d(params).map(|g_d| Note { + value: value, + r: randomness, + g_d: g_d, + pk_d: self.pk_d.clone(), }) } } @@ -174,7 +118,7 @@ pub struct Note { /// The public key of the address, g_d^ivk pub pk_d: edwards::Point, /// The commitment randomness - pub r: E::Fs + pub r: E::Fs, } impl Note { @@ -188,8 +132,7 @@ impl Note { } /// Computes the note commitment, returning the full point. - fn cm_full_point(&self, params: &E::Params) -> edwards::Point - { + fn cm_full_point(&self, params: &E::Params) -> edwards::Point { // Calculate the note contents, as bytes let mut note_contents = vec![]; @@ -207,36 +150,19 @@ impl Note { // Compute the Pedersen hash of the note contents let hash_of_contents = pedersen_hash( Personalization::NoteCommitment, - note_contents.into_iter() - .flat_map(|byte| { - (0..8).map(move |i| ((byte >> i) & 1) == 1) - }), - params + note_contents.into_iter().flat_map(|byte| (0..8).map(move |i| ((byte >> i) & 1) == 1)), + params, ); // Compute final commitment - params.generator(FixedGenerators::NoteCommitmentRandomness) - .mul(self.r, params) - .add(&hash_of_contents, params) + params.generator(FixedGenerators::NoteCommitmentRandomness).mul(self.r, params).add(&hash_of_contents, params) } /// Computes the nullifier given the viewing key and /// note position - pub fn nf( - &self, - viewing_key: &ViewingKey, - position: u64, - params: &E::Params - ) -> Vec - { + pub fn nf(&self, viewing_key: &ViewingKey, position: u64, params: &E::Params) -> Vec { // Compute rho = cm + position.G - let rho = self - .cm_full_point(params) - .add( - ¶ms.generator(FixedGenerators::NullifierPosition) - .mul(position, params), - params - ); + let rho = self.cm_full_point(params).add(¶ms.generator(FixedGenerators::NullifierPosition).mul(position, params), params); // Compute nf = BLAKE2s(nk | rho) let mut nf_preimage = [0u8; 64]; @@ -244,13 +170,12 @@ impl Note { rho.write(&mut nf_preimage[32..64]).unwrap(); let mut h = Blake2s::with_params(32, &[], &[], constants::PRF_NF_PERSONALIZATION); h.update(&nf_preimage); - + h.finalize().as_ref().to_vec() } /// Computes the note commitment - pub fn cm(&self, params: &E::Params) -> E::Fr - { + pub fn cm(&self, params: &E::Params) -> E::Fr { // The commitment is in the prime order subgroup, so mapping the // commitment to the x-coordinate is an injective encoding. self.cm_full_point(params).into_xy().0 diff --git a/crates/franklin-crypto/src/redjubjub.rs b/crates/franklin-crypto/src/redjubjub.rs index b70e504..199ef88 100644 --- a/crates/franklin-crypto/src/redjubjub.rs +++ b/crates/franklin-crypto/src/redjubjub.rs @@ -2,11 +2,11 @@ //! See section 5.4.6 of the Sapling protocol specification. use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use rand::{Rng, Rand}; +use rand::{Rand, Rng}; use std::io::{self, Read, Write}; -use jubjub::{FixedGenerators, JubjubEngine, JubjubParams, Unknown, edwards::Point}; -use util::{hash_to_scalar}; +use jubjub::{edwards::Point, FixedGenerators, JubjubEngine, JubjubParams, Unknown}; +use util::hash_to_scalar; fn read_scalar(reader: R) -> io::Result { let mut s_repr = ::Repr::default(); @@ -14,10 +14,7 @@ fn read_scalar(reader: R) -> io::Result { match E::Fs::from_repr(s_repr) { Ok(s) => Ok(s), - Err(_) => Err(io::Error::new( - io::ErrorKind::InvalidInput, - "scalar is not in field", - )), + Err(_) => Err(io::Error::new(io::ErrorKind::InvalidInput, "scalar is not in field")), } } @@ -71,13 +68,7 @@ impl PrivateKey { write_scalar::(&self.0, writer) } - pub fn sign( - &self, - msg: &[u8], - rng: &mut R, - p_g: FixedGenerators, - params: &E::Params, - ) -> Signature { + pub fn sign(&self, msg: &[u8], rng: &mut R, p_g: FixedGenerators, params: &E::Params) -> Signature { // T = (l_H + 128) bits of randomness // For H*, l_H = 512 bits let mut t = [0u8; 80]; @@ -89,16 +80,14 @@ impl PrivateKey { // R = r . P_G let r_g = params.generator(p_g).mul(r, params); let mut rbar = [0u8; 32]; - r_g.write(&mut rbar[..]) - .expect("Jubjub points should serialize to 32 bytes"); + r_g.write(&mut rbar[..]).expect("Jubjub points should serialize to 32 bytes"); // S = r + H*(Rbar || M) . sk let mut s = h_star::(&rbar[..], msg); s.mul_assign(&self.0); s.add_assign(&r); let mut sbar = [0u8; 32]; - write_scalar::(&s, &mut sbar[..]) - .expect("Jubjub scalars should serialize to 32 bytes"); + write_scalar::(&s, &mut sbar[..]).expect("Jubjub scalars should serialize to 32 bytes"); Signature { rbar, sbar } } @@ -125,13 +114,7 @@ impl PublicKey { self.0.write(writer) } - pub fn verify( - &self, - msg: &[u8], - sig: &Signature, - p_g: FixedGenerators, - params: &E::Params, - ) -> bool { + pub fn verify(&self, msg: &[u8], sig: &Signature, p_g: FixedGenerators, params: &E::Params) -> bool { // c = H*(Rbar || M) let c = h_star::(&sig.rbar[..], msg); @@ -148,10 +131,12 @@ impl PublicKey { Err(_) => return false, }; // 0 = h_G(-S . P_G + R + c . vk) - self.0.mul(c, params).add(&r, params).add( - ¶ms.generator(p_g).mul(s, params).negate().into(), - params - ).mul_by_cofactor(params).eq(&Point::zero()) + self.0 + .mul(c, params) + .add(&r, params) + .add(¶ms.generator(p_g).mul(s, params).negate().into(), params) + .mul_by_cofactor(params) + .eq(&Point::zero()) } } @@ -163,13 +148,7 @@ pub struct BatchEntry<'a, E: JubjubEngine> { // TODO: #82: This is a naive implementation currently, // and doesn't use multiexp. -pub fn batch_verify<'a, E: JubjubEngine, R: Rng>( - rng: &mut R, - batch: &[BatchEntry<'a, E>], - p_g: FixedGenerators, - params: &E::Params, -) -> bool -{ +pub fn batch_verify<'a, E: JubjubEngine, R: Rng>(rng: &mut R, batch: &[BatchEntry<'a, E>], p_g: FixedGenerators, params: &E::Params) -> bool { let mut acc = Point::::zero(); for entry in batch { @@ -208,7 +187,7 @@ mod tests { use bellman::pairing::bls12_381::Bls12; use rand::thread_rng; - use jubjub::{JubjubBls12, fs::Fs, edwards}; + use jubjub::{edwards, fs::Fs, JubjubBls12}; use super::*; @@ -230,10 +209,7 @@ mod tests { let sig2 = sk2.sign(msg2, rng, p_g, params); assert!(vk2.verify(msg2, &sig2, p_g, params)); - let mut batch = vec![ - BatchEntry { vk: vk1, msg: msg1, sig: sig1 }, - BatchEntry { vk: vk2, msg: msg2, sig: sig2 } - ]; + let mut batch = vec![BatchEntry { vk: vk1, msg: msg1, sig: sig1 }, BatchEntry { vk: vk2, msg: msg2, sig: sig2 }]; assert!(batch_verify(rng, &batch, p_g, params)); @@ -348,7 +324,7 @@ mod baby_tests { use bellman::pairing::bn256::Bn256; use rand::thread_rng; - use alt_babyjubjub::{AltJubjubBn256, fs::Fs, edwards, FixedGenerators}; + use alt_babyjubjub::{edwards, fs::Fs, AltJubjubBn256, FixedGenerators}; use super::*; @@ -370,10 +346,7 @@ mod baby_tests { let sig2 = sk2.sign(msg2, rng, p_g, params); assert!(vk2.verify(msg2, &sig2, p_g, params)); - let mut batch = vec![ - BatchEntry { vk: vk1, msg: msg1, sig: sig1 }, - BatchEntry { vk: vk2, msg: msg2, sig: sig2 } - ]; + let mut batch = vec![BatchEntry { vk: vk1, msg: msg1, sig: sig1 }, BatchEntry { vk: vk2, msg: msg2, sig: sig2 }]; assert!(batch_verify(rng, &batch, p_g, params)); @@ -481,4 +454,4 @@ mod baby_tests { assert!(!rvk.verify(msg2, &sig1, p_g, params)); } } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/rescue/bn256/mod.rs b/crates/franklin-crypto/src/rescue/bn256/mod.rs index c612776..07504bd 100644 --- a/crates/franklin-crypto/src/rescue/bn256/mod.rs +++ b/crates/franklin-crypto/src/rescue/bn256/mod.rs @@ -1,14 +1,14 @@ +use super::{generate_mds_matrix, PowerSBox, QuinticSBox, RescueEngine, RescueHashParams, RescueParamsInternal}; use bellman::pairing::bn256; use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use super::{RescueEngine, RescueHashParams, RescueParamsInternal, PowerSBox, QuinticSBox, generate_mds_matrix}; -use group_hash::{GroupHasher, BlakeHasher}; +use group_hash::{BlakeHasher, GroupHasher}; extern crate num_bigint; extern crate num_integer; extern crate num_traits; -use self::num_bigint::{BigUint, BigInt}; -use self::num_integer::{Integer, ExtendedGcd}; -use self::num_traits::{ToPrimitive, Zero, One}; +use self::num_bigint::{BigInt, BigUint}; +use self::num_integer::{ExtendedGcd, Integer}; +use self::num_traits::{One, ToPrimitive, Zero}; impl RescueEngine for bn256::Bn256 { type Params = Bn256RescueParams; @@ -56,7 +56,7 @@ impl Bn256RescueParams { } pub fn new_for_params(c: u32, r: u32, rounds: u32, _security_level: u32) -> Self { - use byteorder::{WriteBytesExt, ReadBytesExt, BigEndian}; + use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use constants; let state_width = c + r; @@ -98,8 +98,8 @@ impl Bn256RescueParams { }; let mds_matrix = { - use rand::{SeedableRng}; use rand::chacha::ChaChaRng; + use rand::SeedableRng; // Create an RNG based on the outcome of the random beacon let mut rng = { // This tag is a first one in a sequence of b"ResMxxxx" @@ -121,7 +121,6 @@ impl Bn256RescueParams { generate_mds_matrix::(state_width, &mut rng) }; - let alpha = BigUint::from(5u64); let mut p_minus_one_biguint = BigUint::from(0u64); @@ -147,7 +146,7 @@ impl Bn256RescueParams { let alpha_signed = BigInt::from(alpha); let p_minus_one_signed = BigInt::from(p_minus_one_biguint); - let ExtendedGcd{ gcd, x: _, y, .. } = p_minus_one_signed.extended_gcd(&alpha_signed); + let ExtendedGcd { gcd, x: _, y, .. } = p_minus_one_signed.extended_gcd(&alpha_signed); assert!(gcd.is_one()); let y = if y < BigInt::zero() { let mut y = y; @@ -205,15 +204,15 @@ impl RescueHashParams for Bn256RescueParams { } fn round_constants(&self, round: u32) -> &[bn256::Fr] { let t = self.c + self.r; - let start = (t*round) as usize; - let end = (t*(round+1)) as usize; + let start = (t * round) as usize; + let end = (t * (round + 1)) as usize; &self.round_constants[start..end] } fn mds_matrix_row(&self, row: u32) -> &[bn256::Fr] { let t = self.c + self.r; - let start = (t*row) as usize; - let end = (t*(row+1)) as usize; + let start = (t * row) as usize; + let end = (t * (row + 1)) as usize; &self.mds_matrix[start..end] } @@ -241,16 +240,15 @@ impl RescueHashParams for Bn256RescueParams { } } - #[cfg(test)] mod test { - use rand::{Rand, Rng, thread_rng, XorShiftRng, SeedableRng}; - use bellman::pairing::bn256::{Bn256, Fr}; - use bellman::pairing::ff::PrimeField; - use bellman::pairing::ff::Field; use super::*; - use crate::rescue::*; use crate::group_hash::BlakeHasher; + use crate::rescue::*; + use bellman::pairing::bn256::{Bn256, Fr}; + use bellman::pairing::ff::Field; + use bellman::pairing::ff::PrimeField; + use rand::{thread_rng, Rand, Rng, SeedableRng, XorShiftRng}; #[test] fn test_generate_bn256_rescue_params() { @@ -322,7 +320,7 @@ mod test { fn test_bn256_long_input_rescue_hash() { let rng = &mut thread_rng(); let params = Bn256RescueParams::new_2_into_1::(); - let input: Vec = (0..((params.rate()*10) + 1)).map(|_| rng.gen()).collect(); + let input: Vec = (0..((params.rate() * 10) + 1)).map(|_| rng.gen()).collect(); let output = rescue_hash::(¶ms, &input[..]); assert!(output.len() == 1); @@ -340,7 +338,7 @@ mod test { fn test_bn256_different_specializations() { let rng = &mut thread_rng(); let params = Bn256RescueParams::new_2_into_1::(); - let input: Vec = (0..((params.rate()*10) + 1)).map(|_| rng.gen()).collect(); + let input: Vec = (0..((params.rate() * 10) + 1)).map(|_| rng.gen()).collect(); let output = rescue_hash::(¶ms, &input[..]); assert!(output.len() == 1); @@ -385,4 +383,4 @@ mod test { println!("[ {} ]", vec.join(",")); } -} \ No newline at end of file +} diff --git a/crates/franklin-crypto/src/rescue/mod.rs b/crates/franklin-crypto/src/rescue/mod.rs index 682c8d2..28d2197 100644 --- a/crates/franklin-crypto/src/rescue/mod.rs +++ b/crates/franklin-crypto/src/rescue/mod.rs @@ -1,7 +1,7 @@ +use super::group_hash::GroupHasher; use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; -use bellman::pairing::{Engine}; +use bellman::pairing::Engine; use std::marker::PhantomData; -use super::group_hash::GroupHasher; use rand::{Rand, Rng}; @@ -14,11 +14,10 @@ pub trait SBox: Sized + Clone + std::fmt::Debug { #[derive(Clone, Debug)] pub struct CubicSBox { - pub _marker: PhantomData + pub _marker: PhantomData, } -implSBox for CubicSBox { - +impl SBox for CubicSBox { fn apply(&self, elements: &mut [E::Fr]) { for element in elements.iter_mut() { let mut squared = *element; @@ -30,7 +29,7 @@ implSBox for CubicSBox { #[derive(Clone, Debug)] pub struct QuinticSBox { - pub _marker: PhantomData + pub _marker: PhantomData, } impl PartialEq for QuinticSBox { @@ -41,7 +40,7 @@ impl PartialEq for QuinticSBox { impl Eq for QuinticSBox {} -implSBox for QuinticSBox { +impl SBox for QuinticSBox { fn apply(&self, elements: &mut [E::Fr]) { for element in elements.iter_mut() { let mut quad = *element; @@ -60,14 +59,13 @@ pub struct PowerSBox { impl PartialEq for PowerSBox { fn eq(&self, other: &Self) -> bool { - self.power.eq(&other.power) && - self.inv.eq(&other.inv) + self.power.eq(&other.power) && self.inv.eq(&other.inv) } } impl Eq for PowerSBox {} -implSBox for PowerSBox { +impl SBox for PowerSBox { fn apply(&self, elements: &mut [E::Fr]) { for element in elements.iter_mut() { *element = element.pow(&self.power); @@ -77,7 +75,7 @@ implSBox for PowerSBox { #[derive(Clone, Debug)] pub struct InversionSBox { - pub _marker: PhantomData + pub _marker: PhantomData, } fn batch_inversion(v: &mut [E::Fr]) { @@ -88,7 +86,8 @@ fn batch_inversion(v: &mut [E::Fr]) { // First pass: compute [a, ab, abc, ...] let mut prod = Vec::with_capacity(v.len()); let mut tmp = E::Fr::one(); - for g in v.iter() + for g in v + .iter() // Ignore zero elements .filter(|g| !g.is_zero()) { @@ -100,13 +99,14 @@ fn batch_inversion(v: &mut [E::Fr]) { tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero. // Second pass: iterate backwards to compute inverses - for (g, s) in v.iter_mut() - // Backwards - .rev() - // Ignore normalized elements - .filter(|g| !g.is_zero()) - // Backwards, skip last element, fill in one for last term. - .zip(prod.into_iter().rev().skip(1).chain(Some(E::Fr::one()))) + for (g, s) in v + .iter_mut() + // Backwards + .rev() + // Ignore normalized elements + .filter(|g| !g.is_zero()) + // Backwards, skip last element, fill in one for last term. + .zip(prod.into_iter().rev().skip(1).chain(Some(E::Fr::one()))) { // tmp := tmp * g.z; g.z := tmp * s = 1/z let mut newtmp = tmp; @@ -117,7 +117,7 @@ fn batch_inversion(v: &mut [E::Fr]) { } } -implSBox for InversionSBox { +impl SBox for InversionSBox { fn apply(&self, elements: &mut [E::Fr]) { batch_inversion::(elements); } @@ -154,25 +154,19 @@ pub trait RescueHashParams: RescueParamsInternal { } } -pub trait RescueParamsInternal: Send + Sync + Sized + Clone + std::fmt::Debug + Eq{ +pub trait RescueParamsInternal: Send + Sync + Sized + Clone + std::fmt::Debug + Eq { fn set_round_constants(&mut self, to: Vec); } pub trait RescueEngine: Engine { - type Params: RescueHashParams; + type Params: RescueHashParams; } -pub fn rescue_hash( - params: &E::Params, - input: &[E::Fr] -) -> Vec { +pub fn rescue_hash(params: &E::Params, input: &[E::Fr]) -> Vec { sponge_fixed_length::(params, input) } -fn sponge_fixed_length( - params: &E::Params, - input: &[E::Fr] -) -> Vec { +fn sponge_fixed_length(params: &E::Params, input: &[E::Fr]) -> Vec { assert!(input.len() > 0); assert!(input.len() < 256); let input_len = input.len() as u64; @@ -203,24 +197,20 @@ fn sponge_fixed_length( debug_assert!(it.next().is_none()); state[..(params.capacity() as usize)].to_vec() -} +} -pub fn rescue_mimc( - params: &E::Params, - old_state: &[E::Fr] -) -> Vec { +pub fn rescue_mimc(params: &E::Params, old_state: &[E::Fr]) -> Vec { let mut state = old_state.to_vec(); let mut mds_application_scratch = vec![E::Fr::zero(); state.len()]; assert_eq!(state.len(), params.state_width() as usize); // add round constatnts - for (s, c) in state.iter_mut() - .zip(params.round_constants(0).iter()) { + for (s, c) in state.iter_mut().zip(params.round_constants(0).iter()) { s.add_assign(c); } // parameters use number of rounds that is number of invocations of each SBox, // so we double - for round_num in 0..(2*params.num_rounds()) { + for round_num in 0..(2 * params.num_rounds()) { // apply corresponding sbox if round_num & 1u32 == 0 { params.sbox_0().apply(&mut state); @@ -232,10 +222,9 @@ pub fn rescue_mimc( mds_application_scratch.copy_from_slice(params.round_constants(round_num + 1)); // mul state by MDS - for (row, place_into) in mds_application_scratch.iter_mut() - .enumerate() { - let tmp = scalar_product::(& state[..], params.mds_matrix_row(row as u32)); - place_into.add_assign(&tmp); + for (row, place_into) in mds_application_scratch.iter_mut().enumerate() { + let tmp = scalar_product::(&state[..], params.mds_matrix_row(row as u32)); + place_into.add_assign(&tmp); // *place_into = scalar_product::(& state[..], params.mds_matrix_row(row as u32)); } @@ -246,7 +235,7 @@ pub fn rescue_mimc( state } -fn scalar_product (input: &[E::Fr], by: &[E::Fr]) -> E::Fr { +fn scalar_product(input: &[E::Fr], by: &[E::Fr]) -> E::Fr { assert!(input.len() == by.len()); let mut result = E::Fr::zero(); for (a, b) in input.iter().zip(by.iter()) { @@ -273,7 +262,7 @@ fn generate_mds_matrix(t: u32, rng: &mut R) -> Vec(t: u32, rng: &mut R) -> Vec(t: u32, rng: &mut R) -> Vec(t: u32, rng: &mut R) -> Vec( - default_params: &E::Params, - key: &[E::Fr] -) -> E::Params { +pub fn make_keyed_params(default_params: &E::Params, key: &[E::Fr]) -> E::Params { // for this purpose we feed the master key through the rescue itself // in a sense that we make non-trivial initial state and run it with empty input @@ -354,8 +340,7 @@ pub fn make_keyed_params( let mut mds_application_scratch = vec![E::Fr::zero(); state.len()]; assert_eq!(state.len(), default_params.state_width() as usize); // add round constatnts - for (s, c) in state.iter_mut() - .zip(default_params.round_constants(0).iter()) { + for (s, c) in state.iter_mut().zip(default_params.round_constants(0).iter()) { s.add_assign(c); } @@ -364,7 +349,7 @@ pub fn make_keyed_params( // parameters use number of rounds that is number of invocations of each SBox, // so we double - for round_num in 0..(2*default_params.num_rounds()) { + for round_num in 0..(2 * default_params.num_rounds()) { // apply corresponding sbox if round_num & 1u32 == 0 { default_params.sbox_0().apply(&mut state); @@ -376,10 +361,9 @@ pub fn make_keyed_params( mds_application_scratch.copy_from_slice(default_params.round_constants(round_num + 1)); // mul state by MDS - for (row, place_into) in mds_application_scratch.iter_mut() - .enumerate() { - let tmp = scalar_product::(& state[..], default_params.mds_matrix_row(row as u32)); - place_into.add_assign(&tmp); + for (row, place_into) in mds_application_scratch.iter_mut().enumerate() { + let tmp = scalar_product::(&state[..], default_params.mds_matrix_row(row as u32)); + place_into.add_assign(&tmp); // *place_into = scalar_product::(& state[..], params.mds_matrix_row(row as u32)); } @@ -388,7 +372,7 @@ pub fn make_keyed_params( new_round_constants.extend_from_slice(&state); } - + let mut new_params = default_params.clone(); new_params.set_round_constants(new_round_constants); @@ -398,37 +382,32 @@ pub fn make_keyed_params( #[derive(Clone, Debug)] pub enum RescueOpMode { AccumulatingToAbsorb(Vec), - SqueezedInto(Vec) + SqueezedInto(Vec), } #[derive(Clone, Debug)] pub struct StatefulRescue<'a, E: RescueEngine> { pub params: &'a E::Params, pub internal_state: Vec, - pub mode: RescueOpMode + pub mode: RescueOpMode, } impl<'a, E: RescueEngine> StatefulRescue<'a, E> { - pub fn new( - params: &'a E::Params - ) -> Self { + pub fn new(params: &'a E::Params) -> Self { let op = RescueOpMode::AccumulatingToAbsorb(Vec::with_capacity(params.rate() as usize)); StatefulRescue::<_> { params, internal_state: vec![E::Fr::zero(); params.state_width() as usize], - mode: op + mode: op, } } - pub fn specialize( - &mut self, - dst: u8 - ) { + pub fn specialize(&mut self, dst: u8) { match self.mode { RescueOpMode::AccumulatingToAbsorb(ref into) => { assert_eq!(into.len(), 0, "can not specialize sponge that absorbed something") - }, + } _ => { panic!("can not specialized sponge in squeezing state"); } @@ -441,14 +420,11 @@ impl<'a, E: RescueEngine> StatefulRescue<'a, E> { self.internal_state[last_state_elem_idx] = as_fe; } - pub fn absorb_single_value( - &mut self, - value: E::Fr - ) { + pub fn absorb_single_value(&mut self, value: E::Fr) { match self.mode { RescueOpMode::AccumulatingToAbsorb(ref mut into) => { // two cases - // either we have accumulated enough already and should to + // either we have accumulated enough already and should to // a mimc round before accumulating more, or just accumulate more let rate = self.params.rate() as usize; if into.len() < rate { @@ -463,7 +439,7 @@ impl<'a, E: RescueEngine> StatefulRescue<'a, E> { into.truncate(0); into.push(value); } - }, + } RescueOpMode::SqueezedInto(_) => { // we don't need anything from the output, so it's dropped @@ -476,10 +452,7 @@ impl<'a, E: RescueEngine> StatefulRescue<'a, E> { } } - pub fn absorb( - &mut self, - input: &[E::Fr] - ) { + pub fn absorb(&mut self, input: &[E::Fr]) { assert!(input.len() > 0); let rate = self.params.rate() as usize; let mut absorbtion_cycles = input.len() / rate; @@ -503,20 +476,18 @@ impl<'a, E: RescueEngine> StatefulRescue<'a, E> { if into.len() != rate { into.resize(rate, E::Fr::one()); } - }, + } RescueOpMode::SqueezedInto(_) => {} } } - pub fn squeeze_out_single( - &mut self, - ) -> E::Fr { + pub fn squeeze_out_single(&mut self) -> E::Fr { match self.mode { RescueOpMode::AccumulatingToAbsorb(ref mut into) => { let rate = self.params.rate() as usize; assert_eq!(into.len(), rate, "padding was necessary!"); // two cases - // either we have accumulated enough already and should to + // either we have accumulated enough already and should to // a mimc round before accumulating more, or just accumulate more for i in 0..rate { self.internal_state[i].add_assign(&into[i]); @@ -531,7 +502,7 @@ impl<'a, E: RescueEngine> StatefulRescue<'a, E> { self.mode = op; return output; - }, + } RescueOpMode::SqueezedInto(ref mut into) => { assert!(into.len() > 0, "squeezed state is depleted!"); let output = into.drain(0..1).next().unwrap(); @@ -541,4 +512,3 @@ impl<'a, E: RescueEngine> StatefulRescue<'a, E> { } } } - diff --git a/crates/franklin-crypto/src/util.rs b/crates/franklin-crypto/src/util.rs index af6d5e1..f80cd92 100644 --- a/crates/franklin-crypto/src/util.rs +++ b/crates/franklin-crypto/src/util.rs @@ -1,10 +1,10 @@ use blake2_rfc::blake2b::Blake2b; use blake2_rfc::blake2s::Blake2s; -use sha2::{Sha256, Digest}; +use sha2::{Digest, Sha256}; +use crate::plonk::circuit::multieq; use jubjub::{JubjubEngine, ToUniform}; use rescue::{self, RescueEngine}; -use crate::plonk::circuit::multieq; pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> E::Fs { let mut hasher = Blake2b::with_params(64, &[], &[], persona); @@ -31,15 +31,10 @@ pub fn sha256_hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8] E::Fs::to_uniform_32(result.as_slice()) } -pub fn rescue_hash_to_scalar( - persona: &[u8], - a: &[u8], - b: &[u8], - params: &::Params -) -> E::Fs { +pub fn rescue_hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8], params: &::Params) -> E::Fs { use crate::rescue::RescueHashParams; - use bellman::{Field, PrimeField}; use bellman::pairing::ff::BitIterator; + use bellman::{Field, PrimeField}; assert!(params.rate() >= 2, "we will need to squeeze twice"); @@ -85,6 +80,6 @@ pub fn rescue_hash_to_scalar( } current.double(); } - + scalar -} \ No newline at end of file +} diff --git a/crates/pairing/benches/bls12_381/ec.rs b/crates/pairing/benches/bls12_381/ec.rs index cbd0590..8aca108 100644 --- a/crates/pairing/benches/bls12_381/ec.rs +++ b/crates/pairing/benches/bls12_381/ec.rs @@ -10,9 +10,7 @@ mod g1 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G1, Fr)> = (0..SAMPLES) - .map(|_| (G1::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(G1, Fr)> = (0..SAMPLES).map(|_| (G1::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -29,9 +27,7 @@ mod g1 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G1, G1)> = (0..SAMPLES) - .map(|_| (G1::rand(&mut rng), G1::rand(&mut rng))) - .collect(); + let v: Vec<(G1, G1)> = (0..SAMPLES).map(|_| (G1::rand(&mut rng), G1::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -48,9 +44,7 @@ mod g1 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G1, G1Affine)> = (0..SAMPLES) - .map(|_| (G1::rand(&mut rng), G1::rand(&mut rng).into())) - .collect(); + let v: Vec<(G1, G1Affine)> = (0..SAMPLES).map(|_| (G1::rand(&mut rng), G1::rand(&mut rng).into())).collect(); let mut count = 0; b.iter(|| { @@ -74,9 +68,7 @@ mod g2 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G2, Fr)> = (0..SAMPLES) - .map(|_| (G2::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(G2, Fr)> = (0..SAMPLES).map(|_| (G2::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -93,9 +85,7 @@ mod g2 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G2, G2)> = (0..SAMPLES) - .map(|_| (G2::rand(&mut rng), G2::rand(&mut rng))) - .collect(); + let v: Vec<(G2, G2)> = (0..SAMPLES).map(|_| (G2::rand(&mut rng), G2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -112,9 +102,7 @@ mod g2 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G2, G2Affine)> = (0..SAMPLES) - .map(|_| (G2::rand(&mut rng), G2::rand(&mut rng).into())) - .collect(); + let v: Vec<(G2, G2Affine)> = (0..SAMPLES).map(|_| (G2::rand(&mut rng), G2::rand(&mut rng).into())).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bls12_381/fq.rs b/crates/pairing/benches/bls12_381/fq.rs index 053a10c..2f901bb 100644 --- a/crates/pairing/benches/bls12_381/fq.rs +++ b/crates/pairing/benches/bls12_381/fq.rs @@ -114,9 +114,7 @@ fn bench_fq_add_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq, Fq)> = (0..SAMPLES) - .map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))) - .collect(); + let v: Vec<(Fq, Fq)> = (0..SAMPLES).map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -133,9 +131,7 @@ fn bench_fq_sub_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq, Fq)> = (0..SAMPLES) - .map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))) - .collect(); + let v: Vec<(Fq, Fq)> = (0..SAMPLES).map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -152,9 +148,7 @@ fn bench_fq_mul_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq, Fq)> = (0..SAMPLES) - .map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))) - .collect(); + let v: Vec<(Fq, Fq)> = (0..SAMPLES).map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -256,9 +250,7 @@ fn bench_fq_from_repr(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec = (0..SAMPLES) - .map(|_| Fq::rand(&mut rng).into_repr()) - .collect(); + let v: Vec = (0..SAMPLES).map(|_| Fq::rand(&mut rng).into_repr()).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bls12_381/fq12.rs b/crates/pairing/benches/bls12_381/fq12.rs index 84daca2..96d0d62 100644 --- a/crates/pairing/benches/bls12_381/fq12.rs +++ b/crates/pairing/benches/bls12_381/fq12.rs @@ -9,9 +9,7 @@ fn bench_fq12_add_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq12, Fq12)> = (0..SAMPLES) - .map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))) - .collect(); + let v: Vec<(Fq12, Fq12)> = (0..SAMPLES).map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -28,9 +26,7 @@ fn bench_fq12_sub_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq12, Fq12)> = (0..SAMPLES) - .map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))) - .collect(); + let v: Vec<(Fq12, Fq12)> = (0..SAMPLES).map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -47,9 +43,7 @@ fn bench_fq12_mul_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq12, Fq12)> = (0..SAMPLES) - .map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))) - .collect(); + let v: Vec<(Fq12, Fq12)> = (0..SAMPLES).map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bls12_381/fq2.rs b/crates/pairing/benches/bls12_381/fq2.rs index 521b6ab..b8c5433 100644 --- a/crates/pairing/benches/bls12_381/fq2.rs +++ b/crates/pairing/benches/bls12_381/fq2.rs @@ -9,9 +9,7 @@ fn bench_fq2_add_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq2, Fq2)> = (0..SAMPLES) - .map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))) - .collect(); + let v: Vec<(Fq2, Fq2)> = (0..SAMPLES).map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -28,9 +26,7 @@ fn bench_fq2_sub_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq2, Fq2)> = (0..SAMPLES) - .map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))) - .collect(); + let v: Vec<(Fq2, Fq2)> = (0..SAMPLES).map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -47,9 +43,7 @@ fn bench_fq2_mul_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq2, Fq2)> = (0..SAMPLES) - .map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))) - .collect(); + let v: Vec<(Fq2, Fq2)> = (0..SAMPLES).map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bls12_381/fr.rs b/crates/pairing/benches/bls12_381/fr.rs index 13b0d0e..6f1ac85 100644 --- a/crates/pairing/benches/bls12_381/fr.rs +++ b/crates/pairing/benches/bls12_381/fr.rs @@ -114,9 +114,7 @@ fn bench_fr_add_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fr, Fr)> = (0..SAMPLES) - .map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(Fr, Fr)> = (0..SAMPLES).map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -133,9 +131,7 @@ fn bench_fr_sub_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fr, Fr)> = (0..SAMPLES) - .map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(Fr, Fr)> = (0..SAMPLES).map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -152,9 +148,7 @@ fn bench_fr_mul_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fr, Fr)> = (0..SAMPLES) - .map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(Fr, Fr)> = (0..SAMPLES).map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -256,9 +250,7 @@ fn bench_fr_from_repr(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec = (0..SAMPLES) - .map(|_| Fr::rand(&mut rng).into_repr()) - .collect(); + let v: Vec = (0..SAMPLES).map(|_| Fr::rand(&mut rng).into_repr()).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bls12_381/mod.rs b/crates/pairing/benches/bls12_381/mod.rs index 9b46c85..4ece8e6 100644 --- a/crates/pairing/benches/bls12_381/mod.rs +++ b/crates/pairing/benches/bls12_381/mod.rs @@ -48,12 +48,7 @@ fn bench_pairing_miller_loop(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let v: Vec<(G1Prepared, G2Prepared)> = (0..SAMPLES) - .map(|_| { - ( - G1Affine::from(G1::rand(&mut rng)).prepare(), - G2Affine::from(G2::rand(&mut rng)).prepare(), - ) - }) + .map(|_| (G1Affine::from(G1::rand(&mut rng)).prepare(), G2Affine::from(G2::rand(&mut rng)).prepare())) .collect(); let mut count = 0; @@ -71,12 +66,7 @@ fn bench_pairing_final_exponentiation(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let v: Vec = (0..SAMPLES) - .map(|_| { - ( - G1Affine::from(G1::rand(&mut rng)).prepare(), - G2Affine::from(G2::rand(&mut rng)).prepare(), - ) - }) + .map(|_| (G1Affine::from(G1::rand(&mut rng)).prepare(), G2Affine::from(G2::rand(&mut rng)).prepare())) .map(|(ref p, ref q)| Bls12::miller_loop(&[(p, q)])) .collect(); @@ -94,9 +84,7 @@ fn bench_pairing_full(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G1, G2)> = (0..SAMPLES) - .map(|_| (G1::rand(&mut rng), G2::rand(&mut rng))) - .collect(); + let v: Vec<(G1, G2)> = (0..SAMPLES).map(|_| (G1::rand(&mut rng), G2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bn256/ec.rs b/crates/pairing/benches/bn256/ec.rs index b188f4c..cb83340 100644 --- a/crates/pairing/benches/bn256/ec.rs +++ b/crates/pairing/benches/bn256/ec.rs @@ -10,9 +10,7 @@ mod g1 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G1, Fr)> = (0..SAMPLES) - .map(|_| (G1::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(G1, Fr)> = (0..SAMPLES).map(|_| (G1::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -29,9 +27,7 @@ mod g1 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G1, G1)> = (0..SAMPLES) - .map(|_| (G1::rand(&mut rng), G1::rand(&mut rng))) - .collect(); + let v: Vec<(G1, G1)> = (0..SAMPLES).map(|_| (G1::rand(&mut rng), G1::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -48,9 +44,7 @@ mod g1 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G1, G1Affine)> = (0..SAMPLES) - .map(|_| (G1::rand(&mut rng), G1::rand(&mut rng).into())) - .collect(); + let v: Vec<(G1, G1Affine)> = (0..SAMPLES).map(|_| (G1::rand(&mut rng), G1::rand(&mut rng).into())).collect(); let mut count = 0; b.iter(|| { @@ -74,9 +68,7 @@ mod g2 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G2, Fr)> = (0..SAMPLES) - .map(|_| (G2::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(G2, Fr)> = (0..SAMPLES).map(|_| (G2::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -93,9 +85,7 @@ mod g2 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G2, G2)> = (0..SAMPLES) - .map(|_| (G2::rand(&mut rng), G2::rand(&mut rng))) - .collect(); + let v: Vec<(G2, G2)> = (0..SAMPLES).map(|_| (G2::rand(&mut rng), G2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -112,9 +102,7 @@ mod g2 { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G2, G2Affine)> = (0..SAMPLES) - .map(|_| (G2::rand(&mut rng), G2::rand(&mut rng).into())) - .collect(); + let v: Vec<(G2, G2Affine)> = (0..SAMPLES).map(|_| (G2::rand(&mut rng), G2::rand(&mut rng).into())).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bn256/fq.rs b/crates/pairing/benches/bn256/fq.rs index 85345b3..ecf5090 100644 --- a/crates/pairing/benches/bn256/fq.rs +++ b/crates/pairing/benches/bn256/fq.rs @@ -114,9 +114,7 @@ fn bench_fq_add_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq, Fq)> = (0..SAMPLES) - .map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))) - .collect(); + let v: Vec<(Fq, Fq)> = (0..SAMPLES).map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -133,9 +131,7 @@ fn bench_fq_sub_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq, Fq)> = (0..SAMPLES) - .map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))) - .collect(); + let v: Vec<(Fq, Fq)> = (0..SAMPLES).map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -152,9 +148,7 @@ fn bench_fq_mul_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq, Fq)> = (0..SAMPLES) - .map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))) - .collect(); + let v: Vec<(Fq, Fq)> = (0..SAMPLES).map(|_| (Fq::rand(&mut rng), Fq::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -256,9 +250,7 @@ fn bench_fq_from_repr(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec = (0..SAMPLES) - .map(|_| Fq::rand(&mut rng).into_repr()) - .collect(); + let v: Vec = (0..SAMPLES).map(|_| Fq::rand(&mut rng).into_repr()).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bn256/fq12.rs b/crates/pairing/benches/bn256/fq12.rs index 42fca9d..f750fb4 100644 --- a/crates/pairing/benches/bn256/fq12.rs +++ b/crates/pairing/benches/bn256/fq12.rs @@ -9,9 +9,7 @@ fn bench_fq12_add_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq12, Fq12)> = (0..SAMPLES) - .map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))) - .collect(); + let v: Vec<(Fq12, Fq12)> = (0..SAMPLES).map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -28,9 +26,7 @@ fn bench_fq12_sub_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq12, Fq12)> = (0..SAMPLES) - .map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))) - .collect(); + let v: Vec<(Fq12, Fq12)> = (0..SAMPLES).map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -47,9 +43,7 @@ fn bench_fq12_mul_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq12, Fq12)> = (0..SAMPLES) - .map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))) - .collect(); + let v: Vec<(Fq12, Fq12)> = (0..SAMPLES).map(|_| (Fq12::rand(&mut rng), Fq12::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bn256/fq2.rs b/crates/pairing/benches/bn256/fq2.rs index ee592ca..415d28d 100644 --- a/crates/pairing/benches/bn256/fq2.rs +++ b/crates/pairing/benches/bn256/fq2.rs @@ -9,9 +9,7 @@ fn bench_fq2_add_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq2, Fq2)> = (0..SAMPLES) - .map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))) - .collect(); + let v: Vec<(Fq2, Fq2)> = (0..SAMPLES).map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -28,9 +26,7 @@ fn bench_fq2_sub_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq2, Fq2)> = (0..SAMPLES) - .map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))) - .collect(); + let v: Vec<(Fq2, Fq2)> = (0..SAMPLES).map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -47,9 +43,7 @@ fn bench_fq2_mul_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fq2, Fq2)> = (0..SAMPLES) - .map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))) - .collect(); + let v: Vec<(Fq2, Fq2)> = (0..SAMPLES).map(|_| (Fq2::rand(&mut rng), Fq2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bn256/fr.rs b/crates/pairing/benches/bn256/fr.rs index 62f0fe7..059f604 100644 --- a/crates/pairing/benches/bn256/fr.rs +++ b/crates/pairing/benches/bn256/fr.rs @@ -114,9 +114,7 @@ fn bench_fr_add_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fr, Fr)> = (0..SAMPLES) - .map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(Fr, Fr)> = (0..SAMPLES).map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -133,9 +131,7 @@ fn bench_fr_sub_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fr, Fr)> = (0..SAMPLES) - .map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(Fr, Fr)> = (0..SAMPLES).map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -152,9 +148,7 @@ fn bench_fr_mul_assign(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(Fr, Fr)> = (0..SAMPLES) - .map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))) - .collect(); + let v: Vec<(Fr, Fr)> = (0..SAMPLES).map(|_| (Fr::rand(&mut rng), Fr::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { @@ -256,9 +250,7 @@ fn bench_fr_from_repr(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec = (0..SAMPLES) - .map(|_| Fr::rand(&mut rng).into_repr()) - .collect(); + let v: Vec = (0..SAMPLES).map(|_| Fr::rand(&mut rng).into_repr()).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/benches/bn256/mod.rs b/crates/pairing/benches/bn256/mod.rs index 3559cca..075b564 100644 --- a/crates/pairing/benches/bn256/mod.rs +++ b/crates/pairing/benches/bn256/mod.rs @@ -48,12 +48,7 @@ fn bench_pairing_miller_loop(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let v: Vec<(G1Prepared, G2Prepared)> = (0..SAMPLES) - .map(|_| { - ( - G1Affine::from(G1::rand(&mut rng)).prepare(), - G2Affine::from(G2::rand(&mut rng)).prepare(), - ) - }) + .map(|_| (G1Affine::from(G1::rand(&mut rng)).prepare(), G2Affine::from(G2::rand(&mut rng)).prepare())) .collect(); let mut count = 0; @@ -71,12 +66,7 @@ fn bench_pairing_final_exponentiation(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); let v: Vec = (0..SAMPLES) - .map(|_| { - ( - G1Affine::from(G1::rand(&mut rng)).prepare(), - G2Affine::from(G2::rand(&mut rng)).prepare(), - ) - }) + .map(|_| (G1Affine::from(G1::rand(&mut rng)).prepare(), G2Affine::from(G2::rand(&mut rng)).prepare())) .map(|(ref p, ref q)| Bn256::miller_loop(&[(p, q)])) .collect(); @@ -94,9 +84,7 @@ fn bench_pairing_full(b: &mut ::test::Bencher) { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let v: Vec<(G1, G2)> = (0..SAMPLES) - .map(|_| (G1::rand(&mut rng), G2::rand(&mut rng))) - .collect(); + let v: Vec<(G1, G2)> = (0..SAMPLES).map(|_| (G1::rand(&mut rng), G2::rand(&mut rng))).collect(); let mut count = 0; b.iter(|| { diff --git a/crates/pairing/src/base.rs b/crates/pairing/src/base.rs index 137e91f..71912e3 100644 --- a/crates/pairing/src/base.rs +++ b/crates/pairing/src/base.rs @@ -4,19 +4,7 @@ use std::fmt; /// Projective representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. -pub trait GenericCurveProjective: - PartialEq - + Eq - + Sized - + Copy - + Clone - + Send - + Sync - + fmt::Debug - + fmt::Display - + rand::Rand - + 'static -{ +pub trait GenericCurveProjective: PartialEq + Eq + Sized + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + rand::Rand + 'static { type Scalar: PrimeField; type Base: SqrtField; type Affine: GenericCurveAffine; @@ -76,7 +64,7 @@ pub trait GenericCurveProjective: fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) { unimplemented!("default implementation does not exist for this function") } - + /// Returns underlying X, Y and Z coordinates. Users should check for infinity /// outside of this call fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) { @@ -98,9 +86,7 @@ pub trait GenericCurveProjective: /// Affine representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. -pub trait GenericCurveAffine: - Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static -{ +pub trait GenericCurveAffine: Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static { type Scalar: PrimeField; type Base: SqrtField; type Projective: GenericCurveProjective; @@ -127,7 +113,7 @@ pub trait GenericCurveAffine: /// Returns references to underlying X and Y coordinates. Users should check for infinity /// outside of this call fn as_xy(&self) -> (&Self::Base, &Self::Base); - + /// Returns underlying X and Y coordinates. Users should check for infinity /// outside of this call fn into_xy_unchecked(self) -> (Self::Base, Self::Base); @@ -175,9 +161,9 @@ pub trait GenericRawEncodable: GenericUncompressedEncodable { } #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] -pub struct EncodingBytes{ +pub struct EncodingBytes { bytes: [u8; N], - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } impl AsRef<[u8]> for EncodingBytes { @@ -197,7 +183,7 @@ impl EncodingBytes { pub fn empty() -> Self { Self { bytes: [0u8; N], - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } @@ -215,7 +201,7 @@ impl EncodingBytes { pub fn from_bytes(bytes: [u8; N]) -> Self { Self { bytes, - _marker: std::marker::PhantomData + _marker: std::marker::PhantomData, } } } @@ -260,7 +246,7 @@ impl GenericCurveAffine for G { fn as_xy(&self) -> (&Self::Base, &Self::Base) { ::as_xy(&self) } - + /// Returns underlying X and Y coordinates. Users should check for infinity /// outside of this call fn into_xy_unchecked(self) -> (Self::Base, Self::Base) { @@ -312,7 +298,7 @@ impl GenericCurveProjective for G { /// Normalizes a slice of projective elements so that /// conversion to affine is cheap. - fn batch_normalization(v: &mut [Self]){ + fn batch_normalization(v: &mut [Self]) { ::batch_normalization(v) } @@ -374,7 +360,7 @@ impl GenericCurveProjective for G { fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) { ::as_xyz(self) } - + /// Returns underlying X, Y and Z coordinates. Users should check for infinity /// outside of this call fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) { @@ -392,4 +378,4 @@ impl GenericCurveProjective for G { fn from_xyz_checked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Result { ::from_xyz_checked(_x, _y, _z) } -} \ No newline at end of file +} diff --git a/crates/pairing/src/bls12_381/ec.rs b/crates/pairing/src/bls12_381/ec.rs index 44efb5e..5e27d81 100644 --- a/crates/pairing/src/bls12_381/ec.rs +++ b/crates/pairing/src/bls12_381/ec.rs @@ -14,11 +14,10 @@ macro_rules! curve_impl { pub struct $affine { pub(crate) x: $basefield, pub(crate) y: $basefield, - pub(crate) infinity: bool + pub(crate) infinity: bool, } - impl ::std::fmt::Display for $affine - { + impl ::std::fmt::Display for $affine { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { if self.infinity { write!(f, "{}(Infinity)", $name) @@ -30,13 +29,12 @@ macro_rules! curve_impl { #[derive(Copy, Clone, Debug, Eq)] pub struct $projective { - pub(crate) x: $basefield, - pub(crate) y: $basefield, - pub(crate) z: $basefield + pub(crate) x: $basefield, + pub(crate) y: $basefield, + pub(crate) z: $basefield, } - impl ::std::fmt::Display for $projective - { + impl ::std::fmt::Display for $projective { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "{}", self.into_affine()) } @@ -89,7 +87,9 @@ macro_rules! curve_impl { let mut res = $projective::zero(); for i in bits { res.double(); - if i { res.add_assign_mixed(self) } + if i { + res.add_assign_mixed(self) + } } res } @@ -112,12 +112,8 @@ macro_rules! curve_impl { $affine { x: x, - y: if (y < negy) ^ greatest { - y - } else { - negy - }, - infinity: false + y: if (y < negy) ^ greatest { y } else { negy }, + infinity: false, } }) } @@ -159,7 +155,7 @@ macro_rules! curve_impl { $affine { x: $basefield::zero(), y: $basefield::one(), - infinity: true + infinity: true, } } @@ -198,7 +194,7 @@ macro_rules! curve_impl { fn as_xy(&self) -> (&Self::Base, &Self::Base) { (&self.x, &self.y) } - + #[inline(always)] fn into_xy_unchecked(self) -> (Self::Base, Self::Base) { (self.x, self.y) @@ -207,20 +203,12 @@ macro_rules! curve_impl { #[inline(always)] fn from_xy_unchecked(x: Self::Base, y: Self::Base) -> Self { let infinity = x.is_zero() && y.is_zero(); - Self { - x: x, - y: y, - infinity - } + Self { x: x, y: y, infinity } } fn from_xy_checked(x: Self::Base, y: Self::Base) -> Result { let infinity = x.is_zero() && y.is_zero(); - let affine = Self { - x: x, - y: y, - infinity - }; + let affine = Self { x: x, y: y, infinity }; if !affine.is_on_curve() { Err(GroupDecodingError::NotOnCurve) @@ -267,7 +255,7 @@ macro_rules! curve_impl { $projective { x: $basefield::zero(), y: $basefield::one(), - z: $basefield::zero() + z: $basefield::zero(), } } @@ -285,8 +273,7 @@ macro_rules! curve_impl { self.is_zero() || self.z == $basefield::one() } - fn batch_normalization(v: &mut [Self]) - { + fn batch_normalization(v: &mut [Self]) { // Montgomery’s Trick and Fast Implementation of Masked AES // Genelle, Prouff and Quisquater // Section 3.2 @@ -294,9 +281,10 @@ macro_rules! curve_impl { // First pass: compute [a, ab, abc, ...] let mut prod = Vec::with_capacity(v.len()); let mut tmp = $basefield::one(); - for g in v.iter_mut() - // Ignore normalized elements - .filter(|g| !g.is_normalized()) + for g in v + .iter_mut() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) { tmp.mul_assign(&g.z); prod.push(tmp); @@ -306,13 +294,14 @@ macro_rules! curve_impl { tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero. // Second pass: iterate backwards to compute inverses - for (g, s) in v.iter_mut() - // Backwards - .rev() - // Ignore normalized elements - .filter(|g| !g.is_normalized()) - // Backwards, skip last element, fill in one for last term. - .zip(prod.into_iter().rev().skip(1).chain(Some($basefield::one()))) + for (g, s) in v + .iter_mut() + // Backwards + .rev() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) + // Backwards, skip last element, fill in one for last term. + .zip(prod.into_iter().rev().skip(1).chain(Some($basefield::one()))) { // tmp := tmp * g.z; g.z := tmp * s = 1/z let mut newtmp = tmp; @@ -323,9 +312,7 @@ macro_rules! curve_impl { } // Perform affine transformations - for g in v.iter_mut() - .filter(|g| !g.is_normalized()) - { + for g in v.iter_mut().filter(|g| !g.is_normalized()) { let mut z = g.z; // 1/z z.square(); // 1/z^2 g.x.mul_assign(&z); // x/z^2 @@ -578,8 +565,7 @@ macro_rules! curve_impl { let mut found_one = false; - for i in BitIterator::new(other.into()) - { + for i in BitIterator::new(other.into()) { if found_one { res.double(); } else { @@ -609,17 +595,13 @@ macro_rules! curve_impl { fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) { (&self.x, &self.y, &self.z) } - + fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) { (self.x, self.y, self.z) } fn from_xyz_unchecked(x: Self::Base, y: Self::Base, z: Self::Base) -> Self { - Self { - x, - y, - z - } + Self { x, y, z } } fn from_xyz_checked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Result { @@ -637,7 +619,7 @@ macro_rules! curve_impl { $projective { x: p.x, y: p.y, - z: $basefield::one() + z: $basefield::one(), } } } @@ -651,11 +633,7 @@ macro_rules! curve_impl { $affine::zero() } else if p.z == $basefield::one() { // If Z is one, the point is already normalized. - $affine { - x: p.x, - y: p.y, - infinity: false - } + $affine { x: p.x, y: p.y, infinity: false } } else { // Z is nonzero, so it must have an inverse in a field. let zinv = p.z.inverse().unwrap(); @@ -671,36 +649,22 @@ macro_rules! curve_impl { zinv_powered.mul_assign(&zinv); y.mul_assign(&zinv_powered); - $affine { - x: x, - y: y, - infinity: false - } + $affine { x: x, y: y, infinity: false } } } } - } + }; } pub mod g1 { use super::super::{Bls12, Fq, Fq12, FqRepr, Fr, FrRepr}; use super::g2::G2Affine; + use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError, RawEncodable}; use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; use rand::{Rand, Rng}; use std::fmt; - use crate::{RawEncodable, CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError}; - - curve_impl!( - "G1", - G1, - G1Affine, - G1Prepared, - Fq, - Fr, - G1Uncompressed, - G1Compressed, - G2Affine - ); + + curve_impl!("G1", G1, G1Affine, G1Prepared, Fq, Fr, G1Uncompressed, G1Compressed, G2Affine); #[derive(Copy, Clone)] pub struct G1Uncompressed([u8; 96]); @@ -756,7 +720,6 @@ pub mod g1 { self.0[..].fmt(formatter) } } - impl EncodedPoint for G1Uncompressed { type Affine = G1Affine; @@ -819,12 +782,8 @@ pub mod g1 { } Ok(G1Affine { - x: Fq::from_repr(x).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate", e) - })?, - y: Fq::from_repr(y).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate", e) - })?, + x: Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?, + y: Fq::from_repr(y).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate", e))?, infinity: false, }) } @@ -860,10 +819,7 @@ pub mod g1 { res } - fn from_raw_uncompressed_le_unchecked( - encoded: &Self::Uncompressed, - _infinity: bool - ) -> Result { + fn from_raw_uncompressed_le_unchecked(encoded: &Self::Uncompressed, _infinity: bool) -> Result { let copy = encoded.0; if copy.iter().all(|b| *b == 0) { return Ok(Self::zero()); @@ -879,12 +835,8 @@ pub mod g1 { } Ok(G1Affine { - x: Fq::from_raw_repr(x).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate", e) - })?, - y: Fq::from_raw_repr(y).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate", e) - })?, + x: Fq::from_raw_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?, + y: Fq::from_raw_repr(y).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate", e))?, infinity: false, }) } @@ -978,8 +930,7 @@ pub mod g1 { } // Interpret as Fq element. - let x = Fq::from_repr(x) - .map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?; + let x = Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?; G1Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve) } @@ -1053,8 +1004,7 @@ pub mod g1 { } fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { - const RECOMMENDATIONS: [usize; 12] = - [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; + const RECOMMENDATIONS: [usize; 12] = [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; let mut ret = 4; for r in &RECOMMENDATIONS { @@ -1137,7 +1087,8 @@ pub mod g1 { 0x9fe83b1b4a5d648d, 0xf583cc5a508f6a40, 0xc3ad2aefde0bb13, - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0x60aa6f9552f03aae, 0xecd01d5181300d35, @@ -1145,7 +1096,8 @@ pub mod g1 { 0xe760f57922998c9d, 0x953703f5795a39e5, 0xfe3ae0922df702c, - ])).unwrap(), + ])) + .unwrap(), infinity: false, }; assert!(!p.is_on_curve()); @@ -1162,7 +1114,8 @@ pub mod g1 { 0xea034ee2928b30a8, 0xbd8833dc7c79a7f7, 0xe45c9f0c0438675, - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0x3b450eb1ab7b5dad, 0xa65cb81e975e8675, @@ -1170,7 +1123,8 @@ pub mod g1 { 0x753ddf21a2601d20, 0x532d0b640bd3ff8b, 0x118d2c543f031102, - ])).unwrap(), + ])) + .unwrap(), infinity: false, }; assert!(!p.is_on_curve()); @@ -1188,7 +1142,8 @@ pub mod g1 { 0xf35de9ce0d6b4e84, 0x265bddd23d1dec54, 0x12a8778088458308, - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0x8a22defa0d526256, 0xc57ca55456fcb9ae, @@ -1196,7 +1151,8 @@ pub mod g1 { 0x921beef89d4f29df, 0x5b6fda44ad85fa78, 0xed74ab9f302cbe0, - ])).unwrap(), + ])) + .unwrap(), infinity: false, }; assert!(p.is_on_curve()); @@ -1214,7 +1170,8 @@ pub mod g1 { 0x485e77d50a5df10d, 0x4c6fcac4b55fd479, 0x86ed4d9906fb064, - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0xd25ee6461538c65, 0x9f3bbb2ecd3719b9, @@ -1222,7 +1179,8 @@ pub mod g1 { 0xcefca68333c35288, 0x570c8005f8573fa6, 0x152ca696fe034442, - ])).unwrap(), + ])) + .unwrap(), z: Fq::one(), }; @@ -1234,7 +1192,8 @@ pub mod g1 { 0x5f44314ec5e3fb03, 0x24e8538737c6e675, 0x8abd623a594fba8, - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0x6b0528f088bb7044, 0x2fdeb5c82917ff9e, @@ -1242,7 +1201,8 @@ pub mod g1 { 0xd65104c6f95a872a, 0x1f2998a5a9c61253, 0xe74846154a9e44, - ])).unwrap(), + ])) + .unwrap(), z: Fq::one(), }); @@ -1258,7 +1218,8 @@ pub mod g1 { 0xc4f9a52a428e23bb, 0xd178b28dd4f407ef, 0x17fb8905e9183c69 - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0xd0de9d65292b7710, 0xf6a05f2bcf1d9ca7, @@ -1266,7 +1227,8 @@ pub mod g1 { 0xeec8d1a5b7466c58, 0x4bc362649dce6376, 0x430cbdc5455b00a - ])).unwrap(), + ])) + .unwrap(), infinity: false, } ); @@ -1282,7 +1244,8 @@ pub mod g1 { 0x485e77d50a5df10d, 0x4c6fcac4b55fd479, 0x86ed4d9906fb064, - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0xd25ee6461538c65, 0x9f3bbb2ecd3719b9, @@ -1290,7 +1253,8 @@ pub mod g1 { 0xcefca68333c35288, 0x570c8005f8573fa6, 0x152ca696fe034442, - ])).unwrap(), + ])) + .unwrap(), z: Fq::one(), }; @@ -1308,7 +1272,8 @@ pub mod g1 { 0x4b914c16687dcde0, 0x66c8baf177d20533, 0xaf960cff3d83833 - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0x3f0675695f5177a8, 0x2b6d82ae178a1ba0, @@ -1316,7 +1281,8 @@ pub mod g1 { 0x1771a65b60572f4e, 0x8b547c1313b27555, 0x135075589a687b1e - ])).unwrap(), + ])) + .unwrap(), infinity: false, } ); @@ -1339,7 +1305,8 @@ pub mod g1 { 0x71ffa8021531705, 0x7418d484386d267, 0xd5108d8ff1fbd6, - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0xa776ccbfe9981766, 0x255632964ff40f4a, @@ -1347,7 +1314,8 @@ pub mod g1 { 0x520f74773e74c8c3, 0x484c8fc982008f0, 0xee2c3d922008cc6, - ])).unwrap(), + ])) + .unwrap(), infinity: false, }; @@ -1359,7 +1327,8 @@ pub mod g1 { 0xc6e05201e5f83991, 0xf7c75910816f207c, 0x18d4043e78103106, - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0xa776ccbfe9981766, 0x255632964ff40f4a, @@ -1367,7 +1336,8 @@ pub mod g1 { 0x520f74773e74c8c3, 0x484c8fc982008f0, 0xee2c3d922008cc6, - ])).unwrap(), + ])) + .unwrap(), infinity: false, }; @@ -1382,7 +1352,8 @@ pub mod g1 { 0x9676ff02ec39c227, 0x4c12c15d7e55b9f3, 0x57fd1e317db9bd, - ])).unwrap(), + ])) + .unwrap(), y: Fq::from_repr(FqRepr([ 0x1288334016679345, 0xf955cd68615ff0b5, @@ -1390,7 +1361,8 @@ pub mod g1 { 0x1267d70db51049fb, 0x4696deb9ab2ba3e7, 0xb1e4e11177f59d4, - ])).unwrap(), + ])) + .unwrap(), infinity: false, }; @@ -1419,26 +1391,16 @@ pub mod g1 { pub mod g2 { use super::super::{Bls12, Fq, Fq12, Fq2, FqRepr, Fr, FrRepr}; use super::g1::G1Affine; + use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError}; use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; use rand::{Rand, Rng}; use std::fmt; - use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError}; - curve_impl!( - "G2", - G2, - G2Affine, - G2Prepared, - Fq2, - Fr, - G2Uncompressed, - G2Compressed, - G1Affine - ); + curve_impl!("G2", G2, G2Affine, G2Prepared, Fq2, Fr, G2Uncompressed, G2Compressed, G1Affine); #[derive(Copy, Clone)] pub struct G2Uncompressed([u8; 192]); - + impl Rand for G2 { fn rand(rng: &mut R) -> Self { loop { @@ -1547,20 +1509,12 @@ pub mod g2 { Ok(G2Affine { x: Fq2 { - c0: Fq::from_repr(x_c0).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e) - })?, - c1: Fq::from_repr(x_c1).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e) - })?, + c0: Fq::from_repr(x_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e))?, + c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))?, }, y: Fq2 { - c0: Fq::from_repr(y_c0).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate (c0)", e) - })?, - c1: Fq::from_repr(y_c1).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate (c1)", e) - })?, + c0: Fq::from_repr(y_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate (c0)", e))?, + c1: Fq::from_repr(y_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate (c1)", e))?, }, infinity: false, }) @@ -1667,12 +1621,8 @@ pub mod g2 { // Interpret as Fq element. let x = Fq2 { - c0: Fq::from_repr(x_c0).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e) - })?, - c1: Fq::from_repr(x_c1).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e) - })?, + c0: Fq::from_repr(x_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e))?, + c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))?, }; G2Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve) @@ -1767,8 +1717,7 @@ pub mod g2 { } fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { - const RECOMMENDATIONS: [usize; 11] = - [1, 3, 8, 20, 47, 126, 260, 826, 1501, 4555, 84071]; + const RECOMMENDATIONS: [usize; 11] = [1, 3, 8, 20, 47, 126, 260, 826, 1501, 4555, 84071]; let mut ret = 4; for r in &RECOMMENDATIONS { @@ -1843,7 +1792,8 @@ pub mod g2 { 0x7a17a004747e3dbe, 0xcc65406a7c2e5a73, 0x10b8c03d64db4d0c, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xd30e70fe2f029778, 0xda30772df0f5212e, @@ -1851,7 +1801,8 @@ pub mod g2 { 0xfb777e5b9b568608, 0x789bac1fec71a2b9, 0x1342f02e2da54405, - ])).unwrap(), + ])) + .unwrap(), }, y: Fq2 { c0: Fq::from_repr(FqRepr([ @@ -1861,7 +1812,8 @@ pub mod g2 { 0x663015d9410eb608, 0x78e82a79d829a544, 0x40a00545bb3c1e, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x4709802348e79377, 0xb5ac4dc9204bcfbd, @@ -1869,7 +1821,8 @@ pub mod g2 { 0x15008b1dc399e8df, 0x68128fd0548a3829, 0x16a613db5c873aaa, - ])).unwrap(), + ])) + .unwrap(), }, infinity: false, }; @@ -1888,7 +1841,8 @@ pub mod g2 { 0x41abba710d6c692c, 0xffcc4b2b62ce8484, 0x6993ec01b8934ed, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xb94e92d5f874e26, 0x44516408bc115d95, @@ -1896,7 +1850,8 @@ pub mod g2 { 0xa5a0c2b7131f3555, 0x83800965822367e7, 0x10cf1d3ad8d90bfa, - ])).unwrap(), + ])) + .unwrap(), }, y: Fq2 { c0: Fq::from_repr(FqRepr([ @@ -1906,7 +1861,8 @@ pub mod g2 { 0x5a9171720e73eb51, 0x38eb4fd8d658adb7, 0xb649051bbc1164d, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x9225814253d7df75, 0xc196c2513477f887, @@ -1914,7 +1870,8 @@ pub mod g2 { 0x55f2b8efad953e04, 0x7379345eda55265e, 0x377f2e6208fd4cb, - ])).unwrap(), + ])) + .unwrap(), }, infinity: false, }; @@ -1934,7 +1891,8 @@ pub mod g2 { 0x2199bc19c48c393d, 0x4a151b732a6075bf, 0x17762a3b9108c4a7, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x26f461e944bbd3d1, 0x298f3189a9cf6ed6, @@ -1942,7 +1900,8 @@ pub mod g2 { 0x7e147f3f9e6e241, 0x72a9b63583963fff, 0x158b0083c000462, - ])).unwrap(), + ])) + .unwrap(), }, y: Fq2 { c0: Fq::from_repr(FqRepr([ @@ -1952,7 +1911,8 @@ pub mod g2 { 0x68cad19430706b4d, 0x3ccfb97b924dcea8, 0x1660f93434588f8d, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xaaed3985b6dcb9c7, 0xc1e985d6d898d9f4, @@ -1960,7 +1920,8 @@ pub mod g2 { 0x3940a2dbb914b529, 0xbeb88137cf34f3e7, 0x1699ee577c61b694, - ])).unwrap(), + ])) + .unwrap(), }, infinity: false, }; @@ -1980,7 +1941,8 @@ pub mod g2 { 0x72556c999f3707ac, 0x4617f2e6774e9711, 0x100b2fe5bffe030b, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x7a33555977ec608, 0xe23039d1fe9c0881, @@ -1988,7 +1950,8 @@ pub mod g2 { 0x4637c4f417667e2e, 0x93ebe7c3e41f6acc, 0xde884f89a9a371b, - ])).unwrap(), + ])) + .unwrap(), }, y: Fq2 { c0: Fq::from_repr(FqRepr([ @@ -1998,7 +1961,8 @@ pub mod g2 { 0x25fd427b4122f231, 0xd83112aace35cae, 0x191b2432407cbb7f, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xf68ae82fe97662f5, 0xe986057068b50b7d, @@ -2006,7 +1970,8 @@ pub mod g2 { 0x9eaa6d19de569196, 0xf6a03d31e2ec2183, 0x3bdafaf7ca9b39b, - ])).unwrap(), + ])) + .unwrap(), }, z: Fq2::one(), }; @@ -2020,7 +1985,8 @@ pub mod g2 { 0x8e73a96b329ad190, 0x27c546f75ee1f3ab, 0xa33d27add5e7e82, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x93b1ebcd54870dfe, 0xf1578300e1342e11, @@ -2028,7 +1994,8 @@ pub mod g2 { 0x2089faf462438296, 0x828e5848cd48ea66, 0x141ecbac1deb038b, - ])).unwrap(), + ])) + .unwrap(), }, y: Fq2 { c0: Fq::from_repr(FqRepr([ @@ -2038,7 +2005,8 @@ pub mod g2 { 0x2767032fc37cc31d, 0xd5ee2aba84fd10fe, 0x16576ccd3dd0a4e8, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x4da9b6f6a96d1dd2, 0x9657f7da77f1650e, @@ -2046,7 +2014,8 @@ pub mod g2 { 0x31898db63f87363a, 0xabab040ddbd097cc, 0x11ad236b9ba02990, - ])).unwrap(), + ])) + .unwrap(), }, z: Fq2::one(), }); @@ -2064,7 +2033,8 @@ pub mod g2 { 0xf1273e6406eef9cc, 0xababd760ff05cb92, 0xd7c20456617e89 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xd1a50b8572cbd2b8, 0x238f0ac6119d07df, @@ -2072,7 +2042,8 @@ pub mod g2 { 0x8b203284c51edf6b, 0xc8a0b730bbb21f5e, 0x1a3b59d29a31274 - ])).unwrap(), + ])) + .unwrap(), }, y: Fq2 { c0: Fq::from_repr(FqRepr([ @@ -2082,7 +2053,8 @@ pub mod g2 { 0x64528ab3863633dc, 0x159384333d7cba97, 0x4cb84741f3cafe8 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x242af0dc3640e1a4, 0xe90a73ad65c66919, @@ -2090,7 +2062,8 @@ pub mod g2 { 0x38528f92b689644d, 0xb6884deec59fb21f, 0x3c075d3ec52ba90 - ])).unwrap(), + ])) + .unwrap(), }, infinity: false, } @@ -2108,7 +2081,8 @@ pub mod g2 { 0x72556c999f3707ac, 0x4617f2e6774e9711, 0x100b2fe5bffe030b, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x7a33555977ec608, 0xe23039d1fe9c0881, @@ -2116,7 +2090,8 @@ pub mod g2 { 0x4637c4f417667e2e, 0x93ebe7c3e41f6acc, 0xde884f89a9a371b, - ])).unwrap(), + ])) + .unwrap(), }, y: Fq2 { c0: Fq::from_repr(FqRepr([ @@ -2126,7 +2101,8 @@ pub mod g2 { 0x25fd427b4122f231, 0xd83112aace35cae, 0x191b2432407cbb7f, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xf68ae82fe97662f5, 0xe986057068b50b7d, @@ -2134,7 +2110,8 @@ pub mod g2 { 0x9eaa6d19de569196, 0xf6a03d31e2ec2183, 0x3bdafaf7ca9b39b, - ])).unwrap(), + ])) + .unwrap(), }, z: Fq2::one(), }; @@ -2154,7 +2131,8 @@ pub mod g2 { 0xbcedcfce1e52d986, 0x9755d4a3926e9862, 0x18bab73760fd8024 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x4e7c5e0a2ae5b99e, 0x96e582a27f028961, @@ -2162,7 +2140,8 @@ pub mod g2 { 0xeb0cf5e610ef4fe7, 0x7b4c2bae8db6e70b, 0xf136e43909fca0 - ])).unwrap(), + ])) + .unwrap(), }, y: Fq2 { c0: Fq::from_repr(FqRepr([ @@ -2172,7 +2151,8 @@ pub mod g2 { 0xa5a2a51f7fde787b, 0x8b92866bc6384188, 0x81a53fe531d64ef - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x4c5d607666239b34, 0xeddb5f48304d14b3, @@ -2180,7 +2160,8 @@ pub mod g2 { 0xb271f52f12ead742, 0x244e6c2015c83348, 0x19e2deae6eb9b441 - ])).unwrap(), + ])) + .unwrap(), }, infinity: false, } diff --git a/crates/pairing/src/bls12_381/fq.rs b/crates/pairing/src/bls12_381/fq.rs index 964c659..d4da5bb 100644 --- a/crates/pairing/src/bls12_381/fq.rs +++ b/crates/pairing/src/bls12_381/fq.rs @@ -92,7 +92,7 @@ pub const FROBENIUS_COEFF_FQ2_C1: [Fq; 2] = [ 0x40ab3263eff0206, ])), ]; - // Fq2(u + 1)**(((q^1) - 1) / 2)**-1 +// Fq2(u + 1)**(((q^1) - 1) / 2)**-1 pub const XI_TO_Q_MINUS_1_OVER_2_: Fq2 = Fq2 { c0: Fq(FqRepr([ 0x3e2f585da55c9ad1, @@ -480,32 +480,15 @@ fn test_frob_coeffs() { assert_eq!(FROBENIUS_COEFF_FQ2_C1[0], Fq::one()); assert_eq!( FROBENIUS_COEFF_FQ2_C1[1], - nqr.pow([ - 0xdcff7fffffffd555, - 0xf55ffff58a9ffff, - 0xb39869507b587b12, - 0xb23ba5c279c2895f, - 0x258dd3db21a5d66b, - 0xd0088f51cbff34d - ]) + nqr.pow([0xdcff7fffffffd555, 0xf55ffff58a9ffff, 0xb39869507b587b12, 0xb23ba5c279c2895f, 0x258dd3db21a5d66b, 0xd0088f51cbff34d]) ); - let nqr = Fq2 { - c0: Fq::one(), - c1: Fq::one(), - }; + let nqr = Fq2 { c0: Fq::one(), c1: Fq::one() }; assert_eq!(FROBENIUS_COEFF_FQ6_C1[0], Fq2::one()); assert_eq!( FROBENIUS_COEFF_FQ6_C1[1], - nqr.pow([ - 0x9354ffffffffe38e, - 0xa395554e5c6aaaa, - 0xcd104635a790520c, - 0xcc27c3d6fbd7063f, - 0x190937e76bc3e447, - 0x8ab05f8bdd54cde - ]) + nqr.pow([0x9354ffffffffe38e, 0xa395554e5c6aaaa, 0xcd104635a790520c, 0xcc27c3d6fbd7063f, 0x190937e76bc3e447, 0x8ab05f8bdd54cde]) ); assert_eq!( FROBENIUS_COEFF_FQ6_C1[2], @@ -615,14 +598,7 @@ fn test_frob_coeffs() { assert_eq!(FROBENIUS_COEFF_FQ6_C2[0], Fq2::one()); assert_eq!( FROBENIUS_COEFF_FQ6_C2[1], - nqr.pow([ - 0x26a9ffffffffc71c, - 0x1472aaa9cb8d5555, - 0x9a208c6b4f20a418, - 0x984f87adf7ae0c7f, - 0x32126fced787c88f, - 0x11560bf17baa99bc - ]) + nqr.pow([0x26a9ffffffffc71c, 0x1472aaa9cb8d5555, 0x9a208c6b4f20a418, 0x984f87adf7ae0c7f, 0x32126fced787c88f, 0x11560bf17baa99bc]) ); assert_eq!( FROBENIUS_COEFF_FQ6_C2[2], @@ -732,14 +708,7 @@ fn test_frob_coeffs() { assert_eq!(FROBENIUS_COEFF_FQ12_C1[0], Fq2::one()); assert_eq!( FROBENIUS_COEFF_FQ12_C1[1], - nqr.pow([ - 0x49aa7ffffffff1c7, - 0x51caaaa72e35555, - 0xe688231ad3c82906, - 0xe613e1eb7deb831f, - 0xc849bf3b5e1f223, - 0x45582fc5eeaa66f - ]) + nqr.pow([0x49aa7ffffffff1c7, 0x51caaaa72e35555, 0xe688231ad3c82906, 0xe613e1eb7deb831f, 0xc849bf3b5e1f223, 0x45582fc5eeaa66f]) ); assert_eq!( FROBENIUS_COEFF_FQ12_C1[2], @@ -1208,30 +1177,12 @@ fn test_fq_repr_ordering() { assert!(b > a); } - assert_equality( - FqRepr([9999, 9999, 9999, 9999, 9999, 9999]), - FqRepr([9999, 9999, 9999, 9999, 9999, 9999]), - ); - assert_equality( - FqRepr([9999, 9998, 9999, 9999, 9999, 9999]), - FqRepr([9999, 9998, 9999, 9999, 9999, 9999]), - ); - assert_equality( - FqRepr([9999, 9999, 9999, 9997, 9999, 9999]), - FqRepr([9999, 9999, 9999, 9997, 9999, 9999]), - ); - assert_lt( - FqRepr([9999, 9999, 9999, 9997, 9999, 9998]), - FqRepr([9999, 9999, 9999, 9997, 9999, 9999]), - ); - assert_lt( - FqRepr([9999, 9999, 9999, 9997, 9998, 9999]), - FqRepr([9999, 9999, 9999, 9997, 9999, 9999]), - ); - assert_lt( - FqRepr([9, 9999, 9999, 9997, 9998, 9999]), - FqRepr([9999, 9999, 9999, 9997, 9999, 9999]), - ); + assert_equality(FqRepr([9999, 9999, 9999, 9999, 9999, 9999]), FqRepr([9999, 9999, 9999, 9999, 9999, 9999])); + assert_equality(FqRepr([9999, 9998, 9999, 9999, 9999, 9999]), FqRepr([9999, 9998, 9999, 9999, 9999, 9999])); + assert_equality(FqRepr([9999, 9999, 9999, 9997, 9999, 9999]), FqRepr([9999, 9999, 9999, 9997, 9999, 9999])); + assert_lt(FqRepr([9999, 9999, 9999, 9997, 9999, 9998]), FqRepr([9999, 9999, 9999, 9997, 9999, 9999])); + assert_lt(FqRepr([9999, 9999, 9999, 9997, 9998, 9999]), FqRepr([9999, 9999, 9999, 9997, 9999, 9999])); + assert_lt(FqRepr([9, 9999, 9999, 9997, 9998, 9999]), FqRepr([9999, 9999, 9999, 9997, 9999, 9999])); } #[test] @@ -1260,39 +1211,18 @@ fn test_fq_repr_is_zero() { #[test] fn test_fq_repr_div2() { - let mut a = FqRepr([ - 0x8b0ad39f8dd7482a, - 0x147221c9a7178b69, - 0x54764cb08d8a6aa0, - 0x8519d708e1d83041, - 0x41f82777bd13fdb, - 0xf43944578f9b771b, - ]); + let mut a = FqRepr([0x8b0ad39f8dd7482a, 0x147221c9a7178b69, 0x54764cb08d8a6aa0, 0x8519d708e1d83041, 0x41f82777bd13fdb, 0xf43944578f9b771b]); a.div2(); assert_eq!( a, - FqRepr([ - 0xc58569cfc6eba415, - 0xa3910e4d38bc5b4, - 0xaa3b265846c53550, - 0xc28ceb8470ec1820, - 0x820fc13bbde89fed, - 0x7a1ca22bc7cdbb8d - ]) + FqRepr([0xc58569cfc6eba415, 0xa3910e4d38bc5b4, 0xaa3b265846c53550, 0xc28ceb8470ec1820, 0x820fc13bbde89fed, 0x7a1ca22bc7cdbb8d]) ); for _ in 0..10 { a.div2(); } assert_eq!( a, - FqRepr([ - 0x6d31615a73f1bae9, - 0x54028e443934e2f1, - 0x82a8ec99611b14d, - 0xfb70a33ae11c3b06, - 0xe36083f04eef7a27, - 0x1e87288af1f36e - ]) + FqRepr([0x6d31615a73f1bae9, 0x54028e443934e2f1, 0x82a8ec99611b14d, 0xfb70a33ae11c3b06, 0xe36083f04eef7a27, 0x1e87288af1f36e]) ); for _ in 0..300 { a.div2(); @@ -1312,67 +1242,23 @@ fn test_fq_repr_div2() { #[test] fn test_fq_repr_shr() { - let mut a = FqRepr([ - 0xaa5cdd6172847ffd, - 0x43242c06aed55287, - 0x9ddd5b312f3dd104, - 0xc5541fd48046b7e7, - 0x16080cf4071e0b05, - 0x1225f2901aea514e, - ]); + let mut a = FqRepr([0xaa5cdd6172847ffd, 0x43242c06aed55287, 0x9ddd5b312f3dd104, 0xc5541fd48046b7e7, 0x16080cf4071e0b05, 0x1225f2901aea514e]); a.shr(0); assert_eq!( a, - FqRepr([ - 0xaa5cdd6172847ffd, - 0x43242c06aed55287, - 0x9ddd5b312f3dd104, - 0xc5541fd48046b7e7, - 0x16080cf4071e0b05, - 0x1225f2901aea514e - ]) + FqRepr([0xaa5cdd6172847ffd, 0x43242c06aed55287, 0x9ddd5b312f3dd104, 0xc5541fd48046b7e7, 0x16080cf4071e0b05, 0x1225f2901aea514e]) ); a.shr(1); assert_eq!( a, - FqRepr([ - 0xd52e6eb0b9423ffe, - 0x21921603576aa943, - 0xceeead98979ee882, - 0xe2aa0fea40235bf3, - 0xb04067a038f0582, - 0x912f9480d7528a7 - ]) + FqRepr([0xd52e6eb0b9423ffe, 0x21921603576aa943, 0xceeead98979ee882, 0xe2aa0fea40235bf3, 0xb04067a038f0582, 0x912f9480d7528a7]) ); a.shr(50); - assert_eq!( - a, - FqRepr([ - 0x8580d5daaa50f54b, - 0xab6625e7ba208864, - 0x83fa9008d6fcf3bb, - 0x19e80e3c160b8aa, - 0xbe52035d4a29c2c1, - 0x244 - ]) - ); + assert_eq!(a, FqRepr([0x8580d5daaa50f54b, 0xab6625e7ba208864, 0x83fa9008d6fcf3bb, 0x19e80e3c160b8aa, 0xbe52035d4a29c2c1, 0x244])); a.shr(130); - assert_eq!( - a, - FqRepr([ - 0xa0fea40235bf3cee, - 0x4067a038f0582e2a, - 0x2f9480d7528a70b0, - 0x91, - 0x0, - 0x0 - ]) - ); + assert_eq!(a, FqRepr([0xa0fea40235bf3cee, 0x4067a038f0582e2a, 0x2f9480d7528a70b0, 0x91, 0x0, 0x0])); a.shr(64); - assert_eq!( - a, - FqRepr([0x4067a038f0582e2a, 0x2f9480d7528a70b0, 0x91, 0x0, 0x0, 0x0]) - ); + assert_eq!(a, FqRepr([0x4067a038f0582e2a, 0x2f9480d7528a70b0, 0x91, 0x0, 0x0, 0x0])); } #[test] @@ -1383,10 +1269,7 @@ fn test_fq_repr_mul2() { for _ in 0..60 { a.mul2(); } - assert_eq!( - a, - FqRepr([0x6000000000000000, 0xb0acd6c9, 0x0, 0x0, 0x0, 0x0]) - ); + assert_eq!(a, FqRepr([0x6000000000000000, 0xb0acd6c9, 0x0, 0x0, 0x0, 0x0])); for _ in 0..300 { a.mul2(); } @@ -1417,14 +1300,7 @@ fn test_fq_repr_num_bits() { fn test_fq_repr_sub_noborrow() { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let mut t = FqRepr([ - 0x827a4a08041ebd9, - 0x3c239f3dcc8f0d6b, - 0x9ab46a912d555364, - 0x196936b17b43910b, - 0xad0eb3948a5c34fd, - 0xd56f7b5ab8b5ce8, - ]); + let mut t = FqRepr([0x827a4a08041ebd9, 0x3c239f3dcc8f0d6b, 0x9ab46a912d555364, 0x196936b17b43910b, 0xad0eb3948a5c34fd, 0xd56f7b5ab8b5ce8]); t.sub_noborrow(&FqRepr([ 0xc7867917187ca02b, 0x5d75679d4911ffef, @@ -1433,16 +1309,7 @@ fn test_fq_repr_sub_noborrow() { 0x7a37e7265ee1eaf9, 0x7c0577a26f59d5, ])); - assert!( - t == FqRepr([ - 0x40a12b8967c54bae, - 0xdeae37a0837d0d7b, - 0xe592c487bae374e, - 0xaf26bbc934462a61, - 0x32d6cc6e2b7a4a03, - 0xcdaf23e091c0313 - ]) - ); + assert!(t == FqRepr([0x40a12b8967c54bae, 0xdeae37a0837d0d7b, 0xe592c487bae374e, 0xaf26bbc934462a61, 0x32d6cc6e2b7a4a03, 0xcdaf23e091c0313])); for _ in 0..1000 { let mut a = FqRepr::rand(&mut rng); @@ -1471,14 +1338,7 @@ fn test_fq_repr_sub_noborrow() { } // Subtracting q+1 from q should produce -1 (mod 2**384) - let mut qplusone = FqRepr([ - 0xb9feffffffffaaab, - 0x1eabfffeb153ffff, - 0x6730d2a0f6b0f624, - 0x64774b84f38512bf, - 0x4b1ba7b6434bacd7, - 0x1a0111ea397fe69a, - ]); + let mut qplusone = FqRepr([0xb9feffffffffaaab, 0x1eabfffeb153ffff, 0x6730d2a0f6b0f624, 0x64774b84f38512bf, 0x4b1ba7b6434bacd7, 0x1a0111ea397fe69a]); qplusone.sub_noborrow(&FqRepr([ 0xb9feffffffffaaac, 0x1eabfffeb153ffff, @@ -1489,14 +1349,7 @@ fn test_fq_repr_sub_noborrow() { ])); assert_eq!( qplusone, - FqRepr([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff - ]) + FqRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]) ); } @@ -1504,14 +1357,7 @@ fn test_fq_repr_sub_noborrow() { fn test_fq_repr_add_nocarry() { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let mut t = FqRepr([ - 0x827a4a08041ebd9, - 0x3c239f3dcc8f0d6b, - 0x9ab46a912d555364, - 0x196936b17b43910b, - 0xad0eb3948a5c34fd, - 0xd56f7b5ab8b5ce8, - ]); + let mut t = FqRepr([0x827a4a08041ebd9, 0x3c239f3dcc8f0d6b, 0x9ab46a912d555364, 0x196936b17b43910b, 0xad0eb3948a5c34fd, 0xd56f7b5ab8b5ce8]); t.add_nocarry(&FqRepr([ 0xc7867917187ca02b, 0x5d75679d4911ffef, @@ -1520,16 +1366,7 @@ fn test_fq_repr_add_nocarry() { 0x7a37e7265ee1eaf9, 0x7c0577a26f59d5, ])); - assert!( - t == FqRepr([ - 0xcfae1db798be8c04, - 0x999906db15a10d5a, - 0x270fa8d9defc6f79, - 0x83abb199c240f7b6, - 0x27469abae93e1ff6, - 0xdd2fd2d4dfab6be - ]) - ); + assert!(t == FqRepr([0xcfae1db798be8c04, 0x999906db15a10d5a, 0x270fa8d9defc6f79, 0x83abb199c240f7b6, 0x27469abae93e1ff6, 0xdd2fd2d4dfab6be])); // Test for the associativity of addition. for _ in 0..1000 { @@ -1574,14 +1411,7 @@ fn test_fq_repr_add_nocarry() { } // Adding 1 to (2^384 - 1) should produce zero - let mut x = FqRepr([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - ]); + let mut x = FqRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]); x.add_nocarry(&FqRepr::from(1)); assert!(x.is_zero()); } @@ -1593,26 +1423,24 @@ fn test_fq_is_valid() { a.0.sub_noborrow(&FqRepr::from(1)); assert!(a.is_valid()); assert!(Fq(FqRepr::from(0)).is_valid()); - assert!( - Fq(FqRepr([ - 0xdf4671abd14dab3e, - 0xe2dc0c9f534fbd33, - 0x31ca6c880cc444a6, - 0x257a67e70ef33359, - 0xf9b29e493f899b36, - 0x17c8be1800b9f059 - ])).is_valid() - ); - assert!( - !Fq(FqRepr([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff - ])).is_valid() - ); + assert!(Fq(FqRepr([ + 0xdf4671abd14dab3e, + 0xe2dc0c9f534fbd33, + 0x31ca6c880cc444a6, + 0x257a67e70ef33359, + 0xf9b29e493f899b36, + 0x17c8be1800b9f059 + ])) + .is_valid()); + assert!(!Fq(FqRepr([ + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff, + 0xffffffffffffffff + ])) + .is_valid()); let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -1948,7 +1776,8 @@ fn test_fq_squaring() { 0xdc05c659b4e15b27, 0x79361e5a802c6a23, 0x24bcbe5d51b9a6f - ])).unwrap() + ])) + .unwrap() ); let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -2080,47 +1909,25 @@ fn test_fq_sqrt() { #[test] fn test_fq_from_into_repr() { // q + 1 should not be in the field - assert!( - Fq::from_repr(FqRepr([ - 0xb9feffffffffaaac, - 0x1eabfffeb153ffff, - 0x6730d2a0f6b0f624, - 0x64774b84f38512bf, - 0x4b1ba7b6434bacd7, - 0x1a0111ea397fe69a - ])).is_err() - ); + assert!(Fq::from_repr(FqRepr([ + 0xb9feffffffffaaac, + 0x1eabfffeb153ffff, + 0x6730d2a0f6b0f624, + 0x64774b84f38512bf, + 0x4b1ba7b6434bacd7, + 0x1a0111ea397fe69a + ])) + .is_err()); // q should not be in the field assert!(Fq::from_repr(Fq::char()).is_err()); // Multiply some arbitrary representations to see if the result is as expected. - let a = FqRepr([ - 0x4a49dad4ff6cde2d, - 0xac62a82a8f51cd50, - 0x2b1f41ab9f36d640, - 0x908a387f480735f1, - 0xae30740c08a875d7, - 0x6c80918a365ef78, - ]); + let a = FqRepr([0x4a49dad4ff6cde2d, 0xac62a82a8f51cd50, 0x2b1f41ab9f36d640, 0x908a387f480735f1, 0xae30740c08a875d7, 0x6c80918a365ef78]); let mut a_fq = Fq::from_repr(a).unwrap(); - let b = FqRepr([ - 0xbba57917c32f0cf0, - 0xe7f878cf87f05e5d, - 0x9498b4292fd27459, - 0xd59fd94ee4572cfa, - 0x1f607186d5bb0059, - 0xb13955f5ac7f6a3, - ]); + let b = FqRepr([0xbba57917c32f0cf0, 0xe7f878cf87f05e5d, 0x9498b4292fd27459, 0xd59fd94ee4572cfa, 0x1f607186d5bb0059, 0xb13955f5ac7f6a3]); let b_fq = Fq::from_repr(b).unwrap(); - let c = FqRepr([ - 0xf5f70713b717914c, - 0x355ea5ac64cbbab1, - 0xce60dd43417ec960, - 0xf16b9d77b0ad7d10, - 0xa44c204c1de7cdb7, - 0x1684487772bc9a5a, - ]); + let c = FqRepr([0xf5f70713b717914c, 0x355ea5ac64cbbab1, 0xce60dd43417ec960, 0xf16b9d77b0ad7d10, 0xa44c204c1de7cdb7, 0x1684487772bc9a5a]); a_fq.mul_assign(&b_fq); assert_eq!(a_fq.into_repr(), c); @@ -2144,15 +1951,24 @@ fn test_fq_from_into_repr() { #[test] fn test_fq_repr_display() { assert_eq!( - format!("{}", FqRepr([0xa956babf9301ea24, 0x39a8f184f3535c7b, 0xb38d35b3f6779585, 0x676cc4eef4c46f2c, 0xb1d4aad87651e694, 0x1947f0d5f4fe325a])), + format!( + "{}", + FqRepr([0xa956babf9301ea24, 0x39a8f184f3535c7b, 0xb38d35b3f6779585, 0x676cc4eef4c46f2c, 0xb1d4aad87651e694, 0x1947f0d5f4fe325a]) + ), "0x1947f0d5f4fe325ab1d4aad87651e694676cc4eef4c46f2cb38d35b3f677958539a8f184f3535c7ba956babf9301ea24".to_string() ); assert_eq!( - format!("{}", FqRepr([0xb4171485fd8622dd, 0x864229a6edec7ec5, 0xc57f7bdcf8dfb707, 0x6db7ff0ecea4584a, 0xf8d8578c4a57132d, 0x6eb66d42d9fcaaa])), + format!( + "{}", + FqRepr([0xb4171485fd8622dd, 0x864229a6edec7ec5, 0xc57f7bdcf8dfb707, 0x6db7ff0ecea4584a, 0xf8d8578c4a57132d, 0x6eb66d42d9fcaaa]) + ), "0x06eb66d42d9fcaaaf8d8578c4a57132d6db7ff0ecea4584ac57f7bdcf8dfb707864229a6edec7ec5b4171485fd8622dd".to_string() ); assert_eq!( - format!("{}", FqRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])), + format!( + "{}", + FqRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]) + ), "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff".to_string() ); assert_eq!( @@ -2164,11 +1980,33 @@ fn test_fq_repr_display() { #[test] fn test_fq_display() { assert_eq!( - format!("{}", Fq::from_repr(FqRepr([0xa956babf9301ea24, 0x39a8f184f3535c7b, 0xb38d35b3f6779585, 0x676cc4eef4c46f2c, 0xb1d4aad87651e694, 0x1947f0d5f4fe325a])).unwrap()), + format!( + "{}", + Fq::from_repr(FqRepr([ + 0xa956babf9301ea24, + 0x39a8f184f3535c7b, + 0xb38d35b3f6779585, + 0x676cc4eef4c46f2c, + 0xb1d4aad87651e694, + 0x1947f0d5f4fe325a + ])) + .unwrap() + ), "Fq(0x1947f0d5f4fe325ab1d4aad87651e694676cc4eef4c46f2cb38d35b3f677958539a8f184f3535c7ba956babf9301ea24)".to_string() ); assert_eq!( - format!("{}", Fq::from_repr(FqRepr([0xe28e79396ac2bbf8, 0x413f6f7f06ea87eb, 0xa4b62af4a792a689, 0xb7f89f88f59c1dc5, 0x9a551859b1e43a9a, 0x6c9f5a1060de974])).unwrap()), + format!( + "{}", + Fq::from_repr(FqRepr([ + 0xe28e79396ac2bbf8, + 0x413f6f7f06ea87eb, + 0xa4b62af4a792a689, + 0xb7f89f88f59c1dc5, + 0x9a551859b1e43a9a, + 0x6c9f5a1060de974 + ])) + .unwrap() + ), "Fq(0x06c9f5a1060de9749a551859b1e43a9ab7f89f88f59c1dc5a4b62af4a792a689413f6f7f06ea87ebe28e79396ac2bbf8)".to_string() ); } @@ -2184,19 +2022,9 @@ fn test_fq_root_of_unity() { use ff::SqrtField; assert_eq!(Fq::S, 1); + assert_eq!(Fq::multiplicative_generator(), Fq::from_repr(FqRepr::from(2)).unwrap()); assert_eq!( - Fq::multiplicative_generator(), - Fq::from_repr(FqRepr::from(2)).unwrap() - ); - assert_eq!( - Fq::multiplicative_generator().pow([ - 0xdcff7fffffffd555, - 0xf55ffff58a9ffff, - 0xb39869507b587b12, - 0xb23ba5c279c2895f, - 0x258dd3db21a5d66b, - 0xd0088f51cbff34d - ]), + Fq::multiplicative_generator().pow([0xdcff7fffffffd555, 0xf55ffff58a9ffff, 0xb39869507b587b12, 0xb23ba5c279c2895f, 0x258dd3db21a5d66b, 0xd0088f51cbff34d]), Fq::root_of_unity() ); assert_eq!(Fq::root_of_unity().pow([1 << Fq::S]), Fq::one()); @@ -2216,9 +2044,7 @@ fn test_fq_ordering() { // FqRepr's ordering is well-tested, but we still need to make sure the Fq // elements aren't being compared in Montgomery form. for i in 0..100 { - assert!( - Fq::from_repr(FqRepr::from(i + 1)).unwrap() > Fq::from_repr(FqRepr::from(i)).unwrap() - ); + assert!(Fq::from_repr(FqRepr::from(i + 1)).unwrap() > Fq::from_repr(FqRepr::from(i)).unwrap()); } } @@ -2235,31 +2061,11 @@ fn test_fq_legendre() { assert_eq!(QuadraticResidue, Fq::one().legendre()); assert_eq!(Zero, Fq::zero().legendre()); - assert_eq!( - QuadraticNonResidue, - Fq::from_repr(FqRepr::from(2)).unwrap().legendre() - ); - assert_eq!( - QuadraticResidue, - Fq::from_repr(FqRepr::from(4)).unwrap().legendre() - ); + assert_eq!(QuadraticNonResidue, Fq::from_repr(FqRepr::from(2)).unwrap().legendre()); + assert_eq!(QuadraticResidue, Fq::from_repr(FqRepr::from(4)).unwrap().legendre()); - let e = FqRepr([ - 0x52a112f249778642, - 0xd0bedb989b7991f, - 0xdad3b6681aa63c05, - 0xf2efc0bb4721b283, - 0x6057a98f18c24733, - 0x1022c2fd122889e4, - ]); + let e = FqRepr([0x52a112f249778642, 0xd0bedb989b7991f, 0xdad3b6681aa63c05, 0xf2efc0bb4721b283, 0x6057a98f18c24733, 0x1022c2fd122889e4]); assert_eq!(QuadraticNonResidue, Fq::from_repr(e).unwrap().legendre()); - let e = FqRepr([ - 0x6dae594e53a96c74, - 0x19b16ca9ba64b37b, - 0x5c764661a59bfc68, - 0xaa346e9b31c60a, - 0x346059f9d87a9fa9, - 0x1d61ac6bfd5c88b, - ]); + let e = FqRepr([0x6dae594e53a96c74, 0x19b16ca9ba64b37b, 0x5c764661a59bfc68, 0xaa346e9b31c60a, 0x346059f9d87a9fa9, 0x1d61ac6bfd5c88b]); assert_eq!(QuadraticResidue, Fq::from_repr(e).unwrap().legendre()); } diff --git a/crates/pairing/src/bls12_381/fq12.rs b/crates/pairing/src/bls12_381/fq12.rs index bf4d841..07434af 100644 --- a/crates/pairing/src/bls12_381/fq12.rs +++ b/crates/pairing/src/bls12_381/fq12.rs @@ -19,10 +19,7 @@ impl ::std::fmt::Display for Fq12 { impl Rand for Fq12 { fn rand(rng: &mut R) -> Self { - Fq12 { - c0: rng.gen(), - c1: rng.gen(), - } + Fq12 { c0: rng.gen(), c1: rng.gen() } } } @@ -50,17 +47,11 @@ impl Fq12 { impl Field for Fq12 { fn zero() -> Self { - Fq12 { - c0: Fq6::zero(), - c1: Fq6::zero(), - } + Fq12 { c0: Fq6::zero(), c1: Fq6::zero() } } fn one() -> Self { - Fq12 { - c0: Fq6::one(), - c1: Fq6::zero(), - } + Fq12 { c0: Fq6::one(), c1: Fq6::zero() } } fn is_zero(&self) -> bool { @@ -164,11 +155,7 @@ fn test_fq12_mul_by_014() { a.mul_by_014(&c0, &c1, &c5); b.mul_assign(&Fq12 { - c0: Fq6 { - c0: c0, - c1: c1, - c2: Fq2::zero(), - }, + c0: Fq6 { c0: c0, c1: c1, c2: Fq2::zero() }, c1: Fq6 { c0: Fq2::zero(), c1: c5, diff --git a/crates/pairing/src/bls12_381/fq2.rs b/crates/pairing/src/bls12_381/fq2.rs index bb55af2..1eb7879 100644 --- a/crates/pairing/src/bls12_381/fq2.rs +++ b/crates/pairing/src/bls12_381/fq2.rs @@ -1,4 +1,4 @@ -use super::fq::{FROBENIUS_COEFF_FQ2_C1, Fq, NEGATIVE_ONE}; +use super::fq::{Fq, FROBENIUS_COEFF_FQ2_C1, NEGATIVE_ONE}; use ff::{Field, SqrtField}; use rand::{Rand, Rng}; @@ -58,26 +58,17 @@ impl Fq2 { impl Rand for Fq2 { fn rand(rng: &mut R) -> Self { - Fq2 { - c0: rng.gen(), - c1: rng.gen(), - } + Fq2 { c0: rng.gen(), c1: rng.gen() } } } impl Field for Fq2 { fn zero() -> Self { - Fq2 { - c0: Fq::zero(), - c1: Fq::zero(), - } + Fq2 { c0: Fq::zero(), c1: Fq::zero() } } fn one() -> Self { - Fq2 { - c0: Fq::one(), - c1: Fq::zero(), - } + Fq2 { c0: Fq::one(), c1: Fq::zero() } } fn is_zero(&self) -> bool { @@ -142,10 +133,7 @@ impl Field for Fq2 { t0.square(); t0.add_assign(&t1); t0.inverse().map(|t| { - let mut tmp = Fq2 { - c0: self.c0, - c1: self.c1, - }; + let mut tmp = Fq2 { c0: self.c0, c1: self.c1 }; tmp.c0.mul_assign(&t); tmp.c1.mul_assign(&t); tmp.c1.negate(); @@ -171,14 +159,7 @@ impl SqrtField for Fq2 { Some(Self::zero()) } else { // a1 = self^((q - 3) / 4) - let mut a1 = self.pow([ - 0xee7fbfffffffeaaa, - 0x7aaffffac54ffff, - 0xd9cc34a83dac3d89, - 0xd91dd2e13ce144af, - 0x92c6e9ed90d2eb35, - 0x680447a8e5ff9a6, - ]); + let mut a1 = self.pow([0xee7fbfffffffeaaa, 0x7aaffffac54ffff, 0xd9cc34a83dac3d89, 0xd91dd2e13ce144af, 0x92c6e9ed90d2eb35, 0x680447a8e5ff9a6]); let mut alpha = a1; alpha.square(); alpha.mul_assign(self); @@ -186,10 +167,7 @@ impl SqrtField for Fq2 { a0.frobenius_map(1); a0.mul_assign(&alpha); - let neg1 = Fq2 { - c0: NEGATIVE_ONE, - c1: Fq::zero(), - }; + let neg1 = Fq2 { c0: NEGATIVE_ONE, c1: Fq::zero() }; if a0 == neg1 { None @@ -197,21 +175,11 @@ impl SqrtField for Fq2 { a1.mul_assign(self); if alpha == neg1 { - a1.mul_assign(&Fq2 { - c0: Fq::zero(), - c1: Fq::one(), - }); + a1.mul_assign(&Fq2 { c0: Fq::zero(), c1: Fq::one() }); } else { alpha.add_assign(&Fq2::one()); // alpha = alpha^((q - 1) / 2) - alpha = alpha.pow([ - 0xdcff7fffffffd555, - 0xf55ffff58a9ffff, - 0xb39869507b587b12, - 0xb23ba5c279c2895f, - 0x258dd3db21a5d66b, - 0xd0088f51cbff34d, - ]); + alpha = alpha.pow([0xdcff7fffffffd555, 0xf55ffff58a9ffff, 0xb39869507b587b12, 0xb23ba5c279c2895f, 0x258dd3db21a5d66b, 0xd0088f51cbff34d]); a1.mul_assign(&alpha); } @@ -223,10 +191,7 @@ impl SqrtField for Fq2 { #[test] fn test_fq2_ordering() { - let mut a = Fq2 { - c0: Fq::zero(), - c1: Fq::zero(), - }; + let mut a = Fq2 { c0: Fq::zero(), c1: Fq::zero() }; let mut b = a.clone(); @@ -247,28 +212,11 @@ fn test_fq2_ordering() { #[test] fn test_fq2_basics() { - assert_eq!( - Fq2 { - c0: Fq::zero(), - c1: Fq::zero(), - }, - Fq2::zero() - ); - assert_eq!( - Fq2 { - c0: Fq::one(), - c1: Fq::zero(), - }, - Fq2::one() - ); + assert_eq!(Fq2 { c0: Fq::zero(), c1: Fq::zero() }, Fq2::zero()); + assert_eq!(Fq2 { c0: Fq::one(), c1: Fq::zero() }, Fq2::one()); assert!(Fq2::zero().is_zero()); assert!(!Fq2::one().is_zero()); - assert!( - !Fq2 { - c0: Fq::zero(), - c1: Fq::one(), - }.is_zero() - ); + assert!(!Fq2 { c0: Fq::zero(), c1: Fq::one() }.is_zero()); } #[test] @@ -276,31 +224,22 @@ fn test_fq2_squaring() { use super::fq::FqRepr; use ff::PrimeField; - let mut a = Fq2 { - c0: Fq::one(), - c1: Fq::one(), - }; // u + 1 + let mut a = Fq2 { c0: Fq::one(), c1: Fq::one() }; // u + 1 a.square(); assert_eq!( a, Fq2 { c0: Fq::zero(), - c1: Fq::from_repr(FqRepr::from(2)).unwrap(), + c1: Fq::from_repr(FqRepr::from(2)).unwrap() } ); // 2u - let mut a = Fq2 { - c0: Fq::zero(), - c1: Fq::one(), - }; // u + let mut a = Fq2 { c0: Fq::zero(), c1: Fq::one() }; // u a.square(); assert_eq!(a, { let mut neg1 = Fq::one(); neg1.negate(); - Fq2 { - c0: neg1, - c1: Fq::zero(), - } + Fq2 { c0: neg1, c1: Fq::zero() } }); // -1 let mut a = Fq2 { @@ -311,7 +250,8 @@ fn test_fq2_squaring() { 0xf7f295a94e58ae7c, 0x41b76dcc1c3fbe5e, 0x7080c5fa1d8e042, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x38f473b3c870a4ab, 0x6ad3291177c8c7e5, @@ -319,7 +259,8 @@ fn test_fq2_squaring() { 0xbfb99020604137a0, 0xfc58a7b7be815407, 0x10d1615e75250a21, - ])).unwrap(), + ])) + .unwrap(), }; a.square(); assert_eq!( @@ -332,7 +273,8 @@ fn test_fq2_squaring() { 0xcb674157618da176, 0x4cf17b5893c3d327, 0x7eac81369c43361 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xc1579cf58e980cf8, 0xa23eb7e12dd54d98, @@ -340,7 +282,8 @@ fn test_fq2_squaring() { 0x38d0d7275a9689e1, 0x739c983042779a65, 0x1542a61c8a8db994 - ])).unwrap(), + ])) + .unwrap(), } ); } @@ -358,7 +301,8 @@ fn test_fq2_mul() { 0x9ee53e7e84d7532e, 0x1c202d8ed97afb45, 0x51d3f9253e2516f, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xa7348a8b511aedcf, 0x143c215d8176b319, @@ -366,7 +310,8 @@ fn test_fq2_mul() { 0x9533e4a9a5158be, 0x7a5e1ecb676d65f9, 0x180c3ee46656b008, - ])).unwrap(), + ])) + .unwrap(), }; a.mul_assign(&Fq2 { c0: Fq::from_repr(FqRepr([ @@ -376,7 +321,8 @@ fn test_fq2_mul() { 0xcd460f9f0c23e430, 0x6c9110292bfa409, 0x2c93a72eb8af83e, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x4b1c3f936d8992d4, 0x1d2a72916dba4c8a, @@ -384,7 +330,8 @@ fn test_fq2_mul() { 0x57a06d3135a752ae, 0x634cd3c6c565096d, 0x19e17334d4e93558, - ])).unwrap(), + ])) + .unwrap(), }); assert_eq!( a, @@ -396,7 +343,8 @@ fn test_fq2_mul() { 0x5511fe4d84ee5f78, 0x5310a202d92f9963, 0x1751afbe166e5399 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x84af0e1bd630117a, 0x6c63cd4da2c2aa7, @@ -404,7 +352,8 @@ fn test_fq2_mul() { 0xc975106579c275ee, 0x33a9ac82ce4c5083, 0x1ef1a36c201589d - ])).unwrap(), + ])) + .unwrap(), } ); } @@ -424,7 +373,8 @@ fn test_fq2_inverse() { 0x9ee53e7e84d7532e, 0x1c202d8ed97afb45, 0x51d3f9253e2516f, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xa7348a8b511aedcf, 0x143c215d8176b319, @@ -432,7 +382,8 @@ fn test_fq2_inverse() { 0x9533e4a9a5158be, 0x7a5e1ecb676d65f9, 0x180c3ee46656b008, - ])).unwrap(), + ])) + .unwrap(), }; let a = a.inverse().unwrap(); assert_eq!( @@ -445,7 +396,8 @@ fn test_fq2_inverse() { 0xdfba703293941c30, 0xa6c3d8f9586f2636, 0x1351ef01941b70c4 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x8c39fd76a8312cb4, 0x15d7b6b95defbff0, @@ -453,7 +405,8 @@ fn test_fq2_inverse() { 0xcbf651a0f367afb2, 0xdf4e54f0d3ef15a6, 0x103bdf241afb0019 - ])).unwrap(), + ])) + .unwrap(), } ); } @@ -471,7 +424,8 @@ fn test_fq2_addition() { 0xb966ce3bc2108b13, 0xccc649c4b9532bf3, 0xf8d295b2ded9dc, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x977df6efcdaee0db, 0x946ae52d684fa7ed, @@ -479,7 +433,8 @@ fn test_fq2_addition() { 0xb3f8afc0ee248cad, 0x4e464dea5bcfd41e, 0x12d1137b8a6a837, - ])).unwrap(), + ])) + .unwrap(), }; a.add_assign(&Fq2 { c0: Fq::from_repr(FqRepr([ @@ -489,7 +444,8 @@ fn test_fq2_addition() { 0x3b88899a42a6318f, 0x986a4a62fa82a49d, 0x13ce433fa26027f5, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x66323bf80b58b9b9, 0xa1379b6facf6e596, @@ -497,7 +453,8 @@ fn test_fq2_addition() { 0x2236f55246d0d44d, 0x4c8c1800eb104566, 0x11d6e20e986c2085, - ])).unwrap(), + ])) + .unwrap(), }); assert_eq!( a, @@ -509,7 +466,8 @@ fn test_fq2_addition() { 0xf4ef57d604b6bca2, 0x65309427b3d5d090, 0x14c715d5553f01d2 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xfdb032e7d9079a94, 0x35a2809d15468d83, @@ -517,7 +475,8 @@ fn test_fq2_addition() { 0xd62fa51334f560fa, 0x9ad265eb46e01984, 0x1303f3465112c8bc - ])).unwrap(), + ])) + .unwrap(), } ); } @@ -535,7 +494,8 @@ fn test_fq2_subtraction() { 0xb966ce3bc2108b13, 0xccc649c4b9532bf3, 0xf8d295b2ded9dc, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x977df6efcdaee0db, 0x946ae52d684fa7ed, @@ -543,7 +503,8 @@ fn test_fq2_subtraction() { 0xb3f8afc0ee248cad, 0x4e464dea5bcfd41e, 0x12d1137b8a6a837, - ])).unwrap(), + ])) + .unwrap(), }; a.sub_assign(&Fq2 { c0: Fq::from_repr(FqRepr([ @@ -553,7 +514,8 @@ fn test_fq2_subtraction() { 0x3b88899a42a6318f, 0x986a4a62fa82a49d, 0x13ce433fa26027f5, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x66323bf80b58b9b9, 0xa1379b6facf6e596, @@ -561,7 +523,8 @@ fn test_fq2_subtraction() { 0x2236f55246d0d44d, 0x4c8c1800eb104566, 0x11d6e20e986c2085, - ])).unwrap(), + ])) + .unwrap(), }); assert_eq!( a, @@ -573,7 +536,8 @@ fn test_fq2_subtraction() { 0xe255902672ef6c43, 0x7f77a718021c342d, 0x72ba14049fe9881 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xeb4abaf7c255d1cd, 0x11df49bc6cacc256, @@ -581,7 +545,8 @@ fn test_fq2_subtraction() { 0xf63905f39ad8cb1f, 0x4cd5dd9fb40b3b8f, 0x957411359ba6e4c - ])).unwrap(), + ])) + .unwrap(), } ); } @@ -599,7 +564,8 @@ fn test_fq2_negation() { 0xb966ce3bc2108b13, 0xccc649c4b9532bf3, 0xf8d295b2ded9dc, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x977df6efcdaee0db, 0x946ae52d684fa7ed, @@ -607,7 +573,8 @@ fn test_fq2_negation() { 0xb3f8afc0ee248cad, 0x4e464dea5bcfd41e, 0x12d1137b8a6a837, - ])).unwrap(), + ])) + .unwrap(), }; a.negate(); assert_eq!( @@ -620,7 +587,8 @@ fn test_fq2_negation() { 0xab107d49317487ab, 0x7e555df189f880e3, 0x19083f5486a10cbd - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x228109103250c9d0, 0x8a411ad149045812, @@ -628,7 +596,8 @@ fn test_fq2_negation() { 0xb07e9bc405608611, 0xfcd559cbe77bd8b8, 0x18d400b280d93e62 - ])).unwrap(), + ])) + .unwrap(), } ); } @@ -646,7 +615,8 @@ fn test_fq2_doubling() { 0xb966ce3bc2108b13, 0xccc649c4b9532bf3, 0xf8d295b2ded9dc, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x977df6efcdaee0db, 0x946ae52d684fa7ed, @@ -654,7 +624,8 @@ fn test_fq2_doubling() { 0xb3f8afc0ee248cad, 0x4e464dea5bcfd41e, 0x12d1137b8a6a837, - ])).unwrap(), + ])) + .unwrap(), }; a.double(); assert_eq!( @@ -667,7 +638,8 @@ fn test_fq2_doubling() { 0x72cd9c7784211627, 0x998c938972a657e7, 0x1f1a52b65bdb3b9 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x2efbeddf9b5dc1b6, 0x28d5ca5ad09f4fdb, @@ -675,7 +647,8 @@ fn test_fq2_doubling() { 0x67f15f81dc49195b, 0x9c8c9bd4b79fa83d, 0x25a226f714d506e - ])).unwrap(), + ])) + .unwrap(), } ); } @@ -693,7 +666,8 @@ fn test_fq2_frobenius_map() { 0xb966ce3bc2108b13, 0xccc649c4b9532bf3, 0xf8d295b2ded9dc, - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x977df6efcdaee0db, 0x946ae52d684fa7ed, @@ -701,7 +675,8 @@ fn test_fq2_frobenius_map() { 0xb3f8afc0ee248cad, 0x4e464dea5bcfd41e, 0x12d1137b8a6a837, - ])).unwrap(), + ])) + .unwrap(), }; a.frobenius_map(0); assert_eq!( @@ -714,7 +689,8 @@ fn test_fq2_frobenius_map() { 0xb966ce3bc2108b13, 0xccc649c4b9532bf3, 0xf8d295b2ded9dc - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x977df6efcdaee0db, 0x946ae52d684fa7ed, @@ -722,7 +698,8 @@ fn test_fq2_frobenius_map() { 0xb3f8afc0ee248cad, 0x4e464dea5bcfd41e, 0x12d1137b8a6a837 - ])).unwrap(), + ])) + .unwrap(), } ); a.frobenius_map(1); @@ -736,7 +713,8 @@ fn test_fq2_frobenius_map() { 0xb966ce3bc2108b13, 0xccc649c4b9532bf3, 0xf8d295b2ded9dc - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x228109103250c9d0, 0x8a411ad149045812, @@ -744,7 +722,8 @@ fn test_fq2_frobenius_map() { 0xb07e9bc405608611, 0xfcd559cbe77bd8b8, 0x18d400b280d93e62 - ])).unwrap(), + ])) + .unwrap(), } ); a.frobenius_map(1); @@ -758,7 +737,8 @@ fn test_fq2_frobenius_map() { 0xb966ce3bc2108b13, 0xccc649c4b9532bf3, 0xf8d295b2ded9dc - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x977df6efcdaee0db, 0x946ae52d684fa7ed, @@ -766,7 +746,8 @@ fn test_fq2_frobenius_map() { 0xb3f8afc0ee248cad, 0x4e464dea5bcfd41e, 0x12d1137b8a6a837 - ])).unwrap(), + ])) + .unwrap(), } ); a.frobenius_map(2); @@ -780,7 +761,8 @@ fn test_fq2_frobenius_map() { 0xb966ce3bc2108b13, 0xccc649c4b9532bf3, 0xf8d295b2ded9dc - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0x977df6efcdaee0db, 0x946ae52d684fa7ed, @@ -788,7 +770,8 @@ fn test_fq2_frobenius_map() { 0xb3f8afc0ee248cad, 0x4e464dea5bcfd41e, 0x12d1137b8a6a837 - ])).unwrap(), + ])) + .unwrap(), } ); } @@ -807,7 +790,8 @@ fn test_fq2_sqrt() { 0xdb4a116b5bf74aa1, 0x1e58b2159dfe10e2, 0x7ca7da1f13606ac - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xfa8de88b7516d2c3, 0x371a75ed14f41629, @@ -815,9 +799,11 @@ fn test_fq2_sqrt() { 0x212611bca4e99121, 0x8ee5394d77afb3d, 0xec92336650e49d5 - ])).unwrap(), - }.sqrt() + ])) .unwrap(), + } + .sqrt() + .unwrap(), Fq2 { c0: Fq::from_repr(FqRepr([ 0x40b299b2704258c5, @@ -826,7 +812,8 @@ fn test_fq2_sqrt() { 0x8d7f1f723d02c1d3, 0x881b3e01b611c070, 0x10f6963bbad2ebc5 - ])).unwrap(), + ])) + .unwrap(), c1: Fq::from_repr(FqRepr([ 0xc099534fc209e752, 0x7670594665676447, @@ -834,7 +821,8 @@ fn test_fq2_sqrt() { 0x6b852aeaf2afcb1b, 0xa4c93b08105d71a9, 0x8d7cfff94216330 - ])).unwrap(), + ])) + .unwrap(), } ); @@ -847,10 +835,12 @@ fn test_fq2_sqrt() { 0x64774b84f38512bf, 0x4b1ba7b6434bacd7, 0x1a0111ea397fe69a - ])).unwrap(), - c1: Fq::zero(), - }.sqrt() + ])) .unwrap(), + c1: Fq::zero(), + } + .sqrt() + .unwrap(), Fq2 { c0: Fq::zero(), c1: Fq::from_repr(FqRepr([ @@ -860,7 +850,8 @@ fn test_fq2_sqrt() { 0x64774b84f38512bf, 0x4b1ba7b6434bacd7, 0x1a0111ea397fe69a - ])).unwrap(), + ])) + .unwrap(), } ); } @@ -885,10 +876,7 @@ use rand::{SeedableRng, XorShiftRng}; fn test_fq2_mul_nonresidue() { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let nqr = Fq2 { - c0: Fq::one(), - c1: Fq::one(), - }; + let nqr = Fq2 { c0: Fq::one(), c1: Fq::one() }; for _ in 0..1000 { let mut a = Fq2::rand(&mut rng); diff --git a/crates/pairing/src/bls12_381/fq6.rs b/crates/pairing/src/bls12_381/fq6.rs index 6286a54..c756017 100644 --- a/crates/pairing/src/bls12_381/fq6.rs +++ b/crates/pairing/src/bls12_381/fq6.rs @@ -285,11 +285,7 @@ impl Field for Fq6 { match tmp1.inverse() { Some(t) => { - let mut tmp = Fq6 { - c0: t, - c1: t, - c2: t, - }; + let mut tmp = Fq6 { c0: t, c1: t, c2: t }; tmp.c0.mul_assign(&c0); tmp.c1.mul_assign(&c1); tmp.c2.mul_assign(&c2); @@ -355,11 +351,7 @@ fn test_fq6_mul_by_01() { let mut b = a; a.mul_by_01(&c0, &c1); - b.mul_assign(&Fq6 { - c0: c0, - c1: c1, - c2: Fq2::zero(), - }); + b.mul_assign(&Fq6 { c0: c0, c1: c1, c2: Fq2::zero() }); assert_eq!(a, b); } diff --git a/crates/pairing/src/bls12_381/fr.rs b/crates/pairing/src/bls12_381/fr.rs index bcecbaa..1e0c2f8 100644 --- a/crates/pairing/src/bls12_381/fr.rs +++ b/crates/pairing/src/bls12_381/fr.rs @@ -20,30 +20,12 @@ fn test_fr_repr_ordering() { assert!(b > a); } - assert_equality( - FrRepr([9999, 9999, 9999, 9999]), - FrRepr([9999, 9999, 9999, 9999]), - ); - assert_equality( - FrRepr([9999, 9998, 9999, 9999]), - FrRepr([9999, 9998, 9999, 9999]), - ); - assert_equality( - FrRepr([9999, 9999, 9999, 9997]), - FrRepr([9999, 9999, 9999, 9997]), - ); - assert_lt( - FrRepr([9999, 9997, 9999, 9998]), - FrRepr([9999, 9997, 9999, 9999]), - ); - assert_lt( - FrRepr([9999, 9997, 9998, 9999]), - FrRepr([9999, 9997, 9999, 9999]), - ); - assert_lt( - FrRepr([9, 9999, 9999, 9997]), - FrRepr([9999, 9999, 9999, 9997]), - ); + assert_equality(FrRepr([9999, 9999, 9999, 9999]), FrRepr([9999, 9999, 9999, 9999])); + assert_equality(FrRepr([9999, 9998, 9999, 9999]), FrRepr([9999, 9998, 9999, 9999])); + assert_equality(FrRepr([9999, 9999, 9999, 9997]), FrRepr([9999, 9999, 9999, 9997])); + assert_lt(FrRepr([9999, 9997, 9999, 9998]), FrRepr([9999, 9997, 9999, 9999])); + assert_lt(FrRepr([9999, 9997, 9998, 9999]), FrRepr([9999, 9997, 9999, 9999])); + assert_lt(FrRepr([9, 9999, 9999, 9997]), FrRepr([9999, 9999, 9999, 9997])); } #[test] @@ -72,34 +54,13 @@ fn test_fr_repr_is_zero() { #[test] fn test_fr_repr_div2() { - let mut a = FrRepr([ - 0xbd2920b19c972321, - 0x174ed0466a3be37e, - 0xd468d5e3b551f0b5, - 0xcb67c072733beefc, - ]); + let mut a = FrRepr([0xbd2920b19c972321, 0x174ed0466a3be37e, 0xd468d5e3b551f0b5, 0xcb67c072733beefc]); a.div2(); - assert_eq!( - a, - FrRepr([ - 0x5e949058ce4b9190, - 0x8ba76823351df1bf, - 0x6a346af1daa8f85a, - 0x65b3e039399df77e - ]) - ); + assert_eq!(a, FrRepr([0x5e949058ce4b9190, 0x8ba76823351df1bf, 0x6a346af1daa8f85a, 0x65b3e039399df77e])); for _ in 0..10 { a.div2(); } - assert_eq!( - a, - FrRepr([ - 0x6fd7a524163392e4, - 0x16a2e9da08cd477c, - 0xdf9a8d1abc76aa3e, - 0x196cf80e4e677d - ]) - ); + assert_eq!(a, FrRepr([0x6fd7a524163392e4, 0x16a2e9da08cd477c, 0xdf9a8d1abc76aa3e, 0x196cf80e4e677d])); for _ in 0..200 { a.div2(); } @@ -118,42 +79,13 @@ fn test_fr_repr_div2() { #[test] fn test_fr_repr_shr() { - let mut a = FrRepr([ - 0xb33fbaec482a283f, - 0x997de0d3a88cb3df, - 0x9af62d2a9a0e5525, - 0x36003ab08de70da1, - ]); + let mut a = FrRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1]); a.shr(0); - assert_eq!( - a, - FrRepr([ - 0xb33fbaec482a283f, - 0x997de0d3a88cb3df, - 0x9af62d2a9a0e5525, - 0x36003ab08de70da1 - ]) - ); + assert_eq!(a, FrRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1])); a.shr(1); - assert_eq!( - a, - FrRepr([ - 0xd99fdd762415141f, - 0xccbef069d44659ef, - 0xcd7b16954d072a92, - 0x1b001d5846f386d0 - ]) - ); + assert_eq!(a, FrRepr([0xd99fdd762415141f, 0xccbef069d44659ef, 0xcd7b16954d072a92, 0x1b001d5846f386d0])); a.shr(50); - assert_eq!( - a, - FrRepr([ - 0xbc1a7511967bf667, - 0xc5a55341caa4b32f, - 0x75611bce1b4335e, - 0x6c0 - ]) - ); + assert_eq!(a, FrRepr([0xbc1a7511967bf667, 0xc5a55341caa4b32f, 0x75611bce1b4335e, 0x6c0])); a.shr(130); assert_eq!(a, FrRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0])); a.shr(64); @@ -199,26 +131,9 @@ fn test_fr_repr_num_bits() { fn test_fr_repr_sub_noborrow() { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let mut t = FrRepr([ - 0x8e62a7e85264e2c3, - 0xb23d34c1941d3ca, - 0x5976930b7502dd15, - 0x600f3fb517bf5495, - ]); - t.sub_noborrow(&FrRepr([ - 0xd64f669809cbc6a4, - 0xfa76cb9d90cf7637, - 0xfefb0df9038d43b3, - 0x298a30c744b31acf, - ])); - assert!( - t == FrRepr([ - 0xb813415048991c1f, - 0x10ad07ae88725d92, - 0x5a7b851271759961, - 0x36850eedd30c39c5 - ]) - ); + let mut t = FrRepr([0x8e62a7e85264e2c3, 0xb23d34c1941d3ca, 0x5976930b7502dd15, 0x600f3fb517bf5495]); + t.sub_noborrow(&FrRepr([0xd64f669809cbc6a4, 0xfa76cb9d90cf7637, 0xfefb0df9038d43b3, 0x298a30c744b31acf])); + assert!(t == FrRepr([0xb813415048991c1f, 0x10ad07ae88725d92, 0x5a7b851271759961, 0x36850eedd30c39c5])); for _ in 0..1000 { let mut a = FrRepr::rand(&mut rng); @@ -247,27 +162,9 @@ fn test_fr_repr_sub_noborrow() { } // Subtracting r+1 from r should produce -1 (mod 2**256) - let mut qplusone = FrRepr([ - 0xffffffff00000001, - 0x53bda402fffe5bfe, - 0x3339d80809a1d805, - 0x73eda753299d7d48, - ]); - qplusone.sub_noborrow(&FrRepr([ - 0xffffffff00000002, - 0x53bda402fffe5bfe, - 0x3339d80809a1d805, - 0x73eda753299d7d48, - ])); - assert_eq!( - qplusone, - FrRepr([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff - ]) - ); + let mut qplusone = FrRepr([0xffffffff00000001, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48]); + qplusone.sub_noborrow(&FrRepr([0xffffffff00000002, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48])); + assert_eq!(qplusone, FrRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])); } #[test] @@ -278,19 +175,9 @@ fn test_fr_legendre() { assert_eq!(QuadraticResidue, Fr::one().legendre()); assert_eq!(Zero, Fr::zero().legendre()); - let e = FrRepr([ - 0x0dbc5349cd5664da, - 0x8ac5b6296e3ae29d, - 0x127cb819feceaa3b, - 0x3a6b21fb03867191, - ]); + let e = FrRepr([0x0dbc5349cd5664da, 0x8ac5b6296e3ae29d, 0x127cb819feceaa3b, 0x3a6b21fb03867191]); assert_eq!(QuadraticResidue, Fr::from_repr(e).unwrap().legendre()); - let e = FrRepr([ - 0x96341aefd047c045, - 0x9b5f4254500a4d65, - 0x1ee08223b68ac240, - 0x31d9cd545c0ec7c6, - ]); + let e = FrRepr([0x96341aefd047c045, 0x9b5f4254500a4d65, 0x1ee08223b68ac240, 0x31d9cd545c0ec7c6]); assert_eq!(QuadraticNonResidue, Fr::from_repr(e).unwrap().legendre()); } @@ -298,27 +185,9 @@ fn test_fr_legendre() { fn test_fr_repr_add_nocarry() { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - let mut t = FrRepr([ - 0xd64f669809cbc6a4, - 0xfa76cb9d90cf7637, - 0xfefb0df9038d43b3, - 0x298a30c744b31acf, - ]); - t.add_nocarry(&FrRepr([ - 0x8e62a7e85264e2c3, - 0xb23d34c1941d3ca, - 0x5976930b7502dd15, - 0x600f3fb517bf5495, - ])); - assert_eq!( - t, - FrRepr([ - 0x64b20e805c30a967, - 0x59a9ee9aa114a02, - 0x5871a104789020c9, - 0x8999707c5c726f65 - ]) - ); + let mut t = FrRepr([0xd64f669809cbc6a4, 0xfa76cb9d90cf7637, 0xfefb0df9038d43b3, 0x298a30c744b31acf]); + t.add_nocarry(&FrRepr([0x8e62a7e85264e2c3, 0xb23d34c1941d3ca, 0x5976930b7502dd15, 0x600f3fb517bf5495])); + assert_eq!(t, FrRepr([0x64b20e805c30a967, 0x59a9ee9aa114a02, 0x5871a104789020c9, 0x8999707c5c726f65])); // Test for the associativity of addition. for _ in 0..1000 { @@ -363,12 +232,7 @@ fn test_fr_repr_add_nocarry() { } // Adding 1 to (2^256 - 1) should produce zero - let mut x = FrRepr([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - ]); + let mut x = FrRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff]); x.add_nocarry(&FrRepr::from(1)); assert!(x.is_zero()); } @@ -380,22 +244,8 @@ fn test_fr_is_valid() { a.0.sub_noborrow(&FrRepr::from(1)); assert!(a.is_valid()); assert!(Fr(FrRepr::from(0)).is_valid()); - assert!( - Fr(FrRepr([ - 0xffffffff00000000, - 0x53bda402fffe5bfe, - 0x3339d80809a1d805, - 0x73eda753299d7d48 - ])).is_valid() - ); - assert!( - !Fr(FrRepr([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff - ])).is_valid() - ); + assert!(Fr(FrRepr([0xffffffff00000000, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48])).is_valid()); + assert!(!Fr(FrRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])).is_valid()); let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -409,82 +259,25 @@ fn test_fr_is_valid() { fn test_fr_add_assign() { { // Random number - let mut tmp = Fr(FrRepr([ - 0x437ce7616d580765, - 0xd42d1ccb29d1235b, - 0xed8f753821bd1423, - 0x4eede1c9c89528ca, - ])); + let mut tmp = Fr(FrRepr([0x437ce7616d580765, 0xd42d1ccb29d1235b, 0xed8f753821bd1423, 0x4eede1c9c89528ca])); assert!(tmp.is_valid()); // Test that adding zero has no effect. tmp.add_assign(&Fr(FrRepr::from(0))); - assert_eq!( - tmp, - Fr(FrRepr([ - 0x437ce7616d580765, - 0xd42d1ccb29d1235b, - 0xed8f753821bd1423, - 0x4eede1c9c89528ca - ])) - ); + assert_eq!(tmp, Fr(FrRepr([0x437ce7616d580765, 0xd42d1ccb29d1235b, 0xed8f753821bd1423, 0x4eede1c9c89528ca]))); // Add one and test for the result. tmp.add_assign(&Fr(FrRepr::from(1))); - assert_eq!( - tmp, - Fr(FrRepr([ - 0x437ce7616d580766, - 0xd42d1ccb29d1235b, - 0xed8f753821bd1423, - 0x4eede1c9c89528ca - ])) - ); + assert_eq!(tmp, Fr(FrRepr([0x437ce7616d580766, 0xd42d1ccb29d1235b, 0xed8f753821bd1423, 0x4eede1c9c89528ca]))); // Add another random number that exercises the reduction. - tmp.add_assign(&Fr(FrRepr([ - 0x946f435944f7dc79, - 0xb55e7ee6533a9b9b, - 0x1e43b84c2f6194ca, - 0x58717ab525463496, - ]))); - assert_eq!( - tmp, - Fr(FrRepr([ - 0xd7ec2abbb24fe3de, - 0x35cdf7ae7d0d62f7, - 0xd899557c477cd0e9, - 0x3371b52bc43de018 - ])) - ); + tmp.add_assign(&Fr(FrRepr([0x946f435944f7dc79, 0xb55e7ee6533a9b9b, 0x1e43b84c2f6194ca, 0x58717ab525463496]))); + assert_eq!(tmp, Fr(FrRepr([0xd7ec2abbb24fe3de, 0x35cdf7ae7d0d62f7, 0xd899557c477cd0e9, 0x3371b52bc43de018]))); // Add one to (r - 1) and test for the result. - tmp = Fr(FrRepr([ - 0xffffffff00000000, - 0x53bda402fffe5bfe, - 0x3339d80809a1d805, - 0x73eda753299d7d48, - ])); + tmp = Fr(FrRepr([0xffffffff00000000, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48])); tmp.add_assign(&Fr(FrRepr::from(1))); assert!(tmp.0.is_zero()); // Add a random number to another one such that the result is r - 1 - tmp = Fr(FrRepr([ - 0xade5adacdccb6190, - 0xaa21ee0f27db3ccd, - 0x2550f4704ae39086, - 0x591d1902e7c5ba27, - ])); - tmp.add_assign(&Fr(FrRepr([ - 0x521a525223349e70, - 0xa99bb5f3d8231f31, - 0xde8e397bebe477e, - 0x1ad08e5041d7c321, - ]))); - assert_eq!( - tmp, - Fr(FrRepr([ - 0xffffffff00000000, - 0x53bda402fffe5bfe, - 0x3339d80809a1d805, - 0x73eda753299d7d48 - ])) - ); + tmp = Fr(FrRepr([0xade5adacdccb6190, 0xaa21ee0f27db3ccd, 0x2550f4704ae39086, 0x591d1902e7c5ba27])); + tmp.add_assign(&Fr(FrRepr([0x521a525223349e70, 0xa99bb5f3d8231f31, 0xde8e397bebe477e, 0x1ad08e5041d7c321]))); + assert_eq!(tmp, Fr(FrRepr([0xffffffff00000000, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48]))); // Add one to the result and test for it. tmp.add_assign(&Fr(FrRepr::from(1))); assert!(tmp.0.is_zero()); @@ -518,72 +311,23 @@ fn test_fr_add_assign() { fn test_fr_sub_assign() { { // Test arbitrary subtraction that tests reduction. - let mut tmp = Fr(FrRepr([ - 0x6a68c64b6f735a2b, - 0xd5f4d143fe0a1972, - 0x37c17f3829267c62, - 0xa2f37391f30915c, - ])); - tmp.sub_assign(&Fr(FrRepr([ - 0xade5adacdccb6190, - 0xaa21ee0f27db3ccd, - 0x2550f4704ae39086, - 0x591d1902e7c5ba27, - ]))); - assert_eq!( - tmp, - Fr(FrRepr([ - 0xbc83189d92a7f89c, - 0x7f908737d62d38a3, - 0x45aa62cfe7e4c3e1, - 0x24ffc5896108547d - ])) - ); + let mut tmp = Fr(FrRepr([0x6a68c64b6f735a2b, 0xd5f4d143fe0a1972, 0x37c17f3829267c62, 0xa2f37391f30915c])); + tmp.sub_assign(&Fr(FrRepr([0xade5adacdccb6190, 0xaa21ee0f27db3ccd, 0x2550f4704ae39086, 0x591d1902e7c5ba27]))); + assert_eq!(tmp, Fr(FrRepr([0xbc83189d92a7f89c, 0x7f908737d62d38a3, 0x45aa62cfe7e4c3e1, 0x24ffc5896108547d]))); // Test the opposite subtraction which doesn't test reduction. - tmp = Fr(FrRepr([ - 0xade5adacdccb6190, - 0xaa21ee0f27db3ccd, - 0x2550f4704ae39086, - 0x591d1902e7c5ba27, - ])); - tmp.sub_assign(&Fr(FrRepr([ - 0x6a68c64b6f735a2b, - 0xd5f4d143fe0a1972, - 0x37c17f3829267c62, - 0xa2f37391f30915c, - ]))); - assert_eq!( - tmp, - Fr(FrRepr([ - 0x437ce7616d580765, - 0xd42d1ccb29d1235b, - 0xed8f753821bd1423, - 0x4eede1c9c89528ca - ])) - ); + tmp = Fr(FrRepr([0xade5adacdccb6190, 0xaa21ee0f27db3ccd, 0x2550f4704ae39086, 0x591d1902e7c5ba27])); + tmp.sub_assign(&Fr(FrRepr([0x6a68c64b6f735a2b, 0xd5f4d143fe0a1972, 0x37c17f3829267c62, 0xa2f37391f30915c]))); + assert_eq!(tmp, Fr(FrRepr([0x437ce7616d580765, 0xd42d1ccb29d1235b, 0xed8f753821bd1423, 0x4eede1c9c89528ca]))); // Test for sensible results with zero tmp = Fr(FrRepr::from(0)); tmp.sub_assign(&Fr(FrRepr::from(0))); assert!(tmp.is_zero()); - tmp = Fr(FrRepr([ - 0x437ce7616d580765, - 0xd42d1ccb29d1235b, - 0xed8f753821bd1423, - 0x4eede1c9c89528ca, - ])); + tmp = Fr(FrRepr([0x437ce7616d580765, 0xd42d1ccb29d1235b, 0xed8f753821bd1423, 0x4eede1c9c89528ca])); tmp.sub_assign(&Fr(FrRepr::from(0))); - assert_eq!( - tmp, - Fr(FrRepr([ - 0x437ce7616d580765, - 0xd42d1ccb29d1235b, - 0xed8f753821bd1423, - 0x4eede1c9c89528ca - ])) - ); + assert_eq!(tmp, Fr(FrRepr([0x437ce7616d580765, 0xd42d1ccb29d1235b, 0xed8f753821bd1423, 0x4eede1c9c89528ca]))); } let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -606,26 +350,9 @@ fn test_fr_sub_assign() { #[test] fn test_fr_mul_assign() { - let mut tmp = Fr(FrRepr([ - 0x6b7e9b8faeefc81a, - 0xe30a8463f348ba42, - 0xeff3cb67a8279c9c, - 0x3d303651bd7c774d, - ])); - tmp.mul_assign(&Fr(FrRepr([ - 0x13ae28e3bc35ebeb, - 0xa10f4488075cae2c, - 0x8160e95a853c3b5d, - 0x5ae3f03b561a841d, - ]))); - assert!( - tmp == Fr(FrRepr([ - 0x23717213ce710f71, - 0xdbee1fe53a16e1af, - 0xf565d3e1c2a48000, - 0x4426507ee75df9d7 - ])) - ); + let mut tmp = Fr(FrRepr([0x6b7e9b8faeefc81a, 0xe30a8463f348ba42, 0xeff3cb67a8279c9c, 0x3d303651bd7c774d])); + tmp.mul_assign(&Fr(FrRepr([0x13ae28e3bc35ebeb, 0xa10f4488075cae2c, 0x8160e95a853c3b5d, 0x5ae3f03b561a841d]))); + assert!(tmp == Fr(FrRepr([0x23717213ce710f71, 0xdbee1fe53a16e1af, 0xf565d3e1c2a48000, 0x4426507ee75df9d7]))); let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -672,23 +399,10 @@ fn test_fr_mul_assign() { #[test] fn test_fr_squaring() { - let mut a = Fr(FrRepr([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0x73eda753299d7d47, - ])); + let mut a = Fr(FrRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x73eda753299d7d47])); assert!(a.is_valid()); a.square(); - assert_eq!( - a, - Fr::from_repr(FrRepr([ - 0xc0d698e7bde077b8, - 0xb79a310579e76ec2, - 0xac1da8d0a9af4e5f, - 0x13f629c49bf23e97 - ])).unwrap() - ); + assert_eq!(a, Fr::from_repr(FrRepr([0xc0d698e7bde077b8, 0xb79a310579e76ec2, 0xac1da8d0a9af4e5f, 0x13f629c49bf23e97])).unwrap()); let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -819,39 +533,17 @@ fn test_fr_sqrt() { #[test] fn test_fr_from_into_repr() { // r + 1 should not be in the field - assert!( - Fr::from_repr(FrRepr([ - 0xffffffff00000002, - 0x53bda402fffe5bfe, - 0x3339d80809a1d805, - 0x73eda753299d7d48 - ])).is_err() - ); + assert!(Fr::from_repr(FrRepr([0xffffffff00000002, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48])).is_err()); // r should not be in the field assert!(Fr::from_repr(Fr::char()).is_err()); // Multiply some arbitrary representations to see if the result is as expected. - let a = FrRepr([ - 0x25ebe3a3ad3c0c6a, - 0x6990e39d092e817c, - 0x941f900d42f5658e, - 0x44f8a103b38a71e0, - ]); + let a = FrRepr([0x25ebe3a3ad3c0c6a, 0x6990e39d092e817c, 0x941f900d42f5658e, 0x44f8a103b38a71e0]); let mut a_fr = Fr::from_repr(a).unwrap(); - let b = FrRepr([ - 0x264e9454885e2475, - 0x46f7746bb0308370, - 0x4683ef5347411f9, - 0x58838d7f208d4492, - ]); + let b = FrRepr([0x264e9454885e2475, 0x46f7746bb0308370, 0x4683ef5347411f9, 0x58838d7f208d4492]); let b_fr = Fr::from_repr(b).unwrap(); - let c = FrRepr([ - 0x48a09ab93cfc740d, - 0x3a6600fbfc7a671, - 0x838567017501d767, - 0x7161d6da77745512, - ]); + let c = FrRepr([0x48a09ab93cfc740d, 0x3a6600fbfc7a671, 0x838567017501d767, 0x7161d6da77745512]); a_fr.mul_assign(&b_fr); assert_eq!(a_fr.into_repr(), c); @@ -875,71 +567,28 @@ fn test_fr_from_into_repr() { #[test] fn test_fr_repr_display() { assert_eq!( - format!( - "{}", - FrRepr([ - 0x2829c242fa826143, - 0x1f32cf4dd4330917, - 0x932e4e479d168cd9, - 0x513c77587f563f64 - ]) - ), + format!("{}", FrRepr([0x2829c242fa826143, 0x1f32cf4dd4330917, 0x932e4e479d168cd9, 0x513c77587f563f64])), "0x513c77587f563f64932e4e479d168cd91f32cf4dd43309172829c242fa826143".to_string() ); assert_eq!( - format!( - "{}", - FrRepr([ - 0x25ebe3a3ad3c0c6a, - 0x6990e39d092e817c, - 0x941f900d42f5658e, - 0x44f8a103b38a71e0 - ]) - ), + format!("{}", FrRepr([0x25ebe3a3ad3c0c6a, 0x6990e39d092e817c, 0x941f900d42f5658e, 0x44f8a103b38a71e0])), "0x44f8a103b38a71e0941f900d42f5658e6990e39d092e817c25ebe3a3ad3c0c6a".to_string() ); assert_eq!( - format!( - "{}", - FrRepr([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff - ]) - ), + format!("{}", FrRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])), "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff".to_string() ); - assert_eq!( - format!("{}", FrRepr([0, 0, 0, 0])), - "0x0000000000000000000000000000000000000000000000000000000000000000".to_string() - ); + assert_eq!(format!("{}", FrRepr([0, 0, 0, 0])), "0x0000000000000000000000000000000000000000000000000000000000000000".to_string()); } #[test] fn test_fr_display() { assert_eq!( - format!( - "{}", - Fr::from_repr(FrRepr([ - 0xc3cae746a3b5ecc7, - 0x185ec8eb3f5b5aee, - 0x684499ffe4b9dd99, - 0x7c9bba7afb68faa - ])).unwrap() - ), + format!("{}", Fr::from_repr(FrRepr([0xc3cae746a3b5ecc7, 0x185ec8eb3f5b5aee, 0x684499ffe4b9dd99, 0x7c9bba7afb68faa])).unwrap()), "Fr(0x07c9bba7afb68faa684499ffe4b9dd99185ec8eb3f5b5aeec3cae746a3b5ecc7)".to_string() ); assert_eq!( - format!( - "{}", - Fr::from_repr(FrRepr([ - 0x44c71298ff198106, - 0xb0ad10817df79b6a, - 0xd034a80a2b74132b, - 0x41cf9a1336f50719 - ])).unwrap() - ), + format!("{}", Fr::from_repr(FrRepr([0x44c71298ff198106, 0xb0ad10817df79b6a, 0xd034a80a2b74132b, 0x41cf9a1336f50719])).unwrap()), "Fr(0x41cf9a1336f50719d034a80a2b74132bb0ad10817df79b6a44c71298ff198106)".to_string() ); } @@ -955,17 +604,9 @@ fn test_fr_root_of_unity() { use ff::SqrtField; assert_eq!(Fr::S, 32); + assert_eq!(Fr::multiplicative_generator(), Fr::from_repr(FrRepr::from(7)).unwrap()); assert_eq!( - Fr::multiplicative_generator(), - Fr::from_repr(FrRepr::from(7)).unwrap() - ); - assert_eq!( - Fr::multiplicative_generator().pow([ - 0xfffe5bfeffffffff, - 0x9a1d80553bda402, - 0x299d7d483339d808, - 0x73eda753 - ]), + Fr::multiplicative_generator().pow([0xfffe5bfeffffffff, 0x9a1d80553bda402, 0x299d7d483339d808, 0x73eda753]), Fr::root_of_unity() ); assert_eq!(Fr::root_of_unity().pow([1 << Fr::S]), Fr::one()); diff --git a/crates/pairing/src/bls12_381/mod.rs b/crates/pairing/src/bls12_381/mod.rs index 5bc644d..4a99067 100644 --- a/crates/pairing/src/bls12_381/mod.rs +++ b/crates/pairing/src/bls12_381/mod.rs @@ -8,10 +8,7 @@ pub mod fr; #[cfg(test)] mod tests; -pub use self::ec::{ - G1, G1Affine, G1Compressed, G1Prepared, G1Uncompressed, G2, G2Affine, G2Compressed, G2Prepared, - G2Uncompressed, -}; +pub use self::ec::{G1Affine, G1Compressed, G1Prepared, G1Uncompressed, G2Affine, G2Compressed, G2Prepared, G2Uncompressed, G1, G2}; pub use self::fq::{Fq, FqRepr}; pub use self::fq12::Fq12; pub use self::fq2::Fq2; @@ -44,12 +41,7 @@ impl Engine for Bls12 { fn miller_loop<'a, I>(i: I) -> Self::Fqk where - I: IntoIterator< - Item = &'a ( - &'a ::Prepared, - &'a ::Prepared, - ), - >, + I: IntoIterator::Prepared, &'a ::Prepared)>, { let mut pairs = vec![]; for &(p, q) in i { @@ -172,10 +164,7 @@ impl G2Prepared { pub fn from_affine(q: G2Affine) -> Self { if q.is_zero() { - return G2Prepared { - coeffs: vec![], - infinity: true, - }; + return G2Prepared { coeffs: vec![], infinity: true }; } fn doubling_step(r: &mut G2) -> (Fq2, Fq2, Fq2) { @@ -356,10 +345,7 @@ impl G2Prepared { coeffs.push(doubling_step(&mut r)); - G2Prepared { - coeffs, - infinity: false, - } + G2Prepared { coeffs, infinity: false } } } @@ -370,6 +356,6 @@ fn bls12_engine_tests() { #[test] fn bbb() { - let shifting = BLS_X >>1; + let shifting = BLS_X >> 1; println!("{}", shifting); } diff --git a/crates/pairing/src/bls12_381/tests/mod.rs b/crates/pairing/src/bls12_381/tests/mod.rs index dca7bb3..0f4d9a4 100644 --- a/crates/pairing/src/bls12_381/tests/mod.rs +++ b/crates/pairing/src/bls12_381/tests/mod.rs @@ -20,36 +20,39 @@ fn test_pairing_result_against_relic() { 0F41E58663BF08CF 068672CBD01A7EC7 3BACA4D72CA93544 DEFF686BFD6DF543 D48EAA24AFE47E1E FDE449383B676631 */ - assert_eq!(Bls12::pairing(::one(), ::one()), Fq12 { - c0: Fq6 { - c0: Fq2 { - c0: Fq::from_str("2819105605953691245277803056322684086884703000473961065716485506033588504203831029066448642358042597501014294104502").unwrap(), - c1: Fq::from_str("1323968232986996742571315206151405965104242542339680722164220900812303524334628370163366153839984196298685227734799").unwrap() - }, - c1: Fq2 { - c0: Fq::from_str("2987335049721312504428602988447616328830341722376962214011674875969052835043875658579425548512925634040144704192135").unwrap(), - c1: Fq::from_str("3879723582452552452538684314479081967502111497413076598816163759028842927668327542875108457755966417881797966271311").unwrap() - }, - c2: Fq2 { - c0: Fq::from_str("261508182517997003171385743374653339186059518494239543139839025878870012614975302676296704930880982238308326681253").unwrap(), - c1: Fq::from_str("231488992246460459663813598342448669854473942105054381511346786719005883340876032043606739070883099647773793170614").unwrap() - } - }, - c1: Fq6 { - c0: Fq2 { - c0: Fq::from_str("3993582095516422658773669068931361134188738159766715576187490305611759126554796569868053818105850661142222948198557").unwrap(), - c1: Fq::from_str("1074773511698422344502264006159859710502164045911412750831641680783012525555872467108249271286757399121183508900634").unwrap() - }, - c1: Fq2 { - c0: Fq::from_str("2727588299083545686739024317998512740561167011046940249988557419323068809019137624943703910267790601287073339193943").unwrap(), - c1: Fq::from_str("493643299814437640914745677854369670041080344349607504656543355799077485536288866009245028091988146107059514546594").unwrap() + assert_eq!( + Bls12::pairing(::one(), ::one()), + Fq12 { + c0: Fq6 { + c0: Fq2 { + c0: Fq::from_str("2819105605953691245277803056322684086884703000473961065716485506033588504203831029066448642358042597501014294104502").unwrap(), + c1: Fq::from_str("1323968232986996742571315206151405965104242542339680722164220900812303524334628370163366153839984196298685227734799").unwrap() + }, + c1: Fq2 { + c0: Fq::from_str("2987335049721312504428602988447616328830341722376962214011674875969052835043875658579425548512925634040144704192135").unwrap(), + c1: Fq::from_str("3879723582452552452538684314479081967502111497413076598816163759028842927668327542875108457755966417881797966271311").unwrap() + }, + c2: Fq2 { + c0: Fq::from_str("261508182517997003171385743374653339186059518494239543139839025878870012614975302676296704930880982238308326681253").unwrap(), + c1: Fq::from_str("231488992246460459663813598342448669854473942105054381511346786719005883340876032043606739070883099647773793170614").unwrap() + } }, - c2: Fq2 { - c0: Fq::from_str("734401332196641441839439105942623141234148957972407782257355060229193854324927417865401895596108124443575283868655").unwrap(), - c1: Fq::from_str("2348330098288556420918672502923664952620152483128593484301759394583320358354186482723629999370241674973832318248497").unwrap() + c1: Fq6 { + c0: Fq2 { + c0: Fq::from_str("3993582095516422658773669068931361134188738159766715576187490305611759126554796569868053818105850661142222948198557").unwrap(), + c1: Fq::from_str("1074773511698422344502264006159859710502164045911412750831641680783012525555872467108249271286757399121183508900634").unwrap() + }, + c1: Fq2 { + c0: Fq::from_str("2727588299083545686739024317998512740561167011046940249988557419323068809019137624943703910267790601287073339193943").unwrap(), + c1: Fq::from_str("493643299814437640914745677854369670041080344349607504656543355799077485536288866009245028091988146107059514546594").unwrap() + }, + c2: Fq2 { + c0: Fq::from_str("734401332196641441839439105942623141234148957972407782257355060229193854324927417865401895596108124443575283868655").unwrap(), + c1: Fq::from_str("2348330098288556420918672502923664952620152483128593484301759394583320358354186482723629999370241674973832318248497").unwrap() + } } } - }); + ); } fn test_vectors>(expected: &[u8]) { @@ -199,9 +202,7 @@ fn test_g1_uncompressed_invalid_vectors() { if let Err(GroupDecodingError::NotInSubgroup) = o.into_affine() { break; } else { - panic!( - "should have rejected the point because it isn't in the correct subgroup" - ) + panic!("should have rejected the point because it isn't in the correct subgroup") } } else { x.add_assign(&Fq::one()); @@ -341,9 +342,7 @@ fn test_g2_uncompressed_invalid_vectors() { if let Err(GroupDecodingError::NotInSubgroup) = o.into_affine() { break; } else { - panic!( - "should have rejected the point because it isn't in the correct subgroup" - ) + panic!("should have rejected the point because it isn't in the correct subgroup") } } else { x.add_assign(&Fq2::one()); @@ -457,9 +456,7 @@ fn test_g1_compressed_invalid_vectors() { if let Err(GroupDecodingError::NotInSubgroup) = o.into_affine() { break; } else { - panic!( - "should have rejected the point because it isn't in the correct subgroup" - ) + panic!("should have rejected the point because it isn't in the correct subgroup") } } else { x.add_assign(&Fq::one()); @@ -544,10 +541,7 @@ fn test_g2_compressed_invalid_vectors() { { let mut o = o; - let mut x = Fq2 { - c0: Fq::one(), - c1: Fq::one(), - }; + let mut x = Fq2 { c0: Fq::one(), c1: Fq::one() }; loop { let mut x3b = x; @@ -576,10 +570,7 @@ fn test_g2_compressed_invalid_vectors() { { let mut o = o; - let mut x = Fq2 { - c0: Fq::one(), - c1: Fq::one(), - }; + let mut x = Fq2 { c0: Fq::one(), c1: Fq::one() }; loop { let mut x3b = x; @@ -599,9 +590,7 @@ fn test_g2_compressed_invalid_vectors() { if let Err(GroupDecodingError::NotInSubgroup) = o.into_affine() { break; } else { - panic!( - "should have rejected the point because it isn't in the correct subgroup" - ) + panic!("should have rejected the point because it isn't in the correct subgroup") } } else { x.add_assign(&Fq2::one()); diff --git a/crates/pairing/src/bn256/ec.rs b/crates/pairing/src/bn256/ec.rs index 5baf043..5b0a98c 100644 --- a/crates/pairing/src/bn256/ec.rs +++ b/crates/pairing/src/bn256/ec.rs @@ -199,20 +199,12 @@ macro_rules! curve_impl { #[inline(always)] fn from_xy_unchecked(x: Self::Base, y: Self::Base) -> Self { let infinity = x.is_zero() && y.is_zero(); - Self { - x: x, - y: y, - infinity, - } + Self { x: x, y: y, infinity } } fn from_xy_checked(x: Self::Base, y: Self::Base) -> Result { let infinity = x.is_zero() && y.is_zero(); - let affine = Self { - x: x, - y: y, - infinity, - }; + let affine = Self { x: x, y: y, infinity }; if !affine.is_on_curve() { Err(GroupDecodingError::NotOnCurve) @@ -288,12 +280,7 @@ macro_rules! curve_impl { // Ignore normalized elements .filter(|g| !g.is_normalized()) // Backwards, skip last element, fill in one for last term. - .zip( - prod.into_iter() - .rev() - .skip(1) - .chain(Some($basefield::one())), - ) + .zip(prod.into_iter().rev().skip(1).chain(Some($basefield::one()))) { // tmp := tmp * g.z; g.z := tmp * s = 1/z let mut newtmp = tmp; @@ -601,11 +588,7 @@ macro_rules! curve_impl { Self { x, y, z } } - fn from_xyz_checked( - _x: Self::Base, - _y: Self::Base, - _z: Self::Base, - ) -> Result { + fn from_xyz_checked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Result { unimplemented!("on curve check is not implemented for BLS12-381 projective") } } @@ -634,11 +617,7 @@ macro_rules! curve_impl { $affine::zero() } else if p.z == $basefield::one() { // If Z is one, the point is already normalized. - $affine { - x: p.x, - y: p.y, - infinity: false, - } + $affine { x: p.x, y: p.y, infinity: false } } else { // Z is nonzero, so it must have an inverse in a field. let zinv = p.z.inverse().unwrap(); @@ -654,11 +633,7 @@ macro_rules! curve_impl { zinv_powered.mul_assign(&zinv); y.mul_assign(&zinv_powered); - $affine { - x: x, - y: y, - infinity: false, - } + $affine { x: x, y: y, infinity: false } } } } @@ -668,24 +643,12 @@ macro_rules! curve_impl { pub mod g1 { use super::super::{Bn256, Fq, Fq12, FqRepr, Fr, FrRepr}; use super::g2::G2Affine; - use crate::{ - CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError, RawEncodable, - }; + use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError, RawEncodable}; use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; use rand::{Rand, Rng}; use std::fmt; - curve_impl!( - "G1", - G1, - G1Affine, - G1Prepared, - Fq, - Fr, - G1Uncompressed, - G1Compressed, - G2Affine - ); + curve_impl!("G1", G1, G1Affine, G1Prepared, Fq, Fr, G1Uncompressed, G1Compressed, G2Affine); impl RawEncodable for G1Affine { fn into_raw_uncompressed_le(&self) -> Self::Uncompressed { @@ -701,10 +664,7 @@ pub mod g1 { } /// Creates a point from raw encoded coordinates without checking on curve - fn from_raw_uncompressed_le_unchecked( - encoded: &Self::Uncompressed, - _infinity: bool, - ) -> Result { + fn from_raw_uncompressed_le_unchecked(encoded: &Self::Uncompressed, _infinity: bool) -> Result { let copy = encoded.0; if copy.iter().all(|b| *b == 0) { @@ -721,18 +681,13 @@ pub mod g1 { } Ok(G1Affine { - x: Fq::from_raw_repr(x) - .map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?, - y: Fq::from_raw_repr(y) - .map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate", e))?, + x: Fq::from_raw_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?, + y: Fq::from_raw_repr(y).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate", e))?, infinity: false, }) } - fn from_raw_uncompressed_le( - encoded: &Self::Uncompressed, - _infinity: bool, - ) -> Result { + fn from_raw_uncompressed_le(encoded: &Self::Uncompressed, _infinity: bool) -> Result { let affine = Self::from_raw_uncompressed_le_unchecked(&encoded, _infinity)?; if !affine.is_on_curve() { @@ -858,12 +813,8 @@ pub mod g1 { } Ok(G1Affine { - x: Fq::from_repr(x).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate", e) - })?, - y: Fq::from_repr(y).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate", e) - })?, + x: Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?, + y: Fq::from_repr(y).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate", e))?, infinity: false, }) } @@ -961,8 +912,7 @@ pub mod g1 { } // Interpret as Fq element. - let x = Fq::from_repr(x) - .map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?; + let x = Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?; G1Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve) } @@ -1031,8 +981,7 @@ pub mod g1 { } fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { - const RECOMMENDATIONS: [usize; 12] = - [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; + const RECOMMENDATIONS: [usize; 12] = [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; let mut ret = 4; for r in &RECOMMENDATIONS { @@ -1126,17 +1075,7 @@ pub mod g2 { use rand::{Rand, Rng}; use std::fmt; - curve_impl!( - "G2", - G2, - G2Affine, - G2Prepared, - Fq2, - Fr, - G2Uncompressed, - G2Compressed, - G1Affine - ); + curve_impl!("G2", G2, G2Affine, G2Prepared, Fq2, Fr, G2Uncompressed, G2Compressed, G1Affine); impl Rand for G2 { fn rand(rng: &mut R) -> Self { @@ -1247,20 +1186,12 @@ pub mod g2 { Ok(G2Affine { x: Fq2 { - c0: Fq::from_repr(x_c0).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e) - })?, - c1: Fq::from_repr(x_c1).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e) - })?, + c0: Fq::from_repr(x_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e))?, + c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))?, }, y: Fq2 { - c0: Fq::from_repr(y_c0).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate (c0)", e) - })?, - c1: Fq::from_repr(y_c1).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate (c1)", e) - })?, + c0: Fq::from_repr(y_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate (c0)", e))?, + c1: Fq::from_repr(y_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate (c1)", e))?, }, infinity: false, }) @@ -1364,12 +1295,8 @@ pub mod g2 { // Interpret as Fq element. let x = Fq2 { - c0: Fq::from_repr(x_c0).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e) - })?, - c1: Fq::from_repr(x_c1).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e) - })?, + c0: Fq::from_repr(x_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e))?, + c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))?, }; G2Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve) @@ -1408,12 +1335,7 @@ pub mod g2 { pub fn scale_by_cofactor(&self) -> G2 { // G2 cofactor = 2p - n = 2q - r // 0x30644e72e131a029b85045b68181585e06ceecda572a2489345f2299c0f9fa8d - let cofactor = BitIterator::new([ - 0x345f2299c0f9fa8d, - 0x06ceecda572a2489, - 0xb85045b68181585e, - 0x30644e72e131a029, - ]); + let cofactor = BitIterator::new([0x345f2299c0f9fa8d, 0x06ceecda572a2489, 0xb85045b68181585e, 0x30644e72e131a029]); self.mul_bits(cofactor) } @@ -1458,8 +1380,7 @@ pub mod g2 { } fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { - const RECOMMENDATIONS: [usize; 11] = - [1, 3, 8, 20, 47, 126, 260, 826, 1501, 4555, 84071]; + const RECOMMENDATIONS: [usize; 11] = [1, 3, 8, 20, 47, 126, 260, 826, 1501, 4555, 84071]; let mut ret = 4; for r in &RECOMMENDATIONS { diff --git a/crates/pairing/src/bn256/fq.rs b/crates/pairing/src/bn256/fq.rs index e75f2da..05d2ded 100644 --- a/crates/pairing/src/bn256/fq.rs +++ b/crates/pairing/src/bn256/fq.rs @@ -21,271 +21,114 @@ cfg_if::cfg_if! { // B coefficient of BN256 curve, B = 3 // In Montgommery form with R = 2^256 -pub const B_COEFF: Fq = Fq(FqRepr([ - 0x7a17caa950ad28d7, - 0x1f6ac17ae15521b9, - 0x334bea4e696bd284, - 0x2a1f6744ce179d8e, -])); +pub const B_COEFF: Fq = Fq(FqRepr([0x7a17caa950ad28d7, 0x1f6ac17ae15521b9, 0x334bea4e696bd284, 0x2a1f6744ce179d8e])); pub const B_COEFF_FQ2: Fq2 = Fq2 { - c0: Fq(FqRepr([ - 0x3bf938e377b802a8, - 0x020b1b273633535d, - 0x26b7edf049755260, - 0x2514c6324384a86d, - ])), - c1: Fq(FqRepr([ - 0x38e7ecccd1dcff67, - 0x65f0b37d93ce0d3e, - 0xd749d0dd22ac00aa, - 0x0141b9ce4a688d4d, - ])), + c0: Fq(FqRepr([0x3bf938e377b802a8, 0x020b1b273633535d, 0x26b7edf049755260, 0x2514c6324384a86d])), + c1: Fq(FqRepr([0x38e7ecccd1dcff67, 0x65f0b37d93ce0d3e, 0xd749d0dd22ac00aa, 0x0141b9ce4a688d4d])), }; - // The generators of G1/G2 // Generator of G1 // x = 1 // y = 2 -pub const G1_GENERATOR_X: Fq = Fq(FqRepr([ - 0xd35d438dc58f0d9d, - 0x0a78eb28f5c70b3d, - 0x666ea36f7879462c, - 0x0e0a77c19a07df2f, -])); -pub const G1_GENERATOR_Y: Fq = Fq(FqRepr([ - 0xa6ba871b8b1e1b3a, - 0x14f1d651eb8e167b, - 0xccdd46def0f28c58, - 0x1c14ef83340fbe5e, -])); +pub const G1_GENERATOR_X: Fq = Fq(FqRepr([0xd35d438dc58f0d9d, 0x0a78eb28f5c70b3d, 0x666ea36f7879462c, 0x0e0a77c19a07df2f])); +pub const G1_GENERATOR_Y: Fq = Fq(FqRepr([0xa6ba871b8b1e1b3a, 0x14f1d651eb8e167b, 0xccdd46def0f28c58, 0x1c14ef83340fbe5e])); // Generator of G2 -// -// x = 11559732032986387107991004021392285783925812861821192530917403151452391805634*u +// +// x = 11559732032986387107991004021392285783925812861821192530917403151452391805634*u // + 10857046999023057135944570762232829481370756359578518086990519993285655852781 // -// y = 4082367875863433681332203403145435568316851327593401208105741076214120093531*u +// y = 4082367875863433681332203403145435568316851327593401208105741076214120093531*u // + 8495653923123431417604973247489272438418190587263600148770280649306958101930 -pub const G2_GENERATOR_X_C0: Fq = Fq(FqRepr([ - 0x8e83b5d102bc2026, - 0xdceb1935497b0172, - 0xfbb8264797811adf, - 0x19573841af96503b, -])); -pub const G2_GENERATOR_X_C1: Fq = Fq(FqRepr([ - 0xafb4737da84c6140, - 0x6043dd5a5802d8c4, - 0x09e950fc52a02f86, - 0x14fef0833aea7b6b, -])); -pub const G2_GENERATOR_Y_C0: Fq = Fq(FqRepr([ - 0x619dfa9d886be9f6, - 0xfe7fd297f59e9b78, - 0xff9e1a62231b7dfe, - 0x28fd7eebae9e4206, -])); -pub const G2_GENERATOR_Y_C1: Fq = Fq(FqRepr([ - 0x64095b56c71856ee, - 0xdc57f922327d3cbb, - 0x55f935be33351076, - 0x0da4a0e693fd6482, -])); - +pub const G2_GENERATOR_X_C0: Fq = Fq(FqRepr([0x8e83b5d102bc2026, 0xdceb1935497b0172, 0xfbb8264797811adf, 0x19573841af96503b])); +pub const G2_GENERATOR_X_C1: Fq = Fq(FqRepr([0xafb4737da84c6140, 0x6043dd5a5802d8c4, 0x09e950fc52a02f86, 0x14fef0833aea7b6b])); +pub const G2_GENERATOR_Y_C0: Fq = Fq(FqRepr([0x619dfa9d886be9f6, 0xfe7fd297f59e9b78, 0xff9e1a62231b7dfe, 0x28fd7eebae9e4206])); +pub const G2_GENERATOR_Y_C1: Fq = Fq(FqRepr([0x64095b56c71856ee, 0xdc57f922327d3cbb, 0x55f935be33351076, 0x0da4a0e693fd6482])); // Coefficients for the Frobenius automorphism. pub const FROBENIUS_COEFF_FQ2_C1: [Fq; 2] = [ // Fq(-1)**(((q^0) - 1) / 2) // it's 1 in Montgommery form - Fq(FqRepr([ - 0xd35d438dc58f0d9d, - 0x0a78eb28f5c70b3d, - 0x666ea36f7879462c, - 0x0e0a77c19a07df2f, - ])), + Fq(FqRepr([0xd35d438dc58f0d9d, 0x0a78eb28f5c70b3d, 0x666ea36f7879462c, 0x0e0a77c19a07df2f])), // Fq(-1)**(((q^1) - 1) / 2) - Fq(FqRepr([ - 0x68c3488912edefaa, - 0x8d087f6872aabf4f, - 0x51e1a24709081231, - 0x2259d6b14729c0fa, - ])), + Fq(FqRepr([0x68c3488912edefaa, 0x8d087f6872aabf4f, 0x51e1a24709081231, 0x2259d6b14729c0fa])), ]; - // Fq2(u + 9)**(((q^1) - 1) / 2) +// Fq2(u + 9)**(((q^1) - 1) / 2) pub const XI_TO_Q_MINUS_1_OVER_2: Fq2 = Fq2 { - c0: Fq(FqRepr([ - 0xe4bbdd0c2936b629, - 0xbb30f162e133bacb, - 0x31a9d1b6f9645366, - 0x253570bea500f8dd, - ])), - c1: Fq(FqRepr([ - 0xa1d77ce45ffe77c7, - 0x07affd117826d1db, - 0x6d16bd27bb7edc6b, - 0x2c87200285defecc, - ])), + c0: Fq(FqRepr([0xe4bbdd0c2936b629, 0xbb30f162e133bacb, 0x31a9d1b6f9645366, 0x253570bea500f8dd])), + c1: Fq(FqRepr([0xa1d77ce45ffe77c7, 0x07affd117826d1db, 0x6d16bd27bb7edc6b, 0x2c87200285defecc])), }; pub const FROBENIUS_COEFF_FQ6_C1: [Fq2; 6] = [ // Fq2(u + 9)**(((q^0) - 1) / 3) Fq2 { - c0: Fq(FqRepr([ - 0xd35d438dc58f0d9d, - 0x0a78eb28f5c70b3d, - 0x666ea36f7879462c, - 0x0e0a77c19a07df2f, - ])), + c0: Fq(FqRepr([0xd35d438dc58f0d9d, 0x0a78eb28f5c70b3d, 0x666ea36f7879462c, 0x0e0a77c19a07df2f])), c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 9)**(((q^1) - 1) / 3) // taken from go-ethereum and also re-calculated manually Fq2 { - c0: Fq(FqRepr([ - 0xb5773b104563ab30, - 0x347f91c8a9aa6454, - 0x7a007127242e0991, - 0x1956bcd8118214ec, - ])), - c1: Fq(FqRepr([ - 0x6e849f1ea0aa4757, - 0xaa1c7b6d89f89141, - 0xb6e713cdfae0ca3a, - 0x26694fbb4e82ebc3, - ])), + c0: Fq(FqRepr([0xb5773b104563ab30, 0x347f91c8a9aa6454, 0x7a007127242e0991, 0x1956bcd8118214ec])), + c1: Fq(FqRepr([0x6e849f1ea0aa4757, 0xaa1c7b6d89f89141, 0xb6e713cdfae0ca3a, 0x26694fbb4e82ebc3])), }, // Fq2(u + 9)**(((q^2) - 1) / 3) // this one and other below are recalculated manually Fq2 { - c0: Fq(FqRepr([ - 0x3350c88e13e80b9c, - 0x7dce557cdb5e56b9, - 0x6001b4b8b615564a, - 0x2682e617020217e0, - ])), + c0: Fq(FqRepr([0x3350c88e13e80b9c, 0x7dce557cdb5e56b9, 0x6001b4b8b615564a, 0x2682e617020217e0])), c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 9)**(((q^3) - 1) / 3) Fq2 { - c0: Fq(FqRepr([ - 0xc9af22f716ad6bad, - 0xb311782a4aa662b2, - 0x19eeaf64e248c7f4, - 0x20273e77e3439f82, - ])), - c1: Fq(FqRepr([ - 0xacc02860f7ce93ac, - 0x3933d5817ba76b4c, - 0x69e6188b446c8467, - 0x0a46036d4417cc55, - ])), + c0: Fq(FqRepr([0xc9af22f716ad6bad, 0xb311782a4aa662b2, 0x19eeaf64e248c7f4, 0x20273e77e3439f82])), + c1: Fq(FqRepr([0xacc02860f7ce93ac, 0x3933d5817ba76b4c, 0x69e6188b446c8467, 0x0a46036d4417cc55])), }, // Fq2(u + 9)**(((q^4) - 1) / 3) Fq2 { - c0: Fq(FqRepr([ - 0x71930c11d782e155, - 0xa6bb947cffbe3323, - 0xaa303344d4741444, - 0x2c3b3f0d26594943, - ])), - c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0,])), + c0: Fq(FqRepr([0x71930c11d782e155, 0xa6bb947cffbe3323, 0xaa303344d4741444, 0x2c3b3f0d26594943])), + c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 9)**(((q^5) - 1) / 3) Fq2 { - c0: Fq(FqRepr([ - 0xf91aba2654e8e3b1, - 0x4771cb2fdc92ce12, - 0xdcb16ae0fc8bdf35, - 0x274aa195cd9d8be4, - ])), - c1: Fq(FqRepr([ - 0x5cfc50ae18811f8b, - 0x4bb28433cb43988c, - 0x4fd35f13c3b56219, - 0x301949bd2fc8883a, - ])), + c0: Fq(FqRepr([0xf91aba2654e8e3b1, 0x4771cb2fdc92ce12, 0xdcb16ae0fc8bdf35, 0x274aa195cd9d8be4])), + c1: Fq(FqRepr([0x5cfc50ae18811f8b, 0x4bb28433cb43988c, 0x4fd35f13c3b56219, 0x301949bd2fc8883a])), }, ]; pub const FROBENIUS_COEFF_FQ6_C2: [Fq2; 6] = [ // Fq2(u + 1)**(((2q^0) - 2) / 3) Fq2 { - c0: Fq(FqRepr([ - 0xd35d438dc58f0d9d, - 0x0a78eb28f5c70b3d, - 0x666ea36f7879462c, - 0x0e0a77c19a07df2f, - ])), + c0: Fq(FqRepr([0xd35d438dc58f0d9d, 0x0a78eb28f5c70b3d, 0x666ea36f7879462c, 0x0e0a77c19a07df2f])), c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 1)**(((2q^1) - 2) / 3) Fq2 { - c0: Fq(FqRepr([ - 0x7361d77f843abe92, - 0xa5bb2bd3273411fb, - 0x9c941f314b3e2399, - 0x15df9cddbb9fd3ec, - ])), - c1: Fq(FqRepr([ - 0x5dddfd154bd8c949, - 0x62cb29a5a4445b60, - 0x37bc870a0c7dd2b9, - 0x24830a9d3171f0fd, - ])), + c0: Fq(FqRepr([0x7361d77f843abe92, 0xa5bb2bd3273411fb, 0x9c941f314b3e2399, 0x15df9cddbb9fd3ec])), + c1: Fq(FqRepr([0x5dddfd154bd8c949, 0x62cb29a5a4445b60, 0x37bc870a0c7dd2b9, 0x24830a9d3171f0fd])), }, // Fq2(u + 1)**(((2q^2) - 2) / 3) Fq2 { - c0: Fq(FqRepr([ - 0x71930c11d782e155, - 0xa6bb947cffbe3323, - 0xaa303344d4741444, - 0x2c3b3f0d26594943, - ])), - c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0,])), + c0: Fq(FqRepr([0x71930c11d782e155, 0xa6bb947cffbe3323, 0xaa303344d4741444, 0x2c3b3f0d26594943])), + c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 1)**(((2q^3) - 2) / 3) Fq2 { - c0: Fq(FqRepr([ - 0x448a93a57b6762df, - 0xbfd62df528fdeadf, - 0xd858f5d00e9bd47a, - 0x06b03d4d3476ec58, - ])), - c1: Fq(FqRepr([ - 0x2b19daf4bcc936d1, - 0xa1a54e7a56f4299f, - 0xb533eee05adeaef1, - 0x170c812b84dda0b2, - ])), + c0: Fq(FqRepr([0x448a93a57b6762df, 0xbfd62df528fdeadf, 0xd858f5d00e9bd47a, 0x06b03d4d3476ec58])), + c1: Fq(FqRepr([0x2b19daf4bcc936d1, 0xa1a54e7a56f4299f, 0xb533eee05adeaef1, 0x170c812b84dda0b2])), }, // Fq2(u + 1)**(((2q^4) - 2) / 3) Fq2 { - c0: Fq(FqRepr([ - 0x3350c88e13e80b9c, - 0x7dce557cdb5e56b9, - 0x6001b4b8b615564a, - 0x2682e617020217e0, - ])), - c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0,])), + c0: Fq(FqRepr([0x3350c88e13e80b9c, 0x7dce557cdb5e56b9, 0x6001b4b8b615564a, 0x2682e617020217e0])), + c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 1)**(((2q^5) - 2) / 3) Fq2 { - c0: Fq(FqRepr([ - 0x843420f1d8dadbd6, - 0x31f010c9183fcdb2, - 0x436330b527a76049, - 0x13d47447f11adfe4, - ])), - c1: Fq(FqRepr([ - 0xef494023a857fa74, - 0x2a925d02d5ab101a, - 0x83b015829ba62f10, - 0x2539111d0c13aea3, - ])), + c0: Fq(FqRepr([0x843420f1d8dadbd6, 0x31f010c9183fcdb2, 0x436330b527a76049, 0x13d47447f11adfe4])), + c1: Fq(FqRepr([0xef494023a857fa74, 0x2a925d02d5ab101a, 0x83b015829ba62f10, 0x2539111d0c13aea3])), }, ]; @@ -293,163 +136,68 @@ pub const FROBENIUS_COEFF_FQ6_C2: [Fq2; 6] = [ pub const FROBENIUS_COEFF_FQ12_C1: [Fq2; 12] = [ // Fq2(u + 1)**(((q^0) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0xd35d438dc58f0d9d, - 0x0a78eb28f5c70b3d, - 0x666ea36f7879462c, - 0x0e0a77c19a07df2f, - ])), + c0: Fq(FqRepr([0xd35d438dc58f0d9d, 0x0a78eb28f5c70b3d, 0x666ea36f7879462c, 0x0e0a77c19a07df2f])), c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 1)**(((q^1) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0xaf9ba69633144907, - 0xca6b1d7387afb78a, - 0x11bded5ef08a2087, - 0x02f34d751a1f3a7c, - ])), - c1: Fq(FqRepr([ - 0xa222ae234c492d72, - 0xd00f02a4565de15b, - 0xdc2ff3a253dfc926, - 0x10a75716b3899551, - ])), + c0: Fq(FqRepr([0xaf9ba69633144907, 0xca6b1d7387afb78a, 0x11bded5ef08a2087, 0x02f34d751a1f3a7c])), + c1: Fq(FqRepr([0xa222ae234c492d72, 0xd00f02a4565de15b, 0xdc2ff3a253dfc926, 0x10a75716b3899551])), }, // Fq2(u + 1)**(((q^2) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0xca8d800500fa1bf2, - 0xf0c5d61468b39769, - 0x0e201271ad0d4418, - 0x04290f65bad856e6, - ])), + c0: Fq(FqRepr([0xca8d800500fa1bf2, 0xf0c5d61468b39769, 0x0e201271ad0d4418, 0x04290f65bad856e6])), c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 1)**(((q^3) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0x365316184e46d97d, - 0x0af7129ed4c96d9f, - 0x659da72fca1009b5, - 0x08116d8983a20d23, - ])), - c1: Fq(FqRepr([ - 0xb1df4af7c39c1939, - 0x3d9f02878a73bf7f, - 0x9b2220928caf0ae0, - 0x26684515eff054a6, - ])), + c0: Fq(FqRepr([0x365316184e46d97d, 0x0af7129ed4c96d9f, 0x659da72fca1009b5, 0x08116d8983a20d23])), + c1: Fq(FqRepr([0xb1df4af7c39c1939, 0x3d9f02878a73bf7f, 0x9b2220928caf0ae0, 0x26684515eff054a6])), }, // Fq2(u + 1)**(((q^4) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0x3350c88e13e80b9c, - 0x7dce557cdb5e56b9, - 0x6001b4b8b615564a, - 0x2682e617020217e0, - ])), - c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0,])), + c0: Fq(FqRepr([0x3350c88e13e80b9c, 0x7dce557cdb5e56b9, 0x6001b4b8b615564a, 0x2682e617020217e0])), + c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 1)**(((q^5) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0x86b76f821b329076, - 0x408bf52b4d19b614, - 0x53dfb9d0d985e92d, - 0x051e20146982d2a7, - ])), - c1: Fq(FqRepr([ - 0x0fbc9cd47752ebc7, - 0x6d8fffe33415de24, - 0xbef22cf038cf41b9, - 0x15c0edff3c66bf54, - ])), + c0: Fq(FqRepr([0x86b76f821b329076, 0x408bf52b4d19b614, 0x53dfb9d0d985e92d, 0x051e20146982d2a7])), + c1: Fq(FqRepr([0x0fbc9cd47752ebc7, 0x6d8fffe33415de24, 0xbef22cf038cf41b9, 0x15c0edff3c66bf54])), }, // Fq2(u + 1)**(((q^6) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0x68c3488912edefaa, - 0x8d087f6872aabf4f, - 0x51e1a24709081231, - 0x2259d6b14729c0fa, - ])), - c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0,])), + c0: Fq(FqRepr([0x68c3488912edefaa, 0x8d087f6872aabf4f, 0x51e1a24709081231, 0x2259d6b14729c0fa])), + c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 1)**(((q^7) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0x8c84e580a568b440, - 0xcd164d1de0c21302, - 0xa692585790f737d5, - 0x2d7100fdc71265ad, - ])), - c1: Fq(FqRepr([ - 0x99fdddf38c33cfd5, - 0xc77267ed1213e931, - 0xdc2052142da18f36, - 0x1fbcf75c2da80ad7, - ])), + c0: Fq(FqRepr([0x8c84e580a568b440, 0xcd164d1de0c21302, 0xa692585790f737d5, 0x2d7100fdc71265ad])), + c1: Fq(FqRepr([0x99fdddf38c33cfd5, 0xc77267ed1213e931, 0xdc2052142da18f36, 0x1fbcf75c2da80ad7])), }, // Fq2(u + 1)**(((q^8) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0x71930c11d782e155, - 0xa6bb947cffbe3323, - 0xaa303344d4741444, - 0x2c3b3f0d26594943, - ])), - c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0,])), + c0: Fq(FqRepr([0x71930c11d782e155, 0xa6bb947cffbe3323, 0xaa303344d4741444, 0x2c3b3f0d26594943])), + c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 1)**(((q^9) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0x05cd75fe8a3623ca, - 0x8c8a57f293a85cee, - 0x52b29e86b7714ea8, - 0x2852e0e95d8f9306, - ])), - c1: Fq(FqRepr([ - 0x8a41411f14e0e40e, - 0x59e26809ddfe0b0d, - 0x1d2e2523f4d24d7d, - 0x09fc095cf1414b83, - ])), + c0: Fq(FqRepr([0x05cd75fe8a3623ca, 0x8c8a57f293a85cee, 0x52b29e86b7714ea8, 0x2852e0e95d8f9306])), + c1: Fq(FqRepr([0x8a41411f14e0e40e, 0x59e26809ddfe0b0d, 0x1d2e2523f4d24d7d, 0x09fc095cf1414b83])), }, // Fq2(u + 1)**(((q^10) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0x08cfc388c494f1ab, - 0x19b315148d1373d4, - 0x584e90fdcb6c0213, - 0x09e1685bdf2f8849, - ])), - c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0,])), + c0: Fq(FqRepr([0x08cfc388c494f1ab, 0x19b315148d1373d4, 0x584e90fdcb6c0213, 0x09e1685bdf2f8849])), + c1: Fq(FqRepr([0x0, 0x0, 0x0, 0x0])), }, // Fq2(u + 1)**(((q^11) - 1) / 6) Fq2 { - c0: Fq(FqRepr([ - 0xb5691c94bd4a6cd1, - 0x56f575661b581478, - 0x64708be5a7fb6f30, - 0x2b462e5e77aecd82, - ])), - c1: Fq(FqRepr([ - 0x2c63ef42612a1180, - 0x29f16aae345bec69, - 0xf95e18c648b216a4, - 0x1aa36073a4cae0d4, - ])), + c0: Fq(FqRepr([0xb5691c94bd4a6cd1, 0x56f575661b581478, 0x64708be5a7fb6f30, 0x2b462e5e77aecd82])), + c1: Fq(FqRepr([0x2c63ef42612a1180, 0x29f16aae345bec69, 0xf95e18c648b216a4, 0x1aa36073a4cae0d4])), }, ]; // -((2**256) mod q) mod q -pub const NEGATIVE_ONE: Fq = Fq(FqRepr([ - 0x974bc177a0000006, - 0xf13771b2da58a367, - 0x51e1a2470908122e, - 0x2259d6b14729c0fa, -])); +pub const NEGATIVE_ONE: Fq = Fq(FqRepr([0x974bc177a0000006, 0xf13771b2da58a367, 0x51e1a2470908122e, 0x2259d6b14729c0fa])); #[cfg(test)] use rand::{Rand, SeedableRng, XorShiftRng}; @@ -493,22 +241,8 @@ fn test_fq_is_valid() { a.0.sub_noborrow(&FqRepr::from(1)); assert!(a.is_valid()); assert!(Fq(FqRepr::from(0)).is_valid()); - assert!( - Fq(FqRepr([ - 0xdf4671abd14dab3e, - 0xe2dc0c9f534fbd33, - 0x31ca6c880cc444a6, - 0x257a67e70ef33359 - ])).is_valid() - ); - assert!( - !Fq(FqRepr([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - ])).is_valid() - ); + assert!(Fq(FqRepr([0xdf4671abd14dab3e, 0xe2dc0c9f534fbd33, 0x31ca6c880cc444a6, 0x257a67e70ef33359])).is_valid()); + assert!(!Fq(FqRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,])).is_valid()); let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -524,10 +258,7 @@ fn test_fq_repr_display() { format!("{}", Fq::into_repr(&Fq::one())), "0x0000000000000000000000000000000000000000000000000000000000000001".to_string() ); - assert_eq!( - format!("{}", FqRepr([0, 0, 0, 0])), - "0x0000000000000000000000000000000000000000000000000000000000000000".to_string() - ); + assert_eq!(format!("{}", FqRepr([0, 0, 0, 0])), "0x0000000000000000000000000000000000000000000000000000000000000000".to_string()); } #[test] @@ -577,7 +308,7 @@ fn test_fq_sqrt_2() { print!("x = {}\n", x); if let Some(y) = x.sqrt() { print!("y = {}\n", y); - let mut y_other = y; + let mut y_other = y; y_other.negate(); print!("y' = {}\n", y_other); } diff --git a/crates/pairing/src/bn256/fq12.rs b/crates/pairing/src/bn256/fq12.rs index 4161b94..3084651 100644 --- a/crates/pairing/src/bn256/fq12.rs +++ b/crates/pairing/src/bn256/fq12.rs @@ -19,10 +19,7 @@ impl ::std::fmt::Display for Fq12 { impl Rand for Fq12 { fn rand(rng: &mut R) -> Self { - Fq12 { - c0: rng.gen(), - c1: rng.gen(), - } + Fq12 { c0: rng.gen(), c1: rng.gen() } } } @@ -53,33 +50,23 @@ impl Fq12 { // // multiply by (c0, c1, c2) + (c3, c4, c5)*w where only c0, c3 and c4 are non-zero pub fn mul_by_034(&mut self, c0: &Fq2, c3: &Fq2, c4: &Fq2) { self.mul_assign(&Fq12 { - c0: Fq6 { - c0: *c0, - c1: Fq2::zero(), - c2: Fq2::zero(), - }, - c1: Fq6 { - c0: *c3, - c1: *c4, - c2: Fq2::zero(), - }, + c0: Fq6 { + c0: *c0, + c1: Fq2::zero(), + c2: Fq2::zero(), + }, + c1: Fq6 { c0: *c3, c1: *c4, c2: Fq2::zero() }, }); } } impl Field for Fq12 { fn zero() -> Self { - Fq12 { - c0: Fq6::zero(), - c1: Fq6::zero(), - } + Fq12 { c0: Fq6::zero(), c1: Fq6::zero() } } fn one() -> Self { - Fq12 { - c0: Fq6::one(), - c1: Fq6::zero(), - } + Fq12 { c0: Fq6::one(), c1: Fq6::zero() } } fn is_zero(&self) -> bool { @@ -183,11 +170,7 @@ fn test_fq12_mul_by_014() { a.mul_by_014(&c0, &c1, &c5); b.mul_assign(&Fq12 { - c0: Fq6 { - c0: c0, - c1: c1, - c2: Fq2::zero(), - }, + c0: Fq6 { c0: c0, c1: c1, c2: Fq2::zero() }, c1: Fq6 { c0: Fq2::zero(), c1: c5, diff --git a/crates/pairing/src/bn256/fq2.rs b/crates/pairing/src/bn256/fq2.rs index 069fd92..98c9795 100644 --- a/crates/pairing/src/bn256/fq2.rs +++ b/crates/pairing/src/bn256/fq2.rs @@ -1,4 +1,4 @@ -use super::fq::{FROBENIUS_COEFF_FQ2_C1, Fq, NEGATIVE_ONE}; +use super::fq::{Fq, FROBENIUS_COEFF_FQ2_C1, NEGATIVE_ONE}; use ff::{Field, SqrtField}; use rand::{Rand, Rng}; @@ -102,26 +102,17 @@ impl Fq2 { impl Rand for Fq2 { fn rand(rng: &mut R) -> Self { - Fq2 { - c0: rng.gen(), - c1: rng.gen(), - } + Fq2 { c0: rng.gen(), c1: rng.gen() } } } impl Field for Fq2 { fn zero() -> Self { - Fq2 { - c0: Fq::zero(), - c1: Fq::zero(), - } + Fq2 { c0: Fq::zero(), c1: Fq::zero() } } fn one() -> Self { - Fq2 { - c0: Fq::one(), - c1: Fq::zero(), - } + Fq2 { c0: Fq::one(), c1: Fq::zero() } } fn is_zero(&self) -> bool { @@ -186,10 +177,7 @@ impl Field for Fq2 { t0.square(); t0.add_assign(&t1); t0.inverse().map(|t| { - let mut tmp = Fq2 { - c0: self.c0, - c1: self.c1, - }; + let mut tmp = Fq2 { c0: self.c0, c1: self.c1 }; tmp.c0.mul_assign(&t); tmp.c1.mul_assign(&t); tmp.c1.negate(); @@ -215,12 +203,7 @@ impl SqrtField for Fq2 { Some(Self::zero()) } else { // a1 = self^((q - 3) / 4) - let mut a1 = self.pow([ - 0x4f082305b61f3f51, - 0x65e05aa45a1c72a3, - 0x6e14116da0605617, - 0x0c19139cb84c680a, - ]); + let mut a1 = self.pow([0x4f082305b61f3f51, 0x65e05aa45a1c72a3, 0x6e14116da0605617, 0x0c19139cb84c680a]); let mut alpha = a1; alpha.square(); alpha.mul_assign(self); @@ -228,10 +211,7 @@ impl SqrtField for Fq2 { a0.frobenius_map(1); a0.mul_assign(&alpha); - let neg1 = Fq2 { - c0: NEGATIVE_ONE, - c1: Fq::zero(), - }; + let neg1 = Fq2 { c0: NEGATIVE_ONE, c1: Fq::zero() }; if a0 == neg1 { None @@ -239,19 +219,11 @@ impl SqrtField for Fq2 { a1.mul_assign(self); if alpha == neg1 { - a1.mul_assign(&Fq2 { - c0: Fq::zero(), - c1: Fq::one(), - }); + a1.mul_assign(&Fq2 { c0: Fq::zero(), c1: Fq::one() }); } else { alpha.add_assign(&Fq2::one()); // alpha = alpha^((q - 1) / 2) - alpha = alpha.pow([ - 0x9e10460b6c3e7ea3, - 0xcbc0b548b438e546, - 0xdc2822db40c0ac2e, - 0x183227397098d014, - ]); + alpha = alpha.pow([0x9e10460b6c3e7ea3, 0xcbc0b548b438e546, 0xdc2822db40c0ac2e, 0x183227397098d014]); a1.mul_assign(&alpha); } @@ -282,14 +254,9 @@ fn test_fq2_frobc1() { let mut a = Fq2::one(); a.mul_by_nonresidue(); - let res1 = a.pow([ - 0x69602eb24829a9c2, - 0xdd2b2385cd7b4384, - 0xe81ac1e7808072c9, - 0x10216f7ba065e00d, - ]); + let res1 = a.pow([0x69602eb24829a9c2, 0xdd2b2385cd7b4384, 0xe81ac1e7808072c9, 0x10216f7ba065e00d]); print!("Frob1 = {}\n", res1); - + let res2 = a.pow([ 0x691c1d8b62747890, 0x8cab57b9adf8eb00, @@ -299,7 +266,7 @@ fn test_fq2_frobc1() { 0xe5592c705cbd1cac, 0x1dde2529566d9b5e, 0x030c96e827699534, - ]); + ]); print!("Frob2 = {}\n", res2); let res3 = a.pow([ @@ -315,7 +282,7 @@ fn test_fq2_frobc1() { 0x7806da9ba1f6d7fb, 0x110a40708107d53a, 0x00938e25ae57c88f, - ]); + ]); print!("Frob3 = {}\n", res3); let res4 = a.pow([ @@ -335,7 +302,7 @@ fn test_fq2_frobc1() { 0x1cba0005b295d5bc, 0x319c8e7f94b31729, 0x001be477ceef2455, - ]); + ]); print!("Frob4 = {}\n", res4); let res5 = a.pow([ @@ -359,7 +326,7 @@ fn test_fq2_frobc1() { 0x06f8a7579371f67f, 0xa94a371ceb68884c, 0x000545c441ba73d6, - ]); + ]); print!("Frob5 = {}\n", res5); let res6 = a.pow([ @@ -387,7 +354,7 @@ fn test_fq2_frobc1() { 0xfb508020969bab31, 0xb8b71e4e258cf968, 0x0000ff25aa9c2350, - ]); + ]); print!("Frob6 = {}\n", res6); } @@ -398,14 +365,9 @@ fn test_fq2_frobc2() { let mut a = Fq2::one(); a.mul_by_nonresidue(); - let res1 = a.pow([ - 0xd2c05d6490535384, - 0xba56470b9af68708, - 0xd03583cf0100e593, - 0x2042def740cbc01b, - ]); + let res1 = a.pow([0xd2c05d6490535384, 0xba56470b9af68708, 0xd03583cf0100e593, 0x2042def740cbc01b]); print!("Frob1 = {}\n", res1); - + let res2 = a.pow([ 0xd2383b16c4e8f120, 0x1956af735bf1d600, @@ -415,7 +377,7 @@ fn test_fq2_frobc2() { 0xcab258e0b97a3959, 0x3bbc4a52acdb36bd, 0x06192dd04ed32a68, - ]); + ]); print!("Frob2 = {}\n", res2); let res3 = a.pow([ @@ -431,7 +393,7 @@ fn test_fq2_frobc2() { 0xf00db53743edaff6, 0x221480e1020faa74, 0x01271c4b5caf911e, - ]); + ]); print!("Frob3 = {}\n", res3); let res4 = a.pow([ @@ -451,7 +413,7 @@ fn test_fq2_frobc2() { 0x3974000b652bab79, 0x63391cff29662e52, 0x0037c8ef9dde48aa, - ]); + ]); print!("Frob4 = {}\n", res4); let res5 = a.pow([ @@ -475,7 +437,7 @@ fn test_fq2_frobc2() { 0x0df14eaf26e3ecff, 0x52946e39d6d11098, 0x000a8b888374e7ad, - ]); + ]); print!("Frob5 = {}\n", res5); let res6 = a.pow([ @@ -503,7 +465,7 @@ fn test_fq2_frobc2() { 0xf6a100412d375662, 0x716e3c9c4b19f2d1, 0x0001fe4b553846a1, - ]); + ]); print!("Frob6 = {}\n", res6); } @@ -514,14 +476,9 @@ fn test_fq2_frob12() { let mut a = Fq2::one(); a.mul_by_nonresidue(); - let res1 = a.pow([ - 0x34b017592414d4e1, - 0xee9591c2e6bda1c2, - 0xf40d60f3c0403964, - 0x0810b7bdd032f006, - ]); + let res1 = a.pow([0x34b017592414d4e1, 0xee9591c2e6bda1c2, 0xf40d60f3c0403964, 0x0810b7bdd032f006]); print!("Frob1 = {}\n", res1); - + let res2 = a.pow([ 0x348e0ec5b13a3c48, 0xc655abdcd6fc7580, @@ -531,7 +488,7 @@ fn test_fq2_frob12() { 0x72ac96382e5e8e56, 0x0eef1294ab36cdaf, 0x01864b7413b4ca9a, - ]); + ]); print!("Frob2 = {}\n", res2); let res3 = a.pow([ @@ -547,7 +504,7 @@ fn test_fq2_frob12() { 0x3c036d4dd0fb6bfd, 0x888520384083ea9d, 0x0049c712d72be447, - ]); + ]); print!("Frob3 = {}\n", res3); let res4 = a.pow([ @@ -567,7 +524,7 @@ fn test_fq2_frob12() { 0x8e5d0002d94aeade, 0x98ce473fca598b94, 0x000df23be777922a, - ]); + ]); print!("Frob4 = {}\n", res4); let res5 = a.pow([ @@ -591,7 +548,7 @@ fn test_fq2_frob12() { 0x037c53abc9b8fb3f, 0x54a51b8e75b44426, 0x0002a2e220dd39eb, - ]); + ]); print!("Frob5 = {}\n", res5); let res6 = a.pow([ @@ -619,7 +576,7 @@ fn test_fq2_frob12() { 0x7da840104b4dd598, 0x5c5b8f2712c67cb4, 0x00007f92d54e11a8, - ]); + ]); print!("Frob6 = {}\n", res6); let res7 = a.pow([ @@ -651,7 +608,7 @@ fn test_fq2_frob12() { 0xd055177a2fbfcd94, 0x059f68dd1e0cb392, 0x0000181d8471f268, - ]); + ]); print!("Frob7 = {}\n", res7); let res8 = a.pow([ @@ -687,139 +644,145 @@ fn test_fq2_frob12() { 0x516ac4b20d800019, 0x826e9ab28689a4d3, 0x0000048efbc0eaac, - ]); + ]); print!("Frob8 = {}\n", res8); - let res9 = a.pow(&[ - 0x64984dce4c07e3c1, - 0x2e2096f441339496, - 0xd50c9bd49d279670, - 0xd52ead3ce3a93422, - 0x426dad5fc6a6779a, - 0x3f9dd6b6f19bc638, - 0x6be503d3981b0db5, - 0x0b222e7512412d2c, - 0x484bd275e77ff0bf, - 0xb357542fb851205b, - 0xd8c995246bf492ff, - 0xc6b92fc3bf2887bc, - 0xcd27cfd0d4499277, - 0x967aa0012f40dcf9, - 0x312baab0f5bc64e3, - 0xe465b3c98a822e05, - 0x3133d12c8828f7b8, - 0x357a20a6a8a244ca, - 0xd40b61719905e5b9, - 0xcc4f1d5e2aed7a75, - 0x7895032e16409563, - 0x536db2a17eb54630, - 0xdd66ae0d2d5ac57e, - 0xe150b5a7f229f541, - 0xd882dbabee789616, - 0x1f380eb8775416ca, - 0x73eca6c1c0abcd02, - 0x8bd4f78c2fe1861e, - 0xc53f421003b18ea2, - 0xcae3f7b5d0591ecb, - 0xbebe6ab21737113e, - 0x838f0df2a5f7f26d, - 0xbc2aa2593b06d88f, - 0x0cb02b95a74a8a0a, - 0x74bd9a7b50725838, - 0x000000dc98741fbf, - ][..]); + let res9 = a.pow( + &[ + 0x64984dce4c07e3c1, + 0x2e2096f441339496, + 0xd50c9bd49d279670, + 0xd52ead3ce3a93422, + 0x426dad5fc6a6779a, + 0x3f9dd6b6f19bc638, + 0x6be503d3981b0db5, + 0x0b222e7512412d2c, + 0x484bd275e77ff0bf, + 0xb357542fb851205b, + 0xd8c995246bf492ff, + 0xc6b92fc3bf2887bc, + 0xcd27cfd0d4499277, + 0x967aa0012f40dcf9, + 0x312baab0f5bc64e3, + 0xe465b3c98a822e05, + 0x3133d12c8828f7b8, + 0x357a20a6a8a244ca, + 0xd40b61719905e5b9, + 0xcc4f1d5e2aed7a75, + 0x7895032e16409563, + 0x536db2a17eb54630, + 0xdd66ae0d2d5ac57e, + 0xe150b5a7f229f541, + 0xd882dbabee789616, + 0x1f380eb8775416ca, + 0x73eca6c1c0abcd02, + 0x8bd4f78c2fe1861e, + 0xc53f421003b18ea2, + 0xcae3f7b5d0591ecb, + 0xbebe6ab21737113e, + 0x838f0df2a5f7f26d, + 0xbc2aa2593b06d88f, + 0x0cb02b95a74a8a0a, + 0x74bd9a7b50725838, + 0x000000dc98741fbf, + ][..], + ); print!("Frob9 = {}\n", res9); - let res10 = a.pow(&[ - 0xed4127472fd6bc68, - 0x72748872e11c4b47, - 0x9c84e64776edc3f8, - 0x008119b96d78b386, - 0xfb0fbff1c5556968, - 0x5009c51f998020be, - 0xd6e688613527a368, - 0xbe4f27942823152c, - 0xd0f09d15c45fe09e, - 0x7eb531158d2bbea5, - 0x51bbe8e71be2cfd1, - 0xbab37561b8c0c7c4, - 0xd9173b5ab551b267, - 0x05fafd9be4c78781, - 0x61883bc8a78540ee, - 0x7fe7aee3dcb694fb, - 0x0e4e85b12b4ac8a8, - 0x9a0aa13a9ab47a86, - 0xd5a3bd591ae12d4b, - 0x5865cbfabbe53b4d, - 0xf98188a9b0cd490f, - 0x3985ef4af715da43, - 0x573661cd006ced38, - 0x95853a6aaa77d5c1, - 0x165d538f0628b55e, - 0x583e75f890f32cac, - 0x5becf43a08a490b9, - 0x63ed4071c1a8087a, - 0x151d41c7701faa25, - 0x1c661c8e4900b051, - 0x581aa0f552590875, - 0x31bf39ff43375aca, - 0xe27c0f3d11310329, - 0x04071459ef3a42c2, - 0x59a2b029be2d6a1f, - 0x30ef71f271cdbf61, - 0xf3774b177f326e78, - 0x976d79b23e8501c5, - 0x9ed0e138633123c9, - 0x00000029b304ecc1, - ][..]); + let res10 = a.pow( + &[ + 0xed4127472fd6bc68, + 0x72748872e11c4b47, + 0x9c84e64776edc3f8, + 0x008119b96d78b386, + 0xfb0fbff1c5556968, + 0x5009c51f998020be, + 0xd6e688613527a368, + 0xbe4f27942823152c, + 0xd0f09d15c45fe09e, + 0x7eb531158d2bbea5, + 0x51bbe8e71be2cfd1, + 0xbab37561b8c0c7c4, + 0xd9173b5ab551b267, + 0x05fafd9be4c78781, + 0x61883bc8a78540ee, + 0x7fe7aee3dcb694fb, + 0x0e4e85b12b4ac8a8, + 0x9a0aa13a9ab47a86, + 0xd5a3bd591ae12d4b, + 0x5865cbfabbe53b4d, + 0xf98188a9b0cd490f, + 0x3985ef4af715da43, + 0x573661cd006ced38, + 0x95853a6aaa77d5c1, + 0x165d538f0628b55e, + 0x583e75f890f32cac, + 0x5becf43a08a490b9, + 0x63ed4071c1a8087a, + 0x151d41c7701faa25, + 0x1c661c8e4900b051, + 0x581aa0f552590875, + 0x31bf39ff43375aca, + 0xe27c0f3d11310329, + 0x04071459ef3a42c2, + 0x59a2b029be2d6a1f, + 0x30ef71f271cdbf61, + 0xf3774b177f326e78, + 0x976d79b23e8501c5, + 0x9ed0e138633123c9, + 0x00000029b304ecc1, + ][..], + ); print!("Frob10 = {}\n", res10); - let res11 = a.pow(&[ - 0xf4e8c249a335ddb9, - 0x965085c9440aef70, - 0xc16d84a741174aef, - 0xbe1a366b81fe0680, - 0x1c65508409269d2f, - 0x185861e9cd07fb21, - 0x26b682d951220b7a, - 0x09f189f5a7b75876, - 0x0f7133ab3ecff7f0, - 0xbf7d1ada5df0b2fd, - 0x4b0df5207414a4b6, - 0xbf6a6941b58966d3, - 0x6a15cc7b6bb0483a, - 0xc338843b8a236597, - 0xc8d724986bc0856f, - 0x1dcb8b084e928e52, - 0x3645ba97c4af9161, - 0x7d257d1abed180d3, - 0x0a66e85068416bdb, - 0x8b745a2aeb2bd27e, - 0xe34f87ec4949ec06, - 0x6ba47fa06f902fd6, - 0x225cd33864121ed2, - 0xea5d91e41a3b068b, - 0x35d2fbc8b7a05f5c, - 0xe5b1e22f3dcbc837, - 0xa9f7bdbee44d8301, - 0xbb7a57512450e143, - 0x2e2ca4188fd4eb5b, - 0x9d512b5d1e158636, - 0xdd18753b03f38ee8, - 0xbbe44db3214b380e, - 0x4534f7b060cca3d2, - 0xcbb0309736f9df06, - 0xfcb01aba828f0678, - 0xe2e4d5dac5cc7917, - 0x6631e85c4224e136, - 0xb6c334bbd109d480, - 0x2608e9c50edc2cdf, - 0x959dba8288258d16, - 0x00d895fc73e207c8, - 0x6b5ce08dc4a7bf13, - 0xb02a4f252d6a301f, - 0x00000007e1e7a192, - ][..]); + let res11 = a.pow( + &[ + 0xf4e8c249a335ddb9, + 0x965085c9440aef70, + 0xc16d84a741174aef, + 0xbe1a366b81fe0680, + 0x1c65508409269d2f, + 0x185861e9cd07fb21, + 0x26b682d951220b7a, + 0x09f189f5a7b75876, + 0x0f7133ab3ecff7f0, + 0xbf7d1ada5df0b2fd, + 0x4b0df5207414a4b6, + 0xbf6a6941b58966d3, + 0x6a15cc7b6bb0483a, + 0xc338843b8a236597, + 0xc8d724986bc0856f, + 0x1dcb8b084e928e52, + 0x3645ba97c4af9161, + 0x7d257d1abed180d3, + 0x0a66e85068416bdb, + 0x8b745a2aeb2bd27e, + 0xe34f87ec4949ec06, + 0x6ba47fa06f902fd6, + 0x225cd33864121ed2, + 0xea5d91e41a3b068b, + 0x35d2fbc8b7a05f5c, + 0xe5b1e22f3dcbc837, + 0xa9f7bdbee44d8301, + 0xbb7a57512450e143, + 0x2e2ca4188fd4eb5b, + 0x9d512b5d1e158636, + 0xdd18753b03f38ee8, + 0xbbe44db3214b380e, + 0x4534f7b060cca3d2, + 0xcbb0309736f9df06, + 0xfcb01aba828f0678, + 0xe2e4d5dac5cc7917, + 0x6631e85c4224e136, + 0xb6c334bbd109d480, + 0x2608e9c50edc2cdf, + 0x959dba8288258d16, + 0x00d895fc73e207c8, + 0x6b5ce08dc4a7bf13, + 0xb02a4f252d6a301f, + 0x00000007e1e7a192, + ][..], + ); print!("Frob11 = {}\n", res11); } @@ -829,16 +792,13 @@ fn test_calculate_frob_1() { a.mul_by_nonresidue(); // Fq2(u + 9)**(((q^1) - 1) / 3) - + print!("(i + 9) = {}\n", a); } #[test] fn test_fq2_ordering() { - let mut a = Fq2 { - c0: Fq::zero(), - c1: Fq::zero(), - }; + let mut a = Fq2 { c0: Fq::zero(), c1: Fq::zero() }; let mut b = a.clone(); @@ -859,28 +819,11 @@ fn test_fq2_ordering() { #[test] fn test_fq2_basics() { - assert_eq!( - Fq2 { - c0: Fq::zero(), - c1: Fq::zero(), - }, - Fq2::zero() - ); - assert_eq!( - Fq2 { - c0: Fq::one(), - c1: Fq::zero(), - }, - Fq2::one() - ); + assert_eq!(Fq2 { c0: Fq::zero(), c1: Fq::zero() }, Fq2::zero()); + assert_eq!(Fq2 { c0: Fq::one(), c1: Fq::zero() }, Fq2::one()); assert!(Fq2::zero().is_zero()); assert!(!Fq2::one().is_zero()); - assert!( - !Fq2 { - c0: Fq::zero(), - c1: Fq::one(), - }.is_zero() - ); + assert!(!Fq2 { c0: Fq::zero(), c1: Fq::one() }.is_zero()); } #[test] @@ -888,33 +831,23 @@ fn test_fq2_squaring() { use super::fq::FqRepr; use ff::PrimeField; - let mut a = Fq2 { - c0: Fq::one(), - c1: Fq::one(), - }; // u + 1 + let mut a = Fq2 { c0: Fq::one(), c1: Fq::one() }; // u + 1 a.square(); assert_eq!( a, Fq2 { c0: Fq::zero(), - c1: Fq::from_repr(FqRepr::from(2)).unwrap(), + c1: Fq::from_repr(FqRepr::from(2)).unwrap() } ); // 2u - let mut a = Fq2 { - c0: Fq::zero(), - c1: Fq::one(), - }; // u + let mut a = Fq2 { c0: Fq::zero(), c1: Fq::one() }; // u a.square(); assert_eq!(a, { let mut neg1 = Fq::one(); neg1.negate(); - Fq2 { - c0: neg1, - c1: Fq::zero(), - } + Fq2 { c0: neg1, c1: Fq::zero() } }); // -1 - } #[test] @@ -941,10 +874,7 @@ fn test_fq2_mul_nonresidue() { nine.double(); nine.double(); nine.add_assign(&Fq::one()); - let nqr = Fq2 { - c0: nine, - c1: Fq::one(), - }; + let nqr = Fq2 { c0: nine, c1: Fq::one() }; for _ in 0..1000 { let mut a = Fq2::rand(&mut rng); diff --git a/crates/pairing/src/bn256/fq6.rs b/crates/pairing/src/bn256/fq6.rs index 5ba0feb..dfe95b2 100644 --- a/crates/pairing/src/bn256/fq6.rs +++ b/crates/pairing/src/bn256/fq6.rs @@ -33,7 +33,6 @@ impl Rand for Fq6 { // BN256 (v^3 - ξ) where ξ = u + 9 impl Fq6 { - /// Multiply by cubic nonresidue v. pub fn mul_by_nonresidue(&mut self) { use std::mem::swap; @@ -311,11 +310,7 @@ impl Field for Fq6 { match tmp1.inverse() { Some(t) => { - let mut tmp = Fq6 { - c0: t, - c1: t, - c2: t, - }; + let mut tmp = Fq6 { c0: t, c1: t, c2: t }; tmp.c0.mul_assign(&c0); tmp.c1.mul_assign(&c1); tmp.c2.mul_assign(&c2); @@ -381,11 +376,7 @@ fn test_fq6_mul_by_01() { let mut b = a; a.mul_by_01(&c0, &c1); - b.mul_assign(&Fq6 { - c0: c0, - c1: c1, - c2: Fq2::zero(), - }); + b.mul_assign(&Fq6 { c0: c0, c1: c1, c2: Fq2::zero() }); assert_eq!(a, b); } diff --git a/crates/pairing/src/bn256/fr.rs b/crates/pairing/src/bn256/fr.rs index 1af970f..be533eb 100644 --- a/crates/pairing/src/bn256/fr.rs +++ b/crates/pairing/src/bn256/fr.rs @@ -4,7 +4,7 @@ cfg_if::cfg_if! { if #[cfg(feature = "asm")] { use core::arch::asm; use ff::PrimeFieldAsm; - + #[derive(PrimeFieldAsm)] #[PrimeFieldModulus = "21888242871839275222246405745257275088548364400416034343698204186575808495617"] #[PrimeFieldGenerator = "7"] diff --git a/crates/pairing/src/bn256/mod.rs b/crates/pairing/src/bn256/mod.rs index f38cb40..caab559 100644 --- a/crates/pairing/src/bn256/mod.rs +++ b/crates/pairing/src/bn256/mod.rs @@ -5,10 +5,7 @@ pub mod fq2; pub mod fq6; pub mod fr; -pub use self::ec::{ - G1, G1Affine, G1Compressed, G1Prepared, G1Uncompressed, - G2, G2Affine, G2Compressed, G2Prepared, G2Uncompressed, -}; +pub use self::ec::{G1Affine, G1Compressed, G1Prepared, G1Uncompressed, G2Affine, G2Compressed, G2Prepared, G2Uncompressed, G1, G2}; pub use self::fq::{Fq, FqRepr, FROBENIUS_COEFF_FQ6_C1, XI_TO_Q_MINUS_1_OVER_2}; pub use self::fq12::Fq12; pub use self::fq2::Fq2; @@ -26,17 +23,10 @@ pub struct Bn256; pub const BN_U: u64 = 4965661367192848881; // // 6U+2 for in NAF form -pub const SIX_U_PLUS_2_NAF : [i8; 65] = [ - 0, 0, 0, 1, 0, 1, 0, -1, - 0, 0, 1, -1, 0, 0, 1, 0, - 0, 1, 1, 0, -1, 0, 0, 1, - 0, -1, 0, 0, 0, 0, 1, 1, - 1, 0, 0, -1, 0, 0, 1, 0, - 0, 0, 0, 0, -1, 0, 0, 1, - 1, 0, 0, -1, 0, 0, 0, 1, - 1, 0, -1, 0, 0, 1, 0, 1, - 1]; - +pub const SIX_U_PLUS_2_NAF: [i8; 65] = [ + 0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0, 0, 1, 1, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, + 0, 1, 1, +]; impl ScalarEngine for Bn256 { type Fr = Fr; @@ -53,12 +43,7 @@ impl Engine for Bn256 { fn miller_loop<'a, I>(i: I) -> Self::Fqk where - I: IntoIterator< - Item = &'a ( - &'a ::Prepared, - &'a ::Prepared, - ), - >, + I: IntoIterator::Prepared, &'a ::Prepared)>, { let mut pairs = vec![]; for &(p, q) in i { @@ -83,7 +68,7 @@ impl Engine for Bn256 { } let mut f = Fq12::one(); - + for i in (1..SIX_U_PLUS_2_NAF.len()).rev() { if i != SIX_U_PLUS_2_NAF.len() - 1 { f.square(); @@ -91,21 +76,19 @@ impl Engine for Bn256 { for &mut (p, ref mut coeffs) in &mut pairs { ell(&mut f, coeffs.next().unwrap(), &p.0); } - let x = SIX_U_PLUS_2_NAF[i-1]; + let x = SIX_U_PLUS_2_NAF[i - 1]; match x { 1 => { - for &mut (p, ref mut coeffs) in &mut pairs { - ell(&mut f, coeffs.next().unwrap(), &p.0); - } + for &mut (p, ref mut coeffs) in &mut pairs { + ell(&mut f, coeffs.next().unwrap(), &p.0); } + } -1 => { - for &mut (p, ref mut coeffs) in &mut pairs { - ell(&mut f, coeffs.next().unwrap(), &p.0); - } + for &mut (p, ref mut coeffs) in &mut pairs { + ell(&mut f, coeffs.next().unwrap(), &p.0); } - _ => { - continue } + _ => continue, } } @@ -147,7 +130,7 @@ impl Engine for Bn256 { let mut fp = r; fp.frobenius_map(1); - let mut fp2 = r; + let mut fp2 = r; fp2.frobenius_map(2); let mut fp3 = fp2; fp3.frobenius_map(1); @@ -193,7 +176,6 @@ impl Engine for Bn256 { y6.mul_assign(&fu3p); y6.conjugate(); - y6.square(); y6.mul_assign(&y4); y6.mul_assign(&y5); @@ -221,7 +203,6 @@ impl Engine for Bn256 { None => None, } } - } impl G2Prepared { @@ -231,10 +212,7 @@ impl G2Prepared { pub fn from_affine(q: G2Affine) -> Self { if q.is_zero() { - return G2Prepared { - coeffs: vec![], - infinity: true, - }; + return G2Prepared { coeffs: vec![], infinity: true }; } fn doubling_step(r: &mut G2) -> (Fq2, Fq2, Fq2) { @@ -401,7 +379,7 @@ impl G2Prepared { let mut ztsquared = r.z; ztsquared.square(); - + t10.sub_assign(&ztsquared); // corresponds to line 18 @@ -429,15 +407,15 @@ impl G2Prepared { negq.negate(); for i in (1..SIX_U_PLUS_2_NAF.len()).rev() { - coeffs.push(doubling_step(& mut r)); - let x = SIX_U_PLUS_2_NAF[i-1]; + coeffs.push(doubling_step(&mut r)); + let x = SIX_U_PLUS_2_NAF[i - 1]; match x { 1 => { - coeffs.push(addition_step(&mut r, &q)); - } + coeffs.push(addition_step(&mut r, &q)); + } -1 => { - coeffs.push(addition_step(&mut r, &negq)); - } + coeffs.push(addition_step(&mut r, &negq)); + } _ => continue, } } @@ -457,22 +435,18 @@ impl G2Prepared { coeffs.push(addition_step(&mut r, &minusq2)); - G2Prepared { - coeffs, - infinity: false, - } + G2Prepared { coeffs, infinity: false } } } - #[cfg(test)] use rand::{Rand, SeedableRng, XorShiftRng}; #[test] fn test_pairing() { - use crate::{CurveProjective}; + use crate::CurveProjective; let mut g1 = G1::one(); - + let mut g2 = G2::one(); g2.double(); @@ -547,14 +521,12 @@ fn test_pairing() { let pair_ba = Bn256::pairing(g1, g2); assert_eq!(pair_ab, pair_ba); - } - } #[test] fn random_bilinearity_tests() { - use crate::{CurveProjective}; + use crate::CurveProjective; use ff::PrimeField; let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); diff --git a/crates/pairing/src/compact_bn256/ec.rs b/crates/pairing/src/compact_bn256/ec.rs index d0c1f4e..854caaf 100644 --- a/crates/pairing/src/compact_bn256/ec.rs +++ b/crates/pairing/src/compact_bn256/ec.rs @@ -16,8 +16,7 @@ macro_rules! curve_impl { pub(crate) y: $basefield, } - impl ::std::fmt::Display for $affine - { + impl ::std::fmt::Display for $affine { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { if self.x.is_zero() && self.y.is_zero() { write!(f, "{}(Infinity)", $name) @@ -29,13 +28,12 @@ macro_rules! curve_impl { #[derive(Copy, Clone, Debug, Eq)] pub struct $projective { - pub(crate) x: $basefield, - pub(crate) y: $basefield, - pub(crate) z: $basefield + pub(crate) x: $basefield, + pub(crate) y: $basefield, + pub(crate) z: $basefield, } - impl ::std::fmt::Display for $projective - { + impl ::std::fmt::Display for $projective { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { write!(f, "{}", self.into_affine()) } @@ -88,7 +86,9 @@ macro_rules! curve_impl { let mut res = $projective::zero(); for i in bits { res.double(); - if i { res.add_assign_mixed(self) } + if i { + res.add_assign_mixed(self) + } } res } @@ -111,11 +111,7 @@ macro_rules! curve_impl { $affine { x: x, - y: if (y < negy) ^ greatest { - y - } else { - negy - }, + y: if (y < negy) ^ greatest { y } else { negy }, } }) } @@ -136,7 +132,6 @@ macro_rules! curve_impl { y2 == x3b } } - } impl CurveAffine for $affine { @@ -192,7 +187,7 @@ macro_rules! curve_impl { fn as_xy(&self) -> (&Self::Base, &Self::Base) { (&self.x, &self.y) } - + #[inline(always)] fn into_xy_unchecked(self) -> (Self::Base, Self::Base) { (self.x, self.y) @@ -200,17 +195,11 @@ macro_rules! curve_impl { #[inline(always)] fn from_xy_unchecked(x: Self::Base, y: Self::Base) -> Self { - Self { - x: x, - y: y, - } + Self { x: x, y: y } } fn from_xy_checked(x: Self::Base, y: Self::Base) -> Result { - let affine = Self { - x: x, - y: y, - }; + let affine = Self { x: x, y: y }; if !affine.is_on_curve() { Err(GroupDecodingError::NotOnCurve) @@ -227,7 +216,7 @@ macro_rules! curve_impl { $affine::get_coeff_b() } } - + impl CurveProjective for $projective { type Engine = Bn256; type Scalar = $scalarfield; @@ -240,7 +229,7 @@ macro_rules! curve_impl { $projective { x: $basefield::zero(), y: $basefield::one(), - z: $basefield::zero() + z: $basefield::zero(), } } @@ -258,8 +247,7 @@ macro_rules! curve_impl { self.is_zero() || self.z == $basefield::one() } - fn batch_normalization(v: &mut [Self]) - { + fn batch_normalization(v: &mut [Self]) { // Montgomery’s Trick and Fast Implementation of Masked AES // Genelle, Prouff and Quisquater // Section 3.2 @@ -267,9 +255,10 @@ macro_rules! curve_impl { // First pass: compute [a, ab, abc, ...] let mut prod = Vec::with_capacity(v.len()); let mut tmp = $basefield::one(); - for g in v.iter_mut() - // Ignore normalized elements - .filter(|g| !g.is_normalized()) + for g in v + .iter_mut() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) { tmp.mul_assign(&g.z); prod.push(tmp); @@ -279,13 +268,14 @@ macro_rules! curve_impl { tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero. // Second pass: iterate backwards to compute inverses - for (g, s) in v.iter_mut() - // Backwards - .rev() - // Ignore normalized elements - .filter(|g| !g.is_normalized()) - // Backwards, skip last element, fill in one for last term. - .zip(prod.into_iter().rev().skip(1).chain(Some($basefield::one()))) + for (g, s) in v + .iter_mut() + // Backwards + .rev() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) + // Backwards, skip last element, fill in one for last term. + .zip(prod.into_iter().rev().skip(1).chain(Some($basefield::one()))) { // tmp := tmp * g.z; g.z := tmp * s = 1/z let mut newtmp = tmp; @@ -296,9 +286,7 @@ macro_rules! curve_impl { } // Perform affine transformations - for g in v.iter_mut() - .filter(|g| !g.is_normalized()) - { + for g in v.iter_mut().filter(|g| !g.is_normalized()) { let mut z = g.z; // 1/z z.square(); // 1/z^2 g.x.mul_assign(&z); // x/z^2 @@ -556,8 +544,7 @@ macro_rules! curve_impl { let mut found_one = false; - for i in BitIterator::new(other.into()) - { + for i in BitIterator::new(other.into()) { if found_one { res.double(); } else { @@ -587,17 +574,13 @@ macro_rules! curve_impl { fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) { (&self.x, &self.y, &self.z) } - + fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) { (self.x, self.y, self.z) } fn from_xyz_unchecked(x: Self::Base, y: Self::Base, z: Self::Base) -> Self { - Self { - x, - y, - z - } + Self { x, y, z } } fn from_xyz_checked(_x: Self::Base, _y: Self::Base, _z: Self::Base) -> Result { @@ -615,7 +598,7 @@ macro_rules! curve_impl { $projective { x: p.x, y: p.y, - z: $basefield::one() + z: $basefield::one(), } } } @@ -629,10 +612,7 @@ macro_rules! curve_impl { $affine::zero() } else if p.z == $basefield::one() { // If Z is one, the point is already normalized. - $affine { - x: p.x, - y: p.y, - } + $affine { x: p.x, y: p.y } } else { // Z is nonzero, so it must have an inverse in a field. let zinv = p.z.inverse().unwrap(); @@ -648,35 +628,22 @@ macro_rules! curve_impl { zinv_powered.mul_assign(&zinv); y.mul_assign(&zinv_powered); - $affine { - x: x, - y: y, - } + $affine { x: x, y: y } } } } - } + }; } pub mod g1 { use super::super::{Bn256, Fq, Fq12, FqRepr, Fr, FrRepr}; use super::g2::G2Affine; + use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError, RawEncodable}; use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; use rand::{Rand, Rng}; use std::fmt; - use crate::{RawEncodable, CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError}; - - curve_impl!( - "G1", - G1, - G1Affine, - G1Prepared, - Fq, - Fr, - G1Uncompressed, - G1Compressed, - G2Affine - ); + + curve_impl!("G1", G1, G1Affine, G1Prepared, Fq, Fr, G1Uncompressed, G1Compressed, G2Affine); impl RawEncodable for G1Affine { fn into_raw_uncompressed_le(&self) -> Self::Uncompressed { @@ -692,10 +659,7 @@ pub mod g1 { } /// Creates a point from raw encoded coordinates without checking on curve - fn from_raw_uncompressed_le_unchecked( - encoded: &Self::Uncompressed, - _infinity: bool - ) -> Result { + fn from_raw_uncompressed_le_unchecked(encoded: &Self::Uncompressed, _infinity: bool) -> Result { let copy = encoded.0; if copy.iter().all(|b| *b == 0) { @@ -712,12 +676,8 @@ pub mod g1 { } Ok(G1Affine { - x: Fq::from_raw_repr(x).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate", e) - })?, - y: Fq::from_raw_repr(y).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate", e) - })?, + x: Fq::from_raw_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?, + y: Fq::from_raw_repr(y).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate", e))?, }) } @@ -841,12 +801,8 @@ pub mod g1 { } Ok(G1Affine { - x: Fq::from_repr(x).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate", e) - })?, - y: Fq::from_repr(y).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate", e) - })?, + x: Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?, + y: Fq::from_repr(y).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate", e))?, }) } } @@ -937,8 +893,7 @@ pub mod g1 { } // Interpret as Fq element. - let x = Fq::from_repr(x) - .map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?; + let x = Fq::from_repr(x).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate", e))?; G1Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve) } @@ -1006,8 +961,7 @@ pub mod g1 { } fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { - const RECOMMENDATIONS: [usize; 12] = - [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; + const RECOMMENDATIONS: [usize; 12] = [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; let mut ret = 4; for r in &RECOMMENDATIONS { @@ -1095,22 +1049,12 @@ pub mod g1 { pub mod g2 { use super::super::{Bn256, Fq, Fq12, Fq2, FqRepr, Fr, FrRepr}; use super::g1::G1Affine; + use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError}; use ff::{BitIterator, Field, PrimeField, PrimeFieldRepr, SqrtField}; use rand::{Rand, Rng}; use std::fmt; - use crate::{CurveAffine, CurveProjective, EncodedPoint, Engine, GroupDecodingError}; - curve_impl!( - "G2", - G2, - G2Affine, - G2Prepared, - Fq2, - Fr, - G2Uncompressed, - G2Compressed, - G1Affine - ); + curve_impl!("G2", G2, G2Affine, G2Prepared, Fq2, Fr, G2Uncompressed, G2Compressed, G1Affine); impl Rand for G2 { fn rand(rng: &mut R) -> Self { @@ -1196,7 +1140,6 @@ pub mod g2 { Err(GroupDecodingError::UnexpectedInformation) } } else { - // Unset the two most significant bits. copy[0] &= 0x3f; @@ -1216,20 +1159,12 @@ pub mod g2 { Ok(G2Affine { x: Fq2 { - c0: Fq::from_repr(x_c0).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e) - })?, - c1: Fq::from_repr(x_c1).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e) - })?, + c0: Fq::from_repr(x_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e))?, + c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))?, }, y: Fq2 { - c0: Fq::from_repr(y_c0).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate (c0)", e) - })?, - c1: Fq::from_repr(y_c1).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("y coordinate (c1)", e) - })?, + c0: Fq::from_repr(y_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate (c0)", e))?, + c1: Fq::from_repr(y_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("y coordinate (c1)", e))?, }, }) } @@ -1288,7 +1223,7 @@ pub mod g2 { let affine = self.into_affine_unchecked()?; // NB: Decompression guarantees that it is on the curve already. - + Ok(affine) } fn into_affine_unchecked(&self) -> Result { @@ -1326,12 +1261,8 @@ pub mod g2 { // Interpret as Fq element. let x = Fq2 { - c0: Fq::from_repr(x_c0).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e) - })?, - c1: Fq::from_repr(x_c1).map_err(|e| { - GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e) - })?, + c0: Fq::from_repr(x_c0).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c0)", e))?, + c1: Fq::from_repr(x_c1).map_err(|e| GroupDecodingError::CoordinateDecodingError("x coordinate (c1)", e))?, }; G2Affine::get_point_from_x(x, greatest).ok_or(GroupDecodingError::NotOnCurve) @@ -1370,12 +1301,7 @@ pub mod g2 { fn scale_by_cofactor(&self) -> G2 { // G2 cofactor = 2p - n = 2q - r // 0x30644e72e131a029b85045b68181585e06ceecda572a2489345f2299c0f9fa8d - let cofactor = BitIterator::new([ - 0x345f2299c0f9fa8d, - 0x06ceecda572a2489, - 0xb85045b68181585e, - 0x30644e72e131a029, - ]); + let cofactor = BitIterator::new([0x345f2299c0f9fa8d, 0x06ceecda572a2489, 0xb85045b68181585e, 0x30644e72e131a029]); self.mul_bits(cofactor) } @@ -1419,8 +1345,7 @@ pub mod g2 { } fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { - const RECOMMENDATIONS: [usize; 11] = - [1, 3, 8, 20, 47, 126, 260, 826, 1501, 4555, 84071]; + const RECOMMENDATIONS: [usize; 11] = [1, 3, 8, 20, 47, 126, 260, 826, 1501, 4555, 84071]; let mut ret = 4; for r in &RECOMMENDATIONS { @@ -1466,7 +1391,6 @@ pub mod g2 { y: if y < negy { y } else { negy }, }; - let g2 = p.into_projective(); if !g2.is_zero() { let _g2 = G2Affine::from(g2); @@ -1584,7 +1508,6 @@ pub mod g2 { #[test] fn test_addition_and_doubling() { - let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); for _ in 0..1000 { @@ -1668,7 +1591,6 @@ pub mod g2 { assert!(b != tmp[i]); assert!(c != tmp[i]); } - } } @@ -1732,7 +1654,6 @@ pub mod g2 { assert!(t.is_zero()); } } - } pub use self::g1::*; diff --git a/crates/pairing/src/compact_bn256/fq.rs b/crates/pairing/src/compact_bn256/fq.rs index 04a243a..942457e 100644 --- a/crates/pairing/src/compact_bn256/fq.rs +++ b/crates/pairing/src/compact_bn256/fq.rs @@ -1 +1 @@ -pub use super::super::bn256::fq::*; \ No newline at end of file +pub use super::super::bn256::fq::*; diff --git a/crates/pairing/src/compact_bn256/fr.rs b/crates/pairing/src/compact_bn256/fr.rs index fb5835f..d3b3950 100644 --- a/crates/pairing/src/compact_bn256/fr.rs +++ b/crates/pairing/src/compact_bn256/fr.rs @@ -1 +1 @@ -pub use super::super::bn256::fr::*; \ No newline at end of file +pub use super::super::bn256::fr::*; diff --git a/crates/pairing/src/compact_bn256/mod.rs b/crates/pairing/src/compact_bn256/mod.rs index 939f701..a823b74 100644 --- a/crates/pairing/src/compact_bn256/mod.rs +++ b/crates/pairing/src/compact_bn256/mod.rs @@ -8,10 +8,7 @@ pub mod fr; // #[cfg(test)] // mod tests; -pub use self::ec::{ - G1, G1Affine, G1Compressed, G1Prepared, G1Uncompressed, - G2, G2Affine, G2Compressed, G2Prepared, G2Uncompressed, -}; +pub use self::ec::{G1Affine, G1Compressed, G1Prepared, G1Uncompressed, G2Affine, G2Compressed, G2Prepared, G2Uncompressed, G1, G2}; pub use self::fq::{Fq, FqRepr, FROBENIUS_COEFF_FQ6_C1, XI_TO_Q_MINUS_1_OVER_2}; pub use self::fq12::Fq12; pub use self::fq2::Fq2; @@ -29,17 +26,10 @@ pub struct Bn256; pub const BN_U: u64 = 4965661367192848881; // // 6U+2 for in NAF form -pub const SIX_U_PLUS_2_NAF : [i8; 65] = [ - 0, 0, 0, 1, 0, 1, 0, -1, - 0, 0, 1, -1, 0, 0, 1, 0, - 0, 1, 1, 0, -1, 0, 0, 1, - 0, -1, 0, 0, 0, 0, 1, 1, - 1, 0, 0, -1, 0, 0, 1, 0, - 0, 0, 0, 0, -1, 0, 0, 1, - 1, 0, 0, -1, 0, 0, 0, 1, - 1, 0, -1, 0, 0, 1, 0, 1, - 1]; - +pub const SIX_U_PLUS_2_NAF: [i8; 65] = [ + 0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0, 0, 1, 1, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, + 0, 1, 1, +]; impl ScalarEngine for Bn256 { type Fr = Fr; @@ -56,12 +46,7 @@ impl Engine for Bn256 { fn miller_loop<'a, I>(i: I) -> Self::Fqk where - I: IntoIterator< - Item = &'a ( - &'a ::Prepared, - &'a ::Prepared, - ), - >, + I: IntoIterator::Prepared, &'a ::Prepared)>, { let mut pairs = vec![]; for &(p, q) in i { @@ -86,7 +71,7 @@ impl Engine for Bn256 { } let mut f = Fq12::one(); - + for i in (1..SIX_U_PLUS_2_NAF.len()).rev() { if i != SIX_U_PLUS_2_NAF.len() - 1 { f.square(); @@ -94,21 +79,19 @@ impl Engine for Bn256 { for &mut (p, ref mut coeffs) in &mut pairs { ell(&mut f, coeffs.next().unwrap(), &p.0); } - let x = SIX_U_PLUS_2_NAF[i-1]; + let x = SIX_U_PLUS_2_NAF[i - 1]; match x { 1 => { - for &mut (p, ref mut coeffs) in &mut pairs { - ell(&mut f, coeffs.next().unwrap(), &p.0); - } + for &mut (p, ref mut coeffs) in &mut pairs { + ell(&mut f, coeffs.next().unwrap(), &p.0); } + } -1 => { - for &mut (p, ref mut coeffs) in &mut pairs { - ell(&mut f, coeffs.next().unwrap(), &p.0); - } + for &mut (p, ref mut coeffs) in &mut pairs { + ell(&mut f, coeffs.next().unwrap(), &p.0); } - _ => { - continue } + _ => continue, } } @@ -150,7 +133,7 @@ impl Engine for Bn256 { let mut fp = r; fp.frobenius_map(1); - let mut fp2 = r; + let mut fp2 = r; fp2.frobenius_map(2); let mut fp3 = fp2; fp3.frobenius_map(1); @@ -196,7 +179,6 @@ impl Engine for Bn256 { y6.mul_assign(&fu3p); y6.conjugate(); - y6.square(); y6.mul_assign(&y4); y6.mul_assign(&y5); @@ -224,7 +206,6 @@ impl Engine for Bn256 { None => None, } } - } impl G2Prepared { @@ -234,10 +215,7 @@ impl G2Prepared { pub fn from_affine(q: G2Affine) -> Self { if q.is_zero() { - return G2Prepared { - coeffs: vec![], - infinity: true, - }; + return G2Prepared { coeffs: vec![], infinity: true }; } fn doubling_step(r: &mut G2) -> (Fq2, Fq2, Fq2) { @@ -404,7 +382,7 @@ impl G2Prepared { let mut ztsquared = r.z; ztsquared.square(); - + t10.sub_assign(&ztsquared); // corresponds to line 18 @@ -432,15 +410,15 @@ impl G2Prepared { negq.negate(); for i in (1..SIX_U_PLUS_2_NAF.len()).rev() { - coeffs.push(doubling_step(& mut r)); - let x = SIX_U_PLUS_2_NAF[i-1]; + coeffs.push(doubling_step(&mut r)); + let x = SIX_U_PLUS_2_NAF[i - 1]; match x { 1 => { - coeffs.push(addition_step(&mut r, &q)); - } + coeffs.push(addition_step(&mut r, &q)); + } -1 => { - coeffs.push(addition_step(&mut r, &negq)); - } + coeffs.push(addition_step(&mut r, &negq)); + } _ => continue, } } @@ -460,22 +438,18 @@ impl G2Prepared { coeffs.push(addition_step(&mut r, &minusq2)); - G2Prepared { - coeffs, - infinity: false, - } + G2Prepared { coeffs, infinity: false } } } - #[cfg(test)] use rand::{Rand, SeedableRng, XorShiftRng}; #[test] fn test_pairing() { - use crate::{CurveProjective}; + use crate::CurveProjective; let mut g1 = G1::one(); - + let mut g2 = G2::one(); g2.double(); @@ -550,14 +524,12 @@ fn test_pairing() { let pair_ba = Bn256::pairing(g1, g2); assert_eq!(pair_ab, pair_ba); - } - } #[test] fn random_bilinearity_tests() { - use crate::{CurveProjective}; + use crate::CurveProjective; use ff::PrimeField; let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); diff --git a/crates/pairing/src/lib.rs b/crates/pairing/src/lib.rs index 11277ff..b7c44aa 100644 --- a/crates/pairing/src/lib.rs +++ b/crates/pairing/src/lib.rs @@ -34,7 +34,7 @@ mod base; pub use self::base::*; use ff::{Field, PrimeField, PrimeFieldDecodingError, PrimeFieldRepr, ScalarEngine, SqrtField}; -use std::{error::Error}; +use std::error::Error; use std::fmt; /// An "engine" is a collection of types (fields, elliptic curve groups, etc.) @@ -42,44 +42,16 @@ use std::fmt; /// of prime order `r`, and are equipped with a bilinear pairing function. pub trait Engine: ScalarEngine { /// The projective representation of an element in G1. - type G1: CurveProjective< - Engine = Self, - Base = Self::Fq, - Scalar = Self::Fr, - Affine = Self::G1Affine, - > - + From; + type G1: CurveProjective + From; /// The affine representation of an element in G1. - type G1Affine: CurveAffine< - Engine = Self, - Base = Self::Fq, - Scalar = Self::Fr, - Projective = Self::G1, - Pair = Self::G2Affine, - PairingResult = Self::Fqk, - > - + From + RawEncodable; + type G1Affine: CurveAffine + From + RawEncodable; /// The projective representation of an element in G2. - type G2: CurveProjective< - Engine = Self, - Base = Self::Fqe, - Scalar = Self::Fr, - Affine = Self::G2Affine, - > - + From; + type G2: CurveProjective + From; /// The affine representation of an element in G2. - type G2Affine: CurveAffine< - Engine = Self, - Base = Self::Fqe, - Scalar = Self::Fr, - Projective = Self::G2, - Pair = Self::G1Affine, - PairingResult = Self::Fqk, - > - + From; + type G2Affine: CurveAffine + From; /// The base field that hosts G1. type Fq: PrimeField + SqrtField; @@ -93,12 +65,7 @@ pub trait Engine: ScalarEngine { /// Perform a miller loop with some number of (G1, G2) pairs. fn miller_loop<'a, I>(i: I) -> Self::Fqk where - I: IntoIterator< - Item = &'a ( - &'a ::Prepared, - &'a ::Prepared, - ), - >; + I: IntoIterator::Prepared, &'a ::Prepared)>; /// Perform final exponentiation of the result of a miller loop. fn final_exponentiation(r: &Self::Fqk) -> Option; @@ -109,27 +76,13 @@ pub trait Engine: ScalarEngine { G1: Into, G2: Into, { - Self::final_exponentiation(&Self::miller_loop( - [(&(p.into().prepare()), &(q.into().prepare()))].iter(), - )).unwrap() + Self::final_exponentiation(&Self::miller_loop([(&(p.into().prepare()), &(q.into().prepare()))].iter())).unwrap() } } /// Projective representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. -pub trait CurveProjective: - PartialEq - + Eq - + Sized - + Copy - + Clone - + Send - + Sync - + fmt::Debug - + fmt::Display - + rand::Rand - + 'static -{ +pub trait CurveProjective: PartialEq + Eq + Sized + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + rand::Rand + 'static { type Engine: Engine; type Scalar: PrimeField + SqrtField; type Base: SqrtField; @@ -190,7 +143,7 @@ pub trait CurveProjective: fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) { unimplemented!("default implementation does not exist for this function") } - + /// Returns underlying X, Y and Z coordinates. Users should check for infinity /// outside of this call fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) { @@ -212,20 +165,7 @@ pub trait CurveProjective: /// Affine representation of an elliptic curve point guaranteed to be /// in the correct prime order subgroup. -pub trait CurveAffine: - Copy - + Clone - + Sized - + Send - + Sync - + fmt::Debug - + fmt::Display - + PartialEq - + Eq - + 'static - + serde::Serialize - + serde::de::DeserializeOwned -{ +pub trait CurveAffine: Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static + serde::Serialize + serde::de::DeserializeOwned { type Engine: Engine; type Scalar: PrimeField + SqrtField; type Base: SqrtField; @@ -276,7 +216,7 @@ pub trait CurveAffine: /// Returns references to underlying X and Y coordinates. Users should check for infinity /// outside of this call fn as_xy(&self) -> (&Self::Base, &Self::Base); - + /// Returns underlying X and Y coordinates. Users should check for infinity /// outside of this call fn into_xy_unchecked(self) -> (Self::Base, Self::Base); @@ -309,9 +249,7 @@ pub trait RawEncodable: CurveAffine { } /// An encoded elliptic curve point, which should essentially wrap a `[u8; N]`. -pub trait EncodedPoint: - Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static -{ +pub trait EncodedPoint: Sized + Send + Sync + AsRef<[u8]> + AsMut<[u8]> + Clone + Copy + 'static { type Affine: CurveAffine; /// Creates an empty representation. @@ -359,9 +297,7 @@ impl GroupDecodingError { GroupDecodingError::NotOnCurve => "coordinate(s) do not lie on the curve", GroupDecodingError::NotInSubgroup => "the element is not part of an r-order subgroup", GroupDecodingError::CoordinateDecodingError(..) => "coordinate(s) could not be decoded", - GroupDecodingError::UnexpectedCompressionMode => { - "encoding has unexpected compression mode" - } + GroupDecodingError::UnexpectedCompressionMode => "encoding has unexpected compression mode", GroupDecodingError::UnexpectedInformation => "encoding has unexpected information", } } diff --git a/crates/pairing/src/tests/curve.rs b/crates/pairing/src/tests/curve.rs index 4663a42..94a6bf7 100644 --- a/crates/pairing/src/tests/curve.rs +++ b/crates/pairing/src/tests/curve.rs @@ -48,11 +48,7 @@ pub fn curve_tests() { { let a = G::rand(&mut rng); let b = a.into_affine().into_projective(); - let c = a - .into_affine() - .into_projective() - .into_affine() - .into_projective(); + let c = a.into_affine().into_projective().into_affine().into_projective(); assert_eq!(a, b); assert_eq!(b, c); } @@ -66,8 +62,8 @@ pub fn curve_tests() { } fn random_wnaf_tests() { - use ff::PrimeField; use crate::wnaf::*; + use ff::PrimeField; let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); @@ -369,10 +365,7 @@ pub fn random_transformation_tests() { v[s] = v[s].into_affine().into_projective(); } - let expected_v = v - .iter() - .map(|v| v.into_affine().into_projective()) - .collect::>(); + let expected_v = v.iter().map(|v| v.into_affine().into_projective()).collect::>(); G::batch_normalization(&mut v); for i in &v { @@ -398,7 +391,6 @@ pub fn random_transformation_tests_with_cofactor() { let mut v = (0..1000).map(|_| G::rand(&mut rng)).collect::>(); for i in &v { - assert!(!i.is_normalized()); } @@ -413,10 +405,7 @@ pub fn random_transformation_tests_with_cofactor() { v[s] = v[s].into_affine().into_projective(); } - let expected_v = v - .iter() - .map(|v| v.into_affine().into_projective()) - .collect::>(); + let expected_v = v.iter().map(|v| v.into_affine().into_projective()).collect::>(); G::batch_normalization(&mut v); for i in &v { @@ -430,15 +419,9 @@ pub fn random_transformation_tests_with_cofactor() { fn random_encoding_tests() { let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]); - assert_eq!( - G::zero().into_uncompressed().into_affine().unwrap(), - G::zero() - ); + assert_eq!(G::zero().into_uncompressed().into_affine().unwrap(), G::zero()); - assert_eq!( - G::zero().into_compressed().into_affine().unwrap(), - G::zero() - ); + assert_eq!(G::zero().into_compressed().into_affine().unwrap(), G::zero()); for _ in 0..1000 { let mut r = G::Projective::rand(&mut rng).into_affine(); diff --git a/crates/pairing/src/tests/engine.rs b/crates/pairing/src/tests/engine.rs index 5fc37c4..2c4ec8b 100644 --- a/crates/pairing/src/tests/engine.rs +++ b/crates/pairing/src/tests/engine.rs @@ -22,15 +22,9 @@ pub fn engine_tests() { let c = E::G1::rand(&mut rng).into_affine().prepare(); let d = E::G2::rand(&mut rng).into_affine().prepare(); - assert_eq!( - E::Fqk::one(), - E::final_exponentiation(&E::miller_loop(&[(&z1, &b)])).unwrap() - ); + assert_eq!(E::Fqk::one(), E::final_exponentiation(&E::miller_loop(&[(&z1, &b)])).unwrap()); - assert_eq!( - E::Fqk::one(), - E::final_exponentiation(&E::miller_loop(&[(&a, &z2)])).unwrap() - ); + assert_eq!(E::Fqk::one(), E::final_exponentiation(&E::miller_loop(&[(&a, &z2)])).unwrap()); assert_eq!( E::final_exponentiation(&E::miller_loop(&[(&z1, &b), (&c, &d)])).unwrap(), @@ -83,8 +77,7 @@ fn random_miller_loop_tests() { let c = c.into_affine().prepare(); let d = d.into_affine().prepare(); - let abcd_with_double_loop = - E::final_exponentiation(&E::miller_loop(&[(&a, &b), (&c, &d)])).unwrap(); + let abcd_with_double_loop = E::final_exponentiation(&E::miller_loop(&[(&a, &b), (&c, &d)])).unwrap(); assert_eq!(abcd, abcd_with_double_loop); } diff --git a/crates/pairing/src/wnaf.rs b/crates/pairing/src/wnaf.rs index 69c6fd9..66ab720 100644 --- a/crates/pairing/src/wnaf.rs +++ b/crates/pairing/src/wnaf.rs @@ -108,10 +108,7 @@ impl Wnaf<(), Vec, Vec> { /// Given a scalar, compute its wNAF representation and return a `Wnaf` object that can perform /// exponentiations with `.base(..)`. - pub fn scalar( - &mut self, - scalar: <::Scalar as PrimeField>::Repr, - ) -> Wnaf, &[i64]> { + pub fn scalar(&mut self, scalar: <::Scalar as PrimeField>::Repr) -> Wnaf, &[i64]> { // Compute the appropriate window size for the scalar. let window_size = G::recommended_wnaf_for_scalar(scalar); @@ -166,10 +163,7 @@ impl> Wnaf { impl>> Wnaf { /// Performs exponentiation given a scalar. - pub fn scalar( - &mut self, - scalar: <::Scalar as PrimeField>::Repr, - ) -> G + pub fn scalar(&mut self, scalar: <::Scalar as PrimeField>::Repr) -> G where B: AsRef<[G]>, { diff --git a/crates/rescue-poseidon/benches/hashes.rs b/crates/rescue-poseidon/benches/hashes.rs index bee96df..c5a8911 100644 --- a/crates/rescue-poseidon/benches/hashes.rs +++ b/crates/rescue-poseidon/benches/hashes.rs @@ -12,9 +12,7 @@ use franklin_crypto::{ use rand::{Rand, SeedableRng, XorShiftRng}; use rescue_poseidon::generic_round_function; -use rescue_poseidon::{ - PoseidonParams, RescueParams, RescuePrimeParams, -}; +use rescue_poseidon::{PoseidonParams, RescueParams, RescuePrimeParams}; fn init_rng() -> XorShiftRng { const TEST_SEED: [u32; 4] = [0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]; @@ -73,9 +71,7 @@ fn bench_rescue_round_function_comparison(crit: &mut Criterion) { let params = Bn256RescueParams::new_checked_2_into_1(); let mut rescue = StatefulRescue::::new(¶ms); - group.bench_function("Old Rescue", |b| { - b.iter(|| rescue.absorb(&test_inputs())) - }); + group.bench_function("Old Rescue", |b| b.iter(|| rescue.absorb(&test_inputs()))); } fn bench_rescue_round_function(crit: &mut Criterion) { diff --git a/crates/rescue-poseidon/examples/main.rs b/crates/rescue-poseidon/examples/main.rs index 60d0744..257278b 100644 --- a/crates/rescue-poseidon/examples/main.rs +++ b/crates/rescue-poseidon/examples/main.rs @@ -22,8 +22,7 @@ pub(crate) fn init_rng() -> XorShiftRng { XorShiftRng::from_seed(TEST_SEED) } -pub(crate) fn init_cs( -) -> TrivialAssembly { +pub(crate) fn init_cs() -> TrivialAssembly { TrivialAssembly::::new() } @@ -76,11 +75,7 @@ fn run_generic_hash_fixed_length() { // now, hash with rescue prime params // in this case we use original domain strategy used in RescuePrime paper let rescue_prime_params = RescuePrimeParams::::default(); - let result = generic_hash( - &rescue_prime_params, - &input, - Some(DomainStrategy::FixedLength), - ); + let result = generic_hash(&rescue_prime_params, &input, Some(DomainStrategy::FixedLength)); assert_eq!(result.len(), RATE); } @@ -95,17 +90,13 @@ fn run_generic_hash_var_length() { let rescue_params = RescueParams::::default(); let mut rescue_hasher = GenericSponge::new(); rescue_hasher.absorb_multiple(&input, &rescue_params); - let _ = rescue_hasher - .squeeze(&rescue_params) - .expect("squeezed eleme"); + let _ = rescue_hasher.squeeze(&rescue_params).expect("squeezed eleme"); // go with poseidon let poseidon_params = PoseidonParams::::default(); let mut poseidon_hasher = GenericSponge::new(); poseidon_hasher.absorb_multiple(&input, &poseidon_params); - let _ = poseidon_hasher - .squeeze(&poseidon_params) - .expect("squeezed eleme"); + let _ = poseidon_hasher.squeeze(&poseidon_params).expect("squeezed eleme"); } fn run_circuit_generic_hash_fixed_length() -> Result<(), SynthesisError> { diff --git a/crates/rescue-poseidon/src/circuit/matrix.rs b/crates/rescue-poseidon/src/circuit/matrix.rs index cc22af6..78934aa 100644 --- a/crates/rescue-poseidon/src/circuit/matrix.rs +++ b/crates/rescue-poseidon/src/circuit/matrix.rs @@ -1,10 +1,7 @@ use franklin_crypto::bellman::{Engine, SynthesisError}; use franklin_crypto::plonk::circuit::linear_combination::LinearCombination; // Computes matrix vector product and assigns result into same vector. -pub(crate) fn matrix_vector_product( - matrix: &[[E::Fr; DIM]; DIM], - vector: &mut [LinearCombination; DIM], -) -> Result<(), SynthesisError> { +pub(crate) fn matrix_vector_product(matrix: &[[E::Fr; DIM]; DIM], vector: &mut [LinearCombination; DIM]) -> Result<(), SynthesisError> { let vec_cloned = vector.clone(); for (idx, row) in matrix.iter().enumerate() { @@ -19,10 +16,7 @@ pub(crate) fn matrix_vector_product( } // Computes sparse matrix - vector by exploiting sparsity of optimized matrixes. -pub(crate) fn mul_by_sparse_matrix( - matrix: &[[E::Fr; DIM]; DIM], - vector: &mut [LinearCombination; DIM], -) { +pub(crate) fn mul_by_sparse_matrix(matrix: &[[E::Fr; DIM]; DIM], vector: &mut [LinearCombination; DIM]) { assert_eq!(DIM, 3, "valid only for 3x3 matrix"); let vec_cloned = vector.clone(); @@ -30,7 +24,7 @@ pub(crate) fn mul_by_sparse_matrix( // we will assign result into input vector so set each to zero for lc in vector.iter_mut() { *lc = LinearCombination::zero(); - } + } for (a, b) in vec_cloned.iter().zip(matrix[0].iter()) { vector[0].add_assign_scaled(a, *b); @@ -63,17 +57,11 @@ mod test { let mut vector_fe: [Fr; DIM] = [Fr::rand(rng); DIM]; - let mut vector_lc: [LinearCombination<_>; DIM] = (0..DIM) - .map(|_| LinearCombination::zero()) - .collect::>>() - .try_into() - .expect("vector of lc"); + let mut vector_lc: [LinearCombination<_>; DIM] = (0..DIM).map(|_| LinearCombination::zero()).collect::>>().try_into().expect("vector of lc"); vector_fe .iter() .zip(vector_lc.iter_mut()) - .for_each(|(src, dst)| { - *dst = LinearCombination::from(AllocatedNum::alloc(cs, || Ok(*src)).unwrap()) - }); + .for_each(|(src, dst)| *dst = LinearCombination::from(AllocatedNum::alloc(cs, || Ok(*src)).unwrap())); let mut matrix = [[Fr::zero(); DIM]; DIM]; (0..9) diff --git a/crates/rescue-poseidon/src/circuit/mod.rs b/crates/rescue-poseidon/src/circuit/mod.rs index e77b42f..51f7001 100644 --- a/crates/rescue-poseidon/src/circuit/mod.rs +++ b/crates/rescue-poseidon/src/circuit/mod.rs @@ -1,9 +1,9 @@ -pub(crate) mod sponge; +mod matrix; pub(crate) mod poseidon; pub mod poseidon2; pub(crate) mod rescue; pub(crate) mod rescue_prime; mod sbox; -mod matrix; +pub(crate) mod sponge; #[cfg(test)] mod tests; diff --git a/crates/rescue-poseidon/src/circuit/poseidon.rs b/crates/rescue-poseidon/src/circuit/poseidon.rs index 8a98b32..b9772d0 100644 --- a/crates/rescue-poseidon/src/circuit/poseidon.rs +++ b/crates/rescue-poseidon/src/circuit/poseidon.rs @@ -1,8 +1,8 @@ +use super::matrix::{matrix_vector_product, mul_by_sparse_matrix}; use super::sbox::sbox; use super::sponge::circuit_generic_hash_num; -use super::matrix::{matrix_vector_product, mul_by_sparse_matrix}; -use crate::{DomainStrategy, poseidon::params::PoseidonParams}; use crate::traits::{HashFamily, HashParams}; +use crate::{poseidon::params::PoseidonParams, DomainStrategy}; use franklin_crypto::bellman::plonk::better_better_cs::cs::ConstraintSystem; use franklin_crypto::bellman::{Field, SynthesisError}; use franklin_crypto::{ @@ -15,33 +15,19 @@ use franklin_crypto::{ /// length of input and applies a padding rule which makes input size equals to multiple of /// rate parameter. /// Uses pre-defined state-width=3 and rate=2. -pub fn circuit_poseidon_hash, const L: usize>( - cs: &mut CS, - input: &[Num; L], - domain_strategy: Option, -) -> Result<[Num; 2], SynthesisError> { +pub fn circuit_poseidon_hash, const L: usize>(cs: &mut CS, input: &[Num; L], domain_strategy: Option) -> Result<[Num; 2], SynthesisError> { const WIDTH: usize = 3; const RATE: usize = 2; let params = PoseidonParams::::default(); circuit_generic_hash_num(cs, input, ¶ms, domain_strategy) } -pub(crate) fn circuit_poseidon_round_function< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( +pub(crate) fn circuit_poseidon_round_function, P: HashParams, const RATE: usize, const WIDTH: usize>( cs: &mut CS, params: &P, state: &mut [LinearCombination; WIDTH], ) -> Result<(), SynthesisError> { - assert_eq!( - params.hash_family(), - HashFamily::Poseidon, - "Incorrect hash family!" - ); + assert_eq!(params.hash_family(), HashFamily::Poseidon, "Incorrect hash family!"); assert!(params.number_of_full_rounds() % 2 == 0); let half_of_full_rounds = params.number_of_full_rounds() / 2; @@ -58,34 +44,22 @@ pub(crate) fn circuit_poseidon_round_function< s.add_assign_constant(*c); } // non linear sbox - sbox( - cs, - params.alpha(), - state, - Some(0..WIDTH), - params.custom_gate(), - )?; + sbox(cs, params.alpha(), state, Some(0..WIDTH), params.custom_gate())?; // mul state by mds matrix_vector_product(¶ms.mds_matrix(), state)?; } - state - .iter_mut() - .zip(optimized_round_constants[half_of_full_rounds].iter()) - .for_each(|(a, b)| a.add_assign_constant(*b)); + state.iter_mut().zip(optimized_round_constants[half_of_full_rounds].iter()).for_each(|(a, b)| a.add_assign_constant(*b)); matrix_vector_product(&m_prime, state)?; - let mut constants_for_partial_rounds = optimized_round_constants - [half_of_full_rounds + 1..half_of_full_rounds + params.number_of_partial_rounds()] - .to_vec(); + let mut constants_for_partial_rounds = optimized_round_constants[half_of_full_rounds + 1..half_of_full_rounds + params.number_of_partial_rounds()].to_vec(); constants_for_partial_rounds.push([E::Fr::zero(); WIDTH]); // in order to reduce gate number we merge two consecutive iteration // which costs 2 gates per each - for (round_constant, sparse_matrix) in constants_for_partial_rounds - [..constants_for_partial_rounds.len() - 1] + for (round_constant, sparse_matrix) in constants_for_partial_rounds[..constants_for_partial_rounds.len() - 1] .chunks(2) .zip(sparse_matrixes[..sparse_matrixes.len() - 1].chunks(2)) { @@ -110,9 +84,7 @@ pub(crate) fn circuit_poseidon_round_function< mul_by_sparse_matrix(&sparse_matrixes.last().unwrap(), state); // second full round - for round in (params.number_of_partial_rounds() + half_of_full_rounds) - ..(params.number_of_partial_rounds() + params.number_of_full_rounds()) - { + for round in (params.number_of_partial_rounds() + half_of_full_rounds)..(params.number_of_partial_rounds() + params.number_of_full_rounds()) { let round_constants = &optimized_round_constants[round]; // add round constatnts @@ -120,13 +92,7 @@ pub(crate) fn circuit_poseidon_round_function< s.add_assign_constant(*c); } - sbox( - cs, - params.alpha(), - state, - Some(0..WIDTH), - params.custom_gate(), - )?; + sbox(cs, params.alpha(), state, Some(0..WIDTH), params.custom_gate())?; // mul state by mds matrix_vector_product(¶ms.mds_matrix(), state)?; diff --git a/crates/rescue-poseidon/src/circuit/poseidon2.rs b/crates/rescue-poseidon/src/circuit/poseidon2.rs index 846e5ae..a425656 100644 --- a/crates/rescue-poseidon/src/circuit/poseidon2.rs +++ b/crates/rescue-poseidon/src/circuit/poseidon2.rs @@ -1,9 +1,9 @@ +use super::matrix::{matrix_vector_product, mul_by_sparse_matrix}; use super::sbox::sbox; use super::sponge::circuit_generic_hash_num; -use super::matrix::{matrix_vector_product, mul_by_sparse_matrix}; -use crate::{DomainStrategy, poseidon::params::PoseidonParams}; use crate::poseidon2::Poseidon2Params; use crate::traits::{HashFamily, HashParams}; +use crate::{poseidon::params::PoseidonParams, DomainStrategy}; use franklin_crypto::bellman::plonk::better_better_cs::cs::ConstraintSystem; use franklin_crypto::bellman::{Field, SynthesisError}; use franklin_crypto::{ @@ -16,23 +16,14 @@ use franklin_crypto::{ /// length of input and applies a padding rule which makes input size equals to multiple of /// rate parameter. /// Uses pre-defined state-width=3 and rate=2. -pub fn circuit_poseidon2_hash, const L: usize>( - cs: &mut CS, - input: &[Num; L], - domain_strategy: Option, -) -> Result<[Num; 2], SynthesisError> { +pub fn circuit_poseidon2_hash, const L: usize>(cs: &mut CS, input: &[Num; L], domain_strategy: Option) -> Result<[Num; 2], SynthesisError> { const WIDTH: usize = 3; const RATE: usize = 2; let params = Poseidon2Params::::default(); circuit_generic_hash_num(cs, input, ¶ms, domain_strategy) } -pub fn circuit_poseidon2_round_function< - E: Engine, - CS: ConstraintSystem, - const RATE: usize, - const WIDTH: usize, ->( +pub fn circuit_poseidon2_round_function, const RATE: usize, const WIDTH: usize>( cs: &mut CS, params: &Poseidon2Params, state: &mut [LinearCombination; WIDTH], @@ -53,13 +44,7 @@ pub fn circuit_poseidon2_round_function< s.add_assign_constant(*c); } // non linear sbox - sbox( - cs, - params.alpha(), - state, - Some(0..WIDTH), - params.custom_gate(), - )?; + sbox(cs, params.alpha(), state, Some(0..WIDTH), params.custom_gate())?; // mul state by mds matrix_vector_product(¶ms.mds_external_matrix, state)?; @@ -91,9 +76,7 @@ pub fn circuit_poseidon2_round_function< } // second full round - for round in (params.number_of_partial_rounds() + half_of_full_rounds) - ..(params.number_of_partial_rounds() + params.number_of_full_rounds()) - { + for round in (params.number_of_partial_rounds() + half_of_full_rounds)..(params.number_of_partial_rounds() + params.number_of_full_rounds()) { let round_constants = ¶ms.round_constants[round]; // add round constatnts @@ -101,13 +84,7 @@ pub fn circuit_poseidon2_round_function< s.add_assign_constant(*c); } // non linear sbox - sbox( - cs, - params.alpha(), - state, - Some(0..WIDTH), - params.custom_gate(), - )?; + sbox(cs, params.alpha(), state, Some(0..WIDTH), params.custom_gate())?; // mul state by mds matrix_vector_product(¶ms.mds_external_matrix, state)?; diff --git a/crates/rescue-poseidon/src/circuit/rescue.rs b/crates/rescue-poseidon/src/circuit/rescue.rs index 5d6255e..b1c4069 100644 --- a/crates/rescue-poseidon/src/circuit/rescue.rs +++ b/crates/rescue-poseidon/src/circuit/rescue.rs @@ -1,79 +1,48 @@ -use super::sbox::sbox; use super::matrix::matrix_vector_product; -use crate::{DomainStrategy, circuit::sponge::circuit_generic_hash_num, traits::{HashFamily, HashParams}}; +use super::sbox::sbox; +use crate::{ + circuit::sponge::circuit_generic_hash_num, + traits::{HashFamily, HashParams}, + DomainStrategy, +}; use franklin_crypto::bellman::plonk::better_better_cs::cs::ConstraintSystem; use crate::rescue::params::RescueParams; use franklin_crypto::bellman::SynthesisError; -use franklin_crypto::{ - bellman::Engine, plonk::circuit::allocated_num::Num, - plonk::circuit::linear_combination::LinearCombination, -}; +use franklin_crypto::{bellman::Engine, plonk::circuit::allocated_num::Num, plonk::circuit::linear_combination::LinearCombination}; /// Receives inputs whose length `known` prior(fixed-length). /// Also uses custom domain strategy which basically sets value of capacity element to /// length of input and applies a padding rule which makes input size equals to multiple of /// rate parameter. /// Uses pre-defined state-width=3 and rate=2. -pub fn circuit_rescue_hash, const L: usize>( - cs: &mut CS, - input: &[Num; L], - domain_strategy: Option, -) -> Result<[Num; 2], SynthesisError> { +pub fn circuit_rescue_hash, const L: usize>(cs: &mut CS, input: &[Num; L], domain_strategy: Option) -> Result<[Num; 2], SynthesisError> { const WIDTH: usize = 3; const RATE: usize = 2; let params = RescueParams::::default(); circuit_generic_hash_num(cs, input, ¶ms, domain_strategy) } -pub(crate) fn circuit_rescue_round_function< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( +pub(crate) fn circuit_rescue_round_function, P: HashParams, const RATE: usize, const WIDTH: usize>( cs: &mut CS, params: &P, state: &mut [LinearCombination; WIDTH], ) -> Result<(), SynthesisError> { - assert_eq!( - params.hash_family(), - HashFamily::Rescue, - "Incorrect hash family!" - ); - state - .iter_mut() - .zip(params.constants_of_round(0).iter()) - .for_each(|(s, c)| s.add_assign_constant(*c)); + assert_eq!(params.hash_family(), HashFamily::Rescue, "Incorrect hash family!"); + state.iter_mut().zip(params.constants_of_round(0).iter()).for_each(|(s, c)| s.add_assign_constant(*c)); for round in 0..2 * params.number_of_full_rounds() { // apply sbox if round & 1 == 0 { - sbox( - cs, - params.alpha_inv(), - state, - None, - params.custom_gate(), - )?; + sbox(cs, params.alpha_inv(), state, None, params.custom_gate())?; } else { - sbox( - cs, - params.alpha(), - state, - None, - params.custom_gate(), - )?; + sbox(cs, params.alpha(), state, None, params.custom_gate())?; } // mds row matrix_vector_product(¶ms.mds_matrix(), state)?; // round constants - for (s, c) in state - .iter_mut() - .zip(params.constants_of_round(round + 1).iter().cloned()) - { + for (s, c) in state.iter_mut().zip(params.constants_of_round(round + 1).iter().cloned()) { s.add_assign_constant(c); } } diff --git a/crates/rescue-poseidon/src/circuit/rescue_prime.rs b/crates/rescue-poseidon/src/circuit/rescue_prime.rs index 9f8e3b5..bf9e502 100644 --- a/crates/rescue-poseidon/src/circuit/rescue_prime.rs +++ b/crates/rescue-poseidon/src/circuit/rescue_prime.rs @@ -1,8 +1,8 @@ +use super::matrix::matrix_vector_product; use super::sbox::*; use super::sponge::circuit_generic_hash_num; -use super::matrix::matrix_vector_product; -use crate::{DomainStrategy, rescue_prime::params::RescuePrimeParams}; use crate::traits::{HashFamily, HashParams}; +use crate::{rescue_prime::params::RescuePrimeParams, DomainStrategy}; use franklin_crypto::bellman::plonk::better_better_cs::cs::ConstraintSystem; use franklin_crypto::bellman::SynthesisError; use franklin_crypto::{ @@ -15,45 +15,25 @@ use franklin_crypto::{ /// length of input and applies a padding rule which makes input size equals to multiple of /// rate parameter. /// Uses pre-defined state-width=3 and rate=2. -pub fn gadget_rescue_prime_hash, const L: usize>( - cs: &mut CS, - input: &[Num; L], - domain_strategy: Option, -) -> Result<[Num; 2], SynthesisError> { +pub fn gadget_rescue_prime_hash, const L: usize>(cs: &mut CS, input: &[Num; L], domain_strategy: Option) -> Result<[Num; 2], SynthesisError> { const WIDTH: usize = 3; const RATE: usize = 2; let params = RescuePrimeParams::::default(); circuit_generic_hash_num(cs, input, ¶ms, domain_strategy) } -pub(crate) fn gadget_rescue_prime_round_function< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( +pub(crate) fn gadget_rescue_prime_round_function, P: HashParams, const RATE: usize, const WIDTH: usize>( cs: &mut CS, params: &P, state: &mut [LinearCombination; WIDTH], ) -> Result<(), SynthesisError> { - assert_eq!( - params.hash_family(), - HashFamily::RescuePrime, - "Incorrect hash family!" - ); + assert_eq!(params.hash_family(), HashFamily::RescuePrime, "Incorrect hash family!"); for round in 0..params.number_of_full_rounds() - 1 { // apply sbox // each lc will have 3 terms but there will be 1 in first iteration // total cost 2 gate per state vars = 6 - sbox( - cs, - params.alpha(), - state, - None, - params.custom_gate(), - )?; + sbox(cs, params.alpha(), state, None, params.custom_gate())?; // mul by mds matrix_vector_product(¶ms.mds_matrix(), state)?; @@ -64,13 +44,7 @@ pub(crate) fn gadget_rescue_prime_round_function< s.add_assign_constant(c); } // apply inverse sbox - sbox( - cs, - params.alpha_inv(), - state, - None, - params.custom_gate(), - )?; + sbox(cs, params.alpha_inv(), state, None, params.custom_gate())?; // mul by mds matrix_vector_product(¶ms.mds_matrix(), state)?; diff --git a/crates/rescue-poseidon/src/circuit/sbox.rs b/crates/rescue-poseidon/src/circuit/sbox.rs index be46ce4..5a4ad3d 100644 --- a/crates/rescue-poseidon/src/circuit/sbox.rs +++ b/crates/rescue-poseidon/src/circuit/sbox.rs @@ -1,16 +1,11 @@ use franklin_crypto::{ bellman::{ - plonk::better_better_cs::cs::{ - ArithmeticTerm, ConstraintSystem, MainGateTerm, PlonkConstraintSystemParams, - }, + plonk::better_better_cs::cs::{ArithmeticTerm, ConstraintSystem, MainGateTerm, PlonkConstraintSystemParams}, Engine, }, bellman::{Field, SynthesisError}, plonk::circuit::allocated_num::AllocatedNum, - plonk::circuit::{ - allocated_num::Num, - linear_combination::LinearCombination, - }, + plonk::circuit::{allocated_num::Num, linear_combination::LinearCombination}, }; use franklin_crypto::plonk::circuit::Assignment; @@ -30,27 +25,15 @@ pub(crate) fn sbox, const WIDTH: usize>( use_partial_state: Option>, custom_gate: CustomGate, ) -> Result<(), SynthesisError> { - let state_range = if let Some(partial_range) = use_partial_state{ - partial_range - }else{ - 0..WIDTH - }; + let state_range = if let Some(partial_range) = use_partial_state { partial_range } else { 0..WIDTH }; match power { - Sbox::Alpha(alpha) => sbox_alpha( - cs, - alpha, - prev_state, - state_range, - custom_gate, - ), - Sbox::AlphaInverse(alpha_inv, alpha) => { - sbox_alpha_inv(cs, alpha_inv, alpha, prev_state, custom_gate) - }, - Sbox::AddChain(chain, alpha) => { - // in circuit there is no difference + Sbox::Alpha(alpha) => sbox_alpha(cs, alpha, prev_state, state_range, custom_gate), + Sbox::AlphaInverse(alpha_inv, alpha) => sbox_alpha_inv(cs, alpha_inv, alpha, prev_state, custom_gate), + Sbox::AddChain(chain, alpha) => { + // in circuit there is no difference sbox_alpha_inv_via_add_chain(cs, chain, alpha, prev_state, custom_gate) - }, + } } } @@ -65,8 +48,7 @@ fn sbox_alpha, const WIDTH: usize>( CustomGate::None => false, _ => true, }; - let use_custom_gate = - use_custom_gate && CS::Params::HAS_CUSTOM_GATES == true && CS::Params::STATE_WIDTH >= 4; + let use_custom_gate = use_custom_gate && CS::Params::HAS_CUSTOM_GATES == true && CS::Params::STATE_WIDTH >= 4; if *alpha != 5u64 { unimplemented!("only 5th power is supported!") @@ -137,8 +119,7 @@ fn sbox_alpha_inv, const WIDTH: usize>( let quad = squared.square(cs)?; let mut term = MainGateTerm::::new(); - let fifth_term = ArithmeticTerm::from_variable(quad.get_variable()) - .mul_by_variable(powered.get_variable()); + let fifth_term = ArithmeticTerm::from_variable(quad.get_variable()).mul_by_variable(powered.get_variable()); let el_term = ArithmeticTerm::from_variable(value.get_variable()); term.add_assign(fifth_term); term.sub_assign(el_term); @@ -152,7 +133,6 @@ fn sbox_alpha_inv, const WIDTH: usize>( return Ok(()); } - // This function computes power of inverse of alpha to each element of state. // By custom gate support, it costs only single gate. Under the hood, it proves // that 5th power of each element of state is equal to itself.(x^(1/5)^5==x) @@ -198,8 +178,7 @@ fn sbox_alpha_inv_via_add_chain, const WIDTH: let quad = squared.square(cs)?; let mut term = MainGateTerm::::new(); - let fifth_term = ArithmeticTerm::from_variable(quad.get_variable()) - .mul_by_variable(powered.get_variable()); + let fifth_term = ArithmeticTerm::from_variable(quad.get_variable()).mul_by_variable(powered.get_variable()); let el_term = ArithmeticTerm::from_variable(value.get_variable()); term.add_assign(fifth_term); term.sub_assign(el_term); @@ -219,32 +198,15 @@ fn inner_apply_5th_power>( existing_5th: Option>, custom_gate: CustomGate, ) -> Result, SynthesisError> { - assert!( - CS::Params::HAS_CUSTOM_GATES, - "CS should have custom gate support" - ); + assert!(CS::Params::HAS_CUSTOM_GATES, "CS should have custom gate support"); match custom_gate { CustomGate::QuinticWidth4 => { - assert!( - CS::Params::STATE_WIDTH >= 4, - "state width should equal or large then 4" - ); - franklin_crypto::plonk::circuit::custom_rescue_gate::apply_5th_power( - cs, - value, - existing_5th, - ) + assert!(CS::Params::STATE_WIDTH >= 4, "state width should equal or large then 4"); + franklin_crypto::plonk::circuit::custom_rescue_gate::apply_5th_power(cs, value, existing_5th) } CustomGate::QuinticWidth3 => { - assert!( - CS::Params::STATE_WIDTH >= 3, - "state width should equal or large then 3" - ); - franklin_crypto::plonk::circuit::custom_5th_degree_gate_optimized::apply_5th_power( - cs, - value, - existing_5th, - ) + assert!(CS::Params::STATE_WIDTH >= 3, "state width should equal or large then 3"); + franklin_crypto::plonk::circuit::custom_5th_degree_gate_optimized::apply_5th_power(cs, value, existing_5th) } _ => unimplemented!(), } @@ -263,14 +225,7 @@ mod test { use super::*; - fn run_test_sbox, const N: usize>( - cs: &mut CS, - power: Sbox, - number_of_rounds: usize, - custom_gate: CustomGate, - use_partial_state: bool, - use_allocated: bool, - ) { + fn run_test_sbox, const N: usize>(cs: &mut CS, power: Sbox, number_of_rounds: usize, custom_gate: CustomGate, use_partial_state: bool, use_allocated: bool) { let (mut state, state_as_nums) = test_inputs::(cs, use_allocated); let mut state_as_lc = vec![]; @@ -280,24 +235,13 @@ mod test { } let mut state_as_lc: [LinearCombination; N] = state_as_lc.try_into().expect("array"); - let state_range = if use_partial_state { - Some(0..1) - } else { - Some(0..N) - }; + let state_range = if use_partial_state { Some(0..1) } else { Some(0..N) }; assert_eq!(state_range.as_ref().unwrap().len(), N); for _ in 0..number_of_rounds { crate::common::sbox::sbox::(&power, &mut state); - sbox( - cs, - &power, - &mut state_as_lc, - state_range.clone(), - custom_gate.clone(), - ) - .expect("5th apply successfu"); + sbox(cs, &power, &mut state_as_lc, state_range.clone(), custom_gate.clone()).expect("5th apply successfu"); } } fn test_sbox(power: Sbox) { @@ -306,75 +250,18 @@ mod test { const INPUT_LENGTH: usize = 3; const NUM_ROUNDS: usize = 1; - run_test_sbox::<_, _, INPUT_LENGTH>( - cs, - power.clone(), - NUM_ROUNDS, - CustomGate::QuinticWidth4, - false, - true, - ); // variable inputs - println!( - "{:?} sbox takes {} gates with custom gate(width4) for {} iteration ", - power, - cs.n(), - NUM_ROUNDS, - ); + run_test_sbox::<_, _, INPUT_LENGTH>(cs, power.clone(), NUM_ROUNDS, CustomGate::QuinticWidth4, false, true); // variable inputs + println!("{:?} sbox takes {} gates with custom gate(width4) for {} iteration ", power, cs.n(), NUM_ROUNDS,); let mut end = cs.n(); - run_test_sbox::<_, _, INPUT_LENGTH>( - cs, - power.clone(), - NUM_ROUNDS, - CustomGate::QuinticWidth3, - false, - true, - ); // variable inputs - println!( - "{:?} takes {} gates with custom gate(width3) for {} iteration ", - power, - cs.n()-end, - NUM_ROUNDS, - ); + run_test_sbox::<_, _, INPUT_LENGTH>(cs, power.clone(), NUM_ROUNDS, CustomGate::QuinticWidth3, false, true); // variable inputs + println!("{:?} takes {} gates with custom gate(width3) for {} iteration ", power, cs.n() - end, NUM_ROUNDS,); end = cs.n(); - run_test_sbox::<_, _, INPUT_LENGTH>( - cs, - power.clone(), - NUM_ROUNDS, - CustomGate::None, - false, - true, - ); // variable inputs + no custom gate - println!( - "{:?} takes {} gates without custom gate for {} iteration ", - power, - cs.n() - end, - NUM_ROUNDS, - ); - run_test_sbox::<_, _, INPUT_LENGTH>( - cs, - power.clone(), - NUM_ROUNDS, - CustomGate::None, - false, - false, - ); // constant inputs + no custom gate - run_test_sbox::<_, _, INPUT_LENGTH>( - cs, - power.clone(), - NUM_ROUNDS, - CustomGate::QuinticWidth4, - false, - false, - ); // constant inputs - run_test_sbox::<_, _, INPUT_LENGTH>( - cs, - power.clone(), - NUM_ROUNDS, - CustomGate::QuinticWidth3, - false, - false, - ); // constant inputs + run_test_sbox::<_, _, INPUT_LENGTH>(cs, power.clone(), NUM_ROUNDS, CustomGate::None, false, true); // variable inputs + no custom gate + println!("{:?} takes {} gates without custom gate for {} iteration ", power, cs.n() - end, NUM_ROUNDS,); + run_test_sbox::<_, _, INPUT_LENGTH>(cs, power.clone(), NUM_ROUNDS, CustomGate::None, false, false); // constant inputs + no custom gate + run_test_sbox::<_, _, INPUT_LENGTH>(cs, power.clone(), NUM_ROUNDS, CustomGate::QuinticWidth4, false, false); // constant inputs + run_test_sbox::<_, _, INPUT_LENGTH>(cs, power.clone(), NUM_ROUNDS, CustomGate::QuinticWidth3, false, false); // constant inputs cs.finalize(); assert!(cs.is_satisfied()); diff --git a/crates/rescue-poseidon/src/circuit/sponge.rs b/crates/rescue-poseidon/src/circuit/sponge.rs index 35c4d63..2435c72 100644 --- a/crates/rescue-poseidon/src/circuit/sponge.rs +++ b/crates/rescue-poseidon/src/circuit/sponge.rs @@ -1,10 +1,9 @@ use crate::{ common::domain_strategy::DomainStrategy, - traits::{HashFamily, HashParams}, poseidon2::Poseidon2Params, -}; -use franklin_crypto::{ - bellman::plonk::better_better_cs::cs::ConstraintSystem, plonk::circuit::allocated_num::Num, + poseidon2::Poseidon2Params, + traits::{HashFamily, HashParams}, }; +use franklin_crypto::{bellman::plonk::better_better_cs::cs::ConstraintSystem, plonk::circuit::allocated_num::Num}; use franklin_crypto::{bellman::Field, plonk::circuit::boolean::Boolean}; use franklin_crypto::{ bellman::{Engine, SynthesisError}, @@ -12,14 +11,7 @@ use franklin_crypto::{ }; use std::convert::TryInto; -pub fn circuit_generic_hash< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, - const LENGTH: usize, ->( +pub fn circuit_generic_hash, P: HashParams, const RATE: usize, const WIDTH: usize, const LENGTH: usize>( cs: &mut CS, input: &[Num; LENGTH], params: &P, @@ -28,14 +20,7 @@ pub fn circuit_generic_hash< CircuitGenericSponge::hash(cs, input, params, domain_strategy) } -pub fn circuit_generic_hash_num< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, - const LENGTH: usize, ->( +pub fn circuit_generic_hash_num, P: HashParams, const RATE: usize, const WIDTH: usize, const LENGTH: usize>( cs: &mut CS, input: &[Num; LENGTH], params: &P, @@ -67,11 +52,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< DomainStrategy::CustomVariableLength | DomainStrategy::VariableLength => (), _ => panic!("only variable length domain strategies allowed"), } - let state = (0..WIDTH) - .map(|_| LinearCombination::zero()) - .collect::>() - .try_into() - .expect("constant array"); + let state = (0..WIDTH).map(|_| LinearCombination::zero()).collect::>().try_into().expect("constant array"); Self { state, mode: SpongeMode::Absorb([None; RATE]), @@ -99,13 +80,8 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< let domain_strategy = DomainStrategy::CustomFixedLength; // specialize capacity - let capacity_value = domain_strategy - .compute_capacity::(input.len(), RATE) - .unwrap_or(E::Fr::zero()); - state - .last_mut() - .expect("last element") - .add_assign_constant(capacity_value); + let capacity_value = domain_strategy.compute_capacity::(input.len(), RATE).unwrap_or(E::Fr::zero()); + state.last_mut().expect("last element").add_assign_constant(capacity_value); // compute padding values let padding_values = domain_strategy @@ -123,12 +99,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< // process each chunk of input for values in padded_input.chunks_exact(RATE) { - absorb( - cs, - &mut state, - values.try_into().expect("constant array"), - params, - )?; + absorb(cs, &mut state, values.try_into().expect("constant array"), params)?; } // prepare output @@ -144,7 +115,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< cs: &mut CS, input: &[Num], params: &P, - domain_strategy: Option + domain_strategy: Option, ) -> Result<[Num; RATE], SynthesisError> { let result = Self::hash(cs, input, params, domain_strategy)?; // prepare output @@ -156,12 +127,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< Ok(output) } - pub fn absorb_multiple, P: HashParams>( - &mut self, - cs: &mut CS, - input: &[Num], - params: &P, - ) -> Result<(), SynthesisError> { + pub fn absorb_multiple, P: HashParams>(&mut self, cs: &mut CS, input: &[Num], params: &P) -> Result<(), SynthesisError> { for inp in input.into_iter() { self.absorb(cs, *inp, params)? } @@ -169,12 +135,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< Ok(()) } - pub fn absorb, P: HashParams>( - &mut self, - cs: &mut CS, - input: Num, - params: &P, - ) -> Result<(), SynthesisError> { + pub fn absorb, P: HashParams>(&mut self, cs: &mut CS, input: Num, params: &P) -> Result<(), SynthesisError> { match self.mode { SpongeMode::Absorb(ref mut buf) => { // push value into buffer @@ -219,8 +180,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< let unwrapped_buffer_len = buf.iter().filter(|el| el.is_some()).count(); // compute padding values let padding_strategy = DomainStrategy::CustomVariableLength; - let padding_values = - padding_strategy.generate_padding_values::(unwrapped_buffer_len, RATE); + let padding_values = padding_strategy.generate_padding_values::(unwrapped_buffer_len, RATE); let mut padding_values_it = padding_values.iter().cloned(); for b in buf { @@ -234,11 +194,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< } } - pub fn squeeze, P: HashParams>( - &mut self, - cs: &mut CS, - params: &P, - ) -> Result>, SynthesisError> { + pub fn squeeze, P: HashParams>(&mut self, cs: &mut CS, params: &P) -> Result>, SynthesisError> { loop { match self.mode { SpongeMode::Absorb(ref mut buf) => { @@ -283,11 +239,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< } } - pub fn squeeze_num, P: HashParams>( - &mut self, - cs: &mut CS, - params: &P, - ) -> Result>, SynthesisError> { + pub fn squeeze_num, P: HashParams>(&mut self, cs: &mut CS, params: &P) -> Result>, SynthesisError> { if let Some(value) = self.squeeze(cs, params)? { Ok(Some(value.into_num(cs)?)) } else { @@ -296,13 +248,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> CircuitGenericSponge< } } -fn absorb< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( +fn absorb, P: HashParams, const RATE: usize, const WIDTH: usize>( cs: &mut CS, state: &mut [LinearCombination; WIDTH], input: &[Num; RATE], @@ -314,13 +260,7 @@ fn absorb< circuit_generic_round_function(cs, state, params) } -pub fn circuit_generic_round_function< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( +pub fn circuit_generic_round_function, P: HashParams, const RATE: usize, const WIDTH: usize>( cs: &mut CS, state: &mut [LinearCombination; WIDTH], params: &P, @@ -328,26 +268,12 @@ pub fn circuit_generic_round_function< match params.hash_family() { HashFamily::Rescue => super::rescue::circuit_rescue_round_function(cs, params, state), HashFamily::Poseidon => super::poseidon::circuit_poseidon_round_function(cs, params, state), - HashFamily::RescuePrime => { - super::rescue_prime::gadget_rescue_prime_round_function(cs, params, state) - } - HashFamily::Poseidon2 => { - super::poseidon2::circuit_poseidon2_round_function( - cs, - params.try_to_poseidon2_params().unwrap(), - state - ) - } + HashFamily::RescuePrime => super::rescue_prime::gadget_rescue_prime_round_function(cs, params, state), + HashFamily::Poseidon2 => super::poseidon2::circuit_poseidon2_round_function(cs, params.try_to_poseidon2_params().unwrap(), state), } } -pub fn circuit_generic_round_function_conditional< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( +pub fn circuit_generic_round_function_conditional, P: HashParams, const RATE: usize, const WIDTH: usize>( cs: &mut CS, state: &mut [LinearCombination; WIDTH], execute: &Boolean, @@ -360,16 +286,8 @@ pub fn circuit_generic_round_function_conditional< let tmp = match params.hash_family() { HashFamily::Rescue => super::rescue::circuit_rescue_round_function(cs, params, state), HashFamily::Poseidon => super::poseidon::circuit_poseidon_round_function(cs, params, state), - HashFamily::RescuePrime => { - super::rescue_prime::gadget_rescue_prime_round_function(cs, params, state) - } - HashFamily::Poseidon2 => { - super::poseidon2::circuit_poseidon2_round_function( - cs, - params.try_to_poseidon2_params().unwrap(), - state - ) - } + HashFamily::RescuePrime => super::rescue_prime::gadget_rescue_prime_round_function(cs, params, state), + HashFamily::Poseidon2 => super::poseidon2::circuit_poseidon2_round_function(cs, params.try_to_poseidon2_params().unwrap(), state), }; let _ = tmp?; diff --git a/crates/rescue-poseidon/src/circuit/tests.rs b/crates/rescue-poseidon/src/circuit/tests.rs index 3f84f91..7f91329 100644 --- a/crates/rescue-poseidon/src/circuit/tests.rs +++ b/crates/rescue-poseidon/src/circuit/tests.rs @@ -13,10 +13,7 @@ use franklin_crypto::plonk::circuit::allocated_num::Num; use franklin_crypto::{bellman::plonk::better_better_cs::cs::ConstraintSystem, bellman::Engine}; use rand::Rand; -pub(crate) fn test_inputs, const N: usize>( - cs: &mut CS, - use_allocated: bool, -) -> ([E::Fr; N], [Num; N]) { +pub(crate) fn test_inputs, const N: usize>(cs: &mut CS, use_allocated: bool) -> ([E::Fr; N], [Num; N]) { let rng = &mut init_rng(); let mut inputs = [E::Fr::zero(); N]; @@ -33,17 +30,7 @@ pub(crate) fn test_inputs, const N: usize>( (inputs, inputs_as_num) } -fn test_circuit_var_len_generic_hasher< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, - const N: usize, ->( - cs: &mut CS, - params: &P, -) { +fn test_circuit_var_len_generic_hasher, P: HashParams, const RATE: usize, const WIDTH: usize, const N: usize>(cs: &mut CS, params: &P) { let (inputs, inputs_as_num) = test_inputs::(cs, true); let mut hasher = GenericSponge::<_, RATE, WIDTH>::new(); @@ -51,34 +38,18 @@ fn test_circuit_var_len_generic_hasher< let expected = hasher.squeeze(params).expect("a squeezed elem"); let mut circuit_gadget = CircuitGenericSponge::<_, RATE, WIDTH>::new(); - circuit_gadget - .absorb_multiple(cs, &inputs_as_num, params) - .unwrap(); - let actual = circuit_gadget - .squeeze(cs, params) - .unwrap() - .expect("a squeezed elem"); + circuit_gadget.absorb_multiple(cs, &inputs_as_num, params).unwrap(); + let actual = circuit_gadget.squeeze(cs, params).unwrap().expect("a squeezed elem"); assert_eq!(actual.get_value().unwrap(), expected); } // TODO add test for a case when padding needed -fn test_circuit_fixed_len_generic_hasher< - E: Engine, - CS: ConstraintSystem, - P: HashParams, - const RATE: usize, - const WIDTH: usize, - const N: usize, ->( - cs: &mut CS, - params: &P, -) { +fn test_circuit_fixed_len_generic_hasher, P: HashParams, const RATE: usize, const WIDTH: usize, const N: usize>(cs: &mut CS, params: &P) { let (inputs, inputs_as_num) = test_inputs::(cs, true); let expected = GenericSponge::<_, RATE, WIDTH>::hash(&inputs, params, None); - let actual = - CircuitGenericSponge::<_, RATE, WIDTH>::hash::<_, P>(cs, &inputs_as_num, ¶ms, None).unwrap(); + let actual = CircuitGenericSponge::<_, RATE, WIDTH>::hash::<_, P>(cs, &inputs_as_num, ¶ms, None).unwrap(); assert_eq!(actual[0].get_value().unwrap(), expected[0]); } @@ -93,10 +64,7 @@ fn test_circuit_fixed_len_rescue_hasher() { let cs = &mut init_cs::(); let params = RescueParams::default(); test_circuit_fixed_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of constant length Rescue hash with 2 input(no custom gate): {}", - cs.n() - ); + println!("CS cost of constant length Rescue hash with 2 input(no custom gate): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -107,10 +75,7 @@ fn test_circuit_fixed_len_rescue_hasher() { let mut params = RescueParams::default(); params.use_custom_gate(CustomGate::QuinticWidth3); test_circuit_fixed_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of constant length Rescue hash with 2 input(custom gate width 3): {}", - cs.n() - ); + println!("CS cost of constant length Rescue hash with 2 input(custom gate width 3): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -121,10 +86,7 @@ fn test_circuit_fixed_len_rescue_hasher() { let mut params = RescueParams::default(); params.use_custom_gate(CustomGate::QuinticWidth4); test_circuit_fixed_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of constant length Rescue hash with 2 input(custom gate width 4): {}", - cs.n() - ); + println!("CS cost of constant length Rescue hash with 2 input(custom gate width 4): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -142,10 +104,7 @@ fn test_circuit_fixed_len_poseidon_hasher() { let cs = &mut init_cs::(); let params = PoseidonParams::default(); test_circuit_fixed_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of constant length Poseidon hash with 2 input(no custom gate): {}", - cs.n() - ); + println!("CS cost of constant length Poseidon hash with 2 input(no custom gate): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -156,10 +115,7 @@ fn test_circuit_fixed_len_poseidon_hasher() { let mut params = PoseidonParams::default(); params.use_custom_gate(CustomGate::QuinticWidth3); test_circuit_fixed_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of constant length Poseidon hash with 2 input(custom gate width 3): {}", - cs.n() - ); + println!("CS cost of constant length Poseidon hash with 2 input(custom gate width 3): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -170,10 +126,7 @@ fn test_circuit_fixed_len_poseidon_hasher() { let mut params = PoseidonParams::default(); params.use_custom_gate(CustomGate::QuinticWidth4); test_circuit_fixed_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of constant length Poseidon hash with 2 input(custom gate width 4): {}", - cs.n() - ); + println!("CS cost of constant length Poseidon hash with 2 input(custom gate width 4): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -191,10 +144,7 @@ fn test_circuit_fixed_len_rescue_prime_hasher() { let cs = &mut init_cs::(); let params = RescuePrimeParams::default(); test_circuit_fixed_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost constant length RescuePrime hash with 2 input(no custom gate): {}", - cs.n() - ); + println!("CS cost constant length RescuePrime hash with 2 input(no custom gate): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -205,10 +155,7 @@ fn test_circuit_fixed_len_rescue_prime_hasher() { let mut params = RescuePrimeParams::default(); params.use_custom_gate(CustomGate::QuinticWidth3); test_circuit_fixed_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of constant length RescuePrime hash with 2 input(custom gate width 3): {}", - cs.n() - ); + println!("CS cost of constant length RescuePrime hash with 2 input(custom gate width 3): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -219,10 +166,7 @@ fn test_circuit_fixed_len_rescue_prime_hasher() { let mut params = RescuePrimeParams::default(); params.use_custom_gate(CustomGate::QuinticWidth4); test_circuit_fixed_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of constant length RescuePrime hash with 2 input(custom gate width 4): {}", - cs.n() - ); + println!("CS cost of constant length RescuePrime hash with 2 input(custom gate width 4): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -240,10 +184,7 @@ fn test_circuit_var_len_rescue_hasher() { let params = RescueParams::default(); test_circuit_var_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of variable length Rescue hash with 2 input (no custom gate): {}", - cs.n() - ); + println!("CS cost of variable length Rescue hash with 2 input (no custom gate): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -255,10 +196,7 @@ fn test_circuit_var_len_rescue_hasher() { let mut params = RescueParams::default(); params.use_custom_gate(CustomGate::QuinticWidth3); test_circuit_var_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of variable length Rescue hash with 2 input(custom gate width 3): {}", - cs.n() - ); + println!("CS cost of variable length Rescue hash with 2 input(custom gate width 3): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -270,10 +208,7 @@ fn test_circuit_var_len_rescue_hasher() { let mut params = RescueParams::default(); params.use_custom_gate(CustomGate::QuinticWidth4); test_circuit_var_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of variable length Rescue hash with 2 input(custom gate width 4): {}", - cs.n() - ); + println!("CS cost of variable length Rescue hash with 2 input(custom gate width 4): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -292,10 +227,7 @@ fn test_circuit_var_len_poseidon_hasher() { let params = PoseidonParams::default(); test_circuit_var_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of variable length Poseidon hash with 2 input(no custom gate): {}", - cs.n() - ); + println!("CS cost of variable length Poseidon hash with 2 input(no custom gate): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -307,10 +239,7 @@ fn test_circuit_var_len_poseidon_hasher() { let mut params = PoseidonParams::default(); params.use_custom_gate(CustomGate::QuinticWidth3); test_circuit_var_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of variable length Poseidon hash with 2 input(custom gate width 3): {}", - cs.n() - ); + println!("CS cost of variable length Poseidon hash with 2 input(custom gate width 3): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -322,10 +251,7 @@ fn test_circuit_var_len_poseidon_hasher() { let mut params = PoseidonParams::default(); params.use_custom_gate(CustomGate::QuinticWidth4); test_circuit_var_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of variable length Poseidon hash with 2 input(custom gate width 4): {}", - cs.n() - ); + println!("CS cost of variable length Poseidon hash with 2 input(custom gate width 4): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -344,10 +270,7 @@ fn test_circuit_var_len_rescue_prime_hasher() { let params = RescuePrimeParams::default(); test_circuit_var_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of variable length RescuePrime hash with 2 input(no custom gate): {}", - cs.n() - ); + println!("CS cost of variable length RescuePrime hash with 2 input(no custom gate): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -359,10 +282,7 @@ fn test_circuit_var_len_rescue_prime_hasher() { let mut params = RescuePrimeParams::default(); params.use_custom_gate(CustomGate::QuinticWidth3); test_circuit_var_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of variable length RescuePrime hash with 2 input(custom gate width 3): {}", - cs.n() - ); + println!("CS cost of variable length RescuePrime hash with 2 input(custom gate width 3): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); @@ -374,10 +294,7 @@ fn test_circuit_var_len_rescue_prime_hasher() { let mut params = RescuePrimeParams::default(); params.use_custom_gate(CustomGate::QuinticWidth4); test_circuit_var_len_generic_hasher::<_, _, _, RATE, WIDTH, INPUT_LENGTH>(cs, ¶ms); - println!( - "CS cost of variable length RescuePrime hash with 2 input(custom gate width 4): {}", - cs.n() - ); + println!("CS cost of variable length RescuePrime hash with 2 input(custom gate width 4): {}", cs.n()); cs.finalize(); assert!(cs.is_satisfied()); diff --git a/crates/rescue-poseidon/src/common/domain_strategy.rs b/crates/rescue-poseidon/src/common/domain_strategy.rs index 28d2a50..c2bdf79 100644 --- a/crates/rescue-poseidon/src/common/domain_strategy.rs +++ b/crates/rescue-poseidon/src/common/domain_strategy.rs @@ -26,11 +26,7 @@ pub enum DomainStrategy { impl DomainStrategy { /// Computes capacity value for specialization and domain seperation. - pub(crate) fn compute_capacity( - &self, - input_len: usize, - rate: usize, - ) -> Option { + pub(crate) fn compute_capacity(&self, input_len: usize, rate: usize) -> Option { let mut repr = ::Repr::default(); repr.as_mut()[1] = 1u64; // 2^64 corresponds second le limb let mut el = E::Fr::from_repr(repr).unwrap(); @@ -66,11 +62,7 @@ impl DomainStrategy { } } /// Computes values for padding. - pub(crate) fn generate_padding_values( - &self, - input_len: usize, - rate: usize - ) -> Vec { + pub(crate) fn generate_padding_values(&self, input_len: usize, rate: usize) -> Vec { assert!(input_len != 0, "empty input"); if input_len % rate == 0 { // input doesn't need padding diff --git a/crates/rescue-poseidon/src/common/matrix.rs b/crates/rescue-poseidon/src/common/matrix.rs index f1dfb21..54b8464 100644 --- a/crates/rescue-poseidon/src/common/matrix.rs +++ b/crates/rescue-poseidon/src/common/matrix.rs @@ -39,12 +39,9 @@ pub(crate) fn compute_optimized_matrixes(matrix).expect("should have inverse"); - }); + sparse_matrixes.iter().chain(&[m_prime.clone()]).for_each(|matrix| { + let _ = try_inverse::(matrix).expect("should have inverse"); + }); (transpose::(&m_prime), sparse_matrixes) } @@ -61,8 +58,7 @@ pub(crate) fn sub_matrix( // w => 1..DIM 0..1 // v => 0..1 1..DIM assert!( - (row_range.len() == SUBDIM || row_range.len() == 1) - && (col_range.len() == SUBDIM || col_range.len() == 1), + (row_range.len() == SUBDIM || row_range.len() == 1) && (col_range.len() == SUBDIM || col_range.len() == 1), "row/col length should be in range" ); let mut sub_matrix = [[E::Fr::zero(); SUBDIM]; SUBDIM]; @@ -91,10 +87,7 @@ pub(crate) fn set_sub_matrix( } // Multiplies matrix with a vector and assigns result into same vector. -pub(crate) fn mmul_assign( - matrix: &[[E::Fr; DIM]; DIM], - vector: &mut [E::Fr; DIM], -) { +pub(crate) fn mmul_assign(matrix: &[[E::Fr; DIM]; DIM], vector: &mut [E::Fr; DIM]) { // [M]xv let mut result = [E::Fr::zero(); DIM]; for col in 0..DIM { @@ -104,10 +97,7 @@ pub(crate) fn mmul_assign( } // Multiplies two same dimension matrixes. -pub(crate) fn multiply( - m1: &[[E::Fr; DIM]; DIM], - m2: &[[E::Fr; DIM]; DIM], -) -> [[E::Fr; DIM]; DIM] { +pub(crate) fn multiply(m1: &[[E::Fr; DIM]; DIM], m2: &[[E::Fr; DIM]; DIM]) -> [[E::Fr; DIM]; DIM] { let transposed_m2 = transpose::(m2); let mut result = [[E::Fr::zero(); DIM]; DIM]; @@ -121,9 +111,7 @@ pub(crate) fn multiply( result } // Transpose of a matrix. -pub(crate) fn transpose( - matrix: &[[E::Fr; DIM]; DIM], -) -> [[E::Fr; DIM]; DIM] { +pub(crate) fn transpose(matrix: &[[E::Fr; DIM]; DIM]) -> [[E::Fr; DIM]; DIM] { let mut values = [[E::Fr::zero(); DIM]; DIM]; for i in 0..DIM { for j in 0..DIM { @@ -135,10 +123,8 @@ pub(crate) fn transpose( } // Computes inverse of 2-d or 3-d matrixes. -// We need inverse of matrix for optimized poseidon -pub(crate) fn try_inverse( - m: &[[E::Fr; DIM]; DIM], -) -> Option<[[E::Fr; DIM]; DIM]> { +// We need inverse of matrix for optimized poseidon +pub(crate) fn try_inverse(m: &[[E::Fr; DIM]; DIM]) -> Option<[[E::Fr; DIM]; DIM]> { match DIM { 2 => try_inverse_dim_2::(m), 3 => try_inverse_dim_3::(m), @@ -147,9 +133,7 @@ pub(crate) fn try_inverse( } // Computes inverse of 2x2 matrix. -fn try_inverse_dim_2( - m: &[[E::Fr; DIM]; DIM], -) -> Option<[[E::Fr; DIM]; DIM]> { +fn try_inverse_dim_2(m: &[[E::Fr; DIM]; DIM]) -> Option<[[E::Fr; DIM]; DIM]> { assert_eq!(DIM, 2); let determinant = { let mut a = m[0][0]; @@ -201,9 +185,7 @@ fn try_inverse_dim_2( } // Computes inverse of 3x3 matrix. -fn try_inverse_dim_3( - m: &[[E::Fr; DIM]; DIM], -) -> Option<[[E::Fr; DIM]; DIM]> { +fn try_inverse_dim_3(m: &[[E::Fr; DIM]; DIM]) -> Option<[[E::Fr; DIM]; DIM]> { assert_eq!(DIM, 3); // m22 * m33 - m32 * m23; let minor_m12_m23 = { @@ -417,13 +399,7 @@ mod test { let _ = try_inverse::(&values); - assert_eq!( - identity::(), - multiply::( - &try_inverse::(&values).expect("inverse"), - &values - ) - ); + assert_eq!(identity::(), multiply::(&try_inverse::(&values).expect("inverse"), &values)); } #[test] @@ -479,10 +455,7 @@ mod test { matrix[i][j] = Fr::rand(rng); } } - assert_eq!( - transpose::(&transpose::(&matrix)), - matrix - ); + assert_eq!(transpose::(&transpose::(&matrix)), matrix); } } diff --git a/crates/rescue-poseidon/src/common/mod.rs b/crates/rescue-poseidon/src/common/mod.rs index c1d7f10..706d248 100644 --- a/crates/rescue-poseidon/src/common/mod.rs +++ b/crates/rescue-poseidon/src/common/mod.rs @@ -1,7 +1,7 @@ #![allow(dead_code)] -pub(crate) mod sbox; -pub(crate) mod utils; -pub(crate) mod matrix; pub(crate) mod domain_strategy; +pub(crate) mod matrix; pub(crate) mod params; +pub(crate) mod sbox; +pub(crate) mod utils; pub(crate) const TEST_SEED: [u32; 4] = [0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]; diff --git a/crates/rescue-poseidon/src/common/params.rs b/crates/rescue-poseidon/src/common/params.rs index f264b8f..47e555f 100644 --- a/crates/rescue-poseidon/src/common/params.rs +++ b/crates/rescue-poseidon/src/common/params.rs @@ -18,7 +18,6 @@ pub struct InnerHashParameters pub mds_matrix: [[E::Fr; WIDTH]; WIDTH], } - type H = BlakeHasher; impl InnerHashParameters { @@ -48,16 +47,14 @@ impl InnerHashParameters(nonce) - .unwrap(); + (&mut nonce_bytes[0..4]).write_u32::(nonce).unwrap(); let mut h = H::new(&tag[..]); h.update(constants::GH_FIRST_BLOCK); h.update(&nonce_bytes[..]); @@ -83,22 +80,18 @@ impl InnerHashParameters(total_round_constants, tag); self.round_constants = vec![[E::Fr::zero(); WIDTH]; number_of_rounds]; round_constants .chunks_exact(WIDTH) .zip(self.round_constants.iter_mut()) - .for_each(|(values, constants)| { - *constants = values.try_into().expect("round constants in const") - }); + .for_each(|(values, constants)| *constants = values.try_into().expect("round constants in const")); } pub(crate) fn compute_mds_matrix_for_poseidon(&mut self) { @@ -116,11 +109,7 @@ impl InnerHashParameters ChaChaRng { assert!(h.len() == 32); let mut seed = [0u32; 8]; for i in 0..8 { - seed[i] = (&h[..]) - .read_u32::() - .expect("digest is large enough for this to work"); + seed[i] = (&h[..]).read_u32::().expect("digest is large enough for this to work"); } ChaChaRng::from_seed(&seed) @@ -159,15 +146,12 @@ fn init_rng_for_poseidon() -> ChaChaRng { let mut seed = [0u32; 8]; for (i, chunk) in h.chunks_exact(4).enumerate() { - seed[i] = (&chunk[..]) - .read_u32::() - .expect("digest is large enough for this to work"); + seed[i] = (&chunk[..]).read_u32::().expect("digest is large enough for this to work"); } ChaChaRng::from_seed(&seed) } - pub(crate) fn get_random_field_elements_from_seed(num_elements: usize, tag: &[u8]) -> Vec { let mut round_constants = Vec::with_capacity(num_elements); let mut nonce = 0u32; @@ -176,9 +160,7 @@ pub(crate) fn get_random_field_elements_from_seed(num_elements: usize assert!((E::Fr::NUM_BITS + 7) / 8 <= 32); loop { - (&mut nonce_bytes[0..4]) - .write_u32::(nonce) - .unwrap(); + (&mut nonce_bytes[0..4]).write_u32::(nonce).unwrap(); use blake2::Digest; let mut h = blake2::Blake2s256::new(); h.update(tag); @@ -204,4 +186,4 @@ pub(crate) fn get_random_field_elements_from_seed(num_elements: usize } round_constants -} \ No newline at end of file +} diff --git a/crates/rescue-poseidon/src/common/sbox.rs b/crates/rescue-poseidon/src/common/sbox.rs index 11e8d27..28a0c5f 100644 --- a/crates/rescue-poseidon/src/common/sbox.rs +++ b/crates/rescue-poseidon/src/common/sbox.rs @@ -61,22 +61,21 @@ pub(crate) fn sbox_alpha_inv_via_add_chain(chain: &[crate::traits::St #[inline] pub(crate) fn sbox_alpha_inv_via_add_chain(chain: &[crate::traits::Step], state: &mut [E::Fr]) { use rayon::prelude::*; - state.par_iter_mut() - .for_each(|el| { - let mut scratch = smallvec::SmallVec::<[E::Fr; 512]>::new(); - *el = crate::add_chain_pow_smallvec(*el, chain, &mut scratch); - }); + state.par_iter_mut().for_each(|el| { + let mut scratch = smallvec::SmallVec::<[E::Fr; 512]>::new(); + *el = crate::add_chain_pow_smallvec(*el, chain, &mut scratch); + }); } #[cfg(feature = "futures")] -lazy_static::lazy_static!{ +lazy_static::lazy_static! { static ref EXECUTOR: futures::executor::ThreadPool = futures::executor::ThreadPool::builder().pool_size(3).create().expect("Failed to build pool"); } #[cfg(feature = "futures")] #[inline] pub(crate) fn sbox_alpha_inv_via_add_chain(chain: &[crate::traits::Step], state: &mut [E::Fr]) { - let chain = unsafe {std::mem::transmute(chain)}; + let chain = unsafe { std::mem::transmute(chain) }; use futures::task::SpawnExt; let f0 = EXECUTOR.spawn_with_handle(sbox_alpha_inv_via_add_chain_fut::(state[0], chain)).unwrap(); let f1 = EXECUTOR.spawn_with_handle(sbox_alpha_inv_via_add_chain_fut::(state[1], chain)).unwrap(); @@ -91,4 +90,4 @@ pub(crate) fn sbox_alpha_inv_via_add_chain(chain: &[crate::traits::St pub(crate) async fn sbox_alpha_inv_via_add_chain_fut(el: E::Fr, chain: &'static [crate::traits::Step]) -> E::Fr { let mut scratch = smallvec::SmallVec::<[E::Fr; 512]>::new(); crate::add_chain_pow_smallvec(el, chain, &mut scratch) -} \ No newline at end of file +} diff --git a/crates/rescue-poseidon/src/common/utils.rs b/crates/rescue-poseidon/src/common/utils.rs index c8086fa..6d2f3f3 100644 --- a/crates/rescue-poseidon/src/common/utils.rs +++ b/crates/rescue-poseidon/src/common/utils.rs @@ -62,9 +62,7 @@ pub(crate) fn scalar_product(a: &[E::Fr], b: &[E::Fr]) -> E::Fr { } // Construct MDS matrix which required by lineary layer of permutation function. -pub(crate) fn construct_mds_matrix( - rng: &mut R, -) -> [[E::Fr; S]; S] { +pub(crate) fn construct_mds_matrix(rng: &mut R) -> [[E::Fr; S]; S] { let width = S; loop { @@ -180,7 +178,6 @@ pub(crate) fn compute_gcd_biguint(n: u64) -> Option { assert!(gcd.is_one()); if y < BigInt::zero() { y += p_minus_one_signed; - } y.to_biguint() @@ -212,4 +209,3 @@ pub(crate) fn biguint_to_u64_vec(mut v: BigUint) -> Vec { assert!(v.is_zero()); ret } - diff --git a/crates/rescue-poseidon/src/lib.rs b/crates/rescue-poseidon/src/lib.rs index 34b4bf9..820afc0 100644 --- a/crates/rescue-poseidon/src/lib.rs +++ b/crates/rescue-poseidon/src/lib.rs @@ -3,36 +3,36 @@ pub mod circuit; #[allow(dead_code)] mod common; -mod sponge; pub mod poseidon; pub mod poseidon2; pub mod rescue; pub mod rescue_prime; +mod sponge; #[cfg(test)] mod tests; mod traits; use std::convert::TryInto; -pub use circuit::sponge::{ - circuit_generic_hash, circuit_generic_round_function, CircuitGenericSponge, circuit_generic_round_function_conditional -}; -use serde::{ser::{SerializeTuple}, Serialize}; -use smallvec::SmallVec; -pub use traits::{HashParams, CustomGate, HashFamily}; -pub use sponge::{generic_hash, generic_round_function, GenericSponge}; +pub use circuit::sponge::{circuit_generic_hash, circuit_generic_round_function, circuit_generic_round_function_conditional, CircuitGenericSponge}; +pub use common::domain_strategy::DomainStrategy; pub use poseidon::{params::PoseidonParams, poseidon_hash}; pub use rescue::{params::RescueParams, rescue_hash}; pub use rescue_prime::{params::RescuePrimeParams, rescue_prime_hash}; -pub use common::domain_strategy::DomainStrategy; +use serde::{ser::SerializeTuple, Serialize}; +use smallvec::SmallVec; +pub use sponge::{generic_hash, generic_round_function, GenericSponge}; +pub use traits::{CustomGate, HashFamily, HashParams}; pub extern crate franklin_crypto; pub trait BigArraySerde<'de>: Sized { fn serialize(&self, serializer: S) -> Result - where S: serde::Serializer; + where + S: serde::Serializer; fn deserialize(deserializer: D) -> Result - where D: serde::Deserializer<'de>; + where + D: serde::Deserializer<'de>; } // some wrappers that make array wrappers serializable themselves (resursively) @@ -41,26 +41,29 @@ pub struct BigArrayRefWrapper<'de, B: BigArraySerde<'de>>(&'de B); impl<'de, B: BigArraySerde<'de>> serde::Serialize for BigArrayRefWrapper<'de, B> { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer { + where + S: serde::Serializer, + { self.0.serialize(serializer) } } -pub struct BigArrayWrapper<'de, B: BigArraySerde<'de>>(B, std::marker::PhantomData<& 'de ()>); +pub struct BigArrayWrapper<'de, B: BigArraySerde<'de>>(B, std::marker::PhantomData<&'de ()>); impl<'de, B: BigArraySerde<'de>> serde::Serialize for BigArrayWrapper<'de, B> { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer { + where + S: serde::Serializer, + { self.0.serialize(serializer) } } impl<'de, B: BigArraySerde<'de>> serde::Deserialize<'de> for BigArrayWrapper<'de, B> { -fn deserialize(deserializer: D) -> Result + fn deserialize(deserializer: D) -> Result where - D: serde::Deserializer<'de> { + D: serde::Deserializer<'de>, + { let new = B::deserialize(deserializer)?; Ok(Self(new, std::marker::PhantomData)) @@ -72,7 +75,8 @@ struct ArrayVisitor { } impl<'de, T, const M: usize> serde::de::Visitor<'de> for ArrayVisitor - where T: serde::Deserialize<'de> +where + T: serde::Deserialize<'de>, { type Value = [T; M]; @@ -81,12 +85,12 @@ impl<'de, T, const M: usize> serde::de::Visitor<'de> for ArrayVisitor } fn visit_seq(self, mut seq: A) -> Result<[T; M], A::Error> - where A: serde::de::SeqAccess<'de> + where + A: serde::de::SeqAccess<'de>, { let mut arr = Vec::with_capacity(M); for i in 0..M { - let el = seq.next_element()? - .ok_or_else(|| serde::de::Error::invalid_length(i, &self))?; + let el = seq.next_element()?.ok_or_else(|| serde::de::Error::invalid_length(i, &self))?; arr.push(el); } let arr: [T; M] = arr.try_into().map_err(|_| serde::de::Error::invalid_length(M, &self))?; @@ -96,10 +100,12 @@ impl<'de, T, const M: usize> serde::de::Visitor<'de> for ArrayVisitor } impl<'de, T, const N: usize> BigArraySerde<'de> for [T; N] - where T: serde::Serialize + serde::Deserialize<'de> +where + T: serde::Serialize + serde::Deserialize<'de>, { fn serialize(&self, serializer: S) -> Result - where S: serde::Serializer + where + S: serde::Serializer, { let mut seq = serializer.serialize_tuple(N)?; for elem in &self[..] { @@ -109,7 +115,8 @@ impl<'de, T, const N: usize> BigArraySerde<'de> for [T; N] } fn deserialize(deserializer: D) -> Result<[T; N], D::Error> - where D: serde::Deserializer<'de> + where + D: serde::Deserializer<'de>, { let visitor = ArrayVisitor::<_, N> { element: std::marker::PhantomData }; deserializer.deserialize_tuple(N, visitor) @@ -174,12 +181,18 @@ impl<'de, T, const N: usize> BigArraySerde<'de> for [T; N] // } // } -fn serialize_vec_of_arrays(t: &Vec<[T; N]>, serializer: S) -> Result where S: serde::Serializer { +fn serialize_vec_of_arrays(t: &Vec<[T; N]>, serializer: S) -> Result +where + S: serde::Serializer, +{ let cast: Vec<_> = t.iter().map(|el| BigArrayRefWrapper(el)).collect(); cast.serialize(serializer) } -fn deserialize_vec_of_arrays<'de, D, T: serde::Serialize + serde::de::DeserializeOwned, const N: usize>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de> { +fn deserialize_vec_of_arrays<'de, D, T: serde::Serialize + serde::de::DeserializeOwned, const N: usize>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ use serde::Deserialize; let result: Vec> = >>::deserialize(deserializer)?; @@ -188,7 +201,10 @@ fn deserialize_vec_of_arrays<'de, D, T: serde::Serialize + serde::de::Deserializ Ok(result) } -fn serialize_vec_of_arrays_of_arrays(t: &Vec<[[T; N]; M]>, serializer: S) -> Result where S: serde::Serializer { +fn serialize_vec_of_arrays_of_arrays(t: &Vec<[[T; N]; M]>, serializer: S) -> Result +where + S: serde::Serializer, +{ let mut flattened = Vec::with_capacity(t.len() * M); for row in t.iter() { for el in row.iter() { @@ -200,7 +216,10 @@ fn serialize_vec_of_arrays_of_arrays(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de> { +fn deserialize_vec_of_arrays_of_arrays<'de, D, T: serde::Serialize + serde::de::DeserializeOwned, const N: usize, const M: usize>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ use serde::Deserialize; let flat_result: Vec> = >>::deserialize(deserializer)?; @@ -212,7 +231,7 @@ fn deserialize_vec_of_arrays_of_arrays<'de, D, T: serde::Serialize + serde::de:: for _ in 0..num_elements { let subarray: [[T; N]; M] = match flat_result.drain(..M).collect::>().try_into() { Ok(a) => a, - Err(..) => panic!("length must patch") + Err(..) => panic!("length must patch"), }; result.push(subarray); } @@ -220,7 +239,10 @@ fn deserialize_vec_of_arrays_of_arrays<'de, D, T: serde::Serialize + serde::de:: Ok(result) } -fn serialize_array_of_arrays(t: &[[T; N]; M], serializer: S) -> Result where S: serde::Serializer { +fn serialize_array_of_arrays(t: &[[T; N]; M], serializer: S) -> Result +where + S: serde::Serializer, +{ let mut seq = serializer.serialize_tuple(M)?; for el in t.iter() { let w = BigArrayRefWrapper(el); @@ -230,7 +252,10 @@ fn serialize_array_of_arrays(deserializer: D) -> Result<[[T; N]; M], D::Error> where D: serde::Deserializer<'de> { +fn deserialize_array_of_arrays<'de, D, T: serde::Serialize + serde::de::DeserializeOwned, const N: usize, const M: usize>(deserializer: D) -> Result<[[T; N]; M], D::Error> +where + D: serde::Deserializer<'de>, +{ let visitor = ArrayVisitor::, M> { element: std::marker::PhantomData }; let result = deserializer.deserialize_tuple(M, visitor)?; @@ -239,11 +264,7 @@ fn deserialize_array_of_arrays<'de, D, T: serde::Serialize + serde::de::Deserial Ok(subarray) } -fn add_chain_pow_smallvec( - base: F, - add_chain: &[crate::traits::Step], - scratch_space: &mut SmallVec<[F; 512]>, -) -> F { +fn add_chain_pow_smallvec(base: F, add_chain: &[crate::traits::Step], scratch_space: &mut SmallVec<[F; 512]>) -> F { scratch_space.push(base); for (_idx, el) in add_chain.iter().enumerate() { @@ -253,7 +274,7 @@ fn add_chain_pow_smallvec( el.square(); scratch_space.push(el); - }, + } crate::traits::Step::Add { left, right } => { let mut el = scratch_space[*left]; el.mul_assign(&scratch_space[*right]); @@ -268,4 +289,4 @@ fn add_chain_pow_smallvec( scratch_space.clear(); result -} \ No newline at end of file +} diff --git a/crates/rescue-poseidon/src/poseidon/params.rs b/crates/rescue-poseidon/src/poseidon/params.rs index 154470e..b40d658 100644 --- a/crates/rescue-poseidon/src/poseidon/params.rs +++ b/crates/rescue-poseidon/src/poseidon/params.rs @@ -26,9 +26,7 @@ pub struct PoseidonParams { pub(crate) custom_gate: CustomGate, } -impl PartialEq - for PoseidonParams -{ +impl PartialEq for PoseidonParams { fn eq(&self, other: &Self) -> bool { self.hash_family() == other.hash_family() } @@ -36,12 +34,7 @@ impl PartialEq impl Default for PoseidonParams { fn default() -> Self { - let (params, - alpha, - optimized_round_constants, - (optimized_mds_matrixes_0, optimized_mds_matrixes_1) - ) = - super::params::poseidon_light_params::(); + let (params, alpha, optimized_round_constants, (optimized_mds_matrixes_0, optimized_mds_matrixes_1)) = super::params::poseidon_light_params::(); Self { state: [E::Fr::zero(); WIDTH], mds_matrix: params.mds_matrix, @@ -56,9 +49,7 @@ impl Default for PoseidonParam } } -impl HashParams - for PoseidonParams -{ +impl HashParams for PoseidonParams { fn hash_family(&self) -> HashFamily { HashFamily::Poseidon } @@ -92,10 +83,7 @@ impl HashParams (&[[E::Fr; WIDTH]; WIDTH], &[[[E::Fr; WIDTH]; WIDTH]]) { - ( - &self.optimized_mds_matrixes_0, - &self.optimized_mds_matrixes_1, - ) + (&self.optimized_mds_matrixes_0, &self.optimized_mds_matrixes_1) } fn custom_gate(&self) -> CustomGate { @@ -107,8 +95,7 @@ impl HashParams( -) -> (InnerHashParameters, u64) { +pub fn poseidon_params() -> (InnerHashParameters, u64) { let security_level = 80; let full_rounds = 8; // let partial_rounds = 83; @@ -126,28 +113,15 @@ pub fn poseidon_params( (params, alpha) } -pub(crate) fn poseidon_light_params() -> ( - InnerHashParameters, - u64, - Vec<[E::Fr; WIDTH]>, - ([[E::Fr; WIDTH]; WIDTH], Vec<[[E::Fr; WIDTH]; WIDTH]>), -) { +pub(crate) fn poseidon_light_params( +) -> (InnerHashParameters, u64, Vec<[E::Fr; WIDTH]>, ([[E::Fr; WIDTH]; WIDTH], Vec<[[E::Fr; WIDTH]; WIDTH]>)) { let (params, alpha) = poseidon_params(); - let optimized_constants = compute_optimized_round_constants::( - params.round_constants(), - ¶ms.mds_matrix, - params.partial_rounds, - params.full_rounds, - ); + let optimized_constants = compute_optimized_round_constants::(params.round_constants(), ¶ms.mds_matrix, params.partial_rounds, params.full_rounds); const SUBDIM: usize = 2; // TODO: - assert!( - WIDTH - SUBDIM == 1, - "only dim 2 and dim 3 matrixes are allowed for now." - ); - let optimized_matrixes = - compute_optimized_matrixes::(params.partial_rounds, ¶ms.mds_matrix); + assert!(WIDTH - SUBDIM == 1, "only dim 2 and dim 3 matrixes are allowed for now."); + let optimized_matrixes = compute_optimized_matrixes::(params.partial_rounds, ¶ms.mds_matrix); (params, alpha, optimized_constants, optimized_matrixes) } @@ -186,26 +160,19 @@ pub(crate) fn compute_optimized_round_constants( // vector addition acc = [E::Fr::zero(); WIDTH]; - constants[round] - .iter() - .enumerate() - .zip(first.iter()) - .for_each(|((idx, a), b)| { - let mut tmp = a.clone(); - tmp.add_assign(&b); - acc[idx] = tmp; - }); + constants[round].iter().enumerate().zip(first.iter()).for_each(|((idx, a), b)| { + let mut tmp = a.clone(); + tmp.add_assign(&b); + acc[idx] = tmp; + }); } optimized_constants.push(acc); optimized_constants.reverse(); let mut final_constants = constants.to_vec(); - final_constants[start..end + 1] - .iter_mut() - .zip(optimized_constants) - .for_each(|(a, b)| { - *a = b; - }); + final_constants[start..end + 1].iter_mut().zip(optimized_constants).for_each(|(a, b)| { + *a = b; + }); final_constants } diff --git a/crates/rescue-poseidon/src/poseidon/poseidon.rs b/crates/rescue-poseidon/src/poseidon/poseidon.rs index d1ba465..dc7545a 100644 --- a/crates/rescue-poseidon/src/poseidon/poseidon.rs +++ b/crates/rescue-poseidon/src/poseidon/poseidon.rs @@ -1,8 +1,8 @@ +use super::params::PoseidonParams; use crate::common::{matrix::mmul_assign, sbox::sbox}; -use crate::sponge::{generic_hash}; +use crate::sponge::generic_hash; use crate::traits::{HashFamily, HashParams}; use franklin_crypto::bellman::{Engine, Field}; -use super::params::PoseidonParams; /// Receives inputs whose length `known` prior(fixed-length). /// Also uses custom domain strategy which basically sets value of capacity element to @@ -16,15 +16,7 @@ pub fn poseidon_hash(input: &[E::Fr; L]) -> [E::Fr; 2 generic_hash(¶ms, input, None) } -pub(crate) fn poseidon_round_function< - E: Engine, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( - params: &P, - state: &mut [E::Fr; WIDTH] -) { +pub(crate) fn poseidon_round_function, const RATE: usize, const WIDTH: usize>(params: &P, state: &mut [E::Fr; WIDTH]) { assert_eq!(params.hash_family(), HashFamily::Poseidon, "Incorrect hash family!"); debug_assert!(params.number_of_full_rounds() & 1 == 0); let half_of_full_rounds = params.number_of_full_rounds() / 2; @@ -50,15 +42,11 @@ pub(crate) fn poseidon_round_function< // - first, use M' instead of sbox and matrix multiplication for other elements of state(not first element) // - second, instead of multiplication by original MDS matrix, multiply by M"(M" is a sparse matrix form) - state - .iter_mut() - .zip(optimized_round_constants[half_of_full_rounds].iter()) - .for_each(|(s, c)| s.add_assign(c)); + state.iter_mut().zip(optimized_round_constants[half_of_full_rounds].iter()).for_each(|(s, c)| s.add_assign(c)); mmul_assign::(&sparse_matrixes.0, state); // this is an unrolled version of partial rounds - for (round_constants, sparse_matrix) in optimized_round_constants - [half_of_full_rounds + 1..half_of_full_rounds + params.number_of_partial_rounds()] + for (round_constants, sparse_matrix) in optimized_round_constants[half_of_full_rounds + 1..half_of_full_rounds + params.number_of_partial_rounds()] .iter() .chain(&[[E::Fr::zero(); WIDTH]]) .zip(sparse_matrixes.1.iter()) @@ -91,9 +79,7 @@ pub(crate) fn poseidon_round_function< } // full rounds - for round in (params.number_of_partial_rounds() + half_of_full_rounds) - ..(params.number_of_partial_rounds() + params.number_of_full_rounds()) - { + for round in (params.number_of_partial_rounds() + half_of_full_rounds)..(params.number_of_partial_rounds() + params.number_of_full_rounds()) { // add round constants for (s, c) in state.iter_mut().zip(&optimized_round_constants[round]) { s.add_assign(c); diff --git a/crates/rescue-poseidon/src/poseidon2/mod.rs b/crates/rescue-poseidon/src/poseidon2/mod.rs index 38c0044..d5ba373 100644 --- a/crates/rescue-poseidon/src/poseidon2/mod.rs +++ b/crates/rescue-poseidon/src/poseidon2/mod.rs @@ -1,11 +1,11 @@ pub mod params; pub mod poseidon2; -pub mod sponge; -pub mod transcript; pub mod pow_runner; +pub mod sponge; #[cfg(test)] mod tests; +pub mod transcript; -pub use self::sponge::*; pub use self::params::Poseidon2Params; pub use self::poseidon2::*; +pub use self::sponge::*; diff --git a/crates/rescue-poseidon/src/poseidon2/params.rs b/crates/rescue-poseidon/src/poseidon2/params.rs index 7d728a8..a80f667 100644 --- a/crates/rescue-poseidon/src/poseidon2/params.rs +++ b/crates/rescue-poseidon/src/poseidon2/params.rs @@ -20,9 +20,7 @@ pub struct Poseidon2Params { pub(crate) custom_gate: CustomGate, } -impl PartialEq - for Poseidon2Params -{ +impl PartialEq for Poseidon2Params { fn eq(&self, other: &Self) -> bool { self.hash_family() == other.hash_family() } @@ -69,9 +67,7 @@ impl Default for Poseidon2Para } } -impl HashParams - for Poseidon2Params -{ +impl HashParams for Poseidon2Params { fn hash_family(&self) -> HashFamily { HashFamily::Poseidon2 } @@ -133,7 +129,7 @@ fn poseidon2_external_matrix() -> [[E::Fr; WIDTH] result[0][1] = one; result[1][0] = one; result[1][1] = two; - }, + } 3 => { // circ(2, 1, 1) result[0][0] = two; @@ -145,7 +141,7 @@ fn poseidon2_external_matrix() -> [[E::Fr; WIDTH] result[2][0] = one; result[2][1] = one; result[2][2] = two; - }, + } _ => { assert!(WIDTH > 0 && WIDTH % 4 == 0); @@ -159,18 +155,13 @@ fn poseidon2_external_matrix() -> [[E::Fr; WIDTH] let six = E::Fr::from_str("6").unwrap(); let seven = E::Fr::from_str("7").unwrap(); - let m_4_mds_matrix = [ - [five, seven, one, three], - [four, six, one, one], - [one, three, five, seven], - [one, one, four, six], - ]; + let m_4_mds_matrix = [[five, seven, one, three], [four, six, one, one], [one, three, five, seven], [one, one, four, six]]; // circ(2*M4, M4, ..., M4) for i in 0..WIDTH { for j in 0..WIDTH { result[i][j] = m_4_mds_matrix[i % 4][j % 4]; - if i/4 == j/4 { + if i / 4 == j / 4 { result[i][j].mul_assign(&two); } } @@ -191,7 +182,7 @@ fn poseidon2_internal_matrix() -> [E::Fr; WIDTH] result[0] = two; result[1] = two; result[2] = three; - }, + } _ => todo!("poseidon_2_internal_matrix for WIDTH == {}", WIDTH), }; diff --git a/crates/rescue-poseidon/src/poseidon2/poseidon2.rs b/crates/rescue-poseidon/src/poseidon2/poseidon2.rs index 2c7ed6b..7aa9ea5 100644 --- a/crates/rescue-poseidon/src/poseidon2/poseidon2.rs +++ b/crates/rescue-poseidon/src/poseidon2/poseidon2.rs @@ -1,17 +1,14 @@ -use crate::traits::HashParams; -use franklin_crypto::bellman::{Engine, Field, PrimeField}; -use crate::common::domain_strategy::DomainStrategy; use super::params::Poseidon2Params; +use crate::common::domain_strategy::DomainStrategy; +use crate::traits::HashParams; use crate::traits::Sbox; +use franklin_crypto::bellman::{Engine, Field, PrimeField}; /// Receives inputs whose length `known` prior(fixed-length). /// Also uses custom domain strategy which basically sets value of capacity element to /// length of input and applies a padding rule which makes input size equals to multiple of /// rate parameter. -pub fn poseidon2_hash< - E: Engine, - const L: usize ->(input: &[E::Fr; L]) -> [E::Fr; 2] { +pub fn poseidon2_hash(input: &[E::Fr; L]) -> [E::Fr; 2] { const WIDTH: usize = 3; const RATE: usize = 2; @@ -19,14 +16,7 @@ pub fn poseidon2_hash< crate::generic_hash(¶ms, input, None) } -pub(crate) fn poseidon2_round_function< - E: Engine, - const RATE: usize, - const WIDTH: usize, ->( - state: &mut [E::Fr; WIDTH], - params: &Poseidon2Params, -) { +pub(crate) fn poseidon2_round_function(state: &mut [E::Fr; WIDTH], params: &Poseidon2Params) { debug_assert!(params.full_rounds & 1 == 0); let half_of_full_rounds = params.number_of_full_rounds() / 2; @@ -44,20 +34,15 @@ pub(crate) fn poseidon2_round_function< apply_sbox::(&mut state[..1], ¶ms.alpha); poseidon2_matmul_internal::(state, ¶ms.diag_internal_matrix); } - - for r in (half_of_full_rounds + params.partial_rounds)..(2*half_of_full_rounds + params.partial_rounds) { + + for r in (half_of_full_rounds + params.partial_rounds)..(2 * half_of_full_rounds + params.partial_rounds) { add_rc::(state, ¶ms.round_constants[r]); apply_sbox::(state, ¶ms.alpha); poseidon2_matmul_external::(state); } } -pub(crate) fn poseidon2_matmul_external< - E: Engine, - const WIDTH: usize, ->( - state: &mut [E::Fr; WIDTH] -) { +pub(crate) fn poseidon2_matmul_external(state: &mut [E::Fr; WIDTH]) { match WIDTH { 2 => { // Matrix circ(2, 1) @@ -102,12 +87,7 @@ pub(crate) fn poseidon2_matmul_external< } } -fn matmul_m4< - E: Engine, - const WIDTH: usize, ->( - state: &mut [E::Fr; WIDTH] -) { +fn matmul_m4(state: &mut [E::Fr; WIDTH]) { // Mul each 4-element chunk by // [5, 7, 1, 3] // [4, 6, 1, 1] @@ -146,14 +126,7 @@ fn matmul_m4< } } - -pub(crate) fn poseidon2_matmul_internal< - E: Engine, - const WIDTH: usize, ->( - state: &mut [E::Fr; WIDTH], - diag_internal_matrix: &[E::Fr; WIDTH] -) { +pub(crate) fn poseidon2_matmul_internal(state: &mut [E::Fr; WIDTH], diag_internal_matrix: &[E::Fr; WIDTH]) { match WIDTH { 2 => { // [2, 1] @@ -186,11 +159,7 @@ pub(crate) fn poseidon2_matmul_internal< 4 | 8 | 12 | 16 | 20 | 24 => { // Compute state sum let mut sum = state[0]; - state - .iter() - .skip(1) - .take(WIDTH-1) - .for_each(|el| sum.add_assign(el)); + state.iter().skip(1).take(WIDTH - 1).for_each(|el| sum.add_assign(el)); // Add sum + (diag entry - 1) * element to each element for i in 0..WIDTH { let mut coeff = diag_internal_matrix[i]; @@ -205,12 +174,7 @@ pub(crate) fn poseidon2_matmul_internal< } } -pub(crate) fn apply_sbox< - E: Engine, ->( - elements: &mut [E::Fr], - sbox: &Sbox -) { +pub(crate) fn apply_sbox(elements: &mut [E::Fr], sbox: &Sbox) { debug_assert!(sbox == &Sbox::Alpha(5)); for element in elements.iter_mut() { @@ -222,13 +186,7 @@ pub(crate) fn apply_sbox< } } -pub(crate) fn add_rc< - E: Engine, - const WIDTH: usize, ->( - elements: &mut [E::Fr; WIDTH], - constants: &[E::Fr; WIDTH] -) { +pub(crate) fn add_rc(elements: &mut [E::Fr; WIDTH], constants: &[E::Fr; WIDTH]) { for (element, constant) in elements.iter_mut().zip(constants.iter()) { element.add_assign(constant); } diff --git a/crates/rescue-poseidon/src/poseidon2/pow_runner.rs b/crates/rescue-poseidon/src/poseidon2/pow_runner.rs index 2629156..7944064 100644 --- a/crates/rescue-poseidon/src/poseidon2/pow_runner.rs +++ b/crates/rescue-poseidon/src/poseidon2/pow_runner.rs @@ -1,23 +1,16 @@ use super::*; -use franklin_crypto::boojum::{worker::Worker, pairing::bls12_381::Fr}; use franklin_crypto::boojum::algebraic_props::round_function::AbsorptionModeTrait; -use franklin_crypto::boojum::field::SmallField; use franklin_crypto::boojum::cs::implementations::pow::PoWRunner; +use franklin_crypto::boojum::field::SmallField; +use franklin_crypto::boojum::{pairing::bls12_381::Fr, worker::Worker}; use franklin_crypto::bellman::{Engine, Field, PrimeField, PrimeFieldRepr}; - const BN256_POSEIDON2_NO_RESULT: u64 = u64::MAX; const BN256_POSEIDON2_ROUNDS_PER_INVOCAITON: usize = 1 << 16u32; -impl< - E: Engine, - F: SmallField, - M: AbsorptionModeTrait, - const RATE: usize, - const WIDTH: usize, -> PoWRunner for Poseidon2Sponge { +impl, const RATE: usize, const WIDTH: usize> PoWRunner for Poseidon2Sponge { fn run_from_bytes(_seed: Vec, _pow_bits: u32, _worker: &Worker) -> u64 { unimplemented!() } @@ -34,9 +27,7 @@ impl< // We expect that F == FF == Goldilocks if F::CHAR >= FF::CHAR { for el in seed.iter() { - base_transcript.absorb_single_small_field( - &F::from_u64(el.as_u64_reduced()).expect("Should be in range") - ); + base_transcript.absorb_single_small_field(&F::from_u64(el.as_u64_reduced()).expect("Should be in range")); } } else { unimplemented!() @@ -77,9 +68,7 @@ impl< let base_transcript = base_transcript.clone(); let result = std::sync::Arc::clone(&result); scope.spawn(move |_| { - for i in - 0..((BN256_POSEIDON2_NO_RESULT - 1) / num_workers / pow_rounds_per_invocation) - { + for i in 0..((BN256_POSEIDON2_NO_RESULT - 1) / num_workers / pow_rounds_per_invocation) { let base = (worker_idx + i * num_workers) * pow_rounds_per_invocation; let current_flag = result.load(Ordering::Relaxed); if current_flag == BN256_POSEIDON2_NO_RESULT { @@ -96,12 +85,7 @@ impl< new_transcript.absorb_single_small_field(&high); if new_transcript.finalize()[0].into_repr().as_ref()[0].trailing_zeros() >= pow_bits { - let _ = result.compare_exchange( - BN256_POSEIDON2_NO_RESULT, - challenge_u64, - Ordering::Acquire, - Ordering::Relaxed, - ); + let _ = result.compare_exchange(BN256_POSEIDON2_NO_RESULT, challenge_u64, Ordering::Acquire, Ordering::Relaxed); break; } @@ -120,21 +104,15 @@ impl< challenge_u64 } - - fn verify_from_field_elements( - seed: Vec, - pow_bits: u32, - challenge: u64, - ) -> bool { + + fn verify_from_field_elements(seed: Vec, pow_bits: u32, challenge: u64) -> bool { assert!(pow_bits <= 32); let mut base_transcript = Self::new(); // We expect that F == FF == Goldilocks if F::CHAR >= FF::CHAR { for el in seed.iter() { - base_transcript.absorb_single_small_field( - &F::from_u64(el.as_u64_reduced()).expect("Should be in range") - ); + base_transcript.absorb_single_small_field(&F::from_u64(el.as_u64_reduced()).expect("Should be in range")); } } else { unimplemented!() @@ -146,7 +124,7 @@ impl< base_transcript.absorb_single_small_field(&low); base_transcript.absorb_single_small_field(&high); - + base_transcript.finalize()[0].into_repr().as_ref()[0].trailing_zeros() >= pow_bits } } diff --git a/crates/rescue-poseidon/src/poseidon2/sponge.rs b/crates/rescue-poseidon/src/poseidon2/sponge.rs index a1c8a25..8856c4e 100644 --- a/crates/rescue-poseidon/src/poseidon2/sponge.rs +++ b/crates/rescue-poseidon/src/poseidon2/sponge.rs @@ -1,27 +1,21 @@ use super::*; use derivative::*; -use franklin_crypto::boojum::field::SmallField; -use franklin_crypto::boojum::cs::oracle::TreeHasher; use franklin_crypto::bellman::{Engine, Field, PrimeField, PrimeFieldRepr}; use franklin_crypto::boojum::algebraic_props::round_function::AbsorptionModeTrait; +use franklin_crypto::boojum::cs::oracle::TreeHasher; +use franklin_crypto::boojum::field::SmallField; -use typemap_rev::{TypeMap, TypeMapKey}; use std::sync::{Arc, RwLock}; +use typemap_rev::{TypeMap, TypeMapKey}; -impl TypeMapKey for Poseidon2Params:: { - type Value = Arc>; +impl TypeMapKey for Poseidon2Params { + type Value = Arc>; } #[derive(Derivative)] #[derivative(Clone, Debug)] -pub struct Poseidon2Sponge< - E: Engine, - F: SmallField, - M: AbsorptionModeTrait, - const RATE: usize, - const WIDTH: usize ->{ +pub struct Poseidon2Sponge, const RATE: usize, const WIDTH: usize> { pub(crate) state: [E::Fr; WIDTH], pub(crate) buffer: [E::Fr; RATE], pub(crate) filled: usize, @@ -30,17 +24,11 @@ pub struct Poseidon2Sponge< _marker: std::marker::PhantomData<(F, M)>, } -impl< - E: Engine, - F: SmallField, - M: AbsorptionModeTrait, - const RATE: usize, - const WIDTH: usize, -> Poseidon2Sponge { +impl, const RATE: usize, const WIDTH: usize> Poseidon2Sponge { pub fn new() -> Self { assert!(Self::capasity_per_element() > 0); - lazy_static::lazy_static!{ + lazy_static::lazy_static! { static ref POSEIDON_PARAMS: RwLock = RwLock::new(TypeMap::new()); }; @@ -83,9 +71,7 @@ impl< } pub fn absorb_buffer_to_state(&mut self) { - for (dst, src) in self.state.iter_mut() - .zip(self.buffer.iter_mut()) - { + for (dst, src) in self.state.iter_mut().zip(self.buffer.iter_mut()) { M::absorb(dst, src); *src = E::Fr::zero(); } @@ -121,7 +107,7 @@ impl< 0 => { self.filled += capasity_per_element; self.buffer[pos] = *value; - }, + } _ => { self.filled = (pos + 1) * capasity_per_element; @@ -154,7 +140,7 @@ impl< } if len + pos < RATE { - self.buffer[pos..pos+len].copy_from_slice(values); + self.buffer[pos..pos + len].copy_from_slice(values); self.filled += len * capasity_per_element; @@ -216,13 +202,7 @@ impl< } } -impl< - E: Engine, - F: SmallField, - M: AbsorptionModeTrait, - const RATE: usize, - const WIDTH: usize, -> TreeHasher for Poseidon2Sponge { +impl, const RATE: usize, const WIDTH: usize> TreeHasher for Poseidon2Sponge { type Output = E::Fr; #[inline] @@ -248,7 +228,7 @@ impl< #[inline] fn hash_into_leaf<'a, S: IntoIterator>(source: S) -> Self::Output where - F: 'a + F: 'a, { let mut hasher = Self::new(); @@ -270,7 +250,7 @@ impl< #[inline] fn hash_into_node(left: &Self::Output, right: &Self::Output, _depth: usize) -> Self::Output { - lazy_static::lazy_static!{ + lazy_static::lazy_static! { static ref POSEIDON_PARAMS: RwLock = RwLock::new(TypeMap::new()); }; diff --git a/crates/rescue-poseidon/src/poseidon2/tests.rs b/crates/rescue-poseidon/src/poseidon2/tests.rs index d27613e..43d9c61 100644 --- a/crates/rescue-poseidon/src/poseidon2/tests.rs +++ b/crates/rescue-poseidon/src/poseidon2/tests.rs @@ -1,18 +1,18 @@ -use franklin_crypto::boojum::cs::implementations::pow::PoWRunner; -use franklin_crypto::boojum::field::goldilocks::GoldilocksField; +use crate::tests::init_cs; use franklin_crypto::bellman::pairing::bn256::{Bn256, Fr}; -use franklin_crypto::plonk::circuit::{allocated_num::Num, linear_combination::LinearCombination}; use franklin_crypto::boojum::algebraic_props::round_function::AbsorptionModeTrait; +use franklin_crypto::boojum::cs::implementations::pow::PoWRunner; +use franklin_crypto::boojum::field::goldilocks::GoldilocksField; use franklin_crypto::boojum::field::SmallField; use franklin_crypto::boojum::field::U64Representable; use franklin_crypto::boojum::worker::Worker; +use franklin_crypto::plonk::circuit::{allocated_num::Num, linear_combination::LinearCombination}; use rand::Rand; use rand::Rng; -use crate::tests::init_cs; +use crate::circuit::poseidon2::{circuit_poseidon2_hash, circuit_poseidon2_round_function}; use crate::poseidon::{poseidon_hash, poseidon_round_function}; use crate::poseidon2::{poseidon2_hash, poseidon2_round_function}; -use crate::circuit::poseidon2::{circuit_poseidon2_round_function, circuit_poseidon2_hash}; use super::Poseidon2Sponge; @@ -95,9 +95,7 @@ fn test_of_sponge_state() { let buffer1: Vec<_> = (0..num_elements).map(|_| Fr::rand(&mut rng)).collect(); let mut rng = rand::thread_rng(); - let buffer2: Vec<_> = (0..num_elements).map(|_| - GoldilocksField::from_u64_unchecked(rng.gen_range(0, GoldilocksField::CHAR)) - ).collect(); + let buffer2: Vec<_> = (0..num_elements).map(|_| GoldilocksField::from_u64_unchecked(rng.gen_range(0, GoldilocksField::CHAR))).collect(); dbg!(&buffer1, &buffer2); @@ -170,11 +168,7 @@ fn test_pow_runner() { let mut rng = rand::thread_rng(); let buffer: Vec<_> = (0..4).map(|_| GoldilocksField::from_u64_unchecked(rng.gen_range(0, GoldilocksField::CHAR))).collect(); - let challenge = Poseidon2Sponge::::run_from_field_elements( - buffer, - 10, - &worker - ); + let challenge = Poseidon2Sponge::::run_from_field_elements(buffer, 10, &worker); dbg!(challenge); } diff --git a/crates/rescue-poseidon/src/poseidon2/transcript.rs b/crates/rescue-poseidon/src/poseidon2/transcript.rs index e5ffbc7..3a99476 100644 --- a/crates/rescue-poseidon/src/poseidon2/transcript.rs +++ b/crates/rescue-poseidon/src/poseidon2/transcript.rs @@ -2,23 +2,17 @@ use super::*; use derivative::*; -use franklin_crypto::boojum::field::SmallField; -use franklin_crypto::boojum::cs::traits::GoodAllocator; use franklin_crypto::boojum::algebraic_props::round_function::AbsorptionModeTrait; use franklin_crypto::boojum::cs::implementations::transcript::Transcript; +use franklin_crypto::boojum::cs::traits::GoodAllocator; +use franklin_crypto::boojum::field::SmallField; use std::collections::VecDeque; use franklin_crypto::bellman::{Engine, Field, PrimeField, PrimeFieldRepr}; #[derive(Derivative)] #[derivative(Clone, Debug)] -pub struct Poseidon2Transcript< - E: Engine, - F: SmallField, - M: AbsorptionModeTrait, - const RATE: usize, - const WIDTH: usize -> { +pub struct Poseidon2Transcript, const RATE: usize, const WIDTH: usize> { buffer: Vec, last_filled: usize, available_challenges: VecDeque, @@ -26,13 +20,7 @@ pub struct Poseidon2Transcript< sponge: Poseidon2Sponge, } -impl< - E: Engine, - F: SmallField, - M: AbsorptionModeTrait, - const RATE: usize, - const WIDTH: usize -> Poseidon2Transcript { +impl, const RATE: usize, const WIDTH: usize> Poseidon2Transcript { pub fn new() -> Self { Self { buffer: Vec::new(), @@ -43,13 +31,7 @@ impl< } } -impl< - E: Engine, - F: SmallField, - M: AbsorptionModeTrait, - const RATE: usize, - const WIDTH: usize -> Transcript for Poseidon2Transcript { +impl, const RATE: usize, const WIDTH: usize> Transcript for Poseidon2Transcript { type CompatibleCap = E::Fr; type TransciptParameters = (); @@ -67,10 +49,8 @@ impl< fn witness_field_elements(&mut self, field_els: &[F]) { let capasity_per_element = Poseidon2Sponge::::capasity_per_element(); debug_assert!(self.last_filled < capasity_per_element); - - let add_to_last = field_els.len().min( - (capasity_per_element - self.last_filled) % capasity_per_element - ); + + let add_to_last = field_els.len().min((capasity_per_element - self.last_filled) % capasity_per_element); if add_to_last != 0 { let mut repr_to_add = ::Repr::default(); @@ -115,10 +95,7 @@ impl< self.sponge.run_round_function(); { - let commitment = self - .sponge - .try_get_committment() - .expect("must have no pending elements in the buffer"); + let commitment = self.sponge.try_get_committment().expect("must have no pending elements in the buffer"); for &el in commitment.iter() { self.available_challenges.extend(get_challenges_from_fr::(el)); } @@ -143,16 +120,9 @@ impl< } } -fn get_challenges_from_fr( - scalar_element: E::Fr, -) -> Vec { +fn get_challenges_from_fr(scalar_element: E::Fr) -> Vec { assert!(F::CHAR_BITS <= 64, "Goldilocks has less than 64 bits per element"); let num_challenges = (E::Fr::CAPACITY as usize) / (F::CHAR_BITS as usize); - scalar_element.into_repr() - .as_ref()[..num_challenges] - .iter() - .map(|x| - F::from_u64_with_reduction(*x) - ).collect() + scalar_element.into_repr().as_ref()[..num_challenges].iter().map(|x| F::from_u64_with_reduction(*x)).collect() } diff --git a/crates/rescue-poseidon/src/rescue/params.rs b/crates/rescue-poseidon/src/rescue/params.rs index 2ee08dd..0f6d980 100644 --- a/crates/rescue-poseidon/src/rescue/params.rs +++ b/crates/rescue-poseidon/src/rescue/params.rs @@ -1,10 +1,9 @@ -use franklin_crypto::bellman::{Engine}; +use franklin_crypto::bellman::Engine; use crate::common::params::InnerHashParameters; -use crate::traits::{HashParams, HashFamily, Sbox, CustomGate}; +use crate::traits::{CustomGate, HashFamily, HashParams, Sbox}; use std::convert::TryInto; - #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct RescueParams { pub(crate) allows_specialization: bool, @@ -20,24 +19,19 @@ pub struct RescueParams { pub(crate) custom_gate: CustomGate, } -impl PartialEq for RescueParams{ +impl PartialEq for RescueParams { fn eq(&self, other: &Self) -> bool { self.hash_family() == other.hash_family() } } -impl Default - for RescueParams -{ +impl Default for RescueParams { fn default() -> Self { let (params, alpha, alpha_inv) = compute_params::(); Self { allows_specialization: false, full_rounds: params.full_rounds, - round_constants: params - .round_constants() - .try_into() - .expect("round constants"), + round_constants: params.round_constants().try_into().expect("round constants"), mds_matrix: *params.mds_matrix(), alpha: Sbox::Alpha(alpha), alpha_inv: Sbox::AlphaInverse(alpha_inv, alpha), @@ -46,9 +40,7 @@ impl Default } } -impl HashParams - for RescueParams -{ +impl HashParams for RescueParams { #[inline] fn allows_specialization(&self) -> bool { self.allows_specialization @@ -82,7 +74,7 @@ impl HashParams (&[[E::Fr; WIDTH]; WIDTH], &[[[E::Fr; WIDTH];WIDTH]]) { + fn optimized_mds_matrixes(&self) -> (&[[E::Fr; WIDTH]; WIDTH], &[[[E::Fr; WIDTH]; WIDTH]]) { unimplemented!("Rescue doesn't use optimized matrixes") } @@ -93,9 +85,9 @@ impl HashParams CustomGate { self.custom_gate } - + fn use_custom_gate(&mut self, custom_gate: CustomGate) { - self.custom_gate = custom_gate; + self.custom_gate = custom_gate; } fn specialized_affine_transformation_for_round(&self, state: &mut [E::Fr; WIDTH], round_constants: &[E::Fr; WIDTH]) { @@ -130,14 +122,11 @@ impl HashParams RescueParams { pub fn specialized_for_num_rounds(num_rounds: usize, claimed_security_bits: usize) -> Self { let (params, alpha, _alpha_inv, addition_chain) = mds_optimized_params_alpha_5::(num_rounds, claimed_security_bits); - + Self { allows_specialization: true, full_rounds: params.full_rounds, - round_constants: params - .round_constants() - .try_into() - .expect("round constants"), + round_constants: params.round_constants().try_into().expect("round constants"), mds_matrix: *params.mds_matrix(), alpha: Sbox::Alpha(alpha), alpha_inv: Sbox::AddChain(addition_chain, alpha), @@ -151,16 +140,12 @@ pub(crate) fn compute_params() let full_rounds = 8; let security_level = 126; - let mut params = InnerHashParameters::new( - security_level, - full_rounds, - 0, - ); + let mut params = InnerHashParameters::new(security_level, full_rounds, 0); let rounds_tag = b"Rescue_f"; let _mds_tag = b"ResM0003"; - let total_number_of_rounds = 2*full_rounds + 1; - + let total_number_of_rounds = 2 * full_rounds + 1; + params.compute_round_constants(total_number_of_rounds, rounds_tag); params.compute_mds_matrix_for_rescue(); @@ -170,18 +155,11 @@ pub(crate) fn compute_params() (params, alpha, alpha_inv) } -pub(crate) fn mds_optimized_params_alpha_5( - full_rounds: usize, - claimed_security_bits: usize, -) -> (InnerHashParameters, u64, Vec, Vec) { - let mut params = InnerHashParameters::new( - claimed_security_bits, - full_rounds, - 0, - ); +pub(crate) fn mds_optimized_params_alpha_5(full_rounds: usize, claimed_security_bits: usize) -> (InnerHashParameters, u64, Vec, Vec) { + let mut params = InnerHashParameters::new(claimed_security_bits, full_rounds, 0); let rounds_tag = b"Rescue_f"; - let total_number_of_rounds = 2*full_rounds + 1; + let total_number_of_rounds = 2 * full_rounds + 1; params.compute_round_constants_with_prefixed_blake2s(total_number_of_rounds, rounds_tag); params.set_circular_optimized_mds(); @@ -193,7 +171,6 @@ pub(crate) fn mds_optimized_params_alpha_5( (params, alpha, alpha_inv, addition_chain) } - #[cfg(test)] mod tests { use crate::add_chain_pow_smallvec; diff --git a/crates/rescue-poseidon/src/rescue/rescue.rs b/crates/rescue-poseidon/src/rescue/rescue.rs index f444ed8..ebd770e 100644 --- a/crates/rescue-poseidon/src/rescue/rescue.rs +++ b/crates/rescue-poseidon/src/rescue/rescue.rs @@ -1,8 +1,8 @@ -use crate::common::{matrix::mmul_assign, sbox::{sbox}}; -use crate::sponge::{generic_hash}; +use super::params::RescueParams; +use crate::common::{matrix::mmul_assign, sbox::sbox}; +use crate::sponge::generic_hash; use crate::traits::{HashFamily, HashParams}; use franklin_crypto::bellman::{Engine, Field}; -use super::params::RescueParams; /// Receives inputs whose length `known` prior(fixed-length). /// Also uses custom domain strategy which basically sets value of capacity element to @@ -16,22 +16,11 @@ pub fn rescue_hash(input: &[E::Fr; L]) -> [E::Fr; 2] generic_hash(¶ms, input, None) } -pub(crate) fn rescue_round_function< - E: Engine, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( - params: &P, - state: &mut [E::Fr; WIDTH] -) { +pub(crate) fn rescue_round_function, const RATE: usize, const WIDTH: usize>(params: &P, state: &mut [E::Fr; WIDTH]) { assert_eq!(params.hash_family(), HashFamily::Rescue, "Incorrect hash family!"); // round constants for first step - state - .iter_mut() - .zip(params.constants_of_round(0).iter()) - .for_each(|(s, c)| s.add_assign(c)); + state.iter_mut().zip(params.constants_of_round(0).iter()).for_each(|(s, c)| s.add_assign(c)); for round in 0..2 * params.number_of_full_rounds() { // sbox @@ -50,10 +39,7 @@ pub(crate) fn rescue_round_function< mmul_assign::(params.mds_matrix(), state); // round constants - state - .iter_mut() - .zip(params.constants_of_round(round + 1).iter()) - .for_each(|(s, c)| s.add_assign(c)); + state.iter_mut().zip(params.constants_of_round(round + 1).iter()).for_each(|(s, c)| s.add_assign(c)); } } } diff --git a/crates/rescue-poseidon/src/rescue_prime/params.rs b/crates/rescue-poseidon/src/rescue_prime/params.rs index 32b5059..7a17b97 100644 --- a/crates/rescue-poseidon/src/rescue_prime/params.rs +++ b/crates/rescue-poseidon/src/rescue_prime/params.rs @@ -28,17 +28,13 @@ pub struct RescuePrimeParams { pub(crate) alpha_inv: Sbox, pub(crate) custom_gate: CustomGate, } -impl PartialEq - for RescuePrimeParams -{ +impl PartialEq for RescuePrimeParams { fn eq(&self, other: &Self) -> bool { self.hash_family() == other.hash_family() } } -impl Default - for RescuePrimeParams -{ +impl Default for RescuePrimeParams { fn default() -> Self { let (params, alpha, alpha_inv) = super::params::rescue_prime_params::(); Self { @@ -73,9 +69,7 @@ impl RescuePrimeParams HashParams - for RescuePrimeParams -{ +impl HashParams for RescuePrimeParams { #[inline] fn allows_specialization(&self) -> bool { self.allows_specialization @@ -175,28 +169,16 @@ fn compute_alpha(p: &[u8]) -> (BigUint, BigUint) { break; } } - let ExtendedGcd { - gcd, - y: mut alpha_inv, - .. - } = p_minus_one.extended_gcd(&actual_alpha); + let ExtendedGcd { gcd, y: mut alpha_inv, .. } = p_minus_one.extended_gcd(&actual_alpha); assert!(gcd.is_one()); if alpha_inv < BigInt::zero() { alpha_inv += p_minus_one; }; - ( - actual_alpha.to_biguint().unwrap(), - alpha_inv.to_biguint().unwrap(), - ) + (actual_alpha.to_biguint().unwrap(), alpha_inv.to_biguint().unwrap()) } -fn compute_round_constants( - modulus_bytes: &[u8], - p_big: BigInt, - security_level: usize, - n: usize, -) -> Vec<[E::Fr; WIDTH]> { +fn compute_round_constants(modulus_bytes: &[u8], p_big: BigInt, security_level: usize, n: usize) -> Vec<[E::Fr; WIDTH]> { fn shake256(input: &[u8], num_bytes: usize) -> Box<[u8]> { use sha3::digest::ExtendableOutput; use sha3::digest::Update; @@ -214,10 +196,7 @@ fn compute_round_constants( let bytes_per_int = ((modulus_bit_len / 8f32) + 1f32).ceil() as usize; let num_bytes = bytes_per_int * 2 * m * n; - let seed_string = format!( - "Rescue-XLIX({},{},{},{})", - p_big, m, capacity, security_level - ); + let seed_string = format!("Rescue-XLIX({},{},{},{})", p_big, m, capacity, security_level); let seed_bytes = seed_string.as_bytes(); let byte_string = shake256(seed_bytes, num_bytes); let mut round_constants = vec![]; @@ -256,8 +235,7 @@ fn compute_round_constants( final_constants } -pub fn rescue_prime_params( -) -> (InnerHashParameters, u64, Vec) { +pub fn rescue_prime_params() -> (InnerHashParameters, u64, Vec) { let security_level = 80; let mut modulus_bytes = vec![]; @@ -266,16 +244,10 @@ pub fn rescue_prime_params( let p_big = BigInt::from_bytes_le(Sign::Plus, &modulus_bytes); let (alpha, alpha_inv) = compute_alpha(&modulus_bytes); let alpha = alpha.to_u64().expect("u64"); - let number_of_rounds = - get_number_of_rounds(WIDTH, WIDTH - RATE, security_level, alpha as usize); + let number_of_rounds = get_number_of_rounds(WIDTH, WIDTH - RATE, security_level, alpha as usize); let mut params = InnerHashParameters::new(security_level, number_of_rounds, 0); - params.round_constants = compute_round_constants::( - &modulus_bytes, - p_big, - security_level, - number_of_rounds, - ); + params.round_constants = compute_round_constants::(&modulus_bytes, p_big, security_level, number_of_rounds); params.compute_mds_matrix_for_rescue(); @@ -303,13 +275,9 @@ mod tests { let alpha = alpha.to_u32_digits()[0] as usize; let n = get_number_of_rounds(m, capacity, security_level, alpha); - println!( - "alpha {} alpha inv {:x} number of rounds {}", - alpha, alpha_inv, n - ); + println!("alpha {} alpha inv {:x} number of rounds {}", alpha, alpha_inv, n); - let round_constants = - compute_round_constants::(&modulus_bytes, p_big, security_level, n); + let round_constants = compute_round_constants::(&modulus_bytes, p_big, security_level, n); println!("number of rounds {}", n); println!("number of round constants {}", round_constants.len()); diff --git a/crates/rescue-poseidon/src/rescue_prime/rescue_prime.rs b/crates/rescue-poseidon/src/rescue_prime/rescue_prime.rs index 2303724..73f54a3 100644 --- a/crates/rescue-poseidon/src/rescue_prime/rescue_prime.rs +++ b/crates/rescue-poseidon/src/rescue_prime/rescue_prime.rs @@ -1,10 +1,10 @@ +use super::params::RescuePrimeParams; use crate::common::matrix::mmul_assign; use crate::common::sbox::sbox; -use crate::sponge::{generic_hash}; +use crate::sponge::generic_hash; use crate::traits::{HashFamily, HashParams}; use franklin_crypto::bellman::pairing::ff::Field; use franklin_crypto::bellman::pairing::Engine; -use super::params::RescuePrimeParams; /// Receives inputs whose length `known` prior(fixed-length). /// Also uses custom domain strategy which basically sets value of capacity element to @@ -19,21 +19,8 @@ pub fn rescue_prime_hash(input: &[E::Fr; L]) -> [E::F generic_hash(¶ms, input, None) } - -pub(crate) fn rescue_prime_round_function< - E: Engine, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( - params: &P, - state: &mut [E::Fr; WIDTH], -) { - assert_eq!( - params.hash_family(), - HashFamily::RescuePrime, - "Incorrect hash family!" - ); +pub(crate) fn rescue_prime_round_function, const RATE: usize, const WIDTH: usize>(params: &P, state: &mut [E::Fr; WIDTH]) { + assert_eq!(params.hash_family(), HashFamily::RescuePrime, "Incorrect hash family!"); for round in 0..params.number_of_full_rounds() - 1 { // sbox alpha sbox::(params.alpha(), state); @@ -41,10 +28,7 @@ pub(crate) fn rescue_prime_round_function< mmul_assign::(¶ms.mds_matrix(), state); // round constants - state - .iter_mut() - .zip(params.constants_of_round(round).iter()) - .for_each(|(s, c)| s.add_assign(c)); + state.iter_mut().zip(params.constants_of_round(round).iter()).for_each(|(s, c)| s.add_assign(c)); // sbox alpha inv sbox::(params.alpha_inv(), state); @@ -52,9 +36,6 @@ pub(crate) fn rescue_prime_round_function< mmul_assign::(¶ms.mds_matrix(), state); // round constants - state - .iter_mut() - .zip(params.constants_of_round(round + 1).iter()) - .for_each(|(s, c)| s.add_assign(c)); + state.iter_mut().zip(params.constants_of_round(round + 1).iter()).for_each(|(s, c)| s.add_assign(c)); } } diff --git a/crates/rescue-poseidon/src/sponge.rs b/crates/rescue-poseidon/src/sponge.rs index 7154dc6..17f7fda 100644 --- a/crates/rescue-poseidon/src/sponge.rs +++ b/crates/rescue-poseidon/src/sponge.rs @@ -3,13 +3,7 @@ use franklin_crypto::bellman::Engine; use franklin_crypto::bellman::Field; use std::convert::TryInto; -pub fn generic_hash< - E: Engine, - P: HashParams, - const RATE: usize, - const WIDTH: usize, - const LENGTH: usize, ->( +pub fn generic_hash, const RATE: usize, const WIDTH: usize, const LENGTH: usize>( params: &P, input: &[E::Fr; LENGTH], domain_strategy: Option, @@ -52,11 +46,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> GenericSponge>( - input: &[E::Fr], - params: &P, - domain_strategy: Option, - ) -> [E::Fr; RATE] { + pub fn hash>(input: &[E::Fr], params: &P, domain_strategy: Option) -> [E::Fr; RATE] { // init state let mut state = [E::Fr::zero(); WIDTH]; @@ -67,9 +57,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> GenericSponge(input.len(), RATE) - .unwrap_or(E::Fr::zero()); + let capacity_value = domain_strategy.compute_capacity::(input.len(), RATE).unwrap_or(E::Fr::zero()); *state.last_mut().expect("last element") = capacity_value; // compute padding values @@ -84,11 +72,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> GenericSponge( - &mut state, - &values.try_into().expect("constant array"), - params, - ); + absorb::(&mut state, &values.try_into().expect("constant array"), params); } // prepare output let mut output = [E::Fr::zero(); RATE]; @@ -100,7 +84,7 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> GenericSponge>(&mut self, input: &[E::Fr], params: &P) { - // compute padding values + // compute padding values let padding_values = self.domain_strategy.generate_padding_values::(input.len(), RATE); for inp in input.iter().chain(padding_values.iter()) { @@ -148,9 +132,8 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> GenericSponge { let unwrapped_buffer_len = buf.iter().filter(|el| el.is_some()).count(); - // compute padding values - let padding_values = - self.domain_strategy.generate_padding_values::(unwrapped_buffer_len, RATE); + // compute padding values + let padding_values = self.domain_strategy.generate_padding_values::(unwrapped_buffer_len, RATE); let mut padding_values_it = padding_values.iter().cloned(); for b in buf { @@ -212,41 +195,18 @@ impl<'a, E: Engine, const RATE: usize, const WIDTH: usize> GenericSponge, const RATE: usize, const WIDTH: usize>( - state: &mut [E::Fr; WIDTH], - input: &[E::Fr; RATE], - params: &P, -) { +fn absorb, const RATE: usize, const WIDTH: usize>(state: &mut [E::Fr; WIDTH], input: &[E::Fr; RATE], params: &P) { for (i, s) in input.iter().zip(state.iter_mut()) { s.add_assign(i); } generic_round_function(params, state); } -pub fn generic_round_function< - E: Engine, - P: HashParams, - const RATE: usize, - const WIDTH: usize, ->( - params: &P, - state: &mut [E::Fr; WIDTH], -) { +pub fn generic_round_function, const RATE: usize, const WIDTH: usize>(params: &P, state: &mut [E::Fr; WIDTH]) { match params.hash_family() { - crate::traits::HashFamily::Rescue => { - crate::rescue::rescue_round_function(params, state) - } - crate::traits::HashFamily::Poseidon => { - crate::poseidon::poseidon_round_function(params, state) - } - crate::traits::HashFamily::RescuePrime => { - crate::rescue_prime::rescue_prime_round_function(params, state) - } - crate::traits::HashFamily::Poseidon2 => { - crate::poseidon2::poseidon2_round_function( - state, - params.try_to_poseidon2_params().unwrap() - ) - } + crate::traits::HashFamily::Rescue => crate::rescue::rescue_round_function(params, state), + crate::traits::HashFamily::Poseidon => crate::poseidon::poseidon_round_function(params, state), + crate::traits::HashFamily::RescuePrime => crate::rescue_prime::rescue_prime_round_function(params, state), + crate::traits::HashFamily::Poseidon2 => crate::poseidon2::poseidon2_round_function(state, params.try_to_poseidon2_params().unwrap()), } } diff --git a/crates/rescue-poseidon/src/tests.rs b/crates/rescue-poseidon/src/tests.rs index 692d2fb..ca0c43b 100644 --- a/crates/rescue-poseidon/src/tests.rs +++ b/crates/rescue-poseidon/src/tests.rs @@ -1,35 +1,33 @@ use crate::poseidon::params::PoseidonParams; use crate::rescue::params::RescueParams; +use crate::GenericSponge; use franklin_crypto::bellman::pairing::bn256::{Bn256, Fr}; -use franklin_crypto::bellman::{Field}; +use franklin_crypto::bellman::Field; use franklin_crypto::rescue::{bn256::Bn256RescueParams, RescueHashParams, StatefulRescue}; use franklin_crypto::{ - bellman::plonk::better_better_cs::cs::{TrivialAssembly, Width4MainGateWithDNext, PlonkCsWidth4WithNextStepParams}, + bellman::plonk::better_better_cs::cs::{PlonkCsWidth4WithNextStepParams, TrivialAssembly, Width4MainGateWithDNext}, bellman::Engine, - plonk::circuit::{Width4WithCustomGates}, + plonk::circuit::Width4WithCustomGates, }; use poseidon_hash::StatefulSponge as PoseidonSponge; use poseidon_hash::{bn256::Bn256PoseidonParams, PoseidonHashParams}; use rand::{Rand, SeedableRng, XorShiftRng}; use std::convert::TryInto; -use crate::GenericSponge; pub(crate) fn init_rng() -> XorShiftRng { XorShiftRng::from_seed(crate::common::TEST_SEED) } -pub(crate) fn init_cs( -) -> TrivialAssembly { +pub(crate) fn init_cs() -> TrivialAssembly { TrivialAssembly::::new() } -pub(crate) fn init_cs_no_custom_gate( -) -> TrivialAssembly { +pub(crate) fn init_cs_no_custom_gate() -> TrivialAssembly { TrivialAssembly::::new() } fn test_inputs() -> [E::Fr; L] { let rng = &mut init_rng(); let mut inputs = [E::Fr::zero(); L]; - for inp in inputs.iter_mut(){ + for inp in inputs.iter_mut() { *inp = E::Fr::rand(rng); } @@ -46,8 +44,7 @@ fn test_rescue_bn256_fixed_length() { let old_params = Bn256RescueParams::new_checked_2_into_1(); let expected = franklin_crypto::rescue::rescue_hash::(&old_params, &input); - let actual = - crate::rescue::rescue_hash::(&input.try_into().expect("static vector")); + let actual = crate::rescue::rescue_hash::(&input.try_into().expect("static vector")); assert_eq!(expected[0], actual[0]); } @@ -79,17 +76,11 @@ fn test_rescue_params() { let number_of_rounds = new_params.full_rounds; for round in 0..number_of_rounds { - assert_eq!( - old_params.round_constants(round as u32), - new_params.constants_of_round(round) - ) + assert_eq!(old_params.round_constants(round as u32), new_params.constants_of_round(round)) } for row in 0..WIDTH { - assert_eq!( - old_params.mds_matrix_row(row as u32), - new_params.mds_matrix[row] - ); + assert_eq!(old_params.mds_matrix_row(row as u32), new_params.mds_matrix[row]); } } @@ -162,7 +153,7 @@ fn test_rescue_hash_var_len() { let new_params = RescueParams::::default(); let mut hasher = GenericSponge::new(); - hasher.absorb_multiple(&input,&new_params); + hasher.absorb_multiple(&input, &new_params); let mut actual = [Fr::zero(); 2]; actual[0] = hasher.squeeze(&new_params).expect("an element"); actual[1] = hasher.squeeze(&new_params).expect("an element"); @@ -170,7 +161,6 @@ fn test_rescue_hash_var_len() { assert_eq!(actual, expected); } - #[ignore] #[test] fn test_new_generic_hasher_fixed_length_single_output_with_hardcoded_input() { @@ -184,25 +174,24 @@ fn test_new_generic_hasher_fixed_length_single_output_with_hardcoded_input() { let mut el1_repr = ::Repr::default(); el1_repr.read_be(&i1[..]).unwrap(); let el1 = Fr::from_repr(el1_repr).unwrap(); - + let mut el2_repr = ::Repr::default(); el2_repr.read_be(&i2[..]).unwrap(); let el2 = Fr::from_repr(el2_repr).unwrap(); - + let mut el3_repr = ::Repr::default(); el3_repr.read_be(&i3[..]).unwrap(); let el3 = Fr::from_repr(el3_repr).unwrap(); let input = [el1, el2, el3]; - let params = RescueParams::::default(); - let mut original_params = Bn256RescueParams::new_checked_2_into_1(); + let mut original_params = Bn256RescueParams::new_checked_2_into_1(); original_params.set_allow_custom_gate(true); let original = franklin_crypto::rescue::rescue_hash::(&original_params, &input); - + let expected = crate::rescue::rescue_hash::(&input); let actual = GenericSponge::<_, 2, 3>::hash(&input, ¶ms, None); @@ -243,13 +232,13 @@ fn test_var_length_multiple_absorbs_without_padding_when_pad_needed() { } #[test] -#[should_panic(expected="padding was necessary!")] +#[should_panic(expected = "padding was necessary!")] fn test_var_length_single_absorb_without_padding_when_pad_needed() { const WIDTH: usize = 3; const RATE: usize = 2; const LENGTH: usize = 1; - let input = test_inputs::(); + let input = test_inputs::(); let new_params = RescueParams::::default(); let mut generic_hasher = GenericSponge::new(); @@ -301,7 +290,7 @@ fn test_multiple_absorb_steps() { fn test_new_generic_hasher_single_absorb_compare_with_old_rescue_sponge() { const WIDTH: usize = 3; const RATE: usize = 2; - const LENGTH: usize =1; + const LENGTH: usize = 1; let input = test_inputs::(); @@ -310,7 +299,7 @@ fn test_new_generic_hasher_single_absorb_compare_with_old_rescue_sponge() { let mut original_rescue = StatefulRescue::::new(&original_params); original_rescue.absorb_single_value(input[0]); original_rescue.pad_if_necessary(); - + let expected = original_rescue.squeeze_out_single(); let new_params = RescueParams::::default(); @@ -318,7 +307,6 @@ fn test_new_generic_hasher_single_absorb_compare_with_old_rescue_sponge() { generic_hasher.absorb(input[0], &new_params); generic_hasher.pad_if_necessary(); - let actual = generic_hasher.squeeze(&new_params).expect("a squeezed elem"); assert_eq!(actual, expected); @@ -346,7 +334,7 @@ fn test_multiple_squeeze() { let original_params = Bn256RescueParams::new_checked_2_into_1(); let mut original_rescue = StatefulRescue::::new(&original_params); - original_rescue.absorb(&input); + original_rescue.absorb(&input); let mut expected = [Fr::zero(); RATE]; expected[0] = original_rescue.squeeze_out_single(); expected[1] = original_rescue.squeeze_out_single(); @@ -364,7 +352,7 @@ fn test_multiple_squeeze() { #[test] fn test_excessive_multiple_squeeze() { const WIDTH: usize = 3; - const RATE: usize = 2; + const RATE: usize = 2; const ILENGTH: usize = 2; let input = test_inputs::(); @@ -377,7 +365,6 @@ fn test_excessive_multiple_squeeze() { let _ = generic_hasher.squeeze(¶ms).expect("a squeezed elem"); let _ = generic_hasher.squeeze(¶ms).expect("a squeezed elem"); let _ = generic_hasher.squeeze(¶ms).is_none(); - } #[ignore] @@ -393,7 +380,7 @@ fn test_rate_absorb_and_squeeze() { let mut original_rescue = StatefulRescue::::new(&original_params); original_rescue.absorb(&input); - + let expected = original_rescue.squeeze_out_single(); let new_params = RescueParams::::default(); @@ -403,5 +390,4 @@ fn test_rate_absorb_and_squeeze() { let actual = generic_hasher.squeeze(&new_params).expect("a squeezed elem"); assert_eq!(actual, expected); - -} \ No newline at end of file +} diff --git a/crates/rescue-poseidon/src/traits.rs b/crates/rescue-poseidon/src/traits.rs index 3372cbd..d19372d 100644 --- a/crates/rescue-poseidon/src/traits.rs +++ b/crates/rescue-poseidon/src/traits.rs @@ -5,7 +5,7 @@ pub enum HashFamily { Rescue, Poseidon, RescuePrime, - Poseidon2 + Poseidon2, } #[derive(Copy, Clone, Debug, serde::Serialize, serde::Deserialize)] @@ -17,13 +17,8 @@ pub enum CustomGate { #[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub enum Step { - Double { - index: usize, - }, - Add { - left: usize, - right: usize, - }, + Double { index: usize }, + Add { left: usize, right: usize }, } #[derive(Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] @@ -46,15 +41,15 @@ impl std::fmt::Debug for Sbox { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::Alpha(alpha) => write!(f, "sbox x^{}", alpha), - Self::AlphaInverse(vec, alpha) => write!(f, "inverse sbox [u64; {}] for x^{}", vec.len(), alpha), + Self::AlphaInverse(vec, alpha) => { + write!(f, "inverse sbox [u64; {}] for x^{}", vec.len(), alpha) + } Self::AddChain(_, alpha) => write!(f, "add chain inverse sbox for x^{}", alpha), } } } -pub trait HashParams: - Clone + Send + Sync + serde::Serialize + serde::de::DeserializeOwned -{ +pub trait HashParams: Clone + Send + Sync + serde::Serialize + serde::de::DeserializeOwned { #[inline] fn allows_specialization(&self) -> bool { false diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..84f1060 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +# Rustfmt breaks with overly long lines and cannot format the code +# without these settings +max_width = 200 +comment_width = 200