From 11600b93c047b13bfccb7daba7dc7198d4066eef Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Wed, 2 Nov 2022 16:54:41 -0700 Subject: [PATCH 01/49] fix: do a first round of a core replacement Signed-off-by: Brandon H. Gomes --- plonky2/examples/bench_recursion.rs | 2 +- plonky2/examples/square_root.rs | 2 +- plonky2/src/fri/structure.rs | 2 +- plonky2/src/gadgets/arithmetic.rs | 2 +- plonky2/src/gadgets/arithmetic_extension.rs | 2 +- plonky2/src/gadgets/split_base.rs | 2 +- plonky2/src/gates/arithmetic_extension.rs | 2 +- plonky2/src/gates/base_sum.rs | 2 +- plonky2/src/gates/exponentiation.rs | 4 ++-- plonky2/src/gates/gate.rs | 6 +++--- plonky2/src/gates/high_degree_interpolation.rs | 6 +++--- plonky2/src/gates/interpolation.rs | 2 +- plonky2/src/gates/low_degree_interpolation.rs | 4 ++-- plonky2/src/gates/multiplication_extension.rs | 2 +- plonky2/src/gates/poseidon.rs | 2 +- plonky2/src/gates/poseidon_mds.rs | 4 ++-- plonky2/src/gates/public_input.rs | 2 +- plonky2/src/gates/random_access.rs | 4 ++-- plonky2/src/gates/reducing.rs | 2 +- plonky2/src/gates/reducing_extension.rs | 2 +- plonky2/src/gates/selectors.rs | 2 +- plonky2/src/gates/util.rs | 2 +- plonky2/src/hash/hash_types.rs | 2 +- plonky2/src/hash/keccak.rs | 4 ++-- plonky2/src/hash/merkle_tree.rs | 4 ++-- plonky2/src/iop/challenger.rs | 4 ++-- plonky2/src/iop/ext_target.rs | 2 +- plonky2/src/iop/generator.rs | 4 ++-- plonky2/src/iop/target.rs | 2 +- plonky2/src/iop/wire.rs | 2 +- plonky2/src/plonk/circuit_builder.rs | 2 +- plonky2/src/plonk/circuit_data.rs | 2 +- plonky2/src/plonk/config.rs | 2 +- plonky2/src/plonk/prover.rs | 5 ++--- plonky2/src/plonk/vars.rs | 2 +- plonky2/src/util/partial_products.rs | 2 +- plonky2/src/util/reducing.rs | 2 +- plonky2/src/util/strided_view.rs | 6 +++--- 38 files changed, 53 insertions(+), 54 deletions(-) diff --git a/plonky2/examples/bench_recursion.rs b/plonky2/examples/bench_recursion.rs index c9d24be7..e0d3cff6 100644 --- a/plonky2/examples/bench_recursion.rs +++ b/plonky2/examples/bench_recursion.rs @@ -5,7 +5,7 @@ #![allow(incomplete_features)] #![feature(generic_const_exprs)] -use std::{num::ParseIntError, ops::RangeInclusive, str::FromStr}; +use core::{num::ParseIntError, ops::RangeInclusive, str::FromStr}; use anyhow::{anyhow, Context as _, Result}; use log::{info, Level, LevelFilter}; diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 7d4d2fee..4411ac50 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use anyhow::Result; use plonky2::field::types::{Field, PrimeField}; diff --git a/plonky2/src/fri/structure.rs b/plonky2/src/fri/structure.rs index 0d64ae20..abcccccd 100644 --- a/plonky2/src/fri/structure.rs +++ b/plonky2/src/fri/structure.rs @@ -1,7 +1,7 @@ //! Information about the structure of a FRI instance, in terms of the oracles and polynomials //! involved, and the points they are opened at. -use std::ops::Range; +use core::ops::Range; use crate::field::extension::Extendable; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/gadgets/arithmetic.rs b/plonky2/src/gadgets/arithmetic.rs index 33facd74..87c5878c 100644 --- a/plonky2/src/gadgets/arithmetic.rs +++ b/plonky2/src/gadgets/arithmetic.rs @@ -1,4 +1,4 @@ -use std::borrow::Borrow; +use core::borrow::Borrow; use plonky2_field::extension::Extendable; use plonky2_field::types::Field64; diff --git a/plonky2/src/gadgets/arithmetic_extension.rs b/plonky2/src/gadgets/arithmetic_extension.rs index 23c401b8..e3b31e17 100644 --- a/plonky2/src/gadgets/arithmetic_extension.rs +++ b/plonky2/src/gadgets/arithmetic_extension.rs @@ -1,4 +1,4 @@ -use std::borrow::Borrow; +use core::borrow::Borrow; use plonky2_field::extension::FieldExtension; use plonky2_field::extension::{Extendable, OEF}; diff --git a/plonky2/src/gadgets/split_base.rs b/plonky2/src/gadgets/split_base.rs index c539d784..37853c2b 100644 --- a/plonky2/src/gadgets/split_base.rs +++ b/plonky2/src/gadgets/split_base.rs @@ -1,4 +1,4 @@ -use std::borrow::Borrow; +use core::borrow::Borrow; use itertools::Itertools; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index 26b7074b..4aa550c2 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::Extendable; use plonky2_field::extension::FieldExtension; diff --git a/plonky2/src/gates/base_sum.rs b/plonky2/src/gates/base_sum.rs index 1252c8e3..916d1b84 100644 --- a/plonky2/src/gates/base_sum.rs +++ b/plonky2/src/gates/base_sum.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::Extendable; use plonky2_field::packed::PackedField; diff --git a/plonky2/src/gates/exponentiation.rs b/plonky2/src/gates/exponentiation.rs index ca1ba395..9a3079e0 100644 --- a/plonky2/src/gates/exponentiation.rs +++ b/plonky2/src/gates/exponentiation.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use plonky2_field::extension::Extendable; use plonky2_field::ops::Square; @@ -282,7 +282,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use plonky2_field::goldilocks_field::GoldilocksField; diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index 781e0cbd..4faac919 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -1,7 +1,7 @@ +use core::fmt::{Debug, Error, Formatter}; +use core::hash::{Hash, Hasher}; +use core::ops::Range; use std::collections::HashMap; -use std::fmt::{Debug, Error, Formatter}; -use std::hash::{Hash, Hasher}; -use std::ops::Range; use std::sync::Arc; use plonky2_field::batch_util::batch_multiply_inplace; diff --git a/plonky2/src/gates/high_degree_interpolation.rs b/plonky2/src/gates/high_degree_interpolation.rs index 0bc4ab65..7460a26d 100644 --- a/plonky2/src/gates/high_degree_interpolation.rs +++ b/plonky2/src/gates/high_degree_interpolation.rs @@ -1,5 +1,5 @@ -use std::marker::PhantomData; -use std::ops::Range; +use core::marker::PhantomData; +use core::ops::Range; use plonky2_field::extension::algebra::PolynomialCoeffsAlgebra; use plonky2_field::extension::{Extendable, FieldExtension}; @@ -270,7 +270,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use plonky2_field::goldilocks_field::GoldilocksField; diff --git a/plonky2/src/gates/interpolation.rs b/plonky2/src/gates/interpolation.rs index d417fa6b..fb61b97e 100644 --- a/plonky2/src/gates/interpolation.rs +++ b/plonky2/src/gates/interpolation.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/gates/low_degree_interpolation.rs b/plonky2/src/gates/low_degree_interpolation.rs index 8fd2ed47..de4292a5 100644 --- a/plonky2/src/gates/low_degree_interpolation.rs +++ b/plonky2/src/gates/low_degree_interpolation.rs @@ -1,5 +1,5 @@ -use std::marker::PhantomData; -use std::ops::Range; +use core::marker::PhantomData; +use core::ops::Range; use plonky2_field::extension::algebra::PolynomialCoeffsAlgebra; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 8e6b44d7..c158c6a6 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::Extendable; use plonky2_field::extension::FieldExtension; diff --git a/plonky2/src/gates/poseidon.rs b/plonky2/src/gates/poseidon.rs index 26ec2594..95678528 100644 --- a/plonky2/src/gates/poseidon.rs +++ b/plonky2/src/gates/poseidon.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use plonky2_field::extension::Extendable; use plonky2_field::types::Field; diff --git a/plonky2/src/gates/poseidon_mds.rs b/plonky2/src/gates/poseidon_mds.rs index 289246e1..f1566e11 100644 --- a/plonky2/src/gates/poseidon_mds.rs +++ b/plonky2/src/gates/poseidon_mds.rs @@ -1,5 +1,5 @@ -use std::marker::PhantomData; -use std::ops::Range; +use core::marker::PhantomData; +use core::ops::Range; use plonky2_field::extension::algebra::ExtensionAlgebra; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/gates/public_input.rs b/plonky2/src/gates/public_input.rs index 60c9a4c3..f84cd82d 100644 --- a/plonky2/src/gates/public_input.rs +++ b/plonky2/src/gates/public_input.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::Extendable; use plonky2_field::packed::PackedField; diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 3ea2f55e..217f5e8a 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use itertools::Itertools; use plonky2_field::extension::Extendable; @@ -376,7 +376,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use plonky2_field::goldilocks_field::GoldilocksField; diff --git a/plonky2/src/gates/reducing.rs b/plonky2/src/gates/reducing.rs index 02f8ac2d..bf312b84 100644 --- a/plonky2/src/gates/reducing.rs +++ b/plonky2/src/gates/reducing.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::Extendable; use plonky2_field::extension::FieldExtension; diff --git a/plonky2/src/gates/reducing_extension.rs b/plonky2/src/gates/reducing_extension.rs index 8b04ec99..e7a4fc8f 100644 --- a/plonky2/src/gates/reducing_extension.rs +++ b/plonky2/src/gates/reducing_extension.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::Extendable; use plonky2_field::extension::FieldExtension; diff --git a/plonky2/src/gates/selectors.rs b/plonky2/src/gates/selectors.rs index 6cea86a7..b2b52b77 100644 --- a/plonky2/src/gates/selectors.rs +++ b/plonky2/src/gates/selectors.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::Extendable; use plonky2_field::polynomial::PolynomialValues; diff --git a/plonky2/src/gates/util.rs b/plonky2/src/gates/util.rs index fb5ab6b1..cd6dc9e1 100644 --- a/plonky2/src/gates/util.rs +++ b/plonky2/src/gates/util.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use plonky2_field::packed::PackedField; diff --git a/plonky2/src/hash/hash_types.rs b/plonky2/src/hash/hash_types.rs index f416732a..f69285f7 100644 --- a/plonky2/src/hash/hash_types.rs +++ b/plonky2/src/hash/hash_types.rs @@ -36,7 +36,7 @@ impl HashOut { Self { elements } } - #[cfg(feature = "parallel")] + #[cfg(all(feature = "parallel", feature = "rand"))] pub fn rand_from_rng(rng: &mut R) -> Self { Self { elements: [ diff --git a/plonky2/src/hash/keccak.rs b/plonky2/src/hash/keccak.rs index 9a061d82..6e4fcdcb 100644 --- a/plonky2/src/hash/keccak.rs +++ b/plonky2/src/hash/keccak.rs @@ -1,5 +1,5 @@ -use std::iter; -use std::mem::size_of; +use core::iter; +use core::mem::size_of; use itertools::Itertools; use keccak_hash::keccak; diff --git a/plonky2/src/hash/merkle_tree.rs b/plonky2/src/hash/merkle_tree.rs index 703a353e..19d49f13 100644 --- a/plonky2/src/hash/merkle_tree.rs +++ b/plonky2/src/hash/merkle_tree.rs @@ -1,5 +1,5 @@ -use std::mem::MaybeUninit; -use std::slice; +use core::mem::MaybeUninit; +use core::slice; use maybe_rayon::*; use plonky2_util::log2_strict; diff --git a/plonky2/src/iop/challenger.rs b/plonky2/src/iop/challenger.rs index c601ae0f..34ed4f67 100644 --- a/plonky2/src/iop/challenger.rs +++ b/plonky2/src/iop/challenger.rs @@ -1,5 +1,5 @@ -use std::convert::TryInto; -use std::marker::PhantomData; +use core::convert::TryInto; +use core::marker::PhantomData; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/iop/ext_target.rs b/plonky2/src/iop/ext_target.rs index 8a63cf44..eb7e572b 100644 --- a/plonky2/src/iop/ext_target.rs +++ b/plonky2/src/iop/ext_target.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::algebra::ExtensionAlgebra; use plonky2_field::extension::{Extendable, FieldExtension, OEF}; diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index 9948198e..3d28ae2e 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -1,5 +1,5 @@ -use std::fmt::Debug; -use std::marker::PhantomData; +use core::fmt::Debug; +use core::marker::PhantomData; use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::types::Field; diff --git a/plonky2/src/iop/target.rs b/plonky2/src/iop/target.rs index bda1a47c..14e77da1 100644 --- a/plonky2/src/iop/target.rs +++ b/plonky2/src/iop/target.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use crate::iop::ext_target::ExtensionTarget; use crate::iop::wire::Wire; diff --git a/plonky2/src/iop/wire.rs b/plonky2/src/iop/wire.rs index dd46afe2..daf0126e 100644 --- a/plonky2/src/iop/wire.rs +++ b/plonky2/src/iop/wire.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use crate::plonk::circuit_data::CircuitConfig; diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index dfd23426..3b48f9cf 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -1,4 +1,4 @@ -use std::cmp::max; +use core::cmp::max; use std::collections::{BTreeMap, HashMap, HashSet}; use std::time::Instant; diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index b5e411f1..b1dea756 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -1,5 +1,5 @@ +use core::ops::{Range, RangeFrom}; use std::collections::BTreeMap; -use std::ops::{Range, RangeFrom}; use anyhow::Result; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/plonk/config.rs b/plonky2/src/plonk/config.rs index f55bad1f..20de09fb 100644 --- a/plonky2/src/plonk/config.rs +++ b/plonky2/src/plonk/config.rs @@ -1,4 +1,4 @@ -use std::fmt::Debug; +use core::fmt::Debug; use plonky2_field::extension::quadratic::QuadraticExtension; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index 621f20ef..c762b5ba 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -1,4 +1,4 @@ -use std::mem::swap; +use core::mem::swap; use anyhow::ensure; use anyhow::Result; @@ -351,7 +351,7 @@ fn compute_quotient_polys< let num_batches = ceil_div_usize(points.len(), BATCH_SIZE); let quotient_values: Vec> = points_batches .enumerate() - .map(|(batch_i, xs_batch)| { + .flat_map(|(batch_i, xs_batch)| { // Each batch must be the same size, except the last one, which may be smaller. debug_assert!( xs_batch.len() == BATCH_SIZE @@ -448,7 +448,6 @@ fn compute_quotient_polys< } quotient_values_batch }) - .flatten() .collect(); transpose("ient_values) diff --git a/plonky2/src/plonk/vars.rs b/plonky2/src/plonk/vars.rs index a2474e79..5be573fc 100644 --- a/plonky2/src/plonk/vars.rs +++ b/plonky2/src/plonk/vars.rs @@ -1,4 +1,4 @@ -use std::ops::Range; +use core::ops::Range; use plonky2_field::extension::algebra::ExtensionAlgebra; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/util/partial_products.rs b/plonky2/src/util/partial_products.rs index 39e59a28..9fad9dc8 100644 --- a/plonky2/src/util/partial_products.rs +++ b/plonky2/src/util/partial_products.rs @@ -1,4 +1,4 @@ -use std::iter; +use core::iter; use itertools::Itertools; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/util/reducing.rs b/plonky2/src/util/reducing.rs index fae5f03b..89b4a4ad 100644 --- a/plonky2/src/util/reducing.rs +++ b/plonky2/src/util/reducing.rs @@ -1,4 +1,4 @@ -use std::borrow::Borrow; +use core::borrow::Borrow; use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::packed::PackedField; diff --git a/plonky2/src/util/strided_view.rs b/plonky2/src/util/strided_view.rs index 0c1094fd..851914bf 100644 --- a/plonky2/src/util/strided_view.rs +++ b/plonky2/src/util/strided_view.rs @@ -1,6 +1,6 @@ -use std::marker::PhantomData; -use std::mem::size_of; -use std::ops::{Index, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}; +use core::marker::PhantomData; +use core::mem::size_of; +use core::ops::{Index, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}; use plonky2_field::packed::PackedField; From 6fd0da216ae471f2135c56916e6d284da1b87280 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Wed, 2 Nov 2022 17:50:31 -0700 Subject: [PATCH 02/49] fix: remove unstable features from plonky2 Signed-off-by: Brandon H. Gomes --- ecdsa/src/curve/curve_msm.rs | 6 ++-- ecdsa/src/curve/curve_multiplication.rs | 3 +- ecdsa/src/curve/secp256k1.rs | 3 +- ecdsa/src/gadgets/biguint.rs | 7 ++-- ecdsa/src/gadgets/curve_fixed_base.rs | 3 +- ecdsa/src/gadgets/nonnative.rs | 4 +-- evm/src/arithmetic/arithmetic_stark.rs | 7 +--- evm/src/arithmetic/modular.rs | 3 +- evm/src/bin/assemble.rs | 3 +- evm/src/cpu/kernel/assembler.rs | 10 +++--- evm/src/keccak/round_flags.rs | 6 ++-- evm/src/keccak_memory/keccak_memory_stark.rs | 3 +- evm/src/keccak_sponge/keccak_sponge_stark.rs | 3 +- evm/src/prover.rs | 2 +- evm/src/recursive_verifier.rs | 14 +++----- evm/src/stark.rs | 3 +- evm/src/stark_testing.rs | 9 ++--- field/src/field_testing.rs | 3 +- plonky2/Cargo.toml | 23 ++++++------ plonky2/examples/bench_recursion.rs | 31 ++++++++-------- plonky2/src/fri/oracle.rs | 20 +++-------- plonky2/src/fri/proof.rs | 8 ++--- plonky2/src/fri/prover.rs | 18 ++++------ plonky2/src/fri/recursive_verifier.rs | 3 +- plonky2/src/fri/verifier.rs | 21 +++++------ plonky2/src/gadgets/arithmetic_extension.rs | 3 +- plonky2/src/gadgets/polynomial.rs | 4 +++ plonky2/src/gates/arithmetic_extension.rs | 3 +- plonky2/src/gates/gate_testing.rs | 10 ++---- plonky2/src/gates/multiplication_extension.rs | 3 +- plonky2/src/gates/poseidon.rs | 11 +++--- plonky2/src/gates/poseidon_mds.rs | 15 ++++---- plonky2/src/gates/reducing.rs | 3 +- plonky2/src/gates/reducing_extension.rs | 3 +- plonky2/src/gates/selectors.rs | 2 +- plonky2/src/hash/hashing.rs | 3 +- plonky2/src/hash/merkle_proofs.rs | 17 ++++----- plonky2/src/hash/merkle_tree.rs | 32 ++++++++--------- plonky2/src/hash/path_compression.rs | 5 +-- plonky2/src/hash/poseidon.rs | 2 +- plonky2/src/hash/poseidon_goldilocks.rs | 3 +- plonky2/src/iop/challenger.rs | 10 +++--- plonky2/src/iop/witness.rs | 9 +++-- plonky2/src/lib.rs | 9 ----- plonky2/src/plonk/circuit_builder.rs | 15 ++------ plonky2/src/plonk/circuit_data.rs | 35 ++++--------------- plonky2/src/plonk/config.rs | 15 ++++---- plonky2/src/plonk/permutation_argument.rs | 4 +-- plonky2/src/plonk/proof.rs | 15 ++------ plonky2/src/plonk/prover.rs | 11 ++---- plonky2/src/plonk/validate_shape.rs | 11 +----- plonky2/src/plonk/vars.rs | 4 +++ plonky2/src/plonk/verifier.rs | 10 ++---- .../conditional_recursive_verifier.rs | 7 ++-- plonky2/src/recursion/cyclic_recursion.rs | 4 --- plonky2/src/recursion/recursive_verifier.rs | 27 +++++--------- plonky2/src/util/reducing.rs | 2 +- plonky2/src/util/serialization.rs | 11 +++--- plonky2/src/util/strided_view.rs | 5 +++ rustfmt.toml | 3 +- starky/src/prover.rs | 2 +- starky/src/stark.rs | 3 +- starky/src/stark_testing.rs | 3 +- system_zero/src/alu/mod.rs | 3 +- system_zero/src/core_registers.rs | 3 +- system_zero/src/lookup.rs | 3 +- system_zero/src/permutation_unit.rs | 3 +- system_zero/src/system_zero.rs | 3 +- u32/src/gates/arithmetic_u32.rs | 3 +- u32/src/gates/comparison.rs | 3 +- u32/src/gates/subtraction_u32.rs | 3 +- waksman/src/gates/assert_le.rs | 3 +- waksman/src/permutation.rs | 6 ++-- 73 files changed, 213 insertions(+), 370 deletions(-) diff --git a/ecdsa/src/curve/curve_msm.rs b/ecdsa/src/curve/curve_msm.rs index f681deb2..400c7ab6 100644 --- a/ecdsa/src/curve/curve_msm.rs +++ b/ecdsa/src/curve/curve_msm.rs @@ -1,6 +1,5 @@ use itertools::Itertools; -use plonky2_field::types::Field; -use plonky2_field::types::PrimeField; +use plonky2_field::types::{Field, PrimeField}; use rayon::prelude::*; use crate::curve::curve_summation::affine_multisummation_best; @@ -188,8 +187,7 @@ pub(crate) fn to_digits(x: &C::ScalarField, w: usize) -> Vec { mod tests { use num::BigUint; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; - use plonky2_field::types::PrimeField; + use plonky2_field::types::{Field, PrimeField}; use crate::curve::curve_msm::{msm_execute, msm_precompute, to_digits}; use crate::curve::curve_types::Curve; diff --git a/ecdsa/src/curve/curve_multiplication.rs b/ecdsa/src/curve/curve_multiplication.rs index 70e49df6..25c603b5 100644 --- a/ecdsa/src/curve/curve_multiplication.rs +++ b/ecdsa/src/curve/curve_multiplication.rs @@ -1,7 +1,6 @@ use std::ops::Mul; -use plonky2_field::types::Field; -use plonky2_field::types::PrimeField; +use plonky2_field::types::{Field, PrimeField}; use crate::curve::curve_types::{Curve, CurveScalar, ProjectivePoint}; diff --git a/ecdsa/src/curve/secp256k1.rs b/ecdsa/src/curve/secp256k1.rs index 8f7bccf3..b5ac8931 100644 --- a/ecdsa/src/curve/secp256k1.rs +++ b/ecdsa/src/curve/secp256k1.rs @@ -41,8 +41,7 @@ const SECP256K1_GENERATOR_Y: Secp256K1Base = Secp256K1Base([ mod tests { use num::BigUint; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; - use plonky2_field::types::PrimeField; + use plonky2_field::types::{Field, PrimeField}; use crate::curve::curve_types::{AffinePoint, Curve, ProjectivePoint}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/gadgets/biguint.rs b/ecdsa/src/gadgets/biguint.rs index faae365c..ef958bd1 100644 --- a/ecdsa/src/gadgets/biguint.rs +++ b/ecdsa/src/gadgets/biguint.rs @@ -346,11 +346,10 @@ impl, const D: usize> SimpleGenerator mod tests { use anyhow::Result; use num::{BigUint, FromPrimitive, Integer}; + use plonky2::iop::witness::PartialWitness; + use plonky2::plonk::circuit_builder::CircuitBuilder; + use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2::{ - iop::witness::PartialWitness, - plonk::{circuit_builder::CircuitBuilder, circuit_data::CircuitConfig}, - }; use rand::Rng; use crate::gadgets::biguint::{CircuitBuilderBiguint, WitnessBigUint}; diff --git a/ecdsa/src/gadgets/curve_fixed_base.rs b/ecdsa/src/gadgets/curve_fixed_base.rs index 0fd8e841..31292ddb 100644 --- a/ecdsa/src/gadgets/curve_fixed_base.rs +++ b/ecdsa/src/gadgets/curve_fixed_base.rs @@ -71,8 +71,7 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; - use plonky2_field::types::PrimeField; + use plonky2_field::types::{Field, PrimeField}; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/gadgets/nonnative.rs b/ecdsa/src/gadgets/nonnative.rs index 29520bed..ad6315a1 100644 --- a/ecdsa/src/gadgets/nonnative.rs +++ b/ecdsa/src/gadgets/nonnative.rs @@ -6,8 +6,8 @@ use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::{BoolTarget, Target}; use plonky2::iop::witness::PartitionWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::types::PrimeField; -use plonky2_field::{extension::Extendable, types::Field}; +use plonky2_field::extension::Extendable; +use plonky2_field::types::{Field, PrimeField}; use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target}; use plonky2_u32::gadgets::range_check::range_check_u32_circuit; use plonky2_u32::witness::GeneratedValuesU32; diff --git a/evm/src/arithmetic/arithmetic_stark.rs b/evm/src/arithmetic/arithmetic_stark.rs index 08813a3b..5d835e77 100644 --- a/evm/src/arithmetic/arithmetic_stark.rs +++ b/evm/src/arithmetic/arithmetic_stark.rs @@ -6,12 +6,7 @@ use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::packed::PackedField; use plonky2::hash::hash_types::RichField; -use crate::arithmetic::add; -use crate::arithmetic::columns; -use crate::arithmetic::compare; -use crate::arithmetic::modular; -use crate::arithmetic::mul; -use crate::arithmetic::sub; +use crate::arithmetic::{add, columns, compare, modular, mul, sub}; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::stark::Stark; use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; diff --git a/evm/src/arithmetic/modular.rs b/evm/src/arithmetic/modular.rs index d0020166..d19768bf 100644 --- a/evm/src/arithmetic/modular.rs +++ b/evm/src/arithmetic/modular.rs @@ -87,7 +87,8 @@ //! In the case of DIV, we do something similar, except that we "replace" //! the modulus with "2^256" to force the quotient to be zero. -use num::{bigint::Sign, BigInt, One, Zero}; +use num::bigint::Sign; +use num::{BigInt, One, Zero}; use plonky2::field::extension::Extendable; use plonky2::field::packed::PackedField; use plonky2::field::types::Field; diff --git a/evm/src/bin/assemble.rs b/evm/src/bin/assemble.rs index 1cf3a67c..2afd54d7 100644 --- a/evm/src/bin/assemble.rs +++ b/evm/src/bin/assemble.rs @@ -1,5 +1,4 @@ -use std::env; -use std::fs; +use std::{env, fs}; use hex::encode; use plonky2_evm::cpu::kernel::assemble_to_bytes; diff --git a/evm/src/cpu/kernel/assembler.rs b/evm/src/cpu/kernel/assembler.rs index aad2dd53..e06fd784 100644 --- a/evm/src/cpu/kernel/assembler.rs +++ b/evm/src/cpu/kernel/assembler.rs @@ -7,15 +7,12 @@ use plonky2_util::ceil_div_usize; use super::ast::PushTarget; use crate::cpu::kernel::ast::Item::LocalLabelDeclaration; -use crate::cpu::kernel::ast::StackReplacement; +use crate::cpu::kernel::ast::{File, Item, StackReplacement}; use crate::cpu::kernel::keccak_util::hash_kernel; +use crate::cpu::kernel::opcodes::{get_opcode, get_push_opcode}; use crate::cpu::kernel::optimizer::optimize_asm; use crate::cpu::kernel::stack::stack_manipulation::expand_stack_manipulation; use crate::cpu::kernel::utils::u256_to_trimmed_be_bytes; -use crate::cpu::kernel::{ - ast::{File, Item}, - opcodes::{get_opcode, get_push_opcode}, -}; use crate::generation::prover_input::ProverInputFn; use crate::keccak_sponge::columns::KECCAK_RATE_BYTES; @@ -374,8 +371,9 @@ mod tests { use itertools::Itertools; + use crate::cpu::kernel::assembler::*; + use crate::cpu::kernel::ast::*; use crate::cpu::kernel::parser::parse; - use crate::cpu::kernel::{assembler::*, ast::*}; #[test] fn two_files() { diff --git a/evm/src/keccak/round_flags.rs b/evm/src/keccak/round_flags.rs index 920ca4c8..d8c46680 100644 --- a/evm/src/keccak/round_flags.rs +++ b/evm/src/keccak/round_flags.rs @@ -5,11 +5,9 @@ use plonky2::hash::hash_types::RichField; use plonky2::plonk::circuit_builder::CircuitBuilder; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use crate::keccak::columns::reg_step; -use crate::keccak::columns::NUM_COLUMNS; +use crate::keccak::columns::{reg_step, NUM_COLUMNS}; use crate::keccak::keccak_stark::NUM_ROUNDS; -use crate::vars::StarkEvaluationTargets; -use crate::vars::StarkEvaluationVars; +use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; pub(crate) fn eval_round_flags>( vars: StarkEvaluationVars, diff --git a/evm/src/keccak_memory/keccak_memory_stark.rs b/evm/src/keccak_memory/keccak_memory_stark.rs index 1bbea168..3719fc8e 100644 --- a/evm/src/keccak_memory/keccak_memory_stark.rs +++ b/evm/src/keccak_memory/keccak_memory_stark.rs @@ -15,8 +15,7 @@ use crate::keccak_memory::columns::*; use crate::memory::segments::Segment; use crate::stark::Stark; use crate::util::trace_rows_to_poly_values; -use crate::vars::StarkEvaluationTargets; -use crate::vars::StarkEvaluationVars; +use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; pub(crate) fn ctl_looked_data() -> Vec> { Column::singles([COL_CONTEXT, COL_SEGMENT, COL_VIRTUAL, COL_READ_TIMESTAMP]).collect() diff --git a/evm/src/keccak_sponge/keccak_sponge_stark.rs b/evm/src/keccak_sponge/keccak_sponge_stark.rs index 219c0c21..f2af8895 100644 --- a/evm/src/keccak_sponge/keccak_sponge_stark.rs +++ b/evm/src/keccak_sponge/keccak_sponge_stark.rs @@ -21,8 +21,7 @@ use crate::keccak_sponge::columns::*; use crate::memory::segments::Segment; use crate::stark::Stark; use crate::util::trace_rows_to_poly_values; -use crate::vars::StarkEvaluationTargets; -use crate::vars::StarkEvaluationVars; +use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; #[allow(unused)] // TODO: Should be used soon. pub(crate) fn ctl_looked_data() -> Vec> { diff --git a/evm/src/prover.rs b/evm/src/prover.rs index 20e8c628..4627784d 100644 --- a/evm/src/prover.rs +++ b/evm/src/prover.rs @@ -27,9 +27,9 @@ use crate::keccak::keccak_stark::KeccakStark; use crate::keccak_memory::keccak_memory_stark::KeccakMemoryStark; use crate::logic::LogicStark; use crate::memory::memory_stark::MemoryStark; -use crate::permutation::PermutationCheckVars; use crate::permutation::{ compute_permutation_z_polys, get_n_grand_product_challenge_sets, GrandProductChallengeSet, + PermutationCheckVars, }; use crate::proof::{AllProof, PublicValues, StarkOpeningSet, StarkProof}; use crate::stark::Stark; diff --git a/evm/src/recursive_verifier.rs b/evm/src/recursive_verifier.rs index 445497f8..999b5e13 100644 --- a/evm/src/recursive_verifier.rs +++ b/evm/src/recursive_verifier.rs @@ -13,13 +13,12 @@ use plonky2::iop::target::Target; use plonky2::iop::witness::Witness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::{CircuitConfig, VerifierCircuitData, VerifierCircuitTarget}; -use plonky2::plonk::config::Hasher; -use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; use plonky2::util::reducing::ReducingFactorTarget; use plonky2::with_context; -use crate::all_stark::NUM_TABLES; +use crate::all_stark::{AllStark, Table, NUM_TABLES}; use crate::config::StarkConfig; use crate::constraint_consumer::RecursiveConstraintConsumer; use crate::cpu::cpu_stark::CpuStark; @@ -41,13 +40,9 @@ use crate::proof::{ TrieRootsTarget, }; use crate::stark::Stark; -use crate::util::h160_limbs; +use crate::util::{h160_limbs, h256_limbs}; use crate::vanishing_poly::eval_vanishing_poly_circuit; use crate::vars::StarkEvaluationTargets; -use crate::{ - all_stark::{AllStark, Table}, - util::h256_limbs, -}; /// Table-wise recursive proofs of an `AllProof`. pub struct RecursiveAllProof< @@ -850,8 +845,7 @@ pub(crate) mod tests { use plonky2::iop::witness::{PartialWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::{CircuitConfig, VerifierCircuitData}; - use plonky2::plonk::config::Hasher; - use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; + use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; use plonky2::plonk::proof::ProofWithPublicInputs; use crate::all_stark::{AllStark, Table}; diff --git a/evm/src/stark.rs b/evm/src/stark.rs index 49c5b70b..72cee0ad 100644 --- a/evm/src/stark.rs +++ b/evm/src/stark.rs @@ -13,8 +13,7 @@ use plonky2_util::ceil_div_usize; use crate::config::StarkConfig; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::permutation::PermutationPair; -use crate::vars::StarkEvaluationTargets; -use crate::vars::StarkEvaluationVars; +use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; const TRACE_ORACLE_INDEX: usize = 0; const PERMUTATION_CTL_ORACLE_INDEX: usize = 1; diff --git a/evm/src/stark_testing.rs b/evm/src/stark_testing.rs index 81b0f68f..bd0df385 100644 --- a/evm/src/stark_testing.rs +++ b/evm/src/stark_testing.rs @@ -1,15 +1,12 @@ use anyhow::{ensure, Result}; -use plonky2::field::extension::Extendable; -use plonky2::field::extension::FieldExtension; +use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues}; use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; -use plonky2::iop::witness::PartialWitness; -use plonky2::iop::witness::Witness; +use plonky2::iop::witness::{PartialWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; -use plonky2::plonk::config::GenericConfig; -use plonky2::plonk::config::Hasher; +use plonky2::plonk::config::{GenericConfig, Hasher}; use plonky2::util::transpose; use plonky2_util::{log2_ceil, log2_strict}; diff --git a/field/src/field_testing.rs b/field/src/field_testing.rs index d85ac5e9..5e495311 100644 --- a/field/src/field_testing.rs +++ b/field/src/field_testing.rs @@ -1,5 +1,4 @@ -use crate::extension::Extendable; -use crate::extension::Frobenius; +use crate::extension::{Extendable, Frobenius}; use crate::ops::Square; use crate::types::Field; diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index b3fa5113..73ff55a5 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -19,30 +19,31 @@ rand_chacha = ["dep:rand_chacha"] timing = [] [dependencies] +anyhow = "1.0.40" +derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } +itertools = "0.10.0" +keccak-hash = "0.8.0" +log = "0.4.14" +maybe_rayon = { path = "../maybe_rayon" } +num = { version = "0.4", features = [ "rand" ] } plonky2_field = { path = "../field" } plonky2_util = { path = "../util" } -log = "0.4.14" -itertools = "0.10.0" -num = { version = "0.4", features = [ "rand" ] } rand = { version = "0.8.4", optional = true } rand_chacha = { version = "0.3.1", optional = true } -maybe_rayon = { path = "../maybe_rayon" } -unroll = "0.1.5" -anyhow = "1.0.40" serde = { version = "1.0", features = ["derive"] } serde_cbor = "0.11.1" -keccak-hash = "0.8.0" static_assertions = "1.1.0" +unroll = "0.1.5" [dev-dependencies] -rand = "0.8.4" -rand_chacha = "0.3.1" criterion = "0.3.5" env_logger = "0.9.0" -tynm = "0.1.6" -structopt = "0.3.26" num_cpus = "1.13.1" +rand = "0.8.4" +rand_chacha = "0.3.1" rayon = "1.5.1" +structopt = "0.3.26" +tynm = "0.1.6" [target.'cfg(not(target_env = "msvc"))'.dev-dependencies] jemallocator = "0.3.2" diff --git a/plonky2/examples/bench_recursion.rs b/plonky2/examples/bench_recursion.rs index e0d3cff6..6e196ef5 100644 --- a/plonky2/examples/bench_recursion.rs +++ b/plonky2/examples/bench_recursion.rs @@ -5,27 +5,26 @@ #![allow(incomplete_features)] #![feature(generic_const_exprs)] -use core::{num::ParseIntError, ops::RangeInclusive, str::FromStr}; +use core::num::ParseIntError; +use core::ops::RangeInclusive; +use core::str::FromStr; use anyhow::{anyhow, Context as _, Result}; use log::{info, Level, LevelFilter}; -use plonky2::{ - gates::noop::NoopGate, - hash::hash_types::RichField, - iop::witness::{PartialWitness, Witness}, - plonk::{ - circuit_builder::CircuitBuilder, - circuit_data::{ - CircuitConfig, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, - }, - config::{AlgebraicHasher, GenericConfig, Hasher, PoseidonGoldilocksConfig}, - proof::{CompressedProofWithPublicInputs, ProofWithPublicInputs}, - prover::prove, - }, - util::timing::TimingTree, +use plonky2::gates::noop::NoopGate; +use plonky2::hash::hash_types::RichField; +use plonky2::iop::witness::{PartialWitness, Witness}; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use plonky2::plonk::circuit_data::{ + CircuitConfig, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher, PoseidonGoldilocksConfig}; +use plonky2::plonk::proof::{CompressedProofWithPublicInputs, ProofWithPublicInputs}; +use plonky2::plonk::prover::prove; +use plonky2::util::timing::TimingTree; use plonky2_field::extension::Extendable; -use rand::{rngs::OsRng, RngCore, SeedableRng}; +use rand::rngs::OsRng; +use rand::{RngCore, SeedableRng}; use rand_chacha::ChaCha8Rng; use structopt::StructOpt; diff --git a/plonky2/src/fri/oracle.rs b/plonky2/src/fri/oracle.rs index 75f8847a..10a93a18 100644 --- a/plonky2/src/fri/oracle.rs +++ b/plonky2/src/fri/oracle.rs @@ -14,12 +14,11 @@ use crate::fri::FriParams; use crate::hash::hash_types::RichField; use crate::hash::merkle_tree::MerkleTree; use crate::iop::challenger::Challenger; -use crate::plonk::config::{GenericConfig, Hasher}; +use crate::plonk::config::GenericConfig; use crate::timed; use crate::util::reducing::ReducingFactor; -use crate::util::reverse_bits; use crate::util::timing::TimingTree; -use crate::util::transpose; +use crate::util::{reverse_bits, transpose}; /// Four (~64 bit) field elements gives ~128 bit security. pub const SALT_SIZE: usize = 4; @@ -45,10 +44,7 @@ impl, C: GenericConfig, const D: usize> cap_height: usize, timing: &mut TimingTree, fft_root_table: Option<&FftRootTable>, - ) -> Self - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> Self { let coeffs = timed!( timing, "IFFT", @@ -73,10 +69,7 @@ impl, C: GenericConfig, const D: usize> cap_height: usize, timing: &mut TimingTree, fft_root_table: Option<&FftRootTable>, - ) -> Self - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> Self { let degree = polynomials[0].len(); let lde_values = timed!( timing, @@ -169,10 +162,7 @@ impl, C: GenericConfig, const D: usize> challenger: &mut Challenger, fri_params: &FriParams, timing: &mut TimingTree, - ) -> FriProof - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> FriProof { assert!(D > 1, "Not implemented for D=1."); let alpha = challenger.get_extension_challenge::(); let mut alpha = ReducingFactor::new(alpha); diff --git a/plonky2/src/fri/proof.rs b/plonky2/src/fri/proof.rs index f7945b28..6a8adcf5 100644 --- a/plonky2/src/fri/proof.rs +++ b/plonky2/src/fri/proof.rs @@ -7,8 +7,7 @@ use serde::{Deserialize, Serialize}; use crate::fri::FriParams; use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; -use crate::hash::hash_types::MerkleCapTarget; -use crate::hash::hash_types::RichField; +use crate::hash::hash_types::{MerkleCapTarget, RichField}; use crate::hash::merkle_proofs::{MerkleProof, MerkleProofTarget}; use crate::hash::merkle_tree::MerkleCap; use crate::hash::path_compression::{compress_merkle_proofs, decompress_merkle_proofs}; @@ -245,10 +244,7 @@ impl, H: Hasher, const D: usize> CompressedFriPr challenges: &ProofChallenges, fri_inferred_elements: FriInferredElements, params: &FriParams, - ) -> FriProof - where - [(); H::HASH_SIZE]:, - { + ) -> FriProof { let CompressedFriProof { commit_phase_merkle_caps, query_round_proofs, diff --git a/plonky2/src/fri/prover.rs b/plonky2/src/fri/prover.rs index 71efe98a..32e41ff3 100644 --- a/plonky2/src/fri/prover.rs +++ b/plonky2/src/fri/prover.rs @@ -24,10 +24,7 @@ pub fn fri_proof, C: GenericConfig, const challenger: &mut Challenger, fri_params: &FriParams, timing: &mut TimingTree, -) -> FriProof -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> FriProof { let n = lde_polynomial_values.len(); assert_eq!(lde_polynomial_coeffs.len(), n); @@ -63,18 +60,17 @@ where } } +type FriCommitedTrees = ( + Vec>::Hasher>>, + PolynomialCoeffs<>::Extension>, +); + fn fri_committed_trees, C: GenericConfig, const D: usize>( mut coeffs: PolynomialCoeffs, mut values: PolynomialValues, challenger: &mut Challenger, fri_params: &FriParams, -) -> ( - Vec>, - PolynomialCoeffs, -) -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> FriCommitedTrees { let mut trees = Vec::new(); let mut shift = F::MULTIPLICATIVE_GROUP_GENERATOR; diff --git a/plonky2/src/fri/recursive_verifier.rs b/plonky2/src/fri/recursive_verifier.rs index d14420c1..c5cb9f07 100644 --- a/plonky2/src/fri/recursive_verifier.rs +++ b/plonky2/src/fri/recursive_verifier.rs @@ -13,8 +13,7 @@ use crate::gates::high_degree_interpolation::HighDegreeInterpolationGate; use crate::gates::interpolation::InterpolationGate; use crate::gates::low_degree_interpolation::LowDegreeInterpolationGate; use crate::gates::random_access::RandomAccessGate; -use crate::hash::hash_types::MerkleCapTarget; -use crate::hash::hash_types::RichField; +use crate::hash::hash_types::{MerkleCapTarget, RichField}; use crate::iop::ext_target::{flatten_target, ExtensionTarget}; use crate::iop::target::{BoolTarget, Target}; use crate::plonk::circuit_builder::CircuitBuilder; diff --git a/plonky2/src/fri/verifier.rs b/plonky2/src/fri/verifier.rs index 02816000..9d01ef6c 100644 --- a/plonky2/src/fri/verifier.rs +++ b/plonky2/src/fri/verifier.rs @@ -57,17 +57,18 @@ pub(crate) fn fri_verify_proof_of_work, const D: us Ok(()) } -pub fn verify_fri_proof, C: GenericConfig, const D: usize>( +pub fn verify_fri_proof< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, +>( instance: &FriInstanceInfo, openings: &FriOpenings, challenges: &FriChallenges, initial_merkle_caps: &[MerkleCap], proof: &FriProof, params: &FriParams, -) -> Result<()> -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> Result<()> { validate_fri_proof_shape::(proof, instance, params)?; // Size of the LDE domain. @@ -109,10 +110,7 @@ fn fri_verify_initial_proof>( x_index: usize, proof: &FriInitialTreeProof, initial_merkle_caps: &[MerkleCap], -) -> Result<()> -where - [(); H::HASH_SIZE]:, -{ +) -> Result<()> { for ((evals, merkle_proof), cap) in proof.evals_proofs.iter().zip(initial_merkle_caps) { verify_merkle_proof_to_cap::(evals.clone(), x_index, cap, merkle_proof)?; } @@ -177,10 +175,7 @@ fn fri_verifier_query_round< n: usize, round_proof: &FriQueryRound, params: &FriParams, -) -> Result<()> -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> Result<()> { fri_verify_initial_proof::( x_index, &round_proof.initial_trees_proof, diff --git a/plonky2/src/gadgets/arithmetic_extension.rs b/plonky2/src/gadgets/arithmetic_extension.rs index e3b31e17..296127b1 100644 --- a/plonky2/src/gadgets/arithmetic_extension.rs +++ b/plonky2/src/gadgets/arithmetic_extension.rs @@ -1,7 +1,6 @@ use core::borrow::Borrow; -use plonky2_field::extension::FieldExtension; -use plonky2_field::extension::{Extendable, OEF}; +use plonky2_field::extension::{Extendable, FieldExtension, OEF}; use plonky2_field::types::{Field, Field64}; use plonky2_util::bits_u64; diff --git a/plonky2/src/gadgets/polynomial.rs b/plonky2/src/gadgets/polynomial.rs index 60bfcca4..d61cf830 100644 --- a/plonky2/src/gadgets/polynomial.rs +++ b/plonky2/src/gadgets/polynomial.rs @@ -14,6 +14,10 @@ impl PolynomialCoeffsExtTarget { self.0.len() } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn eval_scalar>( &self, builder: &mut CircuitBuilder, diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index 4aa550c2..da522b9e 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -1,7 +1,6 @@ use core::ops::Range; -use plonky2_field::extension::Extendable; -use plonky2_field::extension::FieldExtension; +use plonky2_field::extension::{Extendable, FieldExtension}; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; diff --git a/plonky2/src/gates/gate_testing.rs b/plonky2/src/gates/gate_testing.rs index e9c4c237..8492f385 100644 --- a/plonky2/src/gates/gate_testing.rs +++ b/plonky2/src/gates/gate_testing.rs @@ -5,12 +5,11 @@ use plonky2_field::types::Field; use plonky2_util::log2_ceil; use crate::gates::gate::Gate; -use crate::hash::hash_types::HashOut; -use crate::hash::hash_types::RichField; +use crate::hash::hash_types::{HashOut, RichField}; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; -use crate::plonk::config::{GenericConfig, Hasher}; +use crate::plonk::config::GenericConfig; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch}; use crate::plonk::verifier::verify; use crate::util::transpose; @@ -92,10 +91,7 @@ pub fn test_eval_fns< const D: usize, >( gate: G, -) -> Result<()> -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> Result<()> { // Test that `eval_unfiltered` and `eval_unfiltered_base` are coherent. let wires_base = F::rand_vec(gate.num_wires()); let constants_base = F::rand_vec(gate.num_constants()); diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index c158c6a6..97ff538f 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -1,7 +1,6 @@ use core::ops::Range; -use plonky2_field::extension::Extendable; -use plonky2_field::extension::FieldExtension; +use plonky2_field::extension::{Extendable, FieldExtension}; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; diff --git a/plonky2/src/gates/poseidon.rs b/plonky2/src/gates/poseidon.rs index 95678528..0977d7b4 100644 --- a/plonky2/src/gates/poseidon.rs +++ b/plonky2/src/gates/poseidon.rs @@ -23,16 +23,13 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// This also has some extra features to make it suitable for efficiently verifying Merkle proofs. /// It has a flag which can be used to swap the first four inputs with the next four, for ordering /// sibling digests. -#[derive(Debug)] -pub struct PoseidonGate, const D: usize> { - _phantom: PhantomData, -} +#[derive(derivative::Derivative)] +#[derivative(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] +pub struct PoseidonGate, const D: usize>(PhantomData); impl, const D: usize> PoseidonGate { pub fn new() -> Self { - PoseidonGate { - _phantom: PhantomData, - } + Self(PhantomData) } /// The wire index for the `i`th input to the permutation. diff --git a/plonky2/src/gates/poseidon_mds.rs b/plonky2/src/gates/poseidon_mds.rs index f1566e11..d41fdf17 100644 --- a/plonky2/src/gates/poseidon_mds.rs +++ b/plonky2/src/gates/poseidon_mds.rs @@ -2,8 +2,7 @@ use core::marker::PhantomData; use core::ops::Range; use plonky2_field::extension::algebra::ExtensionAlgebra; -use plonky2_field::extension::Extendable; -use plonky2_field::extension::FieldExtension; +use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::types::Field; use crate::gates::gate::Gate; @@ -18,16 +17,14 @@ use crate::iop::witness::{PartitionWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; -#[derive(Debug)] -pub struct PoseidonMdsGate + Poseidon, const D: usize> { - _phantom: PhantomData, -} +/// Poseidon MDS Gate +#[derive(derivative::Derivative)] +#[derivative(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] +pub struct PoseidonMdsGate + Poseidon, const D: usize>(PhantomData); impl + Poseidon, const D: usize> PoseidonMdsGate { pub fn new() -> Self { - PoseidonMdsGate { - _phantom: PhantomData, - } + Self(PhantomData) } pub fn wires_input(i: usize) -> Range { diff --git a/plonky2/src/gates/reducing.rs b/plonky2/src/gates/reducing.rs index bf312b84..c2366558 100644 --- a/plonky2/src/gates/reducing.rs +++ b/plonky2/src/gates/reducing.rs @@ -1,7 +1,6 @@ use core::ops::Range; -use plonky2_field::extension::Extendable; -use plonky2_field::extension::FieldExtension; +use plonky2_field::extension::{Extendable, FieldExtension}; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; diff --git a/plonky2/src/gates/reducing_extension.rs b/plonky2/src/gates/reducing_extension.rs index e7a4fc8f..61377b1b 100644 --- a/plonky2/src/gates/reducing_extension.rs +++ b/plonky2/src/gates/reducing_extension.rs @@ -1,7 +1,6 @@ use core::ops::Range; -use plonky2_field::extension::Extendable; -use plonky2_field::extension::FieldExtension; +use plonky2_field::extension::{Extendable, FieldExtension}; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; diff --git a/plonky2/src/gates/selectors.rs b/plonky2/src/gates/selectors.rs index b2b52b77..d9be7024 100644 --- a/plonky2/src/gates/selectors.rs +++ b/plonky2/src/gates/selectors.rs @@ -28,7 +28,7 @@ impl SelectorsInfo { /// `|G| + max_{g in G} g.degree() <= max_degree`. These groups are constructed greedily from /// the list of gates sorted by degree. /// We build a selector polynomial `S_i` for each group `G_i`, with -/// S_i[j] = +/// S_i\[j\] = /// if j-th row gate=g_k in G_i /// k /// else diff --git a/plonky2/src/hash/hashing.rs b/plonky2/src/hash/hashing.rs index c903201b..e4ba2719 100644 --- a/plonky2/src/hash/hashing.rs +++ b/plonky2/src/hash/hashing.rs @@ -2,8 +2,7 @@ use plonky2_field::extension::Extendable; -use crate::hash::hash_types::RichField; -use crate::hash::hash_types::{HashOut, HashOutTarget}; +use crate::hash::hash_types::{HashOut, HashOutTarget, RichField}; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::config::AlgebraicHasher; diff --git a/plonky2/src/hash/merkle_proofs.rs b/plonky2/src/hash/merkle_proofs.rs index f54793d9..04a7787f 100644 --- a/plonky2/src/hash/merkle_proofs.rs +++ b/plonky2/src/hash/merkle_proofs.rs @@ -2,8 +2,7 @@ use anyhow::{ensure, Result}; use plonky2_field::extension::Extendable; use serde::{Deserialize, Serialize}; -use crate::hash::hash_types::RichField; -use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget}; +use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::hashing::SPONGE_WIDTH; use crate::hash::merkle_tree::MerkleCap; use crate::iop::target::{BoolTarget, Target}; @@ -21,6 +20,10 @@ impl> MerkleProof { pub fn len(&self) -> usize { self.siblings.len() } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } } #[derive(Clone, Debug)] @@ -36,10 +39,7 @@ pub fn verify_merkle_proof>( leaf_index: usize, merkle_root: H::Hash, proof: &MerkleProof, -) -> Result<()> -where - [(); H::HASH_SIZE]:, -{ +) -> Result<()> { let merkle_cap = MerkleCap(vec![merkle_root]); verify_merkle_proof_to_cap(leaf_data, leaf_index, &merkle_cap, proof) } @@ -51,10 +51,7 @@ pub fn verify_merkle_proof_to_cap>( leaf_index: usize, merkle_cap: &MerkleCap, proof: &MerkleProof, -) -> Result<()> -where - [(); H::HASH_SIZE]:, -{ +) -> Result<()> { let mut index = leaf_index; let mut current_digest = H::hash_or_noop(&leaf_data); for &sibling_digest in proof.siblings.iter() { diff --git a/plonky2/src/hash/merkle_tree.rs b/plonky2/src/hash/merkle_tree.rs index 19d49f13..c0799d98 100644 --- a/plonky2/src/hash/merkle_tree.rs +++ b/plonky2/src/hash/merkle_tree.rs @@ -7,8 +7,7 @@ use serde::{Deserialize, Serialize}; use crate::hash::hash_types::RichField; use crate::hash::merkle_proofs::MerkleProof; -use crate::plonk::config::GenericHashOut; -use crate::plonk::config::Hasher; +use crate::plonk::config::{GenericHashOut, Hasher}; /// The Merkle cap of height `h` of a Merkle tree is the `h`-th layer (from the root) of the tree. /// It can be used in place of the root to verify Merkle paths, which are `h` elements shorter. @@ -21,6 +20,10 @@ impl> MerkleCap { self.0.len() } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn height(&self) -> usize { log2_strict(self.len()) } @@ -64,10 +67,7 @@ fn capacity_up_to_mut(v: &mut Vec, len: usize) -> &mut [MaybeUninit] { fn fill_subtree>( digests_buf: &mut [MaybeUninit], leaves: &[Vec], -) -> H::Hash -where - [(); H::HASH_SIZE]:, -{ +) -> H::Hash { assert_eq!(leaves.len(), digests_buf.len() / 2 + 1); if digests_buf.is_empty() { H::hash_or_noop(&leaves[0]) @@ -98,9 +98,7 @@ fn fill_digests_buf>( cap_buf: &mut [MaybeUninit], leaves: &[Vec], cap_height: usize, -) where - [(); H::HASH_SIZE]:, -{ +) { // Special case of a tree that's all cap. The usual case will panic because we'll try to split // an empty slice into chunks of `0`. (We would not need this if there was a way to split into // `blah` chunks as opposed to chunks _of_ `blah`.) @@ -132,10 +130,7 @@ fn fill_digests_buf>( } impl> MerkleTree { - pub fn new(leaves: Vec>, cap_height: usize) -> Self - where - [(); H::HASH_SIZE]:, - { + pub fn new(leaves: Vec>, cap_height: usize) -> Self { let log2_leaves_len = log2_strict(leaves.len()); assert!( cap_height <= log2_leaves_len, @@ -222,13 +217,14 @@ mod tests { (0..n).map(|_| F::rand_vec(k)).collect() } - fn verify_all_leaves, C: GenericConfig, const D: usize>( + fn verify_all_leaves< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, + >( leaves: Vec>, cap_height: usize, - ) -> Result<()> - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> Result<()> { let tree = MerkleTree::::new(leaves.clone(), cap_height); for (i, leaf) in leaves.into_iter().enumerate() { let proof = tree.prove(i); diff --git a/plonky2/src/hash/path_compression.rs b/plonky2/src/hash/path_compression.rs index 2685f723..c57b5e03 100644 --- a/plonky2/src/hash/path_compression.rs +++ b/plonky2/src/hash/path_compression.rs @@ -57,10 +57,7 @@ pub(crate) fn decompress_merkle_proofs>( compressed_proofs: &[MerkleProof], height: usize, cap_height: usize, -) -> Vec> -where - [(); H::HASH_SIZE]:, -{ +) -> Vec> { let num_leaves = 1 << height; let compressed_proofs = compressed_proofs.to_vec(); let mut decompressed_proofs = Vec::with_capacity(compressed_proofs.len()); diff --git a/plonky2/src/hash/poseidon.rs b/plonky2/src/hash/poseidon.rs index 54c2379f..248ab32d 100644 --- a/plonky2/src/hash/poseidon.rs +++ b/plonky2/src/hash/poseidon.rs @@ -1,5 +1,5 @@ //! Implementation of the Poseidon hash function, as described in -//! https://eprint.iacr.org/2019/458.pdf +//! use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::types::{Field, PrimeField64}; diff --git a/plonky2/src/hash/poseidon_goldilocks.rs b/plonky2/src/hash/poseidon_goldilocks.rs index 658b397e..001c5900 100644 --- a/plonky2/src/hash/poseidon_goldilocks.rs +++ b/plonky2/src/hash/poseidon_goldilocks.rs @@ -272,8 +272,7 @@ impl Poseidon for GoldilocksField { #[cfg(test)] mod tests { use plonky2_field::goldilocks_field::GoldilocksField as F; - use plonky2_field::types::Field; - use plonky2_field::types::PrimeField64; + use plonky2_field::types::{Field, PrimeField64}; use crate::hash::poseidon::test_helpers::{check_consistency, check_test_vectors}; diff --git a/plonky2/src/iop/challenger.rs b/plonky2/src/iop/challenger.rs index 34ed4f67..06b7d4ba 100644 --- a/plonky2/src/iop/challenger.rs +++ b/plonky2/src/iop/challenger.rs @@ -3,8 +3,7 @@ use core::marker::PhantomData; use plonky2_field::extension::{Extendable, FieldExtension}; -use crate::hash::hash_types::RichField; -use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget}; +use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::hashing::{PlonkyPermutation, SPONGE_RATE, SPONGE_WIDTH}; use crate::hash::merkle_tree::MerkleCap; use crate::iop::ext_target::ExtensionTarget; @@ -170,6 +169,7 @@ pub struct RecursiveChallenger, H: AlgebraicHasher< sponge_state: [Target; SPONGE_WIDTH], input_buffer: Vec, output_buffer: Vec, + __: PhantomData<(F, H)>, } impl, H: AlgebraicHasher, const D: usize> @@ -177,18 +177,20 @@ impl, H: AlgebraicHasher, const D: usize> { pub fn new(builder: &mut CircuitBuilder) -> Self { let zero = builder.zero(); - RecursiveChallenger { + Self { sponge_state: [zero; SPONGE_WIDTH], input_buffer: Vec::new(), output_buffer: Vec::new(), + __: PhantomData, } } pub fn from_state(sponge_state: [Target; SPONGE_WIDTH]) -> Self { - RecursiveChallenger { + Self { sponge_state, input_buffer: vec![], output_buffer: vec![], + __: PhantomData, } } diff --git a/plonky2/src/iop/witness.rs b/plonky2/src/iop/witness.rs index 9a3cb662..99d6313d 100644 --- a/plonky2/src/iop/witness.rs +++ b/plonky2/src/iop/witness.rs @@ -6,9 +6,7 @@ use plonky2_field::types::Field; use crate::fri::structure::{FriOpenings, FriOpeningsTarget}; use crate::fri::witness_util::set_fri_proof_target; -use crate::hash::hash_types::HashOutTarget; -use crate::hash::hash_types::RichField; -use crate::hash::hash_types::{HashOut, MerkleCapTarget}; +use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_tree::MerkleCap; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::{BoolTarget, Target}; @@ -250,14 +248,15 @@ impl MatrixWitness { } } -#[derive(Clone, Debug)] +#[derive(derivative::Derivative)] +#[derivative(Clone, Debug, Default(bound = ""))] pub struct PartialWitness { pub(crate) target_values: HashMap, } impl PartialWitness { pub fn new() -> Self { - PartialWitness { + Self { target_values: HashMap::new(), } } diff --git a/plonky2/src/lib.rs b/plonky2/src/lib.rs index 8a517a11..db7a213b 100644 --- a/plonky2/src/lib.rs +++ b/plonky2/src/lib.rs @@ -1,14 +1,5 @@ -#![allow(incomplete_features)] -#![allow(const_evaluatable_unchecked)] -#![allow(clippy::new_without_default)] #![allow(clippy::too_many_arguments)] -#![allow(clippy::type_complexity)] -#![allow(clippy::len_without_is_empty)] #![allow(clippy::needless_range_loop)] -#![allow(clippy::return_self_not_must_use)] -#![feature(generic_const_exprs)] -#![feature(specialization)] -#![feature(stdsimd)] pub use plonky2_field as field; diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 3b48f9cf..f071d69c 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -686,10 +686,7 @@ impl, const D: usize> CircuitBuilder { } /// Builds a "full circuit", with both prover and verifier data. - pub fn build>(mut self) -> CircuitData - where - [(); C::Hasher::HASH_SIZE]:, - { + pub fn build>(mut self) -> CircuitData { let mut timing = TimingTree::new("preprocess", Level::Trace); let start = Instant::now(); let rate_bits = self.config.fri_config.rate_bits; @@ -887,20 +884,14 @@ impl, const D: usize> CircuitBuilder { } /// Builds a "prover circuit", with data needed to generate proofs but not verify them. - pub fn build_prover>(self) -> ProverCircuitData - where - [(); C::Hasher::HASH_SIZE]:, - { + pub fn build_prover>(self) -> ProverCircuitData { // TODO: Can skip parts of this. let circuit_data = self.build(); circuit_data.prover_data() } /// Builds a "verifier circuit", with data needed to verify proofs but not generate them. - pub fn build_verifier>(self) -> VerifierCircuitData - where - [(); C::Hasher::HASH_SIZE]:, - { + pub fn build_verifier>(self) -> VerifierCircuitData { // TODO: Can skip parts of this. let circuit_data = self.build(); circuit_data.verifier_data() diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index b1dea756..7a0af7b8 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -112,10 +112,7 @@ pub struct CircuitData, C: GenericConfig, impl, C: GenericConfig, const D: usize> CircuitData { - pub fn prove(&self, inputs: PartialWitness) -> Result> - where - [(); C::Hasher::HASH_SIZE]:, - { + pub fn prove(&self, inputs: PartialWitness) -> Result> { prove( &self.prover_only, &self.common, @@ -124,20 +121,14 @@ impl, C: GenericConfig, const D: usize> ) } - pub fn verify(&self, proof_with_pis: ProofWithPublicInputs) -> Result<()> - where - [(); C::Hasher::HASH_SIZE]:, - { + pub fn verify(&self, proof_with_pis: ProofWithPublicInputs) -> Result<()> { verify(proof_with_pis, &self.verifier_only, &self.common) } pub fn verify_compressed( &self, compressed_proof_with_pis: CompressedProofWithPublicInputs, - ) -> Result<()> - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> Result<()> { compressed_proof_with_pis.verify(&self.verifier_only, &self.common) } @@ -151,10 +142,7 @@ impl, C: GenericConfig, const D: usize> pub fn decompress( &self, proof: CompressedProofWithPublicInputs, - ) -> Result> - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> Result> { proof.decompress(&self.verifier_only.circuit_digest, &self.common) } @@ -202,10 +190,7 @@ pub struct ProverCircuitData< impl, C: GenericConfig, const D: usize> ProverCircuitData { - pub fn prove(&self, inputs: PartialWitness) -> Result> - where - [(); C::Hasher::HASH_SIZE]:, - { + pub fn prove(&self, inputs: PartialWitness) -> Result> { prove( &self.prover_only, &self.common, @@ -229,20 +214,14 @@ pub struct VerifierCircuitData< impl, C: GenericConfig, const D: usize> VerifierCircuitData { - pub fn verify(&self, proof_with_pis: ProofWithPublicInputs) -> Result<()> - where - [(); C::Hasher::HASH_SIZE]:, - { + pub fn verify(&self, proof_with_pis: ProofWithPublicInputs) -> Result<()> { verify(proof_with_pis, &self.verifier_only, &self.common) } pub fn verify_compressed( &self, compressed_proof_with_pis: CompressedProofWithPublicInputs, - ) -> Result<()> - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> Result<()> { compressed_proof_with_pis.verify(&self.verifier_only, &self.common) } } diff --git a/plonky2/src/plonk/config.rs b/plonky2/src/plonk/config.rs index 20de09fb..87395348 100644 --- a/plonky2/src/plonk/config.rs +++ b/plonky2/src/plonk/config.rs @@ -3,10 +3,10 @@ use core::fmt::Debug; use plonky2_field::extension::quadratic::QuadraticExtension; use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::goldilocks_field::GoldilocksField; -use serde::{de::DeserializeOwned, Serialize}; +use serde::de::DeserializeOwned; +use serde::Serialize; -use crate::hash::hash_types::HashOut; -use crate::hash::hash_types::RichField; +use crate::hash::hash_types::{HashOut, RichField}; use crate::hash::hashing::{PlonkyPermutation, SPONGE_WIDTH}; use crate::hash::keccak::KeccakHash; use crate::hash::poseidon::PoseidonHash; @@ -26,6 +26,8 @@ pub trait GenericHashOut: pub trait Hasher: Sized + Clone + Debug + Eq + PartialEq { /// Size of `Hash` in bytes. const HASH_SIZE: usize; + + /// Hash Output type Hash: GenericHashOut; /// Permutation used in the sponge construction. @@ -48,12 +50,9 @@ pub trait Hasher: Sized + Clone + Debug + Eq + PartialEq { /// Hash the slice if necessary to reduce its length to ~256 bits. If it already fits, this is a /// no-op. - fn hash_or_noop(inputs: &[F]) -> Self::Hash - where - [(); Self::HASH_SIZE]:, - { + fn hash_or_noop(inputs: &[F]) -> Self::Hash { if inputs.len() <= 4 { - let mut inputs_bytes = [0u8; Self::HASH_SIZE]; + let mut inputs_bytes = vec![0u8; Self::HASH_SIZE]; for i in 0..inputs.len() { inputs_bytes[i * 8..(i + 1) * 8] .copy_from_slice(&inputs[i].to_canonical_u64().to_le_bytes()); diff --git a/plonky2/src/plonk/permutation_argument.rs b/plonky2/src/plonk/permutation_argument.rs index 3658a12d..44d492d9 100644 --- a/plonky2/src/plonk/permutation_argument.rs +++ b/plonky2/src/plonk/permutation_argument.rs @@ -7,7 +7,7 @@ use plonky2_field::types::Field; use crate::iop::target::Target; use crate::iop::wire::Wire; -/// Disjoint Set Forest data-structure following https://en.wikipedia.org/wiki/Disjoint-set_data_structure. +/// Disjoint Set Forest data-structure following . pub struct Forest { /// A map of parent pointers, stored as indices. pub(crate) parents: Vec, @@ -44,7 +44,7 @@ impl Forest { self.parents.push(index); } - /// Path compression method, see https://en.wikipedia.org/wiki/Disjoint-set_data_structure#Finding_set_representatives. + /// Path compression method, see . pub fn find(&mut self, mut x_index: usize) -> usize { // Note: We avoid recursion here since the chains can be long, causing stack overflows. diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index 1a7a26db..d408d900 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -139,10 +139,7 @@ impl, C: GenericConfig, const D: usize> challenges: &ProofChallenges, fri_inferred_elements: FriInferredElements, params: &FriParams, - ) -> Proof - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> Proof { let CompressedProof { wires_cap, plonk_zs_partial_products_cap, @@ -179,10 +176,7 @@ impl, C: GenericConfig, const D: usize> self, circuit_digest: &<>::Hasher as Hasher>::Hash, common_data: &CommonCircuitData, - ) -> anyhow::Result> - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> anyhow::Result> { let challenges = self.get_challenges(self.get_public_inputs_hash(), circuit_digest, common_data)?; let fri_inferred_elements = self.get_inferred_elements(&challenges, common_data); @@ -199,10 +193,7 @@ impl, C: GenericConfig, const D: usize> self, verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, - ) -> anyhow::Result<()> - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> anyhow::Result<()> { ensure!( self.public_inputs.len() == common_data.num_public_inputs, "Number of public inputs doesn't match circuit data." diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index c762b5ba..c10febde 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -1,7 +1,6 @@ use core::mem::swap; -use anyhow::ensure; -use anyhow::Result; +use anyhow::{ensure, Result}; use maybe_rayon::*; use plonky2_field::extension::Extendable; use plonky2_field::polynomial::{PolynomialCoeffs, PolynomialValues}; @@ -17,8 +16,7 @@ use crate::iop::witness::{MatrixWitness, PartialWitness, Witness}; use crate::plonk::circuit_data::{CommonCircuitData, ProverOnlyCircuitData}; use crate::plonk::config::{GenericConfig, Hasher}; use crate::plonk::plonk_common::PlonkOracle; -use crate::plonk::proof::OpeningSet; -use crate::plonk::proof::{Proof, ProofWithPublicInputs}; +use crate::plonk::proof::{OpeningSet, Proof, ProofWithPublicInputs}; use crate::plonk::vanishing_poly::eval_vanishing_poly_base_batch; use crate::plonk::vars::EvaluationVarsBaseBatch; use crate::timed; @@ -31,10 +29,7 @@ pub fn prove, C: GenericConfig, const D: common_data: &CommonCircuitData, inputs: PartialWitness, timing: &mut TimingTree, -) -> Result> -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> Result> { let config = &common_data.config; let num_challenges = config.num_challenges; let quotient_degree = common_data.quotient_degree(); diff --git a/plonky2/src/plonk/validate_shape.rs b/plonky2/src/plonk/validate_shape.rs index 1e6708cc..81f43332 100644 --- a/plonky2/src/plonk/validate_shape.rs +++ b/plonky2/src/plonk/validate_shape.rs @@ -3,7 +3,7 @@ use plonky2_field::extension::Extendable; use crate::hash::hash_types::RichField; use crate::plonk::circuit_data::CommonCircuitData; -use crate::plonk::config::{GenericConfig, Hasher}; +use crate::plonk::config::GenericConfig; use crate::plonk::proof::{OpeningSet, Proof, ProofWithPublicInputs}; pub(crate) fn validate_proof_with_pis_shape( @@ -13,20 +13,16 @@ pub(crate) fn validate_proof_with_pis_shape( where F: RichField + Extendable, C: GenericConfig, - [(); C::Hasher::HASH_SIZE]:, { let ProofWithPublicInputs { proof, public_inputs, } = proof_with_pis; - validate_proof_shape(proof, common_data)?; - ensure!( public_inputs.len() == common_data.num_public_inputs, "Number of public inputs doesn't match circuit data." ); - Ok(()) } @@ -37,7 +33,6 @@ fn validate_proof_shape( where F: RichField + Extendable, C: GenericConfig, - [(); C::Hasher::HASH_SIZE]:, { let config = &common_data.config; let Proof { @@ -49,7 +44,6 @@ where // validate_fri_proof_shape), so we ignore it here. opening_proof: _, } = proof; - let OpeningSet { constants, plonk_sigmas, @@ -59,12 +53,10 @@ where partial_products, quotient_polys, } = openings; - let cap_height = common_data.fri_params.config.cap_height; ensure!(wires_cap.height() == cap_height); ensure!(plonk_zs_partial_products_cap.height() == cap_height); ensure!(quotient_polys_cap.height() == cap_height); - ensure!(constants.len() == common_data.num_constants); ensure!(plonk_sigmas.len() == config.num_routed_wires); ensure!(wires.len() == config.num_wires); @@ -72,6 +64,5 @@ where ensure!(plonk_zs_next.len() == config.num_challenges); ensure!(partial_products.len() == config.num_challenges * common_data.num_partial_products); ensure!(quotient_polys.len() == common_data.num_quotient_polys()); - Ok(()) } diff --git a/plonky2/src/plonk/vars.rs b/plonky2/src/plonk/vars.rs index 5be573fc..722ebdf1 100644 --- a/plonky2/src/plonk/vars.rs +++ b/plonky2/src/plonk/vars.rs @@ -85,6 +85,10 @@ impl<'a, F: Field> EvaluationVarsBaseBatch<'a, F> { self.batch_size } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn view(&self, index: usize) -> EvaluationVarsBase<'a, F> { // We cannot implement `Index` as `EvaluationVarsBase` is a struct, not a reference. assert!(index < self.len()); diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index 52681558..ba477264 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -16,10 +16,7 @@ pub(crate) fn verify, C: GenericConfig, c proof_with_pis: ProofWithPublicInputs, verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, -) -> Result<()> -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> Result<()> { validate_proof_with_pis_shape(&proof_with_pis, common_data)?; let public_inputs_hash = proof_with_pis.get_public_inputs_hash(); @@ -48,10 +45,7 @@ pub(crate) fn verify_with_challenges< challenges: ProofChallenges, verifier_data: &VerifierOnlyCircuitData, common_data: &CommonCircuitData, -) -> Result<()> -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> Result<()> { let local_constants = &proof.openings.constants; let local_wires = &proof.openings.wires; let vars = EvaluationVars { diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index 6bafc623..c78078e8 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -17,7 +17,7 @@ use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{ CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; -use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher}; +use crate::plonk::config::{AlgebraicHasher, GenericConfig}; use crate::plonk::proof::{ OpeningSetTarget, ProofTarget, ProofWithPublicInputs, ProofWithPublicInputsTarget, }; @@ -33,10 +33,7 @@ pub(crate) fn dummy_proof< ) -> Result<( ProofWithPublicInputs, VerifierOnlyCircuitData, -)> -where - [(); C::Hasher::HASH_SIZE]:, -{ +)> { let config = common_data.config.clone(); let mut pw = PartialWitness::new(); diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index f2ad7eb9..9df74c56 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -12,7 +12,6 @@ use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{ CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; -use crate::plonk::config::Hasher; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; use crate::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; use crate::recursion::conditional_recursive_verifier::dummy_proof; @@ -100,7 +99,6 @@ impl, const D: usize> CircuitBuilder { ) -> Result> where C::Hasher: AlgebraicHasher, - [(); C::Hasher::HASH_SIZE]:, { if self.verifier_data_public_input.is_none() { self.add_verifier_data_public_input(); @@ -179,7 +177,6 @@ pub fn set_cyclic_recursion_data_target< ) -> Result<()> where C::Hasher: AlgebraicHasher, - [(); C::Hasher::HASH_SIZE]:, { if let Some(proof) = cyclic_recursion_data.proof { pw.set_bool_target(cyclic_recursion_data_target.base_case, false); @@ -280,7 +277,6 @@ mod tests { >() -> CommonCircuitData where C::Hasher: AlgebraicHasher, - [(); C::Hasher::HASH_SIZE]:, { let config = CircuitConfig::standard_recursion_config(); let builder = CircuitBuilder::::new(config); diff --git a/plonky2/src/recursion/recursive_verifier.rs b/plonky2/src/recursion/recursive_verifier.rs index 8dbab974..5ddfef01 100644 --- a/plonky2/src/recursion/recursive_verifier.rs +++ b/plonky2/src/recursion/recursive_verifier.rs @@ -323,18 +323,17 @@ mod tests { Ok(()) } + type Proof = ( + ProofWithPublicInputs, + VerifierOnlyCircuitData, + CommonCircuitData, + ); + /// Creates a dummy proof which should have roughly `num_dummy_gates` gates. fn dummy_proof, C: GenericConfig, const D: usize>( config: &CircuitConfig, num_dummy_gates: u64, - ) -> Result<( - ProofWithPublicInputs, - VerifierOnlyCircuitData, - CommonCircuitData, - )> - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> Result> { let mut builder = CircuitBuilder::::new(config.clone()); for _ in 0..num_dummy_gates { builder.add_gate(NoopGate, vec![]); @@ -361,14 +360,9 @@ mod tests { min_degree_bits: Option, print_gate_counts: bool, print_timing: bool, - ) -> Result<( - ProofWithPublicInputs, - VerifierOnlyCircuitData, - CommonCircuitData, - )> + ) -> Result> where InnerC::Hasher: AlgebraicHasher, - [(); C::Hasher::HASH_SIZE]:, { let mut builder = CircuitBuilder::::new(config.clone()); let mut pw = PartialWitness::new(); @@ -423,10 +417,7 @@ mod tests { proof: &ProofWithPublicInputs, vd: &VerifierOnlyCircuitData, cd: &CommonCircuitData, - ) -> Result<()> - where - [(); C::Hasher::HASH_SIZE]:, - { + ) -> Result<()> { let proof_bytes = proof.to_bytes()?; info!("Proof length: {} bytes", proof_bytes.len()); let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, cd)?; diff --git a/plonky2/src/util/reducing.rs b/plonky2/src/util/reducing.rs index 89b4a4ad..9702e196 100644 --- a/plonky2/src/util/reducing.rs +++ b/plonky2/src/util/reducing.rs @@ -19,7 +19,7 @@ use crate::plonk::circuit_builder::CircuitBuilder; /// scale the second one by `a^(r-1-k)`, and add them up. /// This struct abstract away these operations by implementing Horner's method and keeping track /// of the number of multiplications by `a` to compute the scaling factor. -/// See https://github.com/mir-protocol/plonky2/pull/69 for more details and discussions. +/// See for more details and discussions. #[derive(Debug, Clone)] pub struct ReducingFactor { base: F, diff --git a/plonky2/src/util/serialization.rs b/plonky2/src/util/serialization.rs index 076e42f4..de8961ae 100644 --- a/plonky2/src/util/serialization.rs +++ b/plonky2/src/util/serialization.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use std::io::Cursor; -use std::io::{Read, Result, Write}; +use std::io::{Cursor, Read, Result, Write}; use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::polynomial::PolynomialCoeffs; @@ -32,6 +31,10 @@ impl Buffer { self.0.get_ref().len() } + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn bytes(self) -> Vec { self.0.into_inner() } @@ -60,9 +63,7 @@ impl Buffer { fn read_field(&mut self) -> Result { let mut buf = [0; std::mem::size_of::()]; self.0.read_exact(&mut buf)?; - Ok(F::from_canonical_u64(u64::from_le_bytes( - buf.try_into().unwrap(), - ))) + Ok(F::from_canonical_u64(u64::from_le_bytes(buf))) } fn write_field_ext, const D: usize>( diff --git a/plonky2/src/util/strided_view.rs b/plonky2/src/util/strided_view.rs index 851914bf..43fd4894 100644 --- a/plonky2/src/util/strided_view.rs +++ b/plonky2/src/util/strided_view.rs @@ -123,6 +123,11 @@ impl<'a, P: PackedField> PackedStridedView<'a, P> { pub fn len(&self) -> usize { self.length } + + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } } impl<'a, P: PackedField> Index for PackedStridedView<'a, P> { diff --git a/rustfmt.toml b/rustfmt.toml index 65106950..4d029471 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,2 +1,3 @@ -unstable_features = true group_imports = "StdExternalCrate" +imports_granularity = "Module" +unstable_features = true diff --git a/starky/src/prover.rs b/starky/src/prover.rs index 0d291cf3..c9191f1d 100644 --- a/starky/src/prover.rs +++ b/starky/src/prover.rs @@ -20,9 +20,9 @@ use plonky2_util::{log2_ceil, log2_strict}; use crate::config::StarkConfig; use crate::constraint_consumer::ConstraintConsumer; -use crate::permutation::PermutationCheckVars; use crate::permutation::{ compute_permutation_z_polys, get_n_permutation_challenge_sets, PermutationChallengeSet, + PermutationCheckVars, }; use crate::proof::{StarkOpeningSet, StarkProof, StarkProofWithPublicInputs}; use crate::stark::Stark; diff --git a/starky/src/stark.rs b/starky/src/stark.rs index 8ebca87c..668fc4a2 100644 --- a/starky/src/stark.rs +++ b/starky/src/stark.rs @@ -12,8 +12,7 @@ use plonky2_util::ceil_div_usize; use crate::config::StarkConfig; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::permutation::PermutationPair; -use crate::vars::StarkEvaluationTargets; -use crate::vars::StarkEvaluationVars; +use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars}; /// Represents a STARK system. pub trait Stark, const D: usize>: Sync { diff --git a/starky/src/stark_testing.rs b/starky/src/stark_testing.rs index b13b90df..2cec5298 100644 --- a/starky/src/stark_testing.rs +++ b/starky/src/stark_testing.rs @@ -6,8 +6,7 @@ use plonky2::hash::hash_types::RichField; use plonky2::iop::witness::{PartialWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; -use plonky2::plonk::config::GenericConfig; -use plonky2::plonk::config::Hasher; +use plonky2::plonk::config::{GenericConfig, Hasher}; use plonky2::util::transpose; use plonky2_util::{log2_ceil, log2_strict}; diff --git a/system_zero/src/alu/mod.rs b/system_zero/src/alu/mod.rs index 33f5e902..a02a51e2 100644 --- a/system_zero/src/alu/mod.rs +++ b/system_zero/src/alu/mod.rs @@ -4,8 +4,7 @@ use plonky2::field::types::{Field, PrimeField64}; use plonky2::hash::hash_types::RichField; use plonky2::plonk::circuit_builder::CircuitBuilder; use starky::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use starky::vars::StarkEvaluationTargets; -use starky::vars::StarkEvaluationVars; +use starky::vars::{StarkEvaluationTargets, StarkEvaluationVars}; use crate::alu::addition::{eval_addition, eval_addition_circuit, generate_addition}; use crate::alu::bitops::{eval_bitop, eval_bitop_circuit, generate_bitop}; diff --git a/system_zero/src/core_registers.rs b/system_zero/src/core_registers.rs index 3cf7843d..210a9971 100644 --- a/system_zero/src/core_registers.rs +++ b/system_zero/src/core_registers.rs @@ -4,8 +4,7 @@ use plonky2::field::types::{Field, PrimeField64}; use plonky2::hash::hash_types::RichField; use plonky2::plonk::circuit_builder::CircuitBuilder; use starky::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use starky::vars::StarkEvaluationTargets; -use starky::vars::StarkEvaluationVars; +use starky::vars::{StarkEvaluationTargets, StarkEvaluationVars}; use crate::public_input_layout::NUM_PUBLIC_INPUTS; use crate::registers::core::*; diff --git a/system_zero/src/lookup.rs b/system_zero/src/lookup.rs index c4036424..d1d16223 100644 --- a/system_zero/src/lookup.rs +++ b/system_zero/src/lookup.rs @@ -13,8 +13,7 @@ use plonky2::field::types::{Field, PrimeField64}; use plonky2::hash::hash_types::RichField; use plonky2::plonk::circuit_builder::CircuitBuilder; use starky::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use starky::vars::StarkEvaluationTargets; -use starky::vars::StarkEvaluationVars; +use starky::vars::{StarkEvaluationTargets, StarkEvaluationVars}; use crate::public_input_layout::NUM_PUBLIC_INPUTS; use crate::registers::lookup::*; diff --git a/system_zero/src/permutation_unit.rs b/system_zero/src/permutation_unit.rs index c94e1677..809955ca 100644 --- a/system_zero/src/permutation_unit.rs +++ b/system_zero/src/permutation_unit.rs @@ -5,8 +5,7 @@ use plonky2::hash::hashing::SPONGE_WIDTH; use plonky2::hash::poseidon::{Poseidon, HALF_N_FULL_ROUNDS, N_PARTIAL_ROUNDS}; use plonky2::plonk::circuit_builder::CircuitBuilder; use starky::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use starky::vars::StarkEvaluationTargets; -use starky::vars::StarkEvaluationVars; +use starky::vars::{StarkEvaluationTargets, StarkEvaluationVars}; use crate::public_input_layout::NUM_PUBLIC_INPUTS; use crate::registers::permutation::*; diff --git a/system_zero/src/system_zero.rs b/system_zero/src/system_zero.rs index 19c2df8c..00673c7e 100644 --- a/system_zero/src/system_zero.rs +++ b/system_zero/src/system_zero.rs @@ -11,8 +11,7 @@ use plonky2::util::transpose; use starky::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use starky::permutation::PermutationPair; use starky::stark::Stark; -use starky::vars::StarkEvaluationTargets; -use starky::vars::StarkEvaluationVars; +use starky::vars::{StarkEvaluationTargets, StarkEvaluationVars}; use crate::alu::{eval_alu, eval_alu_circuit, generate_alu}; use crate::core_registers::{ diff --git a/u32/src/gates/arithmetic_u32.rs b/u32/src/gates/arithmetic_u32.rs index 47889954..575f3055 100644 --- a/u32/src/gates/arithmetic_u32.rs +++ b/u32/src/gates/arithmetic_u32.rs @@ -416,8 +416,7 @@ mod tests { use anyhow::Result; use plonky2::gates::gate::Gate; use plonky2::gates::gate_testing::{test_eval_fns, test_low_degree}; - use plonky2::hash::hash_types::HashOut; - use plonky2::hash::hash_types::RichField; + use plonky2::hash::hash_types::{HashOut, RichField}; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::plonk::vars::EvaluationVars; use plonky2_field::extension::Extendable; diff --git a/u32/src/gates/comparison.rs b/u32/src/gates/comparison.rs index a2a0cfcf..cbb689e7 100644 --- a/u32/src/gates/comparison.rs +++ b/u32/src/gates/comparison.rs @@ -521,8 +521,7 @@ mod tests { use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::plonk::vars::EvaluationVars; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; - use plonky2_field::types::PrimeField64; + use plonky2_field::types::{Field, PrimeField64}; use rand::Rng; use crate::gates::comparison::ComparisonGate; diff --git a/u32/src/gates/subtraction_u32.rs b/u32/src/gates/subtraction_u32.rs index b08d900b..d29b2348 100644 --- a/u32/src/gates/subtraction_u32.rs +++ b/u32/src/gates/subtraction_u32.rs @@ -339,8 +339,7 @@ mod tests { use plonky2::plonk::vars::EvaluationVars; use plonky2_field::extension::quartic::QuarticExtension; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; - use plonky2_field::types::PrimeField64; + use plonky2_field::types::{Field, PrimeField64}; use rand::Rng; use crate::gates::subtraction_u32::U32SubtractionGate; diff --git a/waksman/src/gates/assert_le.rs b/waksman/src/gates/assert_le.rs index 27242370..7f60fcac 100644 --- a/waksman/src/gates/assert_le.rs +++ b/waksman/src/gates/assert_le.rs @@ -456,8 +456,7 @@ mod tests { use plonky2::plonk::vars::EvaluationVars; use plonky2_field::extension::quartic::QuarticExtension; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; - use plonky2_field::types::PrimeField64; + use plonky2_field::types::{Field, PrimeField64}; use rand::Rng; use crate::gates::assert_le::AssertLessThanGate; diff --git a/waksman/src/permutation.rs b/waksman/src/permutation.rs index 90dc5086..367386c4 100644 --- a/waksman/src/permutation.rs +++ b/waksman/src/permutation.rs @@ -1,7 +1,8 @@ use std::collections::BTreeMap; use std::marker::PhantomData; -use plonky2::field::{extension::Extendable, types::Field}; +use plonky2::field::extension::Extendable; +use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::Target; @@ -374,7 +375,8 @@ mod tests { use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use rand::{seq::SliceRandom, thread_rng, Rng}; + use rand::seq::SliceRandom; + use rand::{thread_rng, Rng}; use super::*; From 7a81c5d46a1b43fdada42cfbfc0bce94ca5df14e Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Wed, 2 Nov 2022 19:59:12 -0700 Subject: [PATCH 03/49] feat: move to alloc for Vec/String/Box Signed-off-by: Brandon H. Gomes --- field/Cargo.toml | 20 ++++---- .../src/arch/x86_64/avx2_goldilocks_field.rs | 22 +++++---- .../arch/x86_64/avx512_goldilocks_field.rs | 22 +++++---- field/src/cosets.rs | 2 + field/src/extension/algebra.rs | 11 +++-- field/src/extension/mod.rs | 2 +- field/src/extension/quadratic.rs | 12 ++--- field/src/extension/quartic.rs | 12 ++--- field/src/extension/quintic.rs | 12 ++--- field/src/fft.rs | 4 +- field/src/goldilocks_extensions.rs | 2 +- field/src/goldilocks_field.rs | 14 +++--- field/src/interpolation.rs | 2 + field/src/inversion.rs | 8 ++-- field/src/lib.rs | 8 +++- field/src/ops.rs | 2 +- field/src/packed.rs | 12 ++--- field/src/polynomial/division.rs | 5 +- field/src/polynomial/mod.rs | 8 ++-- field/src/prime_field_testing.rs | 2 +- field/src/secp256k1_base.rs | 12 ++--- field/src/secp256k1_scalar.rs | 13 +++-- field/src/types.rs | 14 +++--- field/src/zero_poly_coset.rs | 2 + plonky2/Cargo.toml | 47 ++++++++++++------- plonky2/src/fri/challenges.rs | 2 + plonky2/src/fri/mod.rs | 2 + plonky2/src/fri/oracle.rs | 3 ++ plonky2/src/fri/proof.rs | 2 + plonky2/src/fri/prover.rs | 2 + plonky2/src/fri/recursive_verifier.rs | 3 ++ plonky2/src/fri/reduction_strategies.rs | 5 ++ plonky2/src/fri/structure.rs | 1 + plonky2/src/fri/verifier.rs | 2 + plonky2/src/gadgets/arithmetic.rs | 2 + plonky2/src/gadgets/arithmetic_extension.rs | 2 + plonky2/src/gadgets/polynomial.rs | 2 + plonky2/src/gadgets/random_access.rs | 2 + plonky2/src/gadgets/range_check.rs | 3 ++ plonky2/src/gadgets/split_base.rs | 2 + plonky2/src/gadgets/split_join.rs | 3 ++ plonky2/src/gates/arithmetic_base.rs | 5 ++ plonky2/src/gates/arithmetic_extension.rs | 4 ++ plonky2/src/gates/base_sum.rs | 4 ++ plonky2/src/gates/constant.rs | 5 ++ plonky2/src/gates/exponentiation.rs | 4 ++ plonky2/src/gates/gate.rs | 6 ++- .../src/gates/high_degree_interpolation.rs | 4 ++ plonky2/src/gates/interpolation.rs | 1 + plonky2/src/gates/low_degree_interpolation.rs | 4 ++ plonky2/src/gates/multiplication_extension.rs | 4 ++ plonky2/src/gates/noop.rs | 4 ++ plonky2/src/gates/packed_util.rs | 3 ++ plonky2/src/gates/poseidon.rs | 4 ++ plonky2/src/gates/poseidon_mds.rs | 4 ++ plonky2/src/gates/public_input.rs | 3 ++ plonky2/src/gates/random_access.rs | 4 ++ plonky2/src/gates/reducing.rs | 4 ++ plonky2/src/gates/reducing_extension.rs | 4 ++ plonky2/src/gates/selectors.rs | 2 + .../arch/aarch64/poseidon_goldilocks_neon.rs | 6 +-- plonky2/src/hash/hash_types.rs | 2 + plonky2/src/hash/hashing.rs | 2 + plonky2/src/hash/keccak.rs | 2 + plonky2/src/hash/merkle_proofs.rs | 3 ++ plonky2/src/hash/merkle_tree.rs | 1 + plonky2/src/hash/path_compression.rs | 2 + plonky2/src/hash/poseidon.rs | 3 ++ plonky2/src/iop/challenger.rs | 3 +- plonky2/src/iop/ext_target.rs | 1 + plonky2/src/iop/generator.rs | 2 + plonky2/src/iop/mod.rs | 1 + plonky2/src/iop/target.rs | 1 + plonky2/src/iop/wire.rs | 1 + plonky2/src/iop/witness.rs | 2 + plonky2/src/lib.rs | 3 ++ plonky2/src/plonk/circuit_builder.rs | 6 ++- plonky2/src/plonk/circuit_data.rs | 5 +- plonky2/src/plonk/config.rs | 2 + plonky2/src/plonk/copy_constraint.rs | 2 + plonky2/src/plonk/get_challenges.rs | 2 + plonky2/src/plonk/permutation_argument.rs | 1 + plonky2/src/plonk/plonk_common.rs | 3 ++ plonky2/src/plonk/proof.rs | 5 ++ plonky2/src/plonk/prover.rs | 2 + plonky2/src/plonk/vanishing_poly.rs | 3 ++ .../conditional_recursive_verifier.rs | 5 +- plonky2/src/recursion/cyclic_recursion.rs | 11 +++-- plonky2/src/util/context_tree.rs | 4 ++ plonky2/src/util/mod.rs | 7 ++- plonky2/src/util/partial_products.rs | 1 + plonky2/src/util/reducing.rs | 2 + util/src/lib.rs | 14 ++++-- util/src/transpose_util.rs | 2 +- 94 files changed, 356 insertions(+), 137 deletions(-) diff --git a/field/Cargo.toml b/field/Cargo.toml index 1a72bd6c..33bb76c2 100644 --- a/field/Cargo.toml +++ b/field/Cargo.toml @@ -5,15 +5,15 @@ version = "0.1.0" edition = "2021" [features] -default = ["rand"] -rand = ["dep:rand"] +default = [] +rand = ["dep:rand", "num/rand"] [dependencies] -plonky2_util = { path = "../util" } -anyhow = "1.0.40" -itertools = "0.10.0" -num = { version = "0.4", features = [ "rand" ] } -rand = { optional = true, version = "0.8.4" } -serde = { version = "1.0", features = ["derive"] } -unroll = "0.1.5" -static_assertions = "1.1.0" +anyhow = { version = "1.0.40", default-features = false } +itertools = { version = "0.10.0", default-features = false } +num = { version = "0.4", default-features = false, features = ["alloc"] } +plonky2_util = { path = "../util", default-features = false } +rand = { version = "0.8.5", optional = true, default-features = false, features = ["getrandom"] } +serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } +static_assertions = { version = "1.1.0", default-features = false } +unroll = { version = "0.1.5", default-features = false } diff --git a/field/src/arch/x86_64/avx2_goldilocks_field.rs b/field/src/arch/x86_64/avx2_goldilocks_field.rs index adef1fac..dafd1503 100644 --- a/field/src/arch/x86_64/avx2_goldilocks_field.rs +++ b/field/src/arch/x86_64/avx2_goldilocks_field.rs @@ -1,20 +1,22 @@ use core::arch::x86_64::*; -use std::fmt; -use std::fmt::{Debug, Formatter}; -use std::iter::{Product, Sum}; -use std::mem::transmute; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::fmt; +use core::fmt::{Debug, Formatter}; +use core::iter::{Product, Sum}; +use core::mem::transmute; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use crate::goldilocks_field::GoldilocksField; use crate::ops::Square; use crate::packed::PackedField; use crate::types::{Field, Field64}; -// Ideally `Avx2GoldilocksField` would wrap `__m256i`. Unfortunately, `__m256i` has an alignment of -// 32B, which would preclude us from casting `[GoldilocksField; 4]` (alignment 8B) to -// `Avx2GoldilocksField`. We need to ensure that `Avx2GoldilocksField` has the same alignment as -// `GoldilocksField`. Thus we wrap `[GoldilocksField; 4]` and use the `new` and `get` methods to -// convert to and from `__m256i`. +/// AVX2 Goldilocks Field +/// +/// Ideally `Avx2GoldilocksField` would wrap `__m256i`. Unfortunately, `__m256i` has an alignment of +/// 32B, which would preclude us from casting `[GoldilocksField; 4]` (alignment 8B) to +/// `Avx2GoldilocksField`. We need to ensure that `Avx2GoldilocksField` has the same alignment as +/// `GoldilocksField`. Thus we wrap `[GoldilocksField; 4]` and use the `new` and `get` methods to +/// convert to and from `__m256i`. #[derive(Copy, Clone)] #[repr(transparent)] pub struct Avx2GoldilocksField(pub [GoldilocksField; 4]); diff --git a/field/src/arch/x86_64/avx512_goldilocks_field.rs b/field/src/arch/x86_64/avx512_goldilocks_field.rs index f67e5000..2939e70e 100644 --- a/field/src/arch/x86_64/avx512_goldilocks_field.rs +++ b/field/src/arch/x86_64/avx512_goldilocks_field.rs @@ -1,20 +1,22 @@ use core::arch::x86_64::*; -use std::fmt; -use std::fmt::{Debug, Formatter}; -use std::iter::{Product, Sum}; -use std::mem::transmute; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::fmt; +use core::fmt::{Debug, Formatter}; +use core::iter::{Product, Sum}; +use core::mem::transmute; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use crate::goldilocks_field::GoldilocksField; use crate::ops::Square; use crate::packed::PackedField; use crate::types::{Field, Field64}; -// Ideally `Avx512GoldilocksField` would wrap `__m512i`. Unfortunately, `__m512i` has an alignment -// of 64B, which would preclude us from casting `[GoldilocksField; 8]` (alignment 8B) to -// `Avx512GoldilocksField`. We need to ensure that `Avx512GoldilocksField` has the same alignment as -// `GoldilocksField`. Thus we wrap `[GoldilocksField; 8]` and use the `new` and `get` methods to -// convert to and from `__m512i`. +/// AVX512 Goldilocks Field +/// +/// Ideally `Avx512GoldilocksField` would wrap `__m512i`. Unfortunately, `__m512i` has an alignment +/// of 64B, which would preclude us from casting `[GoldilocksField; 8]` (alignment 8B) to +/// `Avx512GoldilocksField`. We need to ensure that `Avx512GoldilocksField` has the same alignment as +/// `GoldilocksField`. Thus we wrap `[GoldilocksField; 8]` and use the `new` and `get` methods to +/// convert to and from `__m512i`. #[derive(Copy, Clone)] #[repr(transparent)] pub struct Avx512GoldilocksField(pub [GoldilocksField; 8]); diff --git a/field/src/cosets.rs b/field/src/cosets.rs index 46b43d90..5a59a963 100644 --- a/field/src/cosets.rs +++ b/field/src/cosets.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use num::bigint::BigUint; use crate::types::Field; diff --git a/field/src/extension/algebra.rs b/field/src/extension/algebra.rs index 5840ae81..6e309ba8 100644 --- a/field/src/extension/algebra.rs +++ b/field/src/extension/algebra.rs @@ -1,6 +1,7 @@ -use std::fmt::{Debug, Display, Formatter}; -use std::iter::{Product, Sum}; -use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use alloc::vec::Vec; +use core::fmt::{self, Debug, Display, Formatter}; +use core::iter::{Product, Sum}; +use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use crate::extension::OEF; @@ -42,7 +43,7 @@ impl, const D: usize> From for ExtensionAlgebra { } impl, const D: usize> Display for ExtensionAlgebra { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "({})", self.0[0])?; for i in 1..D { write!(f, " + ({})*b^{i}", self.0[i])?; @@ -52,7 +53,7 @@ impl, const D: usize> Display for ExtensionAlgebra { } impl, const D: usize> Debug for ExtensionAlgebra { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(self, f) } } diff --git a/field/src/extension/mod.rs b/field/src/extension/mod.rs index ed596764..bbbaca25 100644 --- a/field/src/extension/mod.rs +++ b/field/src/extension/mod.rs @@ -1,4 +1,4 @@ -use std::convert::TryInto; +use alloc::vec::Vec; use crate::types::Field; diff --git a/field/src/extension/quadratic.rs b/field/src/extension/quadratic.rs index 278abba9..1909e35e 100644 --- a/field/src/extension/quadratic.rs +++ b/field/src/extension/quadratic.rs @@ -1,6 +1,6 @@ -use std::fmt::{Debug, Display, Formatter}; -use std::iter::{Product, Sum}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::fmt::{self, Debug, Display, Formatter}; +use core::iter::{Product, Sum}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use num::bigint::BigUint; use serde::{Deserialize, Serialize}; @@ -101,19 +101,19 @@ impl> Field for QuadraticExtension { } #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { + fn rand_from_rng(rng: &mut R) -> Self { Self([F::rand_from_rng(rng), F::rand_from_rng(rng)]) } } impl> Display for QuadraticExtension { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{} + {}*a", self.0[0], self.0[1]) } } impl> Debug for QuadraticExtension { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(self, f) } } diff --git a/field/src/extension/quartic.rs b/field/src/extension/quartic.rs index 6df39903..948c29fb 100644 --- a/field/src/extension/quartic.rs +++ b/field/src/extension/quartic.rs @@ -1,6 +1,6 @@ -use std::fmt::{Debug, Display, Formatter}; -use std::iter::{Product, Sum}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::fmt::{self, Debug, Display, Formatter}; +use core::iter::{Product, Sum}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use num::bigint::BigUint; use num::traits::Pow; @@ -106,7 +106,7 @@ impl> Field for QuarticExtension { } #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { + fn rand_from_rng(rng: &mut R) -> Self { Self::from_basefield_array([ F::rand_from_rng(rng), F::rand_from_rng(rng), @@ -117,7 +117,7 @@ impl> Field for QuarticExtension { } impl> Display for QuarticExtension { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!( f, "{} + {}*a + {}*a^2 + {}*a^3", @@ -127,7 +127,7 @@ impl> Display for QuarticExtension { } impl> Debug for QuarticExtension { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(self, f) } } diff --git a/field/src/extension/quintic.rs b/field/src/extension/quintic.rs index 6680ebc7..343e6f77 100644 --- a/field/src/extension/quintic.rs +++ b/field/src/extension/quintic.rs @@ -1,6 +1,6 @@ -use std::fmt::{Debug, Display, Formatter}; -use std::iter::{Product, Sum}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::fmt::{self, Debug, Display, Formatter}; +use core::iter::{Product, Sum}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use num::bigint::BigUint; use num::traits::Pow; @@ -112,7 +112,7 @@ impl> Field for QuinticExtension { } #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { + fn rand_from_rng(rng: &mut R) -> Self { Self::from_basefield_array([ F::rand_from_rng(rng), F::rand_from_rng(rng), @@ -124,7 +124,7 @@ impl> Field for QuinticExtension { } impl> Display for QuinticExtension { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!( f, "{} + {}*a + {}*a^2 + {}*a^3 + {}*a^4", @@ -134,7 +134,7 @@ impl> Display for QuinticExtension { } impl> Debug for QuinticExtension { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { Display::fmt(self, f) } } diff --git a/field/src/fft.rs b/field/src/fft.rs index 6ede8af6..8fb1809c 100644 --- a/field/src/fft.rs +++ b/field/src/fft.rs @@ -1,5 +1,5 @@ -use std::cmp::{max, min}; -use std::option::Option; +use alloc::vec::Vec; +use core::cmp::{max, min}; use plonky2_util::{log2_strict, reverse_index_bits_in_place}; use unroll::unroll_for_loops; diff --git a/field/src/goldilocks_extensions.rs b/field/src/goldilocks_extensions.rs index 2175494f..8b53f8b5 100644 --- a/field/src/goldilocks_extensions.rs +++ b/field/src/goldilocks_extensions.rs @@ -1,4 +1,4 @@ -use std::ops::Mul; +use core::ops::Mul; use static_assertions::const_assert; diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index e036ab9b..9c7e8d1b 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -1,8 +1,7 @@ -use std::fmt; -use std::fmt::{Debug, Display, Formatter}; -use std::hash::{Hash, Hasher}; -use std::iter::{Product, Sum}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::fmt::{self, Debug, Display, Formatter}; +use core::hash::{Hash, Hasher}; +use core::iter::{Product, Sum}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use num::{BigUint, Integer}; use plonky2_util::{assume, branch_hint}; @@ -105,7 +104,8 @@ impl Field for GoldilocksField { } #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { + fn rand_from_rng(rng: &mut R) -> Self { + use rand::Rng; Self::from_canonical_u64(rng.gen_range(0..Self::ORDER)) } @@ -300,7 +300,7 @@ impl DivAssign for GoldilocksField { #[inline(always)] #[cfg(target_arch = "x86_64")] unsafe fn add_no_canonicalize_trashing_input(x: u64, y: u64) -> u64 { - use std::arch::asm; + use core::arch::asm; let res_wrapped: u64; let adjustment: u64; asm!( diff --git a/field/src/interpolation.rs b/field/src/interpolation.rs index 8f64e9d7..4a42e4af 100644 --- a/field/src/interpolation.rs +++ b/field/src/interpolation.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use plonky2_util::log2_ceil; use crate::fft::ifft; diff --git a/field/src/inversion.rs b/field/src/inversion.rs index 740e6562..45d17ab5 100644 --- a/field/src/inversion.rs +++ b/field/src/inversion.rs @@ -6,8 +6,8 @@ use crate::types::PrimeField64; #[inline(always)] fn safe_iteration(f: &mut u64, g: &mut u64, c: &mut i128, d: &mut i128, k: &mut u32) { if f < g { - std::mem::swap(f, g); - std::mem::swap(c, d); + core::mem::swap(f, g); + core::mem::swap(c, d); } if *f & 3 == *g & 3 { // f - g = 0 (mod 4) @@ -36,8 +36,8 @@ fn safe_iteration(f: &mut u64, g: &mut u64, c: &mut i128, d: &mut i128, k: &mut #[inline(always)] unsafe fn unsafe_iteration(f: &mut u64, g: &mut u64, c: &mut i128, d: &mut i128, k: &mut u32) { if *f < *g { - std::mem::swap(f, g); - std::mem::swap(c, d); + core::mem::swap(f, g); + core::mem::swap(c, d); } if *f & 3 == *g & 3 { // f - g = 0 (mod 4) diff --git a/field/src/lib.rs b/field/src/lib.rs index ec5fc80e..5459b38a 100644 --- a/field/src/lib.rs +++ b/field/src/lib.rs @@ -8,8 +8,14 @@ #![feature(generic_const_exprs)] #![feature(specialization)] #![feature(stdsimd)] +#![no_std] + +extern crate alloc; + +mod inversion; pub(crate) mod arch; + pub mod batch_util; pub mod cosets; pub mod extension; @@ -17,7 +23,6 @@ pub mod fft; pub mod goldilocks_extensions; pub mod goldilocks_field; pub mod interpolation; -mod inversion; pub mod ops; pub mod packable; pub mod packed; @@ -29,5 +34,6 @@ pub mod zero_poly_coset; #[cfg(test)] mod field_testing; + #[cfg(test)] mod prime_field_testing; diff --git a/field/src/ops.rs b/field/src/ops.rs index bf8ff8a9..ce05ea78 100644 --- a/field/src/ops.rs +++ b/field/src/ops.rs @@ -1,4 +1,4 @@ -use std::ops::Mul; +use core::ops::Mul; pub trait Square { fn square(&self) -> Self; diff --git a/field/src/packed.rs b/field/src/packed.rs index 9708f9e3..531071fd 100644 --- a/field/src/packed.rs +++ b/field/src/packed.rs @@ -1,7 +1,7 @@ -use std::fmt::Debug; -use std::iter::{Product, Sum}; -use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign}; -use std::slice; +use core::fmt::Debug; +use core::iter::{Product, Sum}; +use core::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign}; +use core::slice; use crate::ops::Square; use crate::types::Field; @@ -82,7 +82,7 @@ where ); let buf_ptr = buf.as_ptr().cast::(); let n = buf.len() / Self::WIDTH; - unsafe { std::slice::from_raw_parts(buf_ptr, n) } + unsafe { slice::from_raw_parts(buf_ptr, n) } } fn pack_slice_mut(buf: &mut [Self::Scalar]) -> &mut [Self] { assert!( @@ -93,7 +93,7 @@ where ); let buf_ptr = buf.as_mut_ptr().cast::(); let n = buf.len() / Self::WIDTH; - unsafe { std::slice::from_raw_parts_mut(buf_ptr, n) } + unsafe { slice::from_raw_parts_mut(buf_ptr, n) } } fn doubles(&self) -> Self { diff --git a/field/src/polynomial/division.rs b/field/src/polynomial/division.rs index 561b9661..14e16841 100644 --- a/field/src/polynomial/division.rs +++ b/field/src/polynomial/division.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use plonky2_util::log2_ceil; use crate::polynomial::PolynomialCoeffs; @@ -68,7 +71,7 @@ impl PolynomialCoeffs { } /// Let `self=p(X)`, this returns `(p(X)-p(z))/(X-z)`. - /// See https://en.wikipedia.org/wiki/Horner%27s_method + /// See pub fn divide_by_linear(&self, z: F) -> PolynomialCoeffs { let mut bs = self .coeffs diff --git a/field/src/polynomial/mod.rs b/field/src/polynomial/mod.rs index 09ed69c7..e5143292 100644 --- a/field/src/polynomial/mod.rs +++ b/field/src/polynomial/mod.rs @@ -1,8 +1,10 @@ pub(crate) mod division; -use std::cmp::max; -use std::iter::Sum; -use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; +use alloc::vec; +use alloc::vec::Vec; +use core::cmp::max; +use core::iter::Sum; +use core::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}; use anyhow::{ensure, Result}; use itertools::Itertools; diff --git a/field/src/prime_field_testing.rs b/field/src/prime_field_testing.rs index 13431265..7b0d9624 100644 --- a/field/src/prime_field_testing.rs +++ b/field/src/prime_field_testing.rs @@ -68,7 +68,7 @@ where macro_rules! test_prime_field_arithmetic { ($field:ty) => { mod prime_field_arithmetic { - use std::ops::{Add, Mul, Neg, Sub}; + use core::ops::{Add, Mul, Neg, Sub}; use $crate::ops::Square; use $crate::types::{Field, Field64}; diff --git a/field/src/secp256k1_base.rs b/field/src/secp256k1_base.rs index 504d63d7..9d90da9b 100644 --- a/field/src/secp256k1_base.rs +++ b/field/src/secp256k1_base.rs @@ -1,8 +1,8 @@ -use std::fmt; -use std::fmt::{Debug, Display, Formatter}; -use std::hash::{Hash, Hasher}; -use std::iter::{Product, Sum}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use alloc::vec::Vec; +use core::fmt::{self, Debug, Display, Formatter}; +use core::hash::{Hash, Hasher}; +use core::iter::{Product, Sum}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use itertools::Itertools; use num::bigint::BigUint; @@ -133,7 +133,7 @@ impl Field for Secp256K1Base { } #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { + fn rand_from_rng(rng: &mut R) -> Self { use num::bigint::RandBigInt; Self::from_noncanonical_biguint(rng.gen_biguint_below(&Self::order())) } diff --git a/field/src/secp256k1_scalar.rs b/field/src/secp256k1_scalar.rs index e70b154d..3a98d9e7 100644 --- a/field/src/secp256k1_scalar.rs +++ b/field/src/secp256k1_scalar.rs @@ -1,9 +1,8 @@ -use std::convert::TryInto; -use std::fmt; -use std::fmt::{Debug, Display, Formatter}; -use std::hash::{Hash, Hasher}; -use std::iter::{Product, Sum}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use alloc::vec::Vec; +use core::fmt::{self, Debug, Display, Formatter}; +use core::hash::{Hash, Hasher}; +use core::iter::{Product, Sum}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use itertools::Itertools; use num::bigint::BigUint; @@ -142,7 +141,7 @@ impl Field for Secp256K1Scalar { } #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { + fn rand_from_rng(rng: &mut R) -> Self { use num::bigint::RandBigInt; Self::from_noncanonical_biguint(rng.gen_biguint_below(&Self::order())) } diff --git a/field/src/types.rs b/field/src/types.rs index 545f90c5..4df26ea2 100644 --- a/field/src/types.rs +++ b/field/src/types.rs @@ -1,7 +1,9 @@ -use std::fmt::{Debug, Display}; -use std::hash::Hash; -use std::iter::{Product, Sum}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; +use alloc::vec; +use alloc::vec::Vec; +use core::fmt::{Debug, Display}; +use core::hash::Hash; +use core::iter::{Product, Sum}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; use num::bigint::BigUint; use num::{Integer, One, ToPrimitive, Zero}; @@ -318,7 +320,7 @@ pub trait Field: } #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self; + fn rand_from_rng(rng: &mut R) -> Self; fn exp_power_of_2(&self, power_log: usize) -> Self { let mut res = *self; @@ -399,7 +401,7 @@ pub trait Field: #[cfg(feature = "rand")] fn rand() -> Self { - Self::rand_from_rng(&mut rand::thread_rng()) + Self::rand_from_rng(&mut rand::rngs::OsRng) } #[cfg(feature = "rand")] diff --git a/field/src/zero_poly_coset.rs b/field/src/zero_poly_coset.rs index 8d63bc69..53b66a75 100644 --- a/field/src/zero_poly_coset.rs +++ b/field/src/zero_poly_coset.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use crate::packed::PackedField; use crate::types::Field; diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index 73ff55a5..6de787d2 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -11,29 +11,40 @@ edition = "2021" default-run = "generate_constants" [features] -default = ["parallel", "rand", "rand_chacha", "timing", "gate_testing"] -parallel = ["maybe_rayon/parallel"] -rand = ["dep:rand", "plonky2_field/rand"] +default = [ + "gate_testing", + "parallel", + "rand", + "rand_chacha", + "std", + "timing", +] +rand = [ + "dep:rand", + "num/rand", + "plonky2_field/rand" +] gate_testing = ["rand"] -rand_chacha = ["dep:rand_chacha"] +parallel = ["maybe_rayon/parallel"] +std = ["anyhow/std"] timing = [] [dependencies] -anyhow = "1.0.40" +anyhow = { version = "1.0.40", default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } -itertools = "0.10.0" -keccak-hash = "0.8.0" -log = "0.4.14" -maybe_rayon = { path = "../maybe_rayon" } -num = { version = "0.4", features = [ "rand" ] } -plonky2_field = { path = "../field" } -plonky2_util = { path = "../util" } -rand = { version = "0.8.4", optional = true } -rand_chacha = { version = "0.3.1", optional = true } -serde = { version = "1.0", features = ["derive"] } -serde_cbor = "0.11.1" -static_assertions = "1.1.0" -unroll = "0.1.5" +itertools = { version = "0.10.0", default-features = false } +keccak-hash = { version = "0.8.0", default-features = false } +log = { version = "0.4.14", default-features = false } +maybe_rayon = { path = "../maybe_rayon", default-features = false } +num = { version = "0.4", default-features = false } +plonky2_field = { path = "../field", default-features = false } +plonky2_util = { path = "../util", default-features = false } +rand = { version = "0.8.4", optional = true, default-features = false } +rand_chacha = { version = "0.3.1", optional = true, default-features = false } +serde = { version = "1.0", default-features = false, features = ["derive"] } +serde_cbor = { version = "0.11.1", default-features = false } +static_assertions = { version = "1.1.0", default-features = false } +unroll = { version = "0.1.5", default-features = false } [dev-dependencies] criterion = "0.3.5" diff --git a/plonky2/src/fri/challenges.rs b/plonky2/src/fri/challenges.rs index 011a8897..3a750dd6 100644 --- a/plonky2/src/fri/challenges.rs +++ b/plonky2/src/fri/challenges.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use plonky2_field::polynomial::PolynomialCoeffs; diff --git a/plonky2/src/fri/mod.rs b/plonky2/src/fri/mod.rs index 90f1c940..ca800b98 100644 --- a/plonky2/src/fri/mod.rs +++ b/plonky2/src/fri/mod.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use crate::fri::reduction_strategies::FriReductionStrategy; mod challenges; diff --git a/plonky2/src/fri/oracle.rs b/plonky2/src/fri/oracle.rs index 10a93a18..b670944d 100644 --- a/plonky2/src/fri/oracle.rs +++ b/plonky2/src/fri/oracle.rs @@ -1,3 +1,6 @@ +use alloc::format; +use alloc::vec::Vec; + use itertools::Itertools; use maybe_rayon::*; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/fri/proof.rs b/plonky2/src/fri/proof.rs index 6a8adcf5..2404a7bd 100644 --- a/plonky2/src/fri/proof.rs +++ b/plonky2/src/fri/proof.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use std::collections::HashMap; use itertools::izip; diff --git a/plonky2/src/fri/prover.rs b/plonky2/src/fri/prover.rs index 32e41ff3..adbf5e29 100644 --- a/plonky2/src/fri/prover.rs +++ b/plonky2/src/fri/prover.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use itertools::Itertools; use maybe_rayon::*; use plonky2_field::extension::{flatten, unflatten, Extendable}; diff --git a/plonky2/src/fri/recursive_verifier.rs b/plonky2/src/fri/recursive_verifier.rs index c5cb9f07..a5b50041 100644 --- a/plonky2/src/fri/recursive_verifier.rs +++ b/plonky2/src/fri/recursive_verifier.rs @@ -1,3 +1,6 @@ +use alloc::vec::Vec; +use alloc::{format, vec}; + use itertools::Itertools; use plonky2_field::extension::Extendable; use plonky2_util::{log2_strict, reverse_index_bits_in_place}; diff --git a/plonky2/src/fri/reduction_strategies.rs b/plonky2/src/fri/reduction_strategies.rs index 4252564e..7035100d 100644 --- a/plonky2/src/fri/reduction_strategies.rs +++ b/plonky2/src/fri/reduction_strategies.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; +#[cfg(feature = "timing")] use std::time::Instant; use log::debug; @@ -63,11 +66,13 @@ fn min_size_arity_bits( // in an optimal sequence, we would need a really massive polynomial. let max_arity_bits = opt_max_arity_bits.unwrap_or(4); + #[cfg(feature = "timing")] let start = Instant::now(); let (mut arity_bits, fri_proof_size) = min_size_arity_bits_helper(degree_bits, rate_bits, num_queries, max_arity_bits, vec![]); arity_bits.shrink_to_fit(); + #[cfg(feature = "timing")] debug!( "min_size_arity_bits took {:.3}s", start.elapsed().as_secs_f32() diff --git a/plonky2/src/fri/structure.rs b/plonky2/src/fri/structure.rs index abcccccd..7d7436d5 100644 --- a/plonky2/src/fri/structure.rs +++ b/plonky2/src/fri/structure.rs @@ -1,6 +1,7 @@ //! Information about the structure of a FRI instance, in terms of the oracles and polynomials //! involved, and the points they are opened at. +use alloc::vec::Vec; use core::ops::Range; use crate::field::extension::Extendable; diff --git a/plonky2/src/fri/verifier.rs b/plonky2/src/fri/verifier.rs index 9d01ef6c..7060ce95 100644 --- a/plonky2/src/fri/verifier.rs +++ b/plonky2/src/fri/verifier.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use anyhow::{ensure, Result}; use plonky2_field::extension::{flatten, Extendable, FieldExtension}; use plonky2_field::interpolation::{barycentric_weights, interpolate}; diff --git a/plonky2/src/gadgets/arithmetic.rs b/plonky2/src/gadgets/arithmetic.rs index 87c5878c..c18ea034 100644 --- a/plonky2/src/gadgets/arithmetic.rs +++ b/plonky2/src/gadgets/arithmetic.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::borrow::Borrow; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/gadgets/arithmetic_extension.rs b/plonky2/src/gadgets/arithmetic_extension.rs index 296127b1..b56d245c 100644 --- a/plonky2/src/gadgets/arithmetic_extension.rs +++ b/plonky2/src/gadgets/arithmetic_extension.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::borrow::Borrow; use plonky2_field::extension::{Extendable, FieldExtension, OEF}; diff --git a/plonky2/src/gadgets/polynomial.rs b/plonky2/src/gadgets/polynomial.rs index d61cf830..bf5c2207 100644 --- a/plonky2/src/gadgets/polynomial.rs +++ b/plonky2/src/gadgets/polynomial.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/gadgets/random_access.rs b/plonky2/src/gadgets/random_access.rs index 0d32c360..b9561962 100644 --- a/plonky2/src/gadgets/random_access.rs +++ b/plonky2/src/gadgets/random_access.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use plonky2_util::log2_strict; diff --git a/plonky2/src/gadgets/range_check.rs b/plonky2/src/gadgets/range_check.rs index 267b1040..fd22c17d 100644 --- a/plonky2/src/gadgets/range_check.rs +++ b/plonky2/src/gadgets/range_check.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/gadgets/split_base.rs b/plonky2/src/gadgets/split_base.rs index 37853c2b..43e67cb8 100644 --- a/plonky2/src/gadgets/split_base.rs +++ b/plonky2/src/gadgets/split_base.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::borrow::Borrow; use itertools::Itertools; diff --git a/plonky2/src/gadgets/split_join.rs b/plonky2/src/gadgets/split_join.rs index cd2bbc93..ee4bd7ef 100644 --- a/plonky2/src/gadgets/split_join.rs +++ b/plonky2/src/gadgets/split_join.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use plonky2_util::ceil_div_usize; diff --git a/plonky2/src/gates/arithmetic_base.rs b/plonky2/src/gates/arithmetic_base.rs index 03560faf..69f2c179 100644 --- a/plonky2/src/gates/arithmetic_base.rs +++ b/plonky2/src/gates/arithmetic_base.rs @@ -1,3 +1,8 @@ +use alloc::boxed::Box; +use alloc::format; +use alloc::string::String; +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use plonky2_field::packed::PackedField; diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index da522b9e..da686739 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::format; +use alloc::string::String; +use alloc::vec::Vec; use core::ops::Range; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/gates/base_sum.rs b/plonky2/src/gates/base_sum.rs index 916d1b84..dd3542e1 100644 --- a/plonky2/src/gates/base_sum.rs +++ b/plonky2/src/gates/base_sum.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::ops::Range; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/gates/constant.rs b/plonky2/src/gates/constant.rs index 513caad9..dcb730af 100644 --- a/plonky2/src/gates/constant.rs +++ b/plonky2/src/gates/constant.rs @@ -1,3 +1,8 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; + use plonky2_field::extension::Extendable; use plonky2_field::packed::PackedField; diff --git a/plonky2/src/gates/exponentiation.rs b/plonky2/src/gates/exponentiation.rs index 9a3079e0..87975f94 100644 --- a/plonky2/src/gates/exponentiation.rs +++ b/plonky2/src/gates/exponentiation.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::marker::PhantomData; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index 4faac919..648bf779 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -1,8 +1,12 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::sync::Arc; +use alloc::vec; +use alloc::vec::Vec; use core::fmt::{Debug, Error, Formatter}; use core::hash::{Hash, Hasher}; use core::ops::Range; use std::collections::HashMap; -use std::sync::Arc; use plonky2_field::batch_util::batch_multiply_inplace; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/gates/high_degree_interpolation.rs b/plonky2/src/gates/high_degree_interpolation.rs index 7460a26d..71584c60 100644 --- a/plonky2/src/gates/high_degree_interpolation.rs +++ b/plonky2/src/gates/high_degree_interpolation.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::marker::PhantomData; use core::ops::Range; diff --git a/plonky2/src/gates/interpolation.rs b/plonky2/src/gates/interpolation.rs index fb61b97e..a707f192 100644 --- a/plonky2/src/gates/interpolation.rs +++ b/plonky2/src/gates/interpolation.rs @@ -1,3 +1,4 @@ +use alloc::vec; use core::ops::Range; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/gates/low_degree_interpolation.rs b/plonky2/src/gates/low_degree_interpolation.rs index de4292a5..4c9c7ecc 100644 --- a/plonky2/src/gates/low_degree_interpolation.rs +++ b/plonky2/src/gates/low_degree_interpolation.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::marker::PhantomData; use core::ops::Range; diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 97ff538f..5941f978 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::format; +use alloc::string::String; +use alloc::vec::Vec; use core::ops::Range; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/gates/noop.rs b/plonky2/src/gates/noop.rs index fb5326bd..a4d41a5c 100644 --- a/plonky2/src/gates/noop.rs +++ b/plonky2/src/gates/noop.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use crate::gates::gate::Gate; diff --git a/plonky2/src/gates/packed_util.rs b/plonky2/src/gates/packed_util.rs index 0889f9ae..62bc2d54 100644 --- a/plonky2/src/gates/packed_util.rs +++ b/plonky2/src/gates/packed_util.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use plonky2_field::packable::Packable; use plonky2_field::packed::PackedField; diff --git a/plonky2/src/gates/poseidon.rs b/plonky2/src/gates/poseidon.rs index 0977d7b4..d491cce6 100644 --- a/plonky2/src/gates/poseidon.rs +++ b/plonky2/src/gates/poseidon.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::marker::PhantomData; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/gates/poseidon_mds.rs b/plonky2/src/gates/poseidon_mds.rs index d41fdf17..880a21ff 100644 --- a/plonky2/src/gates/poseidon_mds.rs +++ b/plonky2/src/gates/poseidon_mds.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::marker::PhantomData; use core::ops::Range; diff --git a/plonky2/src/gates/public_input.rs b/plonky2/src/gates/public_input.rs index f84cd82d..d2ab2568 100644 --- a/plonky2/src/gates/public_input.rs +++ b/plonky2/src/gates/public_input.rs @@ -1,3 +1,6 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; use core::ops::Range; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index 217f5e8a..caf466bd 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::marker::PhantomData; use itertools::Itertools; diff --git a/plonky2/src/gates/reducing.rs b/plonky2/src/gates/reducing.rs index c2366558..12880b28 100644 --- a/plonky2/src/gates/reducing.rs +++ b/plonky2/src/gates/reducing.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::ops::Range; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/gates/reducing_extension.rs b/plonky2/src/gates/reducing_extension.rs index 61377b1b..f952c0c8 100644 --- a/plonky2/src/gates/reducing_extension.rs +++ b/plonky2/src/gates/reducing_extension.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::ops::Range; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/gates/selectors.rs b/plonky2/src/gates/selectors.rs index d9be7024..bfd13073 100644 --- a/plonky2/src/gates/selectors.rs +++ b/plonky2/src/gates/selectors.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::ops::Range; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/hash/arch/aarch64/poseidon_goldilocks_neon.rs b/plonky2/src/hash/arch/aarch64/poseidon_goldilocks_neon.rs index 352456e7..5cf25dce 100644 --- a/plonky2/src/hash/arch/aarch64/poseidon_goldilocks_neon.rs +++ b/plonky2/src/hash/arch/aarch64/poseidon_goldilocks_neon.rs @@ -1,8 +1,8 @@ #![allow(clippy::assertions_on_constants)] -use std::arch::aarch64::*; -use std::arch::asm; -use std::mem::transmute; +use core::arch::aarch64::*; +use core::arch::asm; +use core::mem::transmute; use plonky2_field::goldilocks_field::GoldilocksField; use plonky2_util::branch_hint; diff --git a/plonky2/src/hash/hash_types.rs b/plonky2/src/hash/hash_types.rs index f69285f7..626d5eb0 100644 --- a/plonky2/src/hash/hash_types.rs +++ b/plonky2/src/hash/hash_types.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use plonky2_field::goldilocks_field::GoldilocksField; use plonky2_field::types::{Field, PrimeField64}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; diff --git a/plonky2/src/hash/hashing.rs b/plonky2/src/hash/hashing.rs index e4ba2719..ac115152 100644 --- a/plonky2/src/hash/hashing.rs +++ b/plonky2/src/hash/hashing.rs @@ -1,5 +1,7 @@ //! Concrete instantiation of a hash function. +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use crate::hash::hash_types::{HashOut, HashOutTarget, RichField}; diff --git a/plonky2/src/hash/keccak.rs b/plonky2/src/hash/keccak.rs index 6e4fcdcb..1a4f5472 100644 --- a/plonky2/src/hash/keccak.rs +++ b/plonky2/src/hash/keccak.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::iter; use core::mem::size_of; diff --git a/plonky2/src/hash/merkle_proofs.rs b/plonky2/src/hash/merkle_proofs.rs index 04a7787f..01a4a395 100644 --- a/plonky2/src/hash/merkle_proofs.rs +++ b/plonky2/src/hash/merkle_proofs.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use anyhow::{ensure, Result}; use plonky2_field::extension::Extendable; use serde::{Deserialize, Serialize}; diff --git a/plonky2/src/hash/merkle_tree.rs b/plonky2/src/hash/merkle_tree.rs index c0799d98..6958bb9c 100644 --- a/plonky2/src/hash/merkle_tree.rs +++ b/plonky2/src/hash/merkle_tree.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use core::mem::MaybeUninit; use core::slice; diff --git a/plonky2/src/hash/path_compression.rs b/plonky2/src/hash/path_compression.rs index c57b5e03..ed3f49b8 100644 --- a/plonky2/src/hash/path_compression.rs +++ b/plonky2/src/hash/path_compression.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use std::collections::HashMap; use num::Integer; diff --git a/plonky2/src/hash/poseidon.rs b/plonky2/src/hash/poseidon.rs index 248ab32d..6a30c2bd 100644 --- a/plonky2/src/hash/poseidon.rs +++ b/plonky2/src/hash/poseidon.rs @@ -1,6 +1,9 @@ //! Implementation of the Poseidon hash function, as described in //! +use alloc::vec; +use alloc::vec::Vec; + use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::types::{Field, PrimeField64}; use unroll::unroll_for_loops; diff --git a/plonky2/src/iop/challenger.rs b/plonky2/src/iop/challenger.rs index 06b7d4ba..3e8d4148 100644 --- a/plonky2/src/iop/challenger.rs +++ b/plonky2/src/iop/challenger.rs @@ -1,4 +1,5 @@ -use core::convert::TryInto; +use alloc::vec; +use alloc::vec::Vec; use core::marker::PhantomData; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/plonky2/src/iop/ext_target.rs b/plonky2/src/iop/ext_target.rs index eb7e572b..73effa8e 100644 --- a/plonky2/src/iop/ext_target.rs +++ b/plonky2/src/iop/ext_target.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use core::ops::Range; use plonky2_field::extension::algebra::ExtensionAlgebra; diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index 3d28ae2e..6cd85971 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::fmt::Debug; use core::marker::PhantomData; diff --git a/plonky2/src/iop/mod.rs b/plonky2/src/iop/mod.rs index de315a09..47642edc 100644 --- a/plonky2/src/iop/mod.rs +++ b/plonky2/src/iop/mod.rs @@ -1,4 +1,5 @@ //! Logic common to multiple IOPs. + pub mod challenger; pub mod ext_target; pub mod generator; diff --git a/plonky2/src/iop/target.rs b/plonky2/src/iop/target.rs index 14e77da1..15be6943 100644 --- a/plonky2/src/iop/target.rs +++ b/plonky2/src/iop/target.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use core::ops::Range; use crate::iop::ext_target::ExtensionTarget; diff --git a/plonky2/src/iop/wire.rs b/plonky2/src/iop/wire.rs index daf0126e..e6161bf3 100644 --- a/plonky2/src/iop/wire.rs +++ b/plonky2/src/iop/wire.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use core::ops::Range; use crate::plonk::circuit_data::CircuitConfig; diff --git a/plonky2/src/iop/witness.rs b/plonky2/src/iop/witness.rs index 99d6313d..ef0ff7ae 100644 --- a/plonky2/src/iop/witness.rs +++ b/plonky2/src/iop/witness.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use std::collections::HashMap; use itertools::Itertools; diff --git a/plonky2/src/lib.rs b/plonky2/src/lib.rs index db7a213b..49bc8248 100644 --- a/plonky2/src/lib.rs +++ b/plonky2/src/lib.rs @@ -1,5 +1,8 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::needless_range_loop)] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; pub use plonky2_field as field; diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index f071d69c..06b11c05 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -1,5 +1,9 @@ +use alloc::boxed::Box; +use alloc::collections::BTreeMap; +use alloc::vec; +use alloc::vec::Vec; use core::cmp::max; -use std::collections::{BTreeMap, HashMap, HashSet}; +use std::collections::{HashMap, HashSet}; use std::time::Instant; use itertools::Itertools; diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 7a0af7b8..791160ad 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -1,5 +1,8 @@ +use alloc::boxed::Box; +use alloc::collections::BTreeMap; +use alloc::vec; +use alloc::vec::Vec; use core::ops::{Range, RangeFrom}; -use std::collections::BTreeMap; use anyhow::Result; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/plonk/config.rs b/plonky2/src/plonk/config.rs index 87395348..ac7399f7 100644 --- a/plonky2/src/plonk/config.rs +++ b/plonky2/src/plonk/config.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::fmt::Debug; use plonky2_field::extension::quadratic::QuadraticExtension; diff --git a/plonky2/src/plonk/copy_constraint.rs b/plonky2/src/plonk/copy_constraint.rs index a838ed37..50e85fbf 100644 --- a/plonky2/src/plonk/copy_constraint.rs +++ b/plonky2/src/plonk/copy_constraint.rs @@ -1,3 +1,5 @@ +use alloc::string::String; + use crate::iop::target::Target; /// A named copy constraint. diff --git a/plonky2/src/plonk/get_challenges.rs b/plonky2/src/plonk/get_challenges.rs index 116529e7..f0635d93 100644 --- a/plonky2/src/plonk/get_challenges.rs +++ b/plonky2/src/plonk/get_challenges.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use std::collections::HashSet; use plonky2_field::extension::Extendable; diff --git a/plonky2/src/plonk/permutation_argument.rs b/plonky2/src/plonk/permutation_argument.rs index 44d492d9..d9d56f93 100644 --- a/plonky2/src/plonk/permutation_argument.rs +++ b/plonky2/src/plonk/permutation_argument.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use std::collections::HashMap; use maybe_rayon::*; diff --git a/plonky2/src/plonk/plonk_common.rs b/plonky2/src/plonk/plonk_common.rs index 24a94bb3..fdd53035 100644 --- a/plonky2/src/plonk/plonk_common.rs +++ b/plonky2/src/plonk/plonk_common.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use plonky2_field::extension::Extendable; use plonky2_field::packed::PackedField; use plonky2_field::types::Field; diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index d408d900..a2a60d8c 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use anyhow::ensure; use maybe_rayon::*; use plonky2_field::extension::Extendable; @@ -223,12 +226,14 @@ impl, C: GenericConfig, const D: usize> C::InnerHasher::hash_no_pad(&self.public_inputs) } + #[cfg(feature = "std")] pub fn to_bytes(&self) -> anyhow::Result> { let mut buffer = Buffer::new(Vec::new()); buffer.write_compressed_proof_with_public_inputs(self)?; Ok(buffer.bytes()) } + #[cfg(feature = "std")] pub fn from_bytes( bytes: Vec, common_data: &CommonCircuitData, diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index c10febde..35490d7f 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; +use alloc::{format, vec}; use core::mem::swap; use anyhow::{ensure, Result}; diff --git a/plonky2/src/plonk/vanishing_poly.rs b/plonky2/src/plonk/vanishing_poly.rs index 28d43f4f..f27eba48 100644 --- a/plonky2/src/plonk/vanishing_poly.rs +++ b/plonky2/src/plonk/vanishing_poly.rs @@ -1,3 +1,6 @@ +use alloc::vec::Vec; +use alloc::{format, vec}; + use plonky2_field::batch_util::batch_add_inplace; use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::types::Field; diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index c78078e8..f91c1d5b 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use anyhow::{ensure, Result}; use itertools::Itertools; use plonky2_field::extension::Extendable; @@ -186,7 +189,7 @@ impl, const D: usize> CircuitBuilder { h1: HashOutTarget, ) -> HashOutTarget { HashOutTarget { - elements: std::array::from_fn(|i| self.select(b, h0.elements[i], h1.elements[i])), + elements: core::array::from_fn(|i| self.select(b, h0.elements[i], h1.elements[i])), } } diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index 9df74c56..b50eecfe 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -1,4 +1,7 @@ #![allow(clippy::int_plus_one)] // Makes more sense for some inequalities below. + +use alloc::vec; + use anyhow::{ensure, Result}; use itertools::Itertools; use plonky2_field::extension::Extendable; @@ -47,7 +50,7 @@ impl, const D: usize> VerifierOnlyCircuitData { let constants_sigmas_cap = MerkleCap( (0..cap_len) .map(|i| HashOut { - elements: std::array::from_fn(|j| slice[len - 4 * (cap_len - i) + j]), + elements: core::array::from_fn(|j| slice[len - 4 * (cap_len - i) + j]), }) .collect(), ); @@ -72,12 +75,12 @@ impl VerifierCircuitTarget { let constants_sigmas_cap = MerkleCapTarget( (0..cap_len) .map(|i| HashOutTarget { - elements: std::array::from_fn(|j| slice[len - 4 * (cap_len - i) + j]), + elements: core::array::from_fn(|j| slice[len - 4 * (cap_len - i) + j]), }) .collect(), ); let circuit_digest = HashOutTarget { - elements: std::array::from_fn(|i| slice[len - 4 - 4 * cap_len + i]), + elements: core::array::from_fn(|i| slice[len - 4 - 4 * cap_len + i]), }; Ok(Self { @@ -420,7 +423,7 @@ mod tests { let mut h: [F; 4] = initial_hash.try_into().unwrap(); assert_eq!( hash, - std::iter::repeat_with(|| { + core::iter::repeat_with(|| { h = hash_n_to_hash_no_pad::(&h).elements; h }) diff --git a/plonky2/src/util/context_tree.rs b/plonky2/src/util/context_tree.rs index 7ec5214c..bc37b2b0 100644 --- a/plonky2/src/util/context_tree.rs +++ b/plonky2/src/util/context_tree.rs @@ -1,3 +1,7 @@ +use alloc::string::String; +use alloc::vec; +use alloc::vec::Vec; + use log::{log, Level}; /// The hierarchy of contexts, and the gate count contributed by each one. Useful for debugging. diff --git a/plonky2/src/util/mod.rs b/plonky2/src/util/mod.rs index 9f15b8a1..d978dbc5 100644 --- a/plonky2/src/util/mod.rs +++ b/plonky2/src/util/mod.rs @@ -1,13 +1,18 @@ +use alloc::vec; +use alloc::vec::Vec; + use plonky2_field::polynomial::PolynomialValues; use plonky2_field::types::Field; pub(crate) mod context_tree; pub(crate) mod partial_products; pub mod reducing; -pub mod serialization; pub mod strided_view; pub mod timing; +#[cfg(feature = "std")] +pub mod serialization; + pub(crate) fn transpose_poly_values(polys: Vec>) -> Vec> { let poly_values = polys.into_iter().map(|p| p.values).collect::>(); transpose(&poly_values) diff --git a/plonky2/src/util/partial_products.rs b/plonky2/src/util/partial_products.rs index 9fad9dc8..c1b2e979 100644 --- a/plonky2/src/util/partial_products.rs +++ b/plonky2/src/util/partial_products.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use core::iter; use itertools::Itertools; diff --git a/plonky2/src/util/reducing.rs b/plonky2/src/util/reducing.rs index 9702e196..f91dbb19 100644 --- a/plonky2/src/util/reducing.rs +++ b/plonky2/src/util/reducing.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::borrow::Borrow; use plonky2_field::extension::{Extendable, FieldExtension}; diff --git a/util/src/lib.rs b/util/src/lib.rs index b22a4236..6662f7c0 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -4,16 +4,20 @@ #![allow(clippy::len_without_is_empty)] #![allow(clippy::needless_range_loop)] #![allow(clippy::return_self_not_must_use)] +#![no_std] -use std::arch::asm; -use std::hint::unreachable_unchecked; -use std::mem::size_of; -use std::ptr::{swap, swap_nonoverlapping}; +extern crate alloc; -mod transpose_util; +use alloc::vec::Vec; +use core::arch::asm; +use core::hint::unreachable_unchecked; +use core::mem::size_of; +use core::ptr::{swap, swap_nonoverlapping}; use crate::transpose_util::transpose_in_place_square; +mod transpose_util; + pub fn bits_u64(n: u64) -> usize { (64 - n.leading_zeros()) as usize } diff --git a/util/src/transpose_util.rs b/util/src/transpose_util.rs index 1c8280a8..a79a7adb 100644 --- a/util/src/transpose_util.rs +++ b/util/src/transpose_util.rs @@ -1,4 +1,4 @@ -use std::ptr::swap; +use core::ptr::swap; const LB_BLOCK_SIZE: usize = 3; From 4aaf57e9a992844842dd157d8852ff495d27dd3d Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Wed, 2 Nov 2022 21:07:51 -0700 Subject: [PATCH 04/49] feat: separate reading and writing to get infallible writers Signed-off-by: Brandon H. Gomes --- plonky2/Cargo.toml | 20 +- plonky2/src/fri/proof.rs | 2 +- plonky2/src/gates/gate.rs | 2 +- plonky2/src/hash/keccak.rs | 7 +- plonky2/src/hash/path_compression.rs | 2 +- plonky2/src/iop/witness.rs | 2 +- plonky2/src/plonk/circuit_builder.rs | 5 +- plonky2/src/plonk/get_challenges.rs | 2 +- plonky2/src/plonk/permutation_argument.rs | 2 +- plonky2/src/plonk/proof.rs | 22 +- plonky2/src/util/context_tree.rs | 2 +- plonky2/src/util/mod.rs | 5 +- plonky2/src/util/serialization.rs | 897 ++++++++++++++-------- util/src/lib.rs | 10 + 14 files changed, 612 insertions(+), 368 deletions(-) diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index 6de787d2..b74cc151 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -11,27 +11,17 @@ edition = "2021" default-run = "generate_constants" [features] -default = [ - "gate_testing", - "parallel", - "rand", - "rand_chacha", - "std", - "timing", -] -rand = [ - "dep:rand", - "num/rand", - "plonky2_field/rand" -] +default = ["gate_testing", "parallel", "rand", "rand_chacha", "std", "timing"] +rand = ["dep:rand", "num/rand", "plonky2_field/rand"] gate_testing = ["rand"] -parallel = ["maybe_rayon/parallel"] -std = ["anyhow/std"] +parallel = ["hashbrown/rayon", "maybe_rayon/parallel"] +std = ["anyhow/std", "rand/std"] timing = [] [dependencies] anyhow = { version = "1.0.40", default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } +hashbrown = { version = "0.12.3", default-features = false, features = ["ahash", "serde"] } itertools = { version = "0.10.0", default-features = false } keccak-hash = { version = "0.8.0", default-features = false } log = { version = "0.4.14", default-features = false } diff --git a/plonky2/src/fri/proof.rs b/plonky2/src/fri/proof.rs index 2404a7bd..c3d3ecbb 100644 --- a/plonky2/src/fri/proof.rs +++ b/plonky2/src/fri/proof.rs @@ -1,7 +1,7 @@ use alloc::vec; use alloc::vec::Vec; -use std::collections::HashMap; +use hashbrown::HashMap; use itertools::izip; use plonky2_field::extension::{flatten, unflatten, Extendable}; use plonky2_field::polynomial::PolynomialCoeffs; diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index 648bf779..7b2db413 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -6,8 +6,8 @@ use alloc::vec::Vec; use core::fmt::{Debug, Error, Formatter}; use core::hash::{Hash, Hasher}; use core::ops::Range; -use std::collections::HashMap; +use hashbrown::HashMap; use plonky2_field::batch_util::batch_multiply_inplace; use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::types::Field; diff --git a/plonky2/src/hash/keccak.rs b/plonky2/src/hash/keccak.rs index 1a4f5472..0efa154c 100644 --- a/plonky2/src/hash/keccak.rs +++ b/plonky2/src/hash/keccak.rs @@ -9,7 +9,7 @@ use keccak_hash::keccak; use crate::hash::hash_types::{BytesHash, RichField}; use crate::hash::hashing::{PlonkyPermutation, SPONGE_WIDTH}; use crate::plonk::config::Hasher; -use crate::util::serialization::Buffer; +use crate::util::serialization::Write; /// Keccak-256 pseudo-permutation (not necessarily one-to-one) used in the challenger. /// A state `input: [F; 12]` is sent to the field representation of `H(input) || H(H(input)) || H(H(H(input)))` @@ -53,16 +53,17 @@ impl PlonkyPermutation for KeccakPermutation { /// Keccak-256 hash function. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct KeccakHash; + impl Hasher for KeccakHash { const HASH_SIZE: usize = N; type Hash = BytesHash; type Permutation = KeccakPermutation; fn hash_no_pad(input: &[F]) -> Self::Hash { - let mut buffer = Buffer::new(Vec::new()); + let mut buffer = Vec::new(); buffer.write_field_vec(input).unwrap(); let mut arr = [0; N]; - let hash_bytes = keccak(buffer.bytes()).0; + let hash_bytes = keccak(buffer).0; arr.copy_from_slice(&hash_bytes[..N]); BytesHash(arr) } diff --git a/plonky2/src/hash/path_compression.rs b/plonky2/src/hash/path_compression.rs index ed3f49b8..ed93b25d 100644 --- a/plonky2/src/hash/path_compression.rs +++ b/plonky2/src/hash/path_compression.rs @@ -1,7 +1,7 @@ use alloc::vec; use alloc::vec::Vec; -use std::collections::HashMap; +use hashbrown::HashMap; use num::Integer; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/iop/witness.rs b/plonky2/src/iop/witness.rs index ef0ff7ae..a7cdf1f4 100644 --- a/plonky2/src/iop/witness.rs +++ b/plonky2/src/iop/witness.rs @@ -1,7 +1,7 @@ use alloc::vec; use alloc::vec::Vec; -use std::collections::HashMap; +use hashbrown::HashMap; use itertools::Itertools; use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::types::Field; diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 06b11c05..deb46442 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -3,9 +3,10 @@ use alloc::collections::BTreeMap; use alloc::vec; use alloc::vec::Vec; use core::cmp::max; -use std::collections::{HashMap, HashSet}; +#[cfg(feature = "std")] use std::time::Instant; +use hashbrown::{HashMap, HashSet}; use itertools::Itertools; use log::{debug, info, Level}; use plonky2_field::cosets::get_unique_coset_shifts; @@ -692,6 +693,7 @@ impl, const D: usize> CircuitBuilder { /// Builds a "full circuit", with both prover and verifier data. pub fn build>(mut self) -> CircuitData { let mut timing = TimingTree::new("preprocess", Level::Trace); + #[cfg(feature = "std")] let start = Instant::now(); let rate_bits = self.config.fri_config.rate_bits; let cap_height = self.config.fri_config.cap_height; @@ -879,6 +881,7 @@ impl, const D: usize> CircuitBuilder { }; timing.print(); + #[cfg(feature = "std")] debug!("Building circuit took {}s", start.elapsed().as_secs_f32()); CircuitData { prover_only, diff --git a/plonky2/src/plonk/get_challenges.rs b/plonky2/src/plonk/get_challenges.rs index f0635d93..4c4785f8 100644 --- a/plonky2/src/plonk/get_challenges.rs +++ b/plonky2/src/plonk/get_challenges.rs @@ -1,7 +1,7 @@ use alloc::vec; use alloc::vec::Vec; -use std::collections::HashSet; +use hashbrown::HashSet; use plonky2_field::extension::Extendable; use plonky2_field::polynomial::PolynomialCoeffs; diff --git a/plonky2/src/plonk/permutation_argument.rs b/plonky2/src/plonk/permutation_argument.rs index d9d56f93..2400516a 100644 --- a/plonky2/src/plonk/permutation_argument.rs +++ b/plonky2/src/plonk/permutation_argument.rs @@ -1,6 +1,6 @@ use alloc::vec::Vec; -use std::collections::HashMap; +use hashbrown::HashMap; use maybe_rayon::*; use plonky2_field::polynomial::PolynomialValues; use plonky2_field::types::Field; diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index a2a60d8c..a8a2f418 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -21,7 +21,9 @@ use crate::iop::target::Target; use crate::plonk::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData}; use crate::plonk::config::{GenericConfig, Hasher}; use crate::plonk::verifier::verify_with_challenges; -use crate::util::serialization::Buffer; +use crate::util::serialization::Write; +#[cfg(feature = "std")] +use crate::util::serialization::{Buffer, Read}; #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)] #[serde(bound = "")] @@ -101,12 +103,13 @@ impl, C: GenericConfig, const D: usize> C::InnerHasher::hash_no_pad(&self.public_inputs) } - pub fn to_bytes(&self) -> anyhow::Result> { - let mut buffer = Buffer::new(Vec::new()); - buffer.write_proof_with_public_inputs(self)?; - Ok(buffer.bytes()) + pub fn to_bytes(&self) -> Vec { + let mut buffer = Vec::new(); + let _ = buffer.write_proof_with_public_inputs(self); + buffer } + #[cfg(feature = "std")] pub fn from_bytes( bytes: Vec, common_data: &CommonCircuitData, @@ -226,11 +229,10 @@ impl, C: GenericConfig, const D: usize> C::InnerHasher::hash_no_pad(&self.public_inputs) } - #[cfg(feature = "std")] - pub fn to_bytes(&self) -> anyhow::Result> { - let mut buffer = Buffer::new(Vec::new()); - buffer.write_compressed_proof_with_public_inputs(self)?; - Ok(buffer.bytes()) + pub fn to_bytes(&self) -> Vec { + let mut buffer = Vec::new(); + let _ = buffer.write_compressed_proof_with_public_inputs(self); + buffer } #[cfg(feature = "std")] diff --git a/plonky2/src/util/context_tree.rs b/plonky2/src/util/context_tree.rs index bc37b2b0..565e2d35 100644 --- a/plonky2/src/util/context_tree.rs +++ b/plonky2/src/util/context_tree.rs @@ -1,4 +1,4 @@ -use alloc::string::String; +use alloc::string::{String, ToString}; use alloc::vec; use alloc::vec::Vec; diff --git a/plonky2/src/util/mod.rs b/plonky2/src/util/mod.rs index d978dbc5..2c61b399 100644 --- a/plonky2/src/util/mod.rs +++ b/plonky2/src/util/mod.rs @@ -6,13 +6,12 @@ use plonky2_field::types::Field; pub(crate) mod context_tree; pub(crate) mod partial_products; + pub mod reducing; +pub mod serialization; pub mod strided_view; pub mod timing; -#[cfg(feature = "std")] -pub mod serialization; - pub(crate) fn transpose_poly_values(polys: Vec>) -> Vec> { let poly_values = polys.into_iter().map(|p| p.values).collect::>(); transpose(&poly_values) diff --git a/plonky2/src/util/serialization.rs b/plonky2/src/util/serialization.rs index de8961ae..b5c7ef5c 100644 --- a/plonky2/src/util/serialization.rs +++ b/plonky2/src/util/serialization.rs @@ -1,6 +1,10 @@ -use std::collections::HashMap; -use std::io::{Cursor, Read, Result, Write}; +use alloc::vec; +use alloc::vec::Vec; +use core::convert::Infallible; +#[cfg(feature = "std")] +use std::io::{self, Cursor, Read as _, Write as _}; +use hashbrown::HashMap; use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::polynomial::PolynomialCoeffs; use plonky2_field::types::{Field64, PrimeField64}; @@ -19,65 +23,72 @@ use crate::plonk::proof::{ CompressedProof, CompressedProofWithPublicInputs, OpeningSet, Proof, ProofWithPublicInputs, }; -#[derive(Debug)] -pub struct Buffer(Cursor>); +/// Buffer Position +pub trait Position { + /// Returns the position of the buffer. + fn position(&self) -> u64; +} -impl Buffer { - pub fn new(buffer: Vec) -> Self { - Self(Cursor::new(buffer)) - } +/// Buffer Size +pub trait Size { + /// Returns the length of `self`. + fn len(&self) -> usize; - pub fn len(&self) -> usize { - self.0.get_ref().len() - } - - pub fn is_empty(&self) -> bool { + /// Returns `true` if `self` has length zero. + #[inline] + fn is_empty(&self) -> bool { self.len() == 0 } +} - pub fn bytes(self) -> Vec { - self.0.into_inner() +impl Size for Vec { + #[inline] + fn len(&self) -> usize { + self.len() } +} - fn write_u8(&mut self, x: u8) -> Result<()> { - self.0.write_all(&[x]) - } - fn read_u8(&mut self) -> Result { - let mut buf = [0; std::mem::size_of::()]; - self.0.read_exact(&mut buf)?; +/// +pub trait Read { + /// + type Error; + + /// + fn read_exact(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error>; + + /// + #[inline] + fn read_u8(&mut self) -> Result { + let mut buf = [0; core::mem::size_of::()]; + self.read_exact(&mut buf)?; Ok(buf[0]) } - fn write_u32(&mut self, x: u32) -> Result<()> { - self.0.write_all(&x.to_le_bytes()) - } - fn read_u32(&mut self) -> Result { - let mut buf = [0; std::mem::size_of::()]; - self.0.read_exact(&mut buf)?; + /// + #[inline] + fn read_u32(&mut self) -> Result { + let mut buf = [0; core::mem::size_of::()]; + self.read_exact(&mut buf)?; Ok(u32::from_le_bytes(buf)) } - fn write_field(&mut self, x: F) -> Result<()> { - self.0.write_all(&x.to_canonical_u64().to_le_bytes()) - } - fn read_field(&mut self) -> Result { - let mut buf = [0; std::mem::size_of::()]; - self.0.read_exact(&mut buf)?; + /// + #[inline] + fn read_field(&mut self) -> Result + where + F: Field64, + { + let mut buf = [0; core::mem::size_of::()]; + self.read_exact(&mut buf)?; Ok(F::from_canonical_u64(u64::from_le_bytes(buf))) } - fn write_field_ext, const D: usize>( - &mut self, - x: F::Extension, - ) -> Result<()> { - for &a in &x.to_basefield_array() { - self.write_field(a)?; - } - Ok(()) - } - fn read_field_ext, const D: usize>( - &mut self, - ) -> Result { + /// + #[inline] + fn read_field_ext(&mut self) -> Result + where + F: RichField + Extendable, + { let mut arr = [F::ZERO; D]; for a in arr.iter_mut() { *a = self.read_field()?; @@ -87,87 +98,66 @@ impl Buffer { )) } - fn write_hash>(&mut self, h: H::Hash) -> Result<()> { - self.0.write_all(&h.to_bytes()) - } - - fn read_hash>(&mut self) -> Result { + /// + #[inline] + fn read_hash(&mut self) -> Result + where + F: RichField, + H: Hasher, + { let mut buf = vec![0; H::HASH_SIZE]; - self.0.read_exact(&mut buf)?; + self.read_exact(&mut buf)?; Ok(H::Hash::from_bytes(&buf)) } - fn write_merkle_cap>( - &mut self, - cap: &MerkleCap, - ) -> Result<()> { - for &a in &cap.0 { - self.write_hash::(a)?; - } - Ok(()) - } - fn read_merkle_cap>( - &mut self, - cap_height: usize, - ) -> Result> { + /// + #[inline] + fn read_merkle_cap(&mut self, cap_height: usize) -> Result, Self::Error> + where + F: RichField, + H: Hasher, + { let cap_length = 1 << cap_height; Ok(MerkleCap( (0..cap_length) .map(|_| self.read_hash::()) - .collect::>>()?, + .collect::, _>>()?, )) } - pub fn write_field_vec(&mut self, v: &[F]) -> Result<()> { - for &a in v { - self.write_field(a)?; - } - Ok(()) - } - pub fn read_field_vec(&mut self, length: usize) -> Result> { + /// + #[inline] + fn read_field_vec(&mut self, length: usize) -> Result, Self::Error> + where + F: Field64, + { (0..length) .map(|_| self.read_field()) - .collect::>>() + .collect::, _>>() } - fn write_field_ext_vec, const D: usize>( - &mut self, - v: &[F::Extension], - ) -> Result<()> { - for &a in v { - self.write_field_ext::(a)?; - } - Ok(()) - } - fn read_field_ext_vec, const D: usize>( + /// + #[inline] + fn read_field_ext_vec( &mut self, length: usize, - ) -> Result> { - (0..length) - .map(|_| self.read_field_ext::()) - .collect::>>() + ) -> Result, Self::Error> + where + F: RichField + Extendable, + { + (0..length).map(|_| self.read_field_ext::()).collect() } - fn write_opening_set, const D: usize>( - &mut self, - os: &OpeningSet, - ) -> Result<()> { - self.write_field_ext_vec::(&os.constants)?; - self.write_field_ext_vec::(&os.plonk_sigmas)?; - self.write_field_ext_vec::(&os.wires)?; - self.write_field_ext_vec::(&os.plonk_zs)?; - self.write_field_ext_vec::(&os.plonk_zs_next)?; - self.write_field_ext_vec::(&os.partial_products)?; - self.write_field_ext_vec::(&os.quotient_polys) - } - fn read_opening_set< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( + /// + #[inline] + fn read_opening_set( &mut self, common_data: &CommonCircuitData, - ) -> Result> { + ) -> Result, Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let config = &common_data.config; let constants = self.read_field_ext_vec::(common_data.num_constants)?; let plonk_sigmas = self.read_field_ext_vec::(config.num_routed_wires)?; @@ -190,52 +180,31 @@ impl Buffer { }) } - fn write_merkle_proof>( - &mut self, - p: &MerkleProof, - ) -> Result<()> { - let length = p.siblings.len(); - self.write_u8( - length - .try_into() - .expect("Merkle proof length must fit in u8."), - )?; - for &h in &p.siblings { - self.write_hash::(h)?; - } - Ok(()) - } - fn read_merkle_proof>(&mut self) -> Result> { + /// + #[inline] + fn read_merkle_proof(&mut self) -> Result, Self::Error> + where + F: RichField, + H: Hasher, + { let length = self.read_u8()?; Ok(MerkleProof { siblings: (0..length) .map(|_| self.read_hash::()) - .collect::>>()?, + .collect::, _>>()?, }) } - fn write_fri_initial_proof< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - &mut self, - fitp: &FriInitialTreeProof, - ) -> Result<()> { - for (v, p) in &fitp.evals_proofs { - self.write_field_vec(v)?; - self.write_merkle_proof(p)?; - } - Ok(()) - } - fn read_fri_initial_proof< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( + /// + #[inline] + fn read_fri_initial_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result> { + ) -> Result, Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let config = &common_data.config; let salt = salt_size(common_data.fri_params.hiding); let mut evals_proofs = Vec::with_capacity(4); @@ -263,26 +232,17 @@ impl Buffer { Ok(FriInitialTreeProof { evals_proofs }) } - fn write_fri_query_step< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - &mut self, - fqs: &FriQueryStep, - ) -> Result<()> { - self.write_field_ext_vec::(&fqs.evals)?; - self.write_merkle_proof(&fqs.merkle_proof) - } - fn read_fri_query_step< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( + /// + #[inline] + fn read_fri_query_step( &mut self, arity: usize, compressed: bool, - ) -> Result> { + ) -> Result, Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let evals = self.read_field_ext_vec::(arity - usize::from(compressed))?; let merkle_proof = self.read_merkle_proof()?; Ok(FriQueryStep { @@ -291,30 +251,16 @@ impl Buffer { }) } - fn write_fri_query_rounds< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - &mut self, - fqrs: &[FriQueryRound], - ) -> Result<()> { - for fqr in fqrs { - self.write_fri_initial_proof::(&fqr.initial_trees_proof)?; - for fqs in &fqr.steps { - self.write_fri_query_step::(fqs)?; - } - } - Ok(()) - } - fn read_fri_query_rounds< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( + /// + #[inline] + fn read_fri_query_rounds( &mut self, common_data: &CommonCircuitData, - ) -> Result>> { + ) -> Result>, Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let config = &common_data.config; let mut fqrs = Vec::with_capacity(config.fri_config.num_query_rounds); for _ in 0..config.fri_config.num_query_rounds { @@ -324,7 +270,7 @@ impl Buffer { .reduction_arity_bits .iter() .map(|&ar| self.read_fri_query_step::(1 << ar, false)) - .collect::>()?; + .collect::>()?; fqrs.push(FriQueryRound { initial_trees_proof, steps, @@ -333,25 +279,20 @@ impl Buffer { Ok(fqrs) } - fn write_fri_proof, C: GenericConfig, const D: usize>( - &mut self, - fp: &FriProof, - ) -> Result<()> { - for cap in &fp.commit_phase_merkle_caps { - self.write_merkle_cap(cap)?; - } - self.write_fri_query_rounds::(&fp.query_round_proofs)?; - self.write_field_ext_vec::(&fp.final_poly.coeffs)?; - self.write_field(fp.pow_witness) - } - fn read_fri_proof, C: GenericConfig, const D: usize>( + /// + #[inline] + fn read_fri_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result> { + ) -> Result, Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let config = &common_data.config; let commit_phase_merkle_caps = (0..common_data.fri_params.reduction_arity_bits.len()) .map(|_| self.read_merkle_cap(config.fri_config.cap_height)) - .collect::>>()?; + .collect::, _>>()?; let query_round_proofs = self.read_fri_query_rounds::(common_data)?; let final_poly = PolynomialCoeffs::new( self.read_field_ext_vec::(common_data.fri_params.final_poly_len())?, @@ -365,27 +306,22 @@ impl Buffer { }) } - pub fn write_proof, C: GenericConfig, const D: usize>( - &mut self, - proof: &Proof, - ) -> Result<()> { - self.write_merkle_cap(&proof.wires_cap)?; - self.write_merkle_cap(&proof.plonk_zs_partial_products_cap)?; - self.write_merkle_cap(&proof.quotient_polys_cap)?; - self.write_opening_set(&proof.openings)?; - self.write_fri_proof::(&proof.opening_proof) - } - pub fn read_proof, C: GenericConfig, const D: usize>( + /// + #[inline] + fn read_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result> { + ) -> Result, Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let config = &common_data.config; let wires_cap = self.read_merkle_cap(config.fri_config.cap_height)?; let plonk_zs_partial_products_cap = self.read_merkle_cap(config.fri_config.cap_height)?; let quotient_polys_cap = self.read_merkle_cap(config.fri_config.cap_height)?; let openings = self.read_opening_set::(common_data)?; let opening_proof = self.read_fri_proof::(common_data)?; - Ok(Proof { wires_cap, plonk_zs_partial_products_cap, @@ -395,78 +331,41 @@ impl Buffer { }) } - pub fn write_proof_with_public_inputs< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - &mut self, - proof_with_pis: &ProofWithPublicInputs, - ) -> Result<()> { - let ProofWithPublicInputs { - proof, - public_inputs, - } = proof_with_pis; - self.write_proof(proof)?; - self.write_field_vec(public_inputs) - } - pub fn read_proof_with_public_inputs< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( + /// + #[inline] + fn read_proof_with_public_inputs( &mut self, common_data: &CommonCircuitData, - ) -> Result> { + ) -> Result, Self::Error> + where + Self: Position + Size, + F: RichField + Extendable, + C: GenericConfig, + { let proof = self.read_proof(common_data)?; let public_inputs = self.read_field_vec( - (self.len() - self.0.position() as usize) / std::mem::size_of::(), + (self.len() - self.position() as usize) / core::mem::size_of::(), )?; - Ok(ProofWithPublicInputs { proof, public_inputs, }) } - fn write_compressed_fri_query_rounds< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - &mut self, - cfqrs: &CompressedFriQueryRounds, - ) -> Result<()> { - for &i in &cfqrs.indices { - self.write_u32(i as u32)?; - } - - let mut initial_trees_proofs = cfqrs.initial_trees_proofs.iter().collect::>(); - initial_trees_proofs.sort_by_key(|&x| x.0); - for (_, itp) in initial_trees_proofs { - self.write_fri_initial_proof::(itp)?; - } - for h in &cfqrs.steps { - let mut fri_query_steps = h.iter().collect::>(); - fri_query_steps.sort_by_key(|&x| x.0); - for (_, fqs) in fri_query_steps { - self.write_fri_query_step::(fqs)?; - } - } - Ok(()) - } - fn read_compressed_fri_query_rounds< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( + /// + #[inline] + fn read_compressed_fri_query_rounds( &mut self, common_data: &CommonCircuitData, - ) -> Result> { + ) -> Result, Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let config = &common_data.config; let original_indices = (0..config.fri_config.num_query_rounds) .map(|_| self.read_u32().map(|i| i as usize)) - .collect::>>()?; + .collect::, _>>()?; let mut indices = original_indices.clone(); indices.sort_unstable(); indices.dedup(); @@ -484,7 +383,7 @@ impl Buffer { indices.dedup(); let query_steps = (0..indices.len()) .map(|_| self.read_fri_query_step::(1 << a, true)) - .collect::>>()?; + .collect::, _>>()?; steps.push( indices .iter() @@ -501,33 +400,20 @@ impl Buffer { }) } - fn write_compressed_fri_proof< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - &mut self, - fp: &CompressedFriProof, - ) -> Result<()> { - for cap in &fp.commit_phase_merkle_caps { - self.write_merkle_cap(cap)?; - } - self.write_compressed_fri_query_rounds::(&fp.query_round_proofs)?; - self.write_field_ext_vec::(&fp.final_poly.coeffs)?; - self.write_field(fp.pow_witness) - } - fn read_compressed_fri_proof< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( + /// + #[inline] + fn read_compressed_fri_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result> { + ) -> Result, Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let config = &common_data.config; let commit_phase_merkle_caps = (0..common_data.fri_params.reduction_arity_bits.len()) .map(|_| self.read_merkle_cap(config.fri_config.cap_height)) - .collect::>>()?; + .collect::, _>>()?; let query_round_proofs = self.read_compressed_fri_query_rounds::(common_data)?; let final_poly = PolynomialCoeffs::new( self.read_field_ext_vec::(common_data.fri_params.final_poly_len())?, @@ -541,35 +427,22 @@ impl Buffer { }) } - pub fn write_compressed_proof< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - &mut self, - proof: &CompressedProof, - ) -> Result<()> { - self.write_merkle_cap(&proof.wires_cap)?; - self.write_merkle_cap(&proof.plonk_zs_partial_products_cap)?; - self.write_merkle_cap(&proof.quotient_polys_cap)?; - self.write_opening_set(&proof.openings)?; - self.write_compressed_fri_proof::(&proof.opening_proof) - } - pub fn read_compressed_proof< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( + /// + #[inline] + fn read_compressed_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result> { + ) -> Result, Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let config = &common_data.config; let wires_cap = self.read_merkle_cap(config.fri_config.cap_height)?; let plonk_zs_partial_products_cap = self.read_merkle_cap(config.fri_config.cap_height)?; let quotient_polys_cap = self.read_merkle_cap(config.fri_config.cap_height)?; let openings = self.read_opening_set::(common_data)?; let opening_proof = self.read_compressed_fri_proof::(common_data)?; - Ok(CompressedProof { wires_cap, plonk_zs_partial_products_cap, @@ -579,14 +452,332 @@ impl Buffer { }) } - pub fn write_compressed_proof_with_public_inputs< + /// + #[inline] + fn read_compressed_proof_with_public_inputs( + &mut self, + common_data: &CommonCircuitData, + ) -> Result, Self::Error> + where + Self: Position + Size, F: RichField + Extendable, C: GenericConfig, - const D: usize, - >( + { + let proof = self.read_compressed_proof(common_data)?; + let public_inputs = self.read_field_vec( + (self.len() - self.position() as usize) / core::mem::size_of::(), + )?; + Ok(CompressedProofWithPublicInputs { + proof, + public_inputs, + }) + } +} + +/// +pub trait Write { + /// + type Error; + + /// + fn write_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error>; + + /// + #[inline] + fn write_u8(&mut self, x: u8) -> Result<(), Self::Error> { + self.write_all(&[x]) + } + + /// + #[inline] + fn write_u32(&mut self, x: u32) -> Result<(), Self::Error> { + self.write_all(&x.to_le_bytes()) + } + + /// + #[inline] + fn write_field(&mut self, x: F) -> Result<(), Self::Error> + where + F: PrimeField64, + { + self.write_all(&x.to_canonical_u64().to_le_bytes()) + } + + /// + #[inline] + fn write_field_ext(&mut self, x: F::Extension) -> Result<(), Self::Error> + where + F: RichField + Extendable, + { + for &a in &x.to_basefield_array() { + self.write_field(a)?; + } + Ok(()) + } + + /// + #[inline] + fn write_hash(&mut self, h: H::Hash) -> Result<(), Self::Error> + where + F: RichField, + H: Hasher, + { + self.write_all(&h.to_bytes()) + } + + /// + #[inline] + fn write_merkle_cap(&mut self, cap: &MerkleCap) -> Result<(), Self::Error> + where + F: RichField, + H: Hasher, + { + for &a in &cap.0 { + self.write_hash::(a)?; + } + Ok(()) + } + + /// + #[inline] + fn write_field_vec(&mut self, v: &[F]) -> Result<(), Self::Error> + where + F: PrimeField64, + { + for &a in v { + self.write_field(a)?; + } + Ok(()) + } + + /// + #[inline] + fn write_field_ext_vec( + &mut self, + v: &[F::Extension], + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + { + for &a in v { + self.write_field_ext::(a)?; + } + Ok(()) + } + + /// + #[inline] + fn write_opening_set( + &mut self, + os: &OpeningSet, + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + { + self.write_field_ext_vec::(&os.constants)?; + self.write_field_ext_vec::(&os.plonk_sigmas)?; + self.write_field_ext_vec::(&os.wires)?; + self.write_field_ext_vec::(&os.plonk_zs)?; + self.write_field_ext_vec::(&os.plonk_zs_next)?; + self.write_field_ext_vec::(&os.partial_products)?; + self.write_field_ext_vec::(&os.quotient_polys) + } + + /// + #[inline] + fn write_merkle_proof(&mut self, p: &MerkleProof) -> Result<(), Self::Error> + where + F: RichField, + H: Hasher, + { + let length = p.siblings.len(); + self.write_u8( + length + .try_into() + .expect("Merkle proof length must fit in u8."), + )?; + for &h in &p.siblings { + self.write_hash::(h)?; + } + Ok(()) + } + + /// + #[inline] + fn write_fri_initial_proof( + &mut self, + fitp: &FriInitialTreeProof, + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { + for (v, p) in &fitp.evals_proofs { + self.write_field_vec(v)?; + self.write_merkle_proof(p)?; + } + Ok(()) + } + + /// + #[inline] + fn write_fri_query_step( + &mut self, + fqs: &FriQueryStep, + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { + self.write_field_ext_vec::(&fqs.evals)?; + self.write_merkle_proof(&fqs.merkle_proof) + } + + /// + #[inline] + fn write_fri_query_rounds( + &mut self, + fqrs: &[FriQueryRound], + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { + for fqr in fqrs { + self.write_fri_initial_proof::(&fqr.initial_trees_proof)?; + for fqs in &fqr.steps { + self.write_fri_query_step::(fqs)?; + } + } + Ok(()) + } + + /// + #[inline] + fn write_fri_proof( + &mut self, + fp: &FriProof, + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { + for cap in &fp.commit_phase_merkle_caps { + self.write_merkle_cap(cap)?; + } + self.write_fri_query_rounds::(&fp.query_round_proofs)?; + self.write_field_ext_vec::(&fp.final_poly.coeffs)?; + self.write_field(fp.pow_witness) + } + + /// + #[inline] + fn write_proof( + &mut self, + proof: &Proof, + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { + self.write_merkle_cap(&proof.wires_cap)?; + self.write_merkle_cap(&proof.plonk_zs_partial_products_cap)?; + self.write_merkle_cap(&proof.quotient_polys_cap)?; + self.write_opening_set(&proof.openings)?; + self.write_fri_proof::(&proof.opening_proof) + } + + /// + #[inline] + fn write_proof_with_public_inputs( + &mut self, + proof_with_pis: &ProofWithPublicInputs, + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { + let ProofWithPublicInputs { + proof, + public_inputs, + } = proof_with_pis; + self.write_proof(proof)?; + self.write_field_vec(public_inputs) + } + + /// + #[inline] + fn write_compressed_fri_query_rounds( + &mut self, + cfqrs: &CompressedFriQueryRounds, + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { + for &i in &cfqrs.indices { + self.write_u32(i as u32)?; + } + let mut initial_trees_proofs = cfqrs.initial_trees_proofs.iter().collect::>(); + initial_trees_proofs.sort_by_key(|&x| x.0); + for (_, itp) in initial_trees_proofs { + self.write_fri_initial_proof::(itp)?; + } + for h in &cfqrs.steps { + let mut fri_query_steps = h.iter().collect::>(); + fri_query_steps.sort_by_key(|&x| x.0); + for (_, fqs) in fri_query_steps { + self.write_fri_query_step::(fqs)?; + } + } + Ok(()) + } + + /// + #[inline] + fn write_compressed_fri_proof( + &mut self, + fp: &CompressedFriProof, + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { + for cap in &fp.commit_phase_merkle_caps { + self.write_merkle_cap(cap)?; + } + self.write_compressed_fri_query_rounds::(&fp.query_round_proofs)?; + self.write_field_ext_vec::(&fp.final_poly.coeffs)?; + self.write_field(fp.pow_witness) + } + + /// + #[inline] + fn write_compressed_proof( + &mut self, + proof: &CompressedProof, + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { + self.write_merkle_cap(&proof.wires_cap)?; + self.write_merkle_cap(&proof.plonk_zs_partial_products_cap)?; + self.write_merkle_cap(&proof.quotient_polys_cap)?; + self.write_opening_set(&proof.openings)?; + self.write_compressed_fri_proof::(&proof.opening_proof) + } + + /// + #[inline] + fn write_compressed_proof_with_public_inputs( &mut self, proof_with_pis: &CompressedProofWithPublicInputs, - ) -> Result<()> { + ) -> Result<(), Self::Error> + where + F: RichField + Extendable, + C: GenericConfig, + { let CompressedProofWithPublicInputs { proof, public_inputs, @@ -594,22 +785,70 @@ impl Buffer { self.write_compressed_proof(proof)?; self.write_field_vec(public_inputs) } - pub fn read_compressed_proof_with_public_inputs< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, - >( - &mut self, - common_data: &CommonCircuitData, - ) -> Result> { - let proof = self.read_compressed_proof(common_data)?; - let public_inputs = self.read_field_vec( - (self.len() - self.0.position() as usize) / std::mem::size_of::(), - )?; +} - Ok(CompressedProofWithPublicInputs { - proof, - public_inputs, - }) +impl Write for Vec { + type Error = Infallible; + + #[inline] + fn write_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { + self.extend_from_slice(bytes); + Ok(()) + } +} + +/// +#[cfg(feature = "std")] +#[derive(Debug)] +pub struct Buffer(Cursor>); + +#[cfg(feature = "std")] +impl Buffer { + /// + #[inline] + pub fn new(buffer: Vec) -> Self { + Self(Cursor::new(buffer)) + } + + /// + #[inline] + pub fn bytes(self) -> Vec { + self.0.into_inner() + } +} + +#[cfg(feature = "std")] +impl Size for Buffer { + #[inline] + fn len(&self) -> usize { + self.0.get_ref().len() + } +} + +#[cfg(feature = "std")] +impl Position for Buffer { + #[inline] + fn position(&self) -> u64 { + self.0.position() + } +} + +#[cfg(feature = "std")] +impl Read for Buffer { + type Error = io::Error; + + #[inline] + fn read_exact(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error> { + self.0.read_exact(bytes) + } +} + +#[cfg(feature = "std")] +impl Write for Buffer { + type Error = io::Error; + + #[inline] + fn write_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { + self.0.write_all(bytes) } } diff --git a/util/src/lib.rs b/util/src/lib.rs index 6662f7c0..c840bc69 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -10,6 +10,7 @@ extern crate alloc; use alloc::vec::Vec; use core::arch::asm; +use core::convert::Infallible; use core::hint::unreachable_unchecked; use core::mem::size_of; use core::ptr::{swap, swap_nonoverlapping}; @@ -18,6 +19,15 @@ use crate::transpose_util::transpose_in_place_square; mod transpose_util; +/// Converts `result` into the [`Ok`] variant of [`Result`]. +#[inline] +pub fn into_ok(result: Result) -> T { + match result { + Ok(value) => value, + _ => unreachable!("The `Infallible` value cannot be constructed."), + } +} + pub fn bits_u64(n: u64) -> usize { (64 - n.leading_zeros()) as usize } From e2cdd5a9548809979a7b4ed1e777f8c51b3c89a1 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 3 Nov 2022 08:26:03 -0700 Subject: [PATCH 05/49] feat: upgrade Sampling APIs Signed-off-by: Brandon H. Gomes --- ecdsa/Cargo.toml | 4 +- ecdsa/src/curve/ecdsa.rs | 4 +- ecdsa/src/curve/glv.rs | 2 +- ecdsa/src/gadgets/curve.rs | 4 +- ecdsa/src/gadgets/curve_fixed_base.rs | 2 +- ecdsa/src/gadgets/curve_msm.rs | 2 +- ecdsa/src/gadgets/curve_windowed_mul.rs | 6 +-- ecdsa/src/gadgets/ecdsa.rs | 2 +- ecdsa/src/gadgets/glv.rs | 2 +- ecdsa/src/gadgets/nonnative.rs | 2 +- ecdsa/src/gadgets/split_nonnative.rs | 2 +- evm/Cargo.toml | 2 +- evm/src/arithmetic/add.rs | 6 +-- evm/src/arithmetic/compare.rs | 6 +-- evm/src/arithmetic/modular.rs | 8 +-- evm/src/arithmetic/mul.rs | 6 +-- evm/src/arithmetic/sub.rs | 6 +-- evm/src/stark_testing.rs | 6 +-- evm/src/verifier.rs | 2 +- field/Cargo.toml | 10 ++-- field/src/extension/algebra.rs | 4 +- field/src/extension/quadratic.rs | 17 ++++--- field/src/extension/quartic.rs | 27 +++++----- field/src/extension/quintic.rs | 29 ++++++----- field/src/fft.rs | 4 +- field/src/field_testing.rs | 9 ++-- field/src/goldilocks_field.rs | 19 ++++--- field/src/interpolation.rs | 2 +- field/src/lib.rs | 2 +- field/src/polynomial/division.rs | 7 +-- field/src/polynomial/mod.rs | 16 +++--- field/src/prime_field_testing.rs | 2 + field/src/secp256k1_base.rs | 19 ++++--- field/src/secp256k1_scalar.rs | 19 ++++--- field/src/types.rs | 49 ++++++++++++------- insertion/src/insert_gadget.rs | 2 +- insertion/src/insertion_gate.rs | 4 +- plonky2/Cargo.toml | 14 +++--- plonky2/benches/hashing.rs | 3 +- plonky2/benches/merkle.rs | 1 + plonky2/benches/reverse_index_bits.rs | 2 +- plonky2/benches/transpose.rs | 2 +- plonky2/examples/bench_recursion.rs | 4 +- plonky2/examples/square_root.rs | 2 +- plonky2/src/gadgets/arithmetic_extension.rs | 6 +-- plonky2/src/gadgets/random_access.rs | 2 +- plonky2/src/gadgets/select.rs | 2 +- plonky2/src/gates/exponentiation.rs | 2 +- plonky2/src/gates/gate_testing.rs | 5 +- .../src/gates/high_degree_interpolation.rs | 2 +- plonky2/src/gates/interpolation.rs | 2 +- plonky2/src/gates/low_degree_interpolation.rs | 2 +- plonky2/src/gates/random_access.rs | 2 +- .../x86_64/poseidon_goldilocks_avx2_bmi2.rs | 8 +-- plonky2/src/hash/hash_types.rs | 42 ++++++++-------- plonky2/src/hash/path_compression.rs | 2 +- plonky2/src/iop/challenger.rs | 2 +- plonky2/src/iop/generator.rs | 1 - plonky2/src/plonk/proof.rs | 2 +- .../conditional_recursive_verifier.rs | 2 +- plonky2/src/recursion/cyclic_recursion.rs | 2 +- plonky2/src/recursion/recursive_verifier.rs | 8 ++- plonky2/src/util/reducing.rs | 1 + starky/Cargo.toml | 2 +- starky/src/stark_testing.rs | 10 ++-- starky/src/verifier.rs | 2 +- system_zero/src/alu/bitops.rs | 8 +-- system_zero/src/alu/division.rs | 6 +-- system_zero/src/permutation_unit.rs | 6 +-- u32/src/gates/add_many_u32.rs | 4 +- u32/src/gates/arithmetic_u32.rs | 4 +- u32/src/gates/comparison.rs | 4 +- u32/src/gates/range_check_u32.rs | 4 +- u32/src/gates/subtraction_u32.rs | 4 +- waksman/src/gates/assert_le.rs | 4 +- waksman/src/gates/switch.rs | 2 +- waksman/src/permutation.rs | 2 +- waksman/src/sorting.rs | 2 +- 78 files changed, 278 insertions(+), 224 deletions(-) diff --git a/ecdsa/Cargo.toml b/ecdsa/Cargo.toml index 99f355b9..ce00f3dc 100644 --- a/ecdsa/Cargo.toml +++ b/ecdsa/Cargo.toml @@ -13,6 +13,6 @@ plonky2_u32 = { path = "../u32" } num = "0.4.0" itertools = "0.10.0" rayon = "1.5.1" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1.0", default-features = false, features = ["derive"] } anyhow = "1.0.40" -rand = "0.8.4" \ No newline at end of file +rand = "0.8.4" diff --git a/ecdsa/src/curve/ecdsa.rs b/ecdsa/src/curve/ecdsa.rs index 0b2d396d..bbec08b5 100644 --- a/ecdsa/src/curve/ecdsa.rs +++ b/ecdsa/src/curve/ecdsa.rs @@ -1,4 +1,4 @@ -use plonky2_field::types::Field; +use plonky2_field::types::{Field, Sample}; use serde::{Deserialize, Serialize}; use crate::curve::curve_msm::msm_parallel; @@ -64,7 +64,7 @@ pub fn verify_message( #[cfg(test)] mod tests { use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use crate::curve::ecdsa::{sign_message, verify_message, ECDSASecretKey}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/curve/glv.rs b/ecdsa/src/curve/glv.rs index c58032ec..9cf9bc82 100644 --- a/ecdsa/src/curve/glv.rs +++ b/ecdsa/src/curve/glv.rs @@ -103,7 +103,7 @@ pub fn glv_mul(p: ProjectivePoint, k: Secp256K1Scalar) -> ProjectiveP mod tests { use anyhow::Result; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::curve::glv::{decompose_secp256k1_scalar, glv_mul, GLV_S}; diff --git a/ecdsa/src/gadgets/curve.rs b/ecdsa/src/gadgets/curve.rs index 4aa69733..0d50ba7f 100644 --- a/ecdsa/src/gadgets/curve.rs +++ b/ecdsa/src/gadgets/curve.rs @@ -2,7 +2,7 @@ use plonky2::hash::hash_types::RichField; use plonky2::iop::target::BoolTarget; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; +use plonky2_field::types::Sample; use crate::curve::curve_types::{AffinePoint, Curve, CurveScalar}; use crate::gadgets::nonnative::{CircuitBuilderNonNative, NonNativeTarget}; @@ -263,7 +263,7 @@ mod tests { use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::secp256k1_base::Secp256K1Base; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use crate::curve::curve_types::{AffinePoint, Curve, CurveScalar}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/gadgets/curve_fixed_base.rs b/ecdsa/src/gadgets/curve_fixed_base.rs index 31292ddb..0468fe01 100644 --- a/ecdsa/src/gadgets/curve_fixed_base.rs +++ b/ecdsa/src/gadgets/curve_fixed_base.rs @@ -71,7 +71,7 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::{Field, PrimeField}; + use plonky2_field::types::{PrimeField, Sample}; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/gadgets/curve_msm.rs b/ecdsa/src/gadgets/curve_msm.rs index e059638c..ba7c5a75 100644 --- a/ecdsa/src/gadgets/curve_msm.rs +++ b/ecdsa/src/gadgets/curve_msm.rs @@ -84,7 +84,7 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/gadgets/curve_windowed_mul.rs b/ecdsa/src/gadgets/curve_windowed_mul.rs index bc4e1caf..dce7a0e2 100644 --- a/ecdsa/src/gadgets/curve_windowed_mul.rs +++ b/ecdsa/src/gadgets/curve_windowed_mul.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use num::BigUint; use plonky2::hash::hash_types::RichField; @@ -7,7 +7,7 @@ use plonky2::iop::target::{BoolTarget, Target}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::config::{GenericHashOut, Hasher}; use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; +use plonky2_field::types::{Field, Sample}; use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target}; use crate::curve::curve_types::{Curve, CurveScalar}; @@ -177,7 +177,7 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use rand::Rng; use crate::curve::curve_types::{Curve, CurveScalar}; diff --git a/ecdsa/src/gadgets/ecdsa.rs b/ecdsa/src/gadgets/ecdsa.rs index 3ed6342d..fe2cc397 100644 --- a/ecdsa/src/gadgets/ecdsa.rs +++ b/ecdsa/src/gadgets/ecdsa.rs @@ -57,7 +57,7 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use super::{ECDSAPublicKeyTarget, ECDSASignatureTarget}; use crate::curve::curve_types::{Curve, CurveScalar}; diff --git a/ecdsa/src/gadgets/glv.rs b/ecdsa/src/gadgets/glv.rs index 539b5de3..00cf64d7 100644 --- a/ecdsa/src/gadgets/glv.rs +++ b/ecdsa/src/gadgets/glv.rs @@ -137,7 +137,7 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::curve::glv::glv_mul; diff --git a/ecdsa/src/gadgets/nonnative.rs b/ecdsa/src/gadgets/nonnative.rs index ad6315a1..ca865807 100644 --- a/ecdsa/src/gadgets/nonnative.rs +++ b/ecdsa/src/gadgets/nonnative.rs @@ -647,7 +647,7 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::secp256k1_base::Secp256K1Base; - use plonky2_field::types::{Field, PrimeField}; + use plonky2_field::types::{Field, PrimeField, Sample}; use crate::gadgets::nonnative::CircuitBuilderNonNative; diff --git a/ecdsa/src/gadgets/split_nonnative.rs b/ecdsa/src/gadgets/split_nonnative.rs index 5ee3a864..330c2ea1 100644 --- a/ecdsa/src/gadgets/split_nonnative.rs +++ b/ecdsa/src/gadgets/split_nonnative.rs @@ -101,7 +101,7 @@ mod tests { use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use crate::gadgets::nonnative::{CircuitBuilderNonNative, NonNativeTarget}; use crate::gadgets::split_nonnative::CircuitBuilderSplit; diff --git a/evm/Cargo.toml b/evm/Cargo.toml index cdb8b5d6..314a2b50 100644 --- a/evm/Cargo.toml +++ b/evm/Cargo.toml @@ -5,7 +5,7 @@ version = "0.1.0" edition = "2021" [dependencies] -plonky2 = { path = "../plonky2", default-features = false, features = ["rand", "timing"] } +plonky2 = { path = "../plonky2", default-features = false, features = ["timing"] } plonky2_util = { path = "../util" } eth_trie_utils = "0.4.0" anyhow = "1.0.40" diff --git a/evm/src/arithmetic/add.rs b/evm/src/arithmetic/add.rs index 1bf798cc..b09307b0 100644 --- a/evm/src/arithmetic/add.rs +++ b/evm/src/arithmetic/add.rs @@ -161,7 +161,7 @@ pub fn eval_ext_circuit, const D: usize>( #[cfg(test)] mod tests { use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::Field; + use plonky2::field::types::{Field, Sample}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; @@ -177,7 +177,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); // if `IS_ADD == 0`, then the constraints should be met even // if all values are garbage. @@ -200,7 +200,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); // set `IS_ADD == 1` and ensure all constraints are satisfied. lv[IS_ADD] = F::ONE; diff --git a/evm/src/arithmetic/compare.rs b/evm/src/arithmetic/compare.rs index 55dc5764..f4165260 100644 --- a/evm/src/arithmetic/compare.rs +++ b/evm/src/arithmetic/compare.rs @@ -162,7 +162,7 @@ pub fn eval_ext_circuit, const D: usize>( #[cfg(test)] mod tests { use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::Field; + use plonky2::field::types::{Field, Sample}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; @@ -176,7 +176,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); // if `IS_LT == 0`, then the constraints should be met even if // all values are garbage. `eval_packed_generic` handles IS_GT @@ -201,7 +201,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); const N_ITERS: usize = 1000; for _ in 0..N_ITERS { diff --git a/evm/src/arithmetic/modular.rs b/evm/src/arithmetic/modular.rs index d19768bf..09c3996e 100644 --- a/evm/src/arithmetic/modular.rs +++ b/evm/src/arithmetic/modular.rs @@ -501,7 +501,7 @@ pub(crate) fn eval_ext_circuit, const D: usize>( mod tests { use itertools::izip; use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::Field; + use plonky2::field::types::{Field, Sample}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; @@ -517,7 +517,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); // if `IS_ADDMOD == 0`, then the constraints should be met even // if all values are garbage. @@ -544,7 +544,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); for op_filter in [IS_ADDMOD, IS_DIV, IS_SUBMOD, IS_MOD, IS_MULMOD] { // Reset operation columns, then select one @@ -595,7 +595,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); for op_filter in [IS_ADDMOD, IS_SUBMOD, IS_DIV, IS_MOD, IS_MULMOD] { // Reset operation columns, then select one diff --git a/evm/src/arithmetic/mul.rs b/evm/src/arithmetic/mul.rs index 7dda18e2..d55ab27b 100644 --- a/evm/src/arithmetic/mul.rs +++ b/evm/src/arithmetic/mul.rs @@ -172,7 +172,7 @@ pub fn eval_ext_circuit, const D: usize>( #[cfg(test)] mod tests { use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::Field; + use plonky2::field::types::{Field, Sample}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; @@ -188,7 +188,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); // if `IS_MUL == 0`, then the constraints should be met even // if all values are garbage. @@ -211,7 +211,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); // set `IS_MUL == 1` and ensure all constraints are satisfied. lv[IS_MUL] = F::ONE; diff --git a/evm/src/arithmetic/sub.rs b/evm/src/arithmetic/sub.rs index f8377651..d589f323 100644 --- a/evm/src/arithmetic/sub.rs +++ b/evm/src/arithmetic/sub.rs @@ -93,7 +93,7 @@ pub fn eval_ext_circuit, const D: usize>( #[cfg(test)] mod tests { use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::Field; + use plonky2::field::types::{Field, Sample}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; @@ -109,7 +109,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); // if `IS_SUB == 0`, then the constraints should be met even // if all values are garbage. @@ -132,7 +132,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut lv = [F::default(); NUM_ARITH_COLUMNS].map(|_| F::sample(&mut rng)); // set `IS_SUB == 1` and ensure all constraints are satisfied. lv[IS_SUB] = F::ONE; diff --git a/evm/src/stark_testing.rs b/evm/src/stark_testing.rs index bd0df385..da628403 100644 --- a/evm/src/stark_testing.rs +++ b/evm/src/stark_testing.rs @@ -1,7 +1,7 @@ use anyhow::{ensure, Result}; use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues}; -use plonky2::field::types::Field; +use plonky2::field::types::{Field, Sample}; use plonky2::hash::hash_types::RichField; use plonky2::iop::witness::{PartialWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; @@ -90,8 +90,8 @@ where { // Compute native constraint evaluation on random values. let vars = StarkEvaluationVars { - local_values: &F::Extension::rand_arr::<{ S::COLUMNS }>(), - next_values: &F::Extension::rand_arr::<{ S::COLUMNS }>(), + local_values: &F::Extension::rand_array::<{ S::COLUMNS }>(), + next_values: &F::Extension::rand_array::<{ S::COLUMNS }>(), }; let alphas = F::rand_vec(1); let z_last = F::Extension::rand(); diff --git a/evm/src/verifier.rs b/evm/src/verifier.rs index 0bfbc3d4..ce15399a 100644 --- a/evm/src/verifier.rs +++ b/evm/src/verifier.rs @@ -275,7 +275,7 @@ fn eval_l_0_and_l_last(log_n: usize, x: F) -> (F, F) { mod tests { use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::polynomial::PolynomialValues; - use plonky2::field::types::Field; + use plonky2::field::types::Sample; use crate::verifier::eval_l_0_and_l_last; diff --git a/field/Cargo.toml b/field/Cargo.toml index 33bb76c2..1242dfe3 100644 --- a/field/Cargo.toml +++ b/field/Cargo.toml @@ -4,16 +4,12 @@ description = "Finite field arithmetic" version = "0.1.0" edition = "2021" -[features] -default = [] -rand = ["dep:rand", "num/rand"] - [dependencies] anyhow = { version = "1.0.40", default-features = false } -itertools = { version = "0.10.0", default-features = false } -num = { version = "0.4", default-features = false, features = ["alloc"] } +itertools = { version = "0.10.0", default-features = false, features = ["use_alloc"] } +num = { version = "0.4", default-features = false, features = ["alloc", "rand"] } plonky2_util = { path = "../util", default-features = false } -rand = { version = "0.8.5", optional = true, default-features = false, features = ["getrandom"] } +rand = { version = "0.8.5", default-features = false, features = ["getrandom"] } serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } static_assertions = { version = "1.1.0", default-features = false } unroll = { version = "0.1.5", default-features = false } diff --git a/field/src/extension/algebra.rs b/field/src/extension/algebra.rs index 6e309ba8..8ca939b2 100644 --- a/field/src/extension/algebra.rs +++ b/field/src/extension/algebra.rs @@ -191,12 +191,14 @@ impl, const D: usize> PolynomialCoeffsAlgebra { #[cfg(test)] mod tests { + use alloc::vec::Vec; + use itertools::Itertools; use crate::extension::algebra::ExtensionAlgebra; use crate::extension::{Extendable, FieldExtension}; use crate::goldilocks_field::GoldilocksField; - use crate::types::Field; + use crate::types::{Field, Sample}; /// Tests that the multiplication on the extension algebra lifts that of the field extension. fn test_extension_algebra, const D: usize>() { diff --git a/field/src/extension/quadratic.rs b/field/src/extension/quadratic.rs index 1909e35e..c0c9758b 100644 --- a/field/src/extension/quadratic.rs +++ b/field/src/extension/quadratic.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use crate::extension::{Extendable, FieldExtension, Frobenius, OEF}; use crate::ops::Square; -use crate::types::Field; +use crate::types::{Field, Sample}; #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(bound = "")] @@ -48,6 +48,16 @@ impl> From for QuadraticExtension { } } +impl> Sample for QuadraticExtension { + #[inline] + fn sample(rng: &mut R) -> Self + where + R: rand::RngCore + ?Sized, + { + Self([F::sample(rng), F::sample(rng)]) + } +} + impl> Field for QuadraticExtension { const ZERO: Self = Self([F::ZERO; 2]); const ONE: Self = Self([F::ONE, F::ZERO]); @@ -99,11 +109,6 @@ impl> Field for QuadraticExtension { fn from_noncanonical_u128(n: u128) -> Self { F::from_noncanonical_u128(n).into() } - - #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { - Self([F::rand_from_rng(rng), F::rand_from_rng(rng)]) - } } impl> Display for QuadraticExtension { diff --git a/field/src/extension/quartic.rs b/field/src/extension/quartic.rs index 948c29fb..e7aba63b 100644 --- a/field/src/extension/quartic.rs +++ b/field/src/extension/quartic.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::extension::{Extendable, FieldExtension, Frobenius, OEF}; use crate::ops::Square; -use crate::types::Field; +use crate::types::{Field, Sample}; #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(bound = "")] @@ -49,6 +49,21 @@ impl> From for QuarticExtension { } } +impl> Sample for QuarticExtension { + #[inline] + fn sample(rng: &mut R) -> Self + where + R: rand::RngCore + ?Sized, + { + Self::from_basefield_array([ + F::sample(rng), + F::sample(rng), + F::sample(rng), + F::sample(rng), + ]) + } +} + impl> Field for QuarticExtension { const ZERO: Self = Self([F::ZERO; 4]); const ONE: Self = Self([F::ONE, F::ZERO, F::ZERO, F::ZERO]); @@ -104,16 +119,6 @@ impl> Field for QuarticExtension { fn from_noncanonical_u128(n: u128) -> Self { F::from_noncanonical_u128(n).into() } - - #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { - Self::from_basefield_array([ - F::rand_from_rng(rng), - F::rand_from_rng(rng), - F::rand_from_rng(rng), - F::rand_from_rng(rng), - ]) - } } impl> Display for QuarticExtension { diff --git a/field/src/extension/quintic.rs b/field/src/extension/quintic.rs index 343e6f77..d4b605eb 100644 --- a/field/src/extension/quintic.rs +++ b/field/src/extension/quintic.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::extension::{Extendable, FieldExtension, Frobenius, OEF}; use crate::ops::Square; -use crate::types::Field; +use crate::types::{Field, Sample}; #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(bound = "")] @@ -49,6 +49,22 @@ impl> From for QuinticExtension { } } +impl> Sample for QuinticExtension { + #[inline] + fn sample(rng: &mut R) -> Self + where + R: rand::RngCore + ?Sized, + { + Self::from_basefield_array([ + F::sample(rng), + F::sample(rng), + F::sample(rng), + F::sample(rng), + F::sample(rng), + ]) + } +} + impl> Field for QuinticExtension { const ZERO: Self = Self([F::ZERO; 5]); const ONE: Self = Self([F::ONE, F::ZERO, F::ZERO, F::ZERO, F::ZERO]); @@ -110,17 +126,6 @@ impl> Field for QuinticExtension { fn from_noncanonical_u128(n: u128) -> Self { F::from_noncanonical_u128(n).into() } - - #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { - Self::from_basefield_array([ - F::rand_from_rng(rng), - F::rand_from_rng(rng), - F::rand_from_rng(rng), - F::rand_from_rng(rng), - F::rand_from_rng(rng), - ]) - } } impl> Display for QuinticExtension { diff --git a/field/src/fft.rs b/field/src/fft.rs index 8fb1809c..0a0b5dd8 100644 --- a/field/src/fft.rs +++ b/field/src/fft.rs @@ -207,6 +207,8 @@ pub(crate) fn fft_classic(values: &mut [F], r: usize, root_table: &Fft #[cfg(test)] mod tests { + use alloc::vec::Vec; + use plonky2_util::{log2_ceil, log2_strict}; use crate::fft::{fft, fft_with_options, ifft}; @@ -224,7 +226,7 @@ mod tests { // "random", the last degree_padded-degree of them are zero. let coeffs = (0..degree) .map(|i| F::from_canonical_usize(i * 1337 % 100)) - .chain(std::iter::repeat(F::ZERO).take(degree_padded - degree)) + .chain(core::iter::repeat(F::ZERO).take(degree_padded - degree)) .collect::>(); assert_eq!(coeffs.len(), degree_padded); let coefficients = PolynomialCoeffs { coeffs }; diff --git a/field/src/field_testing.rs b/field/src/field_testing.rs index 5e495311..4c53c234 100644 --- a/field/src/field_testing.rs +++ b/field/src/field_testing.rs @@ -1,14 +1,17 @@ use crate::extension::{Extendable, Frobenius}; use crate::ops::Square; -use crate::types::Field; +use crate::types::{Field, Sample}; #[macro_export] macro_rules! test_field_arithmetic { ($field:ty) => { mod field_arithmetic { + use alloc::vec::Vec; + use num::bigint::BigUint; + use rand::rngs::OsRng; use rand::Rng; - use $crate::types::Field; + use $crate::types::{Field, Sample}; #[test] fn batch_inversion() { @@ -71,7 +74,7 @@ macro_rules! test_field_arithmetic { fn exponentiation_large() { type F = $field; - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let base = F::rand(); let pow = BigUint::from(rng.gen::()); diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index 9c7e8d1b..12c8da3a 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -8,7 +8,7 @@ use plonky2_util::{assume, branch_hint}; use serde::{Deserialize, Serialize}; use crate::inversion::try_inverse_u64; -use crate::types::{Field, Field64, PrimeField, PrimeField64}; +use crate::types::{Field, Field64, PrimeField, PrimeField64, Sample}; const EPSILON: u64 = (1 << 32) - 1; @@ -56,6 +56,17 @@ impl Debug for GoldilocksField { } } +impl Sample for GoldilocksField { + #[inline] + fn sample(rng: &mut R) -> Self + where + R: rand::RngCore + ?Sized, + { + use rand::Rng; + Self::from_canonical_u64(rng.gen_range(0..Self::ORDER)) + } +} + impl Field for GoldilocksField { const ZERO: Self = Self(0); const ONE: Self = Self(1); @@ -103,12 +114,6 @@ impl Field for GoldilocksField { reduce128(n) } - #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { - use rand::Rng; - Self::from_canonical_u64(rng.gen_range(0..Self::ORDER)) - } - #[inline] fn multiply_accumulate(&self, x: Self, y: Self) -> Self { // u64 + u64 * u64 cannot overflow. diff --git a/field/src/interpolation.rs b/field/src/interpolation.rs index 4a42e4af..df708457 100644 --- a/field/src/interpolation.rs +++ b/field/src/interpolation.rs @@ -81,7 +81,7 @@ mod tests { use crate::extension::quartic::QuarticExtension; use crate::goldilocks_field::GoldilocksField; use crate::polynomial::PolynomialCoeffs; - use crate::types::Field; + use crate::types::{Field, Sample}; #[test] fn interpolant_random() { diff --git a/field/src/lib.rs b/field/src/lib.rs index 5459b38a..33db5c27 100644 --- a/field/src/lib.rs +++ b/field/src/lib.rs @@ -8,7 +8,7 @@ #![feature(generic_const_exprs)] #![feature(specialization)] #![feature(stdsimd)] -#![no_std] +#![cfg_attr(not(test), no_std)] extern crate alloc; diff --git a/field/src/polynomial/division.rs b/field/src/polynomial/division.rs index 14e16841..7d85d549 100644 --- a/field/src/polynomial/division.rs +++ b/field/src/polynomial/division.rs @@ -134,17 +134,18 @@ impl PolynomialCoeffs { #[cfg(test)] mod tests { - use rand::{thread_rng, Rng}; + use rand::rngs::OsRng; + use rand::Rng; use crate::extension::quartic::QuarticExtension; use crate::goldilocks_field::GoldilocksField; use crate::polynomial::PolynomialCoeffs; - use crate::types::Field; + use crate::types::{Field, Sample}; #[test] fn test_division_by_linear() { type F = QuarticExtension; - let n = thread_rng().gen_range(1..1000); + let n = OsRng.gen_range(1..1000); let poly = PolynomialCoeffs::new(F::rand_vec(n)); let z = F::rand(); let ev = poly.eval(z); diff --git a/field/src/polynomial/mod.rs b/field/src/polynomial/mod.rs index e5143292..f61ad419 100644 --- a/field/src/polynomial/mod.rs +++ b/field/src/polynomial/mod.rs @@ -442,10 +442,12 @@ impl Mul for &PolynomialCoeffs { mod tests { use std::time::Instant; - use rand::{thread_rng, Rng}; + use rand::rngs::OsRng; + use rand::Rng; use super::*; use crate::goldilocks_field::GoldilocksField; + use crate::types::Sample; #[test] fn test_trimmed() { @@ -518,7 +520,7 @@ mod tests { #[test] fn test_polynomial_multiplication() { type F = GoldilocksField; - let mut rng = thread_rng(); + let mut rng = OsRng; let (a_deg, b_deg) = (rng.gen_range(1..10_000), rng.gen_range(1..10_000)); let a = PolynomialCoeffs::new(F::rand_vec(a_deg)); let b = PolynomialCoeffs::new(F::rand_vec(b_deg)); @@ -534,7 +536,7 @@ mod tests { #[test] fn test_inv_mod_xn() { type F = GoldilocksField; - let mut rng = thread_rng(); + let mut rng = OsRng; let a_deg = rng.gen_range(0..1_000); let n = rng.gen_range(1..1_000); let mut a = PolynomialCoeffs::new(F::rand_vec(a_deg + 1)); @@ -559,7 +561,7 @@ mod tests { #[test] fn test_polynomial_long_division() { type F = GoldilocksField; - let mut rng = thread_rng(); + let mut rng = OsRng; let (a_deg, b_deg) = (rng.gen_range(1..10_000), rng.gen_range(1..10_000)); let a = PolynomialCoeffs::new(F::rand_vec(a_deg)); let b = PolynomialCoeffs::new(F::rand_vec(b_deg)); @@ -573,7 +575,7 @@ mod tests { #[test] fn test_polynomial_division() { type F = GoldilocksField; - let mut rng = thread_rng(); + let mut rng = OsRng; let (a_deg, b_deg) = (rng.gen_range(1..10_000), rng.gen_range(1..10_000)); let a = PolynomialCoeffs::new(F::rand_vec(a_deg)); let b = PolynomialCoeffs::new(F::rand_vec(b_deg)); @@ -587,7 +589,7 @@ mod tests { #[test] fn test_polynomial_division_by_constant() { type F = GoldilocksField; - let mut rng = thread_rng(); + let mut rng = OsRng; let a_deg = rng.gen_range(1..10_000); let a = PolynomialCoeffs::new(F::rand_vec(a_deg)); let b = PolynomialCoeffs::from(vec![F::rand()]); @@ -603,7 +605,7 @@ mod tests { #[test] fn test_division_linear() { type F = GoldilocksField; - let mut rng = thread_rng(); + let mut rng = OsRng; let l = 14; let n = 1 << l; let g = F::primitive_root_of_unity(l); diff --git a/field/src/prime_field_testing.rs b/field/src/prime_field_testing.rs index 7b0d9624..42dc9462 100644 --- a/field/src/prime_field_testing.rs +++ b/field/src/prime_field_testing.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use crate::types::PrimeField64; /// Generates a series of non-negative integers less than `modulus` which cover a range of diff --git a/field/src/secp256k1_base.rs b/field/src/secp256k1_base.rs index 9d90da9b..eaa964f8 100644 --- a/field/src/secp256k1_base.rs +++ b/field/src/secp256k1_base.rs @@ -9,7 +9,7 @@ use num::bigint::BigUint; use num::{Integer, One}; use serde::{Deserialize, Serialize}; -use crate::types::{Field, PrimeField}; +use crate::types::{Field, PrimeField, Sample}; /// The base field of the secp256k1 elliptic curve. /// @@ -65,6 +65,17 @@ impl Debug for Secp256K1Base { } } +impl Sample for Secp256K1Base { + #[inline] + fn sample(rng: &mut R) -> Self + where + R: rand::RngCore + ?Sized, + { + use num::bigint::RandBigInt; + Self::from_noncanonical_biguint(rng.gen_biguint_below(&Self::order())) + } +} + impl Field for Secp256K1Base { const ZERO: Self = Self([0; 4]); const ONE: Self = Self([1, 0, 0, 0]); @@ -131,12 +142,6 @@ impl Field for Secp256K1Base { fn from_noncanonical_u96(n: (u64, u32)) -> Self { Self([n.0, n.1 as u64, 0, 0]) } - - #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { - use num::bigint::RandBigInt; - Self::from_noncanonical_biguint(rng.gen_biguint_below(&Self::order())) - } } impl PrimeField for Secp256K1Base { diff --git a/field/src/secp256k1_scalar.rs b/field/src/secp256k1_scalar.rs index 3a98d9e7..1f1de697 100644 --- a/field/src/secp256k1_scalar.rs +++ b/field/src/secp256k1_scalar.rs @@ -9,7 +9,7 @@ use num::bigint::BigUint; use num::{Integer, One}; use serde::{Deserialize, Serialize}; -use crate::types::{Field, PrimeField}; +use crate::types::{Field, PrimeField, Sample}; /// The base field of the secp256k1 elliptic curve. /// @@ -67,6 +67,17 @@ impl Debug for Secp256K1Scalar { } } +impl Sample for Secp256K1Scalar { + #[inline] + fn sample(rng: &mut R) -> Self + where + R: rand::RngCore + ?Sized, + { + use num::bigint::RandBigInt; + Self::from_noncanonical_biguint(rng.gen_biguint_below(&Self::order())) + } +} + impl Field for Secp256K1Scalar { const ZERO: Self = Self([0; 4]); const ONE: Self = Self([1, 0, 0, 0]); @@ -139,12 +150,6 @@ impl Field for Secp256K1Scalar { fn from_noncanonical_u96(n: (u64, u32)) -> Self { Self([n.0, n.1 as u64, 0, 0]) } - - #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self { - use num::bigint::RandBigInt; - Self::from_noncanonical_biguint(rng.gen_biguint_below(&Self::order())) - } } impl PrimeField for Secp256K1Scalar { diff --git a/field/src/types.rs b/field/src/types.rs index 4df26ea2..0ae31847 100644 --- a/field/src/types.rs +++ b/field/src/types.rs @@ -8,12 +8,42 @@ use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAss use num::bigint::BigUint; use num::{Integer, One, ToPrimitive, Zero}; use plonky2_util::bits_u64; +use rand::rngs::OsRng; use serde::de::DeserializeOwned; use serde::Serialize; use crate::extension::Frobenius; use crate::ops::Square; +/// Sampling +pub trait Sample: Sized { + /// Samples a single value using `rng`. + fn sample(rng: &mut R) -> Self + where + R: rand::RngCore + ?Sized; + + /// Samples a single value using the [`OsRng`]. + #[inline] + fn rand() -> Self { + Self::sample(&mut OsRng) + } + + /// Samples a [`Vec`] of values of length `n` using [`OsRng`]. + #[inline] + fn rand_vec(n: usize) -> Vec { + (0..n).map(|_| Self::rand()).collect() + } + + /// Samples an array of values of length `N` using [`OsRng`]. + #[inline] + fn rand_array() -> [Self; N] { + Self::rand_vec(N) + .try_into() + .ok() + .expect("This conversion can never fail.") + } +} + /// A finite field. pub trait Field: 'static @@ -35,6 +65,7 @@ pub trait Field: + Debug + Default + Display + + Sample + Send + Sync + Serialize @@ -319,9 +350,6 @@ pub trait Field: Self::from_noncanonical_u128(n) } - #[cfg(feature = "rand")] - fn rand_from_rng(rng: &mut R) -> Self; - fn exp_power_of_2(&self, power_log: usize) -> Self { let mut res = *self; for _ in 0..power_log { @@ -399,21 +427,6 @@ pub trait Field: } } - #[cfg(feature = "rand")] - fn rand() -> Self { - Self::rand_from_rng(&mut rand::rngs::OsRng) - } - - #[cfg(feature = "rand")] - fn rand_arr() -> [Self; N] { - Self::rand_vec(N).try_into().unwrap() - } - - #[cfg(feature = "rand")] - fn rand_vec(n: usize) -> Vec { - (0..n).map(|_| Self::rand()).collect() - } - /// Representative `g` of the coset used in FRI, so that LDEs in FRI are done over `gH`. fn coset_shift() -> Self { Self::MULTIPLICATIVE_GROUP_GENERATOR diff --git a/insertion/src/insert_gadget.rs b/insertion/src/insert_gadget.rs index ff0ec397..dde8e940 100644 --- a/insertion/src/insert_gadget.rs +++ b/insertion/src/insert_gadget.rs @@ -50,7 +50,7 @@ impl, const D: usize> CircuitBuilderInsert #[cfg(test)] mod tests { use anyhow::Result; - use plonky2::field::types::Field; + use plonky2::field::types::{Field, Sample}; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/insertion/src/insertion_gate.rs b/insertion/src/insertion_gate.rs index 2757dd23..5694c2b4 100644 --- a/insertion/src/insertion_gate.rs +++ b/insertion/src/insertion_gate.rs @@ -317,11 +317,11 @@ impl, const D: usize> SimpleGenerator for Insert #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::Field; + use plonky2::field::types::{Field, Sample}; use plonky2::gates::gate::Gate; use plonky2::gates::gate_testing::{test_eval_fns, test_low_degree}; use plonky2::hash::hash_types::HashOut; diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index b74cc151..a9ad3de2 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -11,12 +11,11 @@ edition = "2021" default-run = "generate_constants" [features] -default = ["gate_testing", "parallel", "rand", "rand_chacha", "std", "timing"] -rand = ["dep:rand", "num/rand", "plonky2_field/rand"] -gate_testing = ["rand"] +default = ["gate_testing", "parallel", "rand_chacha", "std", "timing"] +gate_testing = [] parallel = ["hashbrown/rayon", "maybe_rayon/parallel"] std = ["anyhow/std", "rand/std"] -timing = [] +timing = ["std"] [dependencies] anyhow = { version = "1.0.40", default-features = false } @@ -26,10 +25,10 @@ itertools = { version = "0.10.0", default-features = false } keccak-hash = { version = "0.8.0", default-features = false } log = { version = "0.4.14", default-features = false } maybe_rayon = { path = "../maybe_rayon", default-features = false } -num = { version = "0.4", default-features = false } +num = { version = "0.4", default-features = false, features = ["rand"] } plonky2_field = { path = "../field", default-features = false } plonky2_util = { path = "../util", default-features = false } -rand = { version = "0.8.4", optional = true, default-features = false } +rand = { version = "0.8.4", default-features = false } rand_chacha = { version = "0.3.1", optional = true, default-features = false } serde = { version = "1.0", default-features = false, features = ["derive"] } serde_cbor = { version = "0.11.1", default-features = false } @@ -40,6 +39,7 @@ unroll = { version = "0.1.5", default-features = false } criterion = "0.3.5" env_logger = "0.9.0" num_cpus = "1.13.1" +plonky2 = { path = "." } rand = "0.8.4" rand_chacha = "0.3.1" rayon = "1.5.1" @@ -51,7 +51,7 @@ jemallocator = "0.3.2" [[bin]] name = "generate_constants" -required-features = ["rand", "rand_chacha"] +required-features = ["rand_chacha"] [[bench]] name = "field_arithmetic" diff --git a/plonky2/benches/hashing.rs b/plonky2/benches/hashing.rs index 673e0572..fd2e0991 100644 --- a/plonky2/benches/hashing.rs +++ b/plonky2/benches/hashing.rs @@ -5,6 +5,7 @@ mod allocator; use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use plonky2::field::goldilocks_field::GoldilocksField; +use plonky2::field::types::Sample; use plonky2::hash::hash_types::{BytesHash, RichField}; use plonky2::hash::hashing::SPONGE_WIDTH; use plonky2::hash::keccak::KeccakHash; @@ -27,7 +28,7 @@ pub(crate) fn bench_poseidon(c: &mut Criterion) { &format!("poseidon<{}, {SPONGE_WIDTH}>", type_name::()), |b| { b.iter_batched( - || F::rand_arr::(), + || F::rand_array::(), |state| F::poseidon(state), BatchSize::SmallInput, ) diff --git a/plonky2/benches/merkle.rs b/plonky2/benches/merkle.rs index 88302ae9..27f23966 100644 --- a/plonky2/benches/merkle.rs +++ b/plonky2/benches/merkle.rs @@ -1,3 +1,4 @@ +#![allow(incomplete_features)] #![feature(generic_const_exprs)] mod allocator; diff --git a/plonky2/benches/reverse_index_bits.rs b/plonky2/benches/reverse_index_bits.rs index 8916fb5d..5c838a18 100644 --- a/plonky2/benches/reverse_index_bits.rs +++ b/plonky2/benches/reverse_index_bits.rs @@ -2,7 +2,7 @@ mod allocator; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use plonky2::field::goldilocks_field::GoldilocksField; -use plonky2::field::types::Field; +use plonky2::field::types::Sample; use plonky2_util::{reverse_index_bits, reverse_index_bits_in_place}; type F = GoldilocksField; diff --git a/plonky2/benches/transpose.rs b/plonky2/benches/transpose.rs index 64d103ad..c2aecd5f 100644 --- a/plonky2/benches/transpose.rs +++ b/plonky2/benches/transpose.rs @@ -2,7 +2,7 @@ mod allocator; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use plonky2::field::goldilocks_field::GoldilocksField; -use plonky2::field::types::Field; +use plonky2::field::types::Sample; use plonky2::util::transpose; fn criterion_benchmark(c: &mut Criterion) { diff --git a/plonky2/examples/bench_recursion.rs b/plonky2/examples/bench_recursion.rs index 6e196ef5..dc88f764 100644 --- a/plonky2/examples/bench_recursion.rs +++ b/plonky2/examples/bench_recursion.rs @@ -154,7 +154,7 @@ fn test_serialization, C: GenericConfig, where [(); C::Hasher::HASH_SIZE]:, { - let proof_bytes = proof.to_bytes()?; + let proof_bytes = proof.to_bytes(); info!("Proof length: {} bytes", proof_bytes.len()); let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, cd)?; assert_eq!(proof, &proof_from_bytes); @@ -167,7 +167,7 @@ where info!("{:.4}s to compress proof", now.elapsed().as_secs_f64()); assert_eq!(proof, &decompressed_compressed_proof); - let compressed_proof_bytes = compressed_proof.to_bytes()?; + let compressed_proof_bytes = compressed_proof.to_bytes(); info!( "Compressed proof length: {} bytes", compressed_proof_bytes.len() diff --git a/plonky2/examples/square_root.rs b/plonky2/examples/square_root.rs index 4411ac50..512c842c 100644 --- a/plonky2/examples/square_root.rs +++ b/plonky2/examples/square_root.rs @@ -1,7 +1,7 @@ use core::marker::PhantomData; use anyhow::Result; -use plonky2::field::types::{Field, PrimeField}; +use plonky2::field::types::{PrimeField, Sample}; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::Target; diff --git a/plonky2/src/gadgets/arithmetic_extension.rs b/plonky2/src/gadgets/arithmetic_extension.rs index b56d245c..6232d7cb 100644 --- a/plonky2/src/gadgets/arithmetic_extension.rs +++ b/plonky2/src/gadgets/arithmetic_extension.rs @@ -571,7 +571,7 @@ pub(crate) struct ExtensionArithmeticOperation, const mod tests { use anyhow::Result; use plonky2_field::extension::algebra::ExtensionAlgebra; - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use crate::iop::ext_target::ExtensionAlgebraTarget; use crate::iop::witness::{PartialWitness, Witness}; @@ -666,8 +666,8 @@ mod tests { builder.connect_extension(zt.0[i], comp_zt.0[i]); } - let x = ExtensionAlgebra::(FF::rand_arr()); - let y = ExtensionAlgebra::(FF::rand_arr()); + let x = ExtensionAlgebra::(FF::rand_array()); + let y = ExtensionAlgebra::(FF::rand_array()); let z = x * y; for i in 0..D { pw.set_extension_target(xt.0[i], x.0[i]); diff --git a/plonky2/src/gadgets/random_access.rs b/plonky2/src/gadgets/random_access.rs index b9561962..a3febec7 100644 --- a/plonky2/src/gadgets/random_access.rs +++ b/plonky2/src/gadgets/random_access.rs @@ -57,7 +57,7 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use super::*; use crate::iop::witness::PartialWitness; diff --git a/plonky2/src/gadgets/select.rs b/plonky2/src/gadgets/select.rs index d234a003..03e18188 100644 --- a/plonky2/src/gadgets/select.rs +++ b/plonky2/src/gadgets/select.rs @@ -40,7 +40,7 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; diff --git a/plonky2/src/gates/exponentiation.rs b/plonky2/src/gates/exponentiation.rs index 87975f94..f7c2bc60 100644 --- a/plonky2/src/gates/exponentiation.rs +++ b/plonky2/src/gates/exponentiation.rs @@ -290,7 +290,7 @@ mod tests { use anyhow::Result; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use plonky2_util::log2_ceil; use rand::Rng; diff --git a/plonky2/src/gates/gate_testing.rs b/plonky2/src/gates/gate_testing.rs index 8492f385..0e87c262 100644 --- a/plonky2/src/gates/gate_testing.rs +++ b/plonky2/src/gates/gate_testing.rs @@ -1,7 +1,10 @@ +use alloc::vec; +use alloc::vec::Vec; + use anyhow::{ensure, Result}; use plonky2_field::extension::{Extendable, FieldExtension}; use plonky2_field::polynomial::{PolynomialCoeffs, PolynomialValues}; -use plonky2_field::types::Field; +use plonky2_field::types::{Field, Sample}; use plonky2_util::log2_ceil; use crate::gates::gate::Gate; diff --git a/plonky2/src/gates/high_degree_interpolation.rs b/plonky2/src/gates/high_degree_interpolation.rs index 71584c60..110ea167 100644 --- a/plonky2/src/gates/high_degree_interpolation.rs +++ b/plonky2/src/gates/high_degree_interpolation.rs @@ -279,7 +279,7 @@ mod tests { use anyhow::Result; use plonky2_field::goldilocks_field::GoldilocksField; use plonky2_field::polynomial::PolynomialCoeffs; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use crate::gates::gate::Gate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; diff --git a/plonky2/src/gates/interpolation.rs b/plonky2/src/gates/interpolation.rs index a707f192..7f4953d5 100644 --- a/plonky2/src/gates/interpolation.rs +++ b/plonky2/src/gates/interpolation.rs @@ -108,7 +108,7 @@ mod tests { use anyhow::Result; use plonky2_field::extension::FieldExtension; use plonky2_field::interpolation::interpolant; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use crate::gates::high_degree_interpolation::HighDegreeInterpolationGate; use crate::gates::low_degree_interpolation::LowDegreeInterpolationGate; diff --git a/plonky2/src/gates/low_degree_interpolation.rs b/plonky2/src/gates/low_degree_interpolation.rs index 4c9c7ecc..77a84484 100644 --- a/plonky2/src/gates/low_degree_interpolation.rs +++ b/plonky2/src/gates/low_degree_interpolation.rs @@ -390,7 +390,7 @@ mod tests { use plonky2_field::extension::quadratic::QuadraticExtension; use plonky2_field::goldilocks_field::GoldilocksField; use plonky2_field::polynomial::PolynomialCoeffs; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use crate::gates::gate::Gate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index caf466bd..dbc3a947 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -384,7 +384,7 @@ mod tests { use anyhow::Result; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use rand::{thread_rng, Rng}; use crate::gates::gate::Gate; diff --git a/plonky2/src/hash/arch/x86_64/poseidon_goldilocks_avx2_bmi2.rs b/plonky2/src/hash/arch/x86_64/poseidon_goldilocks_avx2_bmi2.rs index b40b4277..ae08f568 100644 --- a/plonky2/src/hash/arch/x86_64/poseidon_goldilocks_avx2_bmi2.rs +++ b/plonky2/src/hash/arch/x86_64/poseidon_goldilocks_avx2_bmi2.rs @@ -1,9 +1,9 @@ -use std::arch::asm; -use std::arch::x86_64::*; -use std::mem::size_of; +use core::arch::asm; +use core::arch::x86_64::*; +use core::mem::size_of; -use plonky2_field::types::Field; use plonky2_field::goldilocks_field::GoldilocksField; +use plonky2_field::types::Field; use plonky2_util::branch_hint; use static_assertions::const_assert; diff --git a/plonky2/src/hash/hash_types.rs b/plonky2/src/hash/hash_types.rs index 626d5eb0..e7f29044 100644 --- a/plonky2/src/hash/hash_types.rs +++ b/plonky2/src/hash/hash_types.rs @@ -1,7 +1,7 @@ use alloc::vec::Vec; use plonky2_field::goldilocks_field::GoldilocksField; -use plonky2_field::types::{Field, PrimeField64}; +use plonky2_field::types::{Field, PrimeField64, Sample}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::hash::poseidon::Poseidon; @@ -37,24 +37,26 @@ impl HashOut { elements[0..elements_in.len()].copy_from_slice(elements_in); Self { elements } } +} - #[cfg(all(feature = "parallel", feature = "rand"))] - pub fn rand_from_rng(rng: &mut R) -> Self { +impl Sample for HashOut +where + F: Field, +{ + #[inline] + fn sample(rng: &mut R) -> Self + where + R: rand::RngCore + ?Sized, + { Self { elements: [ - F::rand_from_rng(rng), - F::rand_from_rng(rng), - F::rand_from_rng(rng), - F::rand_from_rng(rng), + F::sample(rng), + F::sample(rng), + F::sample(rng), + F::sample(rng), ], } } - - pub fn rand() -> Self { - Self { - elements: [F::rand(), F::rand(), F::rand(), F::rand()], - } - } } impl GenericHashOut for HashOut { @@ -116,18 +118,16 @@ pub struct MerkleCapTarget(pub Vec); #[derive(Eq, PartialEq, Copy, Clone, Debug)] pub struct BytesHash(pub [u8; N]); -impl BytesHash { - #[cfg(feature = "rand")] - pub fn rand_from_rng(rng: &mut R) -> Self { +impl Sample for BytesHash { + #[inline] + fn sample(rng: &mut R) -> Self + where + R: rand::RngCore + ?Sized, + { let mut buf = [0; N]; rng.fill_bytes(&mut buf); Self(buf) } - - #[cfg(feature = "rand")] - pub fn rand() -> Self { - Self::rand_from_rng(&mut rand::thread_rng()) - } } impl GenericHashOut for BytesHash { diff --git a/plonky2/src/hash/path_compression.rs b/plonky2/src/hash/path_compression.rs index ed93b25d..7efe3a67 100644 --- a/plonky2/src/hash/path_compression.rs +++ b/plonky2/src/hash/path_compression.rs @@ -114,7 +114,7 @@ pub(crate) fn decompress_merkle_proofs>( #[cfg(test)] mod tests { - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use rand::{thread_rng, Rng}; use super::*; diff --git a/plonky2/src/iop/challenger.rs b/plonky2/src/iop/challenger.rs index 3e8d4148..7b666494 100644 --- a/plonky2/src/iop/challenger.rs +++ b/plonky2/src/iop/challenger.rs @@ -301,7 +301,7 @@ impl, H: AlgebraicHasher, const D: usize> #[cfg(test)] mod tests { - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use crate::iop::challenger::{Challenger, RecursiveChallenger}; use crate::iop::generator::generate_partial_witness; diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index 6cd85971..522cee18 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -274,7 +274,6 @@ impl SimpleGenerator for RandomValueGenerator { fn run_once(&self, _witness: &PartitionWitness, out_buffer: &mut GeneratedValues) { let random_value = F::rand(); - out_buffer.set_target(self.target, random_value); } } diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index a8a2f418..065e2328 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -383,7 +383,7 @@ impl OpeningSetTarget { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::Field; + use plonky2_field::types::Sample; use crate::fri::reduction_strategies::FriReductionStrategy; use crate::gates::noop::NoopGate; diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index f91c1d5b..fdbff5a0 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -369,9 +369,9 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { use anyhow::Result; + use plonky2_field::types::Sample; use super::*; - use crate::field::types::Field; use crate::gates::noop::NoopGate; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_data::CircuitConfig; diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index b50eecfe..ab569d27 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -267,7 +267,7 @@ mod tests { use crate::iop::witness::PartialWitness; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData, VerifierCircuitTarget}; - use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher, PoseidonGoldilocksConfig}; + use crate::plonk::config::{AlgebraicHasher, GenericConfig, PoseidonGoldilocksConfig}; use crate::recursion::cyclic_recursion::{ check_cyclic_proof_verifier_data, set_cyclic_recursion_data_target, CyclicRecursionData, }; diff --git a/plonky2/src/recursion/recursive_verifier.rs b/plonky2/src/recursion/recursive_verifier.rs index 5ddfef01..a42494f4 100644 --- a/plonky2/src/recursion/recursive_verifier.rs +++ b/plonky2/src/recursion/recursive_verifier.rs @@ -194,9 +194,7 @@ mod tests { use crate::gates::noop::NoopGate; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_data::{CircuitConfig, VerifierOnlyCircuitData}; - use crate::plonk::config::{ - GenericConfig, Hasher, KeccakGoldilocksConfig, PoseidonGoldilocksConfig, - }; + use crate::plonk::config::{GenericConfig, KeccakGoldilocksConfig, PoseidonGoldilocksConfig}; use crate::plonk::proof::{CompressedProofWithPublicInputs, ProofWithPublicInputs}; use crate::plonk::prover::prove; use crate::util::timing::TimingTree; @@ -418,7 +416,7 @@ mod tests { vd: &VerifierOnlyCircuitData, cd: &CommonCircuitData, ) -> Result<()> { - let proof_bytes = proof.to_bytes()?; + let proof_bytes = proof.to_bytes(); info!("Proof length: {} bytes", proof_bytes.len()); let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, cd)?; assert_eq!(proof, &proof_from_bytes); @@ -431,7 +429,7 @@ mod tests { info!("{:.4}s to compress proof", now.elapsed().as_secs_f64()); assert_eq!(proof, &decompressed_compressed_proof); - let compressed_proof_bytes = compressed_proof.to_bytes()?; + let compressed_proof_bytes = compressed_proof.to_bytes(); info!( "Compressed proof length: {} bytes", compressed_proof_bytes.len() diff --git a/plonky2/src/util/reducing.rs b/plonky2/src/util/reducing.rs index f91dbb19..b1a179b7 100644 --- a/plonky2/src/util/reducing.rs +++ b/plonky2/src/util/reducing.rs @@ -276,6 +276,7 @@ impl ReducingFactorTarget { #[cfg(test)] mod tests { use anyhow::Result; + use plonky2_field::types::Sample; use super::*; use crate::iop::witness::{PartialWitness, Witness}; diff --git a/starky/Cargo.toml b/starky/Cargo.toml index 43bea53e..fd39d098 100644 --- a/starky/Cargo.toml +++ b/starky/Cargo.toml @@ -9,7 +9,7 @@ default = ["parallel"] parallel = ["plonky2/parallel", "maybe_rayon/parallel"] [dependencies] -plonky2 = { path = "../plonky2", default-features = false, features = ["rand", "timing"] } +plonky2 = { path = "../plonky2", default-features = false, features = ["timing"] } plonky2_util = { path = "../util" } maybe_rayon = { path = "../maybe_rayon"} anyhow = "1.0.40" diff --git a/starky/src/stark_testing.rs b/starky/src/stark_testing.rs index 2cec5298..f9f57828 100644 --- a/starky/src/stark_testing.rs +++ b/starky/src/stark_testing.rs @@ -1,7 +1,7 @@ use anyhow::{ensure, Result}; use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues}; -use plonky2::field::types::Field; +use plonky2::field::types::{Field, Sample}; use plonky2::hash::hash_types::RichField; use plonky2::iop::witness::{PartialWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; @@ -29,7 +29,7 @@ where let trace_ldes = random_low_degree_matrix::(S::COLUMNS, rate_bits); let size = trace_ldes.len(); - let public_inputs = F::rand_arr::<{ S::PUBLIC_INPUTS }>(); + let public_inputs = F::rand_array::<{ S::PUBLIC_INPUTS }>(); let lagrange_first = PolynomialValues::selector(WITNESS_SIZE, 0).lde(rate_bits); let lagrange_last = PolynomialValues::selector(WITNESS_SIZE, WITNESS_SIZE - 1).lde(rate_bits); @@ -91,9 +91,9 @@ where { // Compute native constraint evaluation on random values. let vars = StarkEvaluationVars { - local_values: &F::Extension::rand_arr::<{ S::COLUMNS }>(), - next_values: &F::Extension::rand_arr::<{ S::COLUMNS }>(), - public_inputs: &F::Extension::rand_arr::<{ S::PUBLIC_INPUTS }>(), + local_values: &F::Extension::rand_array::<{ S::COLUMNS }>(), + next_values: &F::Extension::rand_array::<{ S::COLUMNS }>(), + public_inputs: &F::Extension::rand_array::<{ S::PUBLIC_INPUTS }>(), }; let alphas = F::rand_vec(1); let z_last = F::Extension::rand(); diff --git a/starky/src/verifier.rs b/starky/src/verifier.rs index 18ae9a27..fe0e41d2 100644 --- a/starky/src/verifier.rs +++ b/starky/src/verifier.rs @@ -260,7 +260,7 @@ fn check_permutation_options< mod tests { use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::polynomial::PolynomialValues; - use plonky2::field::types::Field; + use plonky2::field::types::Sample; use crate::verifier::eval_l_0_and_l_last; diff --git a/system_zero/src/alu/bitops.rs b/system_zero/src/alu/bitops.rs index 1f9875ca..aed63415 100644 --- a/system_zero/src/alu/bitops.rs +++ b/system_zero/src/alu/bitops.rs @@ -237,7 +237,7 @@ pub(crate) fn eval_bitop_circuit, const D: usize>( #[cfg(test)] mod tests { use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::Field; + use plonky2::field::types::Sample; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; use starky::constraint_consumer::ConstraintConsumer; @@ -250,7 +250,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut values = [F::default(); NUM_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut values = [F::default(); NUM_COLUMNS].map(|_| F::sample(&mut rng)); // if `IS_bitop == 0`, then the constraints should be met even // if all values are garbage. @@ -275,7 +275,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut values = [F::default(); NUM_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut values = [F::default(); NUM_COLUMNS].map(|_| F::sample(&mut rng)); const BITOPS: [usize; 4] = [IS_AND, IS_IOR, IS_XOR, IS_ANDNOT]; for bitop in BITOPS { @@ -317,7 +317,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut values = [F::default(); NUM_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut values = [F::default(); NUM_COLUMNS].map(|_| F::sample(&mut rng)); const BITOPS: [usize; 4] = [IS_AND, IS_IOR, IS_XOR, IS_ANDNOT]; for bitop in BITOPS { diff --git a/system_zero/src/alu/division.rs b/system_zero/src/alu/division.rs index 65bedd8f..055aafd3 100644 --- a/system_zero/src/alu/division.rs +++ b/system_zero/src/alu/division.rs @@ -160,7 +160,7 @@ pub(crate) fn eval_division_circuit, const D: usize #[cfg(test)] mod tests { use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::Field; + use plonky2::field::types::Sample; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; use starky::constraint_consumer::ConstraintConsumer; @@ -173,7 +173,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut values = [F::default(); NUM_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut values = [F::default(); NUM_COLUMNS].map(|_| F::sample(&mut rng)); // if `IS_DIV == 0`, then the constraints should be met even if all values are garbage. values[IS_DIV] = F::ZERO; @@ -195,7 +195,7 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let mut values = [F::default(); NUM_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut values = [F::default(); NUM_COLUMNS].map(|_| F::sample(&mut rng)); // set `IS_DIV == 1` and ensure all constraints are satisfied. values[IS_DIV] = F::ONE; diff --git a/system_zero/src/permutation_unit.rs b/system_zero/src/permutation_unit.rs index 809955ca..4ba469b4 100644 --- a/system_zero/src/permutation_unit.rs +++ b/system_zero/src/permutation_unit.rs @@ -254,7 +254,7 @@ pub(crate) fn eval_permutation_unit_circuit, const #[cfg(test)] mod tests { use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::Field; + use plonky2::field::types::{Field, Sample}; use plonky2::hash::poseidon::Poseidon; use rand::SeedableRng; use rand_chacha::ChaCha8Rng; @@ -296,14 +296,14 @@ mod tests { type F = GoldilocksField; let mut rng = ChaCha8Rng::seed_from_u64(0x6feb51b7ec230f25); - let state = [F::default(); SPONGE_WIDTH].map(|_| F::rand_from_rng(&mut rng)); + let state = [F::default(); SPONGE_WIDTH].map(|_| F::sample(&mut rng)); // Get true Poseidon hash let target = GoldilocksField::poseidon(state); // Get result from `generate_permutation_unit` // Initialize `values` with randomness to test that the code doesn't rely on zero-filling. - let mut values = [F::default(); NUM_COLUMNS].map(|_| F::rand_from_rng(&mut rng)); + let mut values = [F::default(); NUM_COLUMNS].map(|_| F::sample(&mut rng)); for i in 0..SPONGE_WIDTH { values[col_input(i)] = state[i]; } diff --git a/u32/src/gates/add_many_u32.rs b/u32/src/gates/add_many_u32.rs index f37075cd..8928b74d 100644 --- a/u32/src/gates/add_many_u32.rs +++ b/u32/src/gates/add_many_u32.rs @@ -340,7 +340,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use itertools::unfold; @@ -351,7 +351,7 @@ mod tests { use plonky2::plonk::vars::EvaluationVars; use plonky2_field::extension::quartic::QuarticExtension; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use rand::Rng; use crate::gates::add_many_u32::U32AddManyGate; diff --git a/u32/src/gates/arithmetic_u32.rs b/u32/src/gates/arithmetic_u32.rs index 575f3055..8946f9de 100644 --- a/u32/src/gates/arithmetic_u32.rs +++ b/u32/src/gates/arithmetic_u32.rs @@ -411,7 +411,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use plonky2::gates::gate::Gate; @@ -421,7 +421,7 @@ mod tests { use plonky2::plonk::vars::EvaluationVars; use plonky2_field::extension::Extendable; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use rand::Rng; use crate::gates::arithmetic_u32::U32ArithmeticGate; diff --git a/u32/src/gates/comparison.rs b/u32/src/gates/comparison.rs index cbb689e7..b7dc74a8 100644 --- a/u32/src/gates/comparison.rs +++ b/u32/src/gates/comparison.rs @@ -512,7 +512,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use plonky2::gates::gate::Gate; @@ -521,7 +521,7 @@ mod tests { use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::plonk::vars::EvaluationVars; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, PrimeField64}; + use plonky2_field::types::{Field, PrimeField64, Sample}; use rand::Rng; use crate::gates::comparison::ComparisonGate; diff --git a/u32/src/gates/range_check_u32.rs b/u32/src/gates/range_check_u32.rs index 6e8f2cd5..ff99e492 100644 --- a/u32/src/gates/range_check_u32.rs +++ b/u32/src/gates/range_check_u32.rs @@ -201,7 +201,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use itertools::unfold; @@ -212,7 +212,7 @@ mod tests { use plonky2::plonk::vars::EvaluationVars; use plonky2_field::extension::quartic::QuarticExtension; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use plonky2_util::ceil_div_usize; use rand::Rng; diff --git a/u32/src/gates/subtraction_u32.rs b/u32/src/gates/subtraction_u32.rs index d29b2348..1657aec1 100644 --- a/u32/src/gates/subtraction_u32.rs +++ b/u32/src/gates/subtraction_u32.rs @@ -329,7 +329,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use plonky2::gates::gate::Gate; @@ -339,7 +339,7 @@ mod tests { use plonky2::plonk::vars::EvaluationVars; use plonky2_field::extension::quartic::QuarticExtension; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, PrimeField64}; + use plonky2_field::types::{Field, PrimeField64, Sample}; use rand::Rng; use crate::gates::subtraction_u32::U32SubtractionGate; diff --git a/waksman/src/gates/assert_le.rs b/waksman/src/gates/assert_le.rs index 7f60fcac..745bb62f 100644 --- a/waksman/src/gates/assert_le.rs +++ b/waksman/src/gates/assert_le.rs @@ -446,7 +446,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use std::marker::PhantomData; + use core::marker::PhantomData; use anyhow::Result; use plonky2::gates::gate::Gate; @@ -456,7 +456,7 @@ mod tests { use plonky2::plonk::vars::EvaluationVars; use plonky2_field::extension::quartic::QuarticExtension; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, PrimeField64}; + use plonky2_field::types::{Field, PrimeField64, Sample}; use rand::Rng; use crate::gates::assert_le::AssertLessThanGate; diff --git a/waksman/src/gates/switch.rs b/waksman/src/gates/switch.rs index 4509bf0a..58fad4c7 100644 --- a/waksman/src/gates/switch.rs +++ b/waksman/src/gates/switch.rs @@ -334,7 +334,7 @@ mod tests { use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::plonk::vars::EvaluationVars; use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; + use plonky2_field::types::{Field, Sample}; use crate::gates::switch::SwitchGate; diff --git a/waksman/src/permutation.rs b/waksman/src/permutation.rs index 367386c4..b9d69f75 100644 --- a/waksman/src/permutation.rs +++ b/waksman/src/permutation.rs @@ -371,7 +371,7 @@ impl SimpleGenerator for PermutationGenerator { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2::field::types::Field; + use plonky2::field::types::{Field, Sample}; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/waksman/src/sorting.rs b/waksman/src/sorting.rs index 010bc8b9..dbfe8a81 100644 --- a/waksman/src/sorting.rs +++ b/waksman/src/sorting.rs @@ -183,7 +183,7 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { use anyhow::Result; - use plonky2::field::types::{Field, PrimeField64}; + use plonky2::field::types::{Field, PrimeField64, Sample}; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; From 703d2c3c9550ccd3a0f47f4fa4e58cc8e84a1486 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 3 Nov 2022 10:58:55 -0700 Subject: [PATCH 06/49] wip: start plonky2_u32 and plonky2_ecdsa no-std impl Signed-off-by: Brandon H. Gomes --- ecdsa/Cargo.toml | 21 +++++++------ ecdsa/src/curve/curve_adds.rs | 6 ++-- ecdsa/src/curve/curve_msm.rs | 16 +++++----- ecdsa/src/curve/curve_multiplication.rs | 5 ++-- ecdsa/src/curve/curve_summation.rs | 13 ++++---- ecdsa/src/curve/curve_types.rs | 13 ++++---- ecdsa/src/curve/ecdsa.rs | 6 ++-- ecdsa/src/curve/glv.rs | 10 +++---- ecdsa/src/curve/secp256k1.rs | 10 +++---- ecdsa/src/gadgets/biguint.rs | 19 +++++++----- ecdsa/src/gadgets/curve.rs | 15 ++++++---- ecdsa/src/gadgets/curve_fixed_base.rs | 10 ++++--- ecdsa/src/gadgets/curve_msm.rs | 10 ++++--- ecdsa/src/gadgets/curve_windowed_mul.rs | 20 ++++++------- ecdsa/src/gadgets/ecdsa.rs | 18 ++++------- ecdsa/src/gadgets/glv.rs | 15 +++++----- ecdsa/src/gadgets/nonnative.rs | 14 +++++---- ecdsa/src/gadgets/split_nonnative.rs | 14 ++++----- ecdsa/src/lib.rs | 6 ++-- plonky2/Cargo.toml | 16 +++++----- plonky2/src/bin/generate_constants.rs | 4 +-- plonky2/src/fri/challenges.rs | 5 ++-- plonky2/src/fri/oracle.rs | 13 ++++---- plonky2/src/fri/proof.rs | 4 +-- plonky2/src/fri/prover.rs | 6 ++-- plonky2/src/fri/recursive_verifier.rs | 4 +-- plonky2/src/fri/reduction_strategies.rs | 2 -- plonky2/src/fri/validate_shape.rs | 2 +- plonky2/src/fri/verifier.rs | 9 +++--- plonky2/src/fri/witness_util.rs | 2 +- plonky2/src/gadgets/arithmetic.rs | 5 ++-- plonky2/src/gadgets/arithmetic_extension.rs | 11 ++++--- plonky2/src/gadgets/hash.rs | 3 +- plonky2/src/gadgets/polynomial.rs | 3 +- plonky2/src/gadgets/random_access.rs | 7 ++--- plonky2/src/gadgets/range_check.rs | 3 +- plonky2/src/gadgets/select.rs | 5 ++-- plonky2/src/gadgets/split_base.rs | 12 ++++---- plonky2/src/gadgets/split_join.rs | 5 ++-- plonky2/src/gates/arithmetic_base.rs | 7 ++--- plonky2/src/gates/arithmetic_extension.rs | 5 ++-- plonky2/src/gates/base_sum.rs | 11 ++++--- plonky2/src/gates/constant.rs | 7 ++--- plonky2/src/gates/exponentiation.rs | 25 +++++++--------- plonky2/src/gates/gate.rs | 6 ++-- plonky2/src/gates/gate_testing.rs | 9 +++--- .../src/gates/high_degree_interpolation.rs | 21 +++++-------- plonky2/src/gates/interpolation.rs | 9 +++--- plonky2/src/gates/low_degree_interpolation.rs | 19 ++++++------ plonky2/src/gates/multiplication_extension.rs | 8 ++--- plonky2/src/gates/noop.rs | 6 ++-- plonky2/src/gates/packed_util.rs | 7 ++--- plonky2/src/gates/poseidon.rs | 9 +++--- plonky2/src/gates/poseidon_mds.rs | 7 ++--- plonky2/src/gates/public_input.rs | 8 ++--- plonky2/src/gates/random_access.rs | 21 ++++++------- plonky2/src/gates/reducing.rs | 5 ++-- plonky2/src/gates/reducing_extension.rs | 5 ++-- plonky2/src/gates/selectors.rs | 5 ++-- plonky2/src/gates/util.rs | 2 +- .../arch/aarch64/poseidon_goldilocks_neon.rs | 4 +-- .../x86_64/poseidon_goldilocks_avx2_bmi2.rs | 6 ++-- plonky2/src/hash/hash_types.rs | 4 +-- plonky2/src/hash/hashing.rs | 3 +- plonky2/src/hash/merkle_proofs.rs | 9 +++--- plonky2/src/hash/merkle_tree.rs | 4 +-- plonky2/src/hash/path_compression.rs | 7 +++-- plonky2/src/hash/poseidon.rs | 7 ++--- plonky2/src/hash/poseidon_goldilocks.rs | 8 ++--- plonky2/src/iop/challenger.rs | 6 ++-- plonky2/src/iop/ext_target.rs | 7 ++--- plonky2/src/iop/generator.rs | 5 ++-- plonky2/src/iop/witness.rs | 4 +-- plonky2/src/lib.rs | 1 + plonky2/src/plonk/circuit_builder.rs | 13 ++++---- plonky2/src/plonk/circuit_data.rs | 4 +-- plonky2/src/plonk/config.rs | 6 ++-- plonky2/src/plonk/get_challenges.rs | 4 +-- plonky2/src/plonk/permutation_argument.rs | 4 +-- plonky2/src/plonk/plonk_common.rs | 7 ++--- plonky2/src/plonk/proof.rs | 4 +-- plonky2/src/plonk/prover.rs | 9 +++--- plonky2/src/plonk/validate_shape.rs | 2 +- plonky2/src/plonk/vanishing_poly.rs | 9 +++--- plonky2/src/plonk/vars.rs | 9 +++--- plonky2/src/plonk/verifier.rs | 4 +-- .../conditional_recursive_verifier.rs | 6 ++-- plonky2/src/recursion/cyclic_recursion.rs | 8 ++--- plonky2/src/recursion/recursive_verifier.rs | 3 +- plonky2/src/util/mod.rs | 11 +++---- plonky2/src/util/partial_products.rs | 9 +++--- plonky2/src/util/reducing.rs | 11 ++++--- plonky2/src/util/serialization.rs | 6 ++-- plonky2/src/util/strided_view.rs | 2 +- u32/Cargo.toml | 18 +++++------ u32/src/gadgets/arithmetic_u32.rs | 14 +++++---- u32/src/gadgets/multiple_comparison.rs | 17 ++++++----- u32/src/gadgets/range_check.rs | 5 +++- u32/src/gates/add_many_u32.rs | 28 ++++++++--------- u32/src/gates/arithmetic_u32.rs | 28 ++++++++--------- u32/src/gates/comparison.rs | 27 +++++++++-------- u32/src/gates/range_check_u32.rs | 30 +++++++++---------- u32/src/gates/subtraction_u32.rs | 27 +++++++++-------- u32/src/lib.rs | 3 ++ u32/src/witness.rs | 2 +- 105 files changed, 464 insertions(+), 505 deletions(-) diff --git a/ecdsa/Cargo.toml b/ecdsa/Cargo.toml index ce00f3dc..522856ef 100644 --- a/ecdsa/Cargo.toml +++ b/ecdsa/Cargo.toml @@ -3,16 +3,15 @@ name = "plonky2_ecdsa" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -plonky2 = { path = "../plonky2" } -plonky2_util = { path = "../util" } -plonky2_field = { path = "../field" } -plonky2_u32 = { path = "../u32" } -num = "0.4.0" -itertools = "0.10.0" -rayon = "1.5.1" +anyhow = { version = "1.0.40", default-features = false } +itertools = { version = "0.10.0", default-features = false } +maybe_rayon = { path = "../maybe_rayon", default-features = false } +num = { version = "0.4.0", default-features = false } +plonky2 = { path = "../plonky2", default-features = false } +plonky2_u32 = { path = "../u32", default-features = false } serde = { version = "1.0", default-features = false, features = ["derive"] } -anyhow = "1.0.40" -rand = "0.8.4" + +[dev-dependencies] +rand = { version = "0.8.4", default-features = false, features = ["getrandom"] } + diff --git a/ecdsa/src/curve/curve_adds.rs b/ecdsa/src/curve/curve_adds.rs index 05d9d515..319c5614 100644 --- a/ecdsa/src/curve/curve_adds.rs +++ b/ecdsa/src/curve/curve_adds.rs @@ -1,7 +1,7 @@ -use std::ops::Add; +use core::ops::Add; -use plonky2_field::ops::Square; -use plonky2_field::types::Field; +use plonky2::field::ops::Square; +use plonky2::field::types::Field; use crate::curve::curve_types::{AffinePoint, Curve, ProjectivePoint}; diff --git a/ecdsa/src/curve/curve_msm.rs b/ecdsa/src/curve/curve_msm.rs index 400c7ab6..bc04b6cc 100644 --- a/ecdsa/src/curve/curve_msm.rs +++ b/ecdsa/src/curve/curve_msm.rs @@ -1,6 +1,8 @@ +use alloc::vec::Vec; + use itertools::Itertools; -use plonky2_field::types::{Field, PrimeField}; -use rayon::prelude::*; +use maybe_rayon::{MaybeIntoParIter, MaybeParChunks}; +use plonky2::field::types::{Field, PrimeField}; use crate::curve::curve_summation::affine_multisummation_best; use crate::curve::curve_types::{AffinePoint, Curve, ProjectivePoint}; @@ -185,12 +187,12 @@ pub(crate) fn to_digits(x: &C::ScalarField, w: usize) -> Vec { #[cfg(test)] mod tests { - use num::BigUint; - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::{Field, PrimeField}; + use alloc::vec; - use crate::curve::curve_msm::{msm_execute, msm_precompute, to_digits}; - use crate::curve::curve_types::Curve; + use num::BigUint; + use plonky2::field::secp256k1_scalar::Secp256K1Scalar; + + use super::*; use crate::curve::secp256k1::Secp256K1; #[test] diff --git a/ecdsa/src/curve/curve_multiplication.rs b/ecdsa/src/curve/curve_multiplication.rs index 25c603b5..1f9c653d 100644 --- a/ecdsa/src/curve/curve_multiplication.rs +++ b/ecdsa/src/curve/curve_multiplication.rs @@ -1,6 +1,7 @@ -use std::ops::Mul; +use alloc::vec::Vec; +use core::ops::Mul; -use plonky2_field::types::{Field, PrimeField}; +use plonky2::field::types::{Field, PrimeField}; use crate::curve::curve_types::{Curve, CurveScalar, ProjectivePoint}; diff --git a/ecdsa/src/curve/curve_summation.rs b/ecdsa/src/curve/curve_summation.rs index 492d7722..7bb633af 100644 --- a/ecdsa/src/curve/curve_summation.rs +++ b/ecdsa/src/curve/curve_summation.rs @@ -1,7 +1,9 @@ -use std::iter::Sum; +use alloc::vec; +use alloc::vec::Vec; +use core::iter::Sum; -use plonky2_field::ops::Square; -use plonky2_field::types::Field; +use plonky2::field::ops::Square; +use plonky2::field::types::Field; use crate::curve::curve_types::{AffinePoint, Curve, ProjectivePoint}; @@ -188,10 +190,7 @@ pub fn affine_multisummation_batch_inversion( #[cfg(test)] mod tests { - use crate::curve::curve_summation::{ - affine_summation_batch_inversion, affine_summation_pairwise, - }; - use crate::curve::curve_types::{Curve, ProjectivePoint}; + use super::*; use crate::curve::secp256k1::Secp256K1; #[test] diff --git a/ecdsa/src/curve/curve_types.rs b/ecdsa/src/curve/curve_types.rs index 96821672..91047393 100644 --- a/ecdsa/src/curve/curve_types.rs +++ b/ecdsa/src/curve/curve_types.rs @@ -1,9 +1,10 @@ -use std::fmt::Debug; -use std::hash::Hash; -use std::ops::Neg; +use alloc::vec::Vec; +use core::fmt::Debug; +use core::hash::{Hash, Hasher}; +use core::ops::Neg; -use plonky2_field::ops::Square; -use plonky2_field::types::{Field, PrimeField}; +use plonky2::field::ops::Square; +use plonky2::field::types::{Field, PrimeField}; use serde::{Deserialize, Serialize}; // To avoid implementation conflicts from associated types, @@ -123,7 +124,7 @@ impl PartialEq for AffinePoint { impl Eq for AffinePoint {} impl Hash for AffinePoint { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { if self.zero { self.zero.hash(state); } else { diff --git a/ecdsa/src/curve/ecdsa.rs b/ecdsa/src/curve/ecdsa.rs index bbec08b5..131d8b4d 100644 --- a/ecdsa/src/curve/ecdsa.rs +++ b/ecdsa/src/curve/ecdsa.rs @@ -1,4 +1,4 @@ -use plonky2_field::types::{Field, Sample}; +use plonky2::field::types::{Field, Sample}; use serde::{Deserialize, Serialize}; use crate::curve::curve_msm::msm_parallel; @@ -63,8 +63,8 @@ pub fn verify_message( #[cfg(test)] mod tests { - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Sample; + use plonky2::field::secp256k1_scalar::Secp256K1Scalar; + use plonky2::field::types::Sample; use crate::curve::ecdsa::{sign_message, verify_message, ECDSASecretKey}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/curve/glv.rs b/ecdsa/src/curve/glv.rs index 9cf9bc82..7c3e5de0 100644 --- a/ecdsa/src/curve/glv.rs +++ b/ecdsa/src/curve/glv.rs @@ -1,8 +1,8 @@ use num::rational::Ratio; use num::BigUint; -use plonky2_field::secp256k1_base::Secp256K1Base; -use plonky2_field::secp256k1_scalar::Secp256K1Scalar; -use plonky2_field::types::{Field, PrimeField}; +use plonky2::field::secp256k1_base::Secp256K1Base; +use plonky2::field::secp256k1_scalar::Secp256K1Scalar; +use plonky2::field::types::{Field, PrimeField}; use crate::curve::curve_msm::msm_parallel; use crate::curve::curve_types::{AffinePoint, ProjectivePoint}; @@ -102,8 +102,8 @@ pub fn glv_mul(p: ProjectivePoint, k: Secp256K1Scalar) -> ProjectiveP #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::{Field, Sample}; + use plonky2::field::secp256k1_scalar::Secp256K1Scalar; + use plonky2::field::types::{Field, Sample}; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::curve::glv::{decompose_secp256k1_scalar, glv_mul, GLV_S}; diff --git a/ecdsa/src/curve/secp256k1.rs b/ecdsa/src/curve/secp256k1.rs index b5ac8931..0b899a71 100644 --- a/ecdsa/src/curve/secp256k1.rs +++ b/ecdsa/src/curve/secp256k1.rs @@ -1,6 +1,6 @@ -use plonky2_field::secp256k1_base::Secp256K1Base; -use plonky2_field::secp256k1_scalar::Secp256K1Scalar; -use plonky2_field::types::Field; +use plonky2::field::secp256k1_base::Secp256K1Base; +use plonky2::field::secp256k1_scalar::Secp256K1Scalar; +use plonky2::field::types::Field; use serde::{Deserialize, Serialize}; use crate::curve::curve_types::{AffinePoint, Curve}; @@ -40,8 +40,8 @@ const SECP256K1_GENERATOR_Y: Secp256K1Base = Secp256K1Base([ #[cfg(test)] mod tests { use num::BigUint; - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::{Field, PrimeField}; + use plonky2::field::secp256k1_scalar::Secp256K1Scalar; + use plonky2::field::types::{Field, PrimeField}; use crate::curve::curve_types::{AffinePoint, Curve, ProjectivePoint}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/gadgets/biguint.rs b/ecdsa/src/gadgets/biguint.rs index ef958bd1..59e48d01 100644 --- a/ecdsa/src/gadgets/biguint.rs +++ b/ecdsa/src/gadgets/biguint.rs @@ -1,13 +1,15 @@ -use std::marker::PhantomData; +use alloc::vec; +use alloc::vec::Vec; +use core::marker::PhantomData; use num::{BigUint, Integer, Zero}; +use plonky2::field::extension::Extendable; +use plonky2::field::types::{PrimeField, PrimeField64}; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::{BoolTarget, Target}; use plonky2::iop::witness::{PartitionWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::extension::Extendable; -use plonky2_field::types::{PrimeField, PrimeField64}; use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target}; use plonky2_u32::gadgets::multiple_comparison::list_le_u32_circuit; use plonky2_u32::witness::{GeneratedValuesU32, WitnessU32}; @@ -350,6 +352,7 @@ mod tests { use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; + use rand::rngs::OsRng; use rand::Rng; use crate::gadgets::biguint::{CircuitBuilderBiguint, WitnessBigUint}; @@ -359,7 +362,7 @@ mod tests { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let x_value = BigUint::from_u128(rng.gen()).unwrap(); let y_value = BigUint::from_u128(rng.gen()).unwrap(); @@ -389,7 +392,7 @@ mod tests { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let mut x_value = BigUint::from_u128(rng.gen()).unwrap(); let mut y_value = BigUint::from_u128(rng.gen()).unwrap(); @@ -419,7 +422,7 @@ mod tests { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let x_value = BigUint::from_u128(rng.gen()).unwrap(); let y_value = BigUint::from_u128(rng.gen()).unwrap(); @@ -449,7 +452,7 @@ mod tests { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let x_value = BigUint::from_u128(rng.gen()).unwrap(); let y_value = BigUint::from_u128(rng.gen()).unwrap(); @@ -475,7 +478,7 @@ mod tests { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let mut x_value = BigUint::from_u128(rng.gen()).unwrap(); let mut y_value = BigUint::from_u128(rng.gen()).unwrap(); diff --git a/ecdsa/src/gadgets/curve.rs b/ecdsa/src/gadgets/curve.rs index 0d50ba7f..11075322 100644 --- a/ecdsa/src/gadgets/curve.rs +++ b/ecdsa/src/gadgets/curve.rs @@ -1,8 +1,11 @@ +use alloc::vec; +use alloc::vec::Vec; + +use plonky2::field::extension::Extendable; +use plonky2::field::types::Sample; use plonky2::hash::hash_types::RichField; use plonky2::iop::target::BoolTarget; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Sample; use crate::curve::curve_types::{AffinePoint, Curve, CurveScalar}; use crate::gadgets::nonnative::{CircuitBuilderNonNative, NonNativeTarget}; @@ -254,16 +257,16 @@ impl, const D: usize> CircuitBuilderCurve #[cfg(test)] mod tests { - use std::ops::Neg; + use core::ops::Neg; use anyhow::Result; + use plonky2::field::secp256k1_base::Secp256K1Base; + use plonky2::field::secp256k1_scalar::Secp256K1Scalar; + use plonky2::field::types::{Field, Sample}; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2_field::secp256k1_base::Secp256K1Base; - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::{Field, Sample}; use crate::curve::curve_types::{AffinePoint, Curve, CurveScalar}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/gadgets/curve_fixed_base.rs b/ecdsa/src/gadgets/curve_fixed_base.rs index 0468fe01..e7656f5c 100644 --- a/ecdsa/src/gadgets/curve_fixed_base.rs +++ b/ecdsa/src/gadgets/curve_fixed_base.rs @@ -1,10 +1,12 @@ +use alloc::vec::Vec; + use num::BigUint; +use plonky2::field::extension::Extendable; +use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::hash::keccak::KeccakHash; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::config::{GenericHashOut, Hasher}; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; use crate::curve::curve_types::{AffinePoint, Curve, CurveScalar}; use crate::gadgets::curve::{AffinePointTarget, CircuitBuilderCurve}; @@ -66,12 +68,12 @@ pub fn fixed_base_curve_mul_circuit, cons #[cfg(test)] mod tests { use anyhow::Result; + use plonky2::field::secp256k1_scalar::Secp256K1Scalar; + use plonky2::field::types::{PrimeField, Sample}; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::{PrimeField, Sample}; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/gadgets/curve_msm.rs b/ecdsa/src/gadgets/curve_msm.rs index ba7c5a75..7bb4a6cc 100644 --- a/ecdsa/src/gadgets/curve_msm.rs +++ b/ecdsa/src/gadgets/curve_msm.rs @@ -1,10 +1,12 @@ +use alloc::vec; + use num::BigUint; +use plonky2::field::extension::Extendable; +use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::hash::keccak::KeccakHash; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::config::{GenericHashOut, Hasher}; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::gadgets::curve::{AffinePointTarget, CircuitBuilderCurve}; @@ -79,12 +81,12 @@ pub fn curve_msm_circuit, const D: usize> #[cfg(test)] mod tests { use anyhow::Result; + use plonky2::field::secp256k1_scalar::Secp256K1Scalar; + use plonky2::field::types::Sample; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Sample; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::curve::secp256k1::Secp256K1; diff --git a/ecdsa/src/gadgets/curve_windowed_mul.rs b/ecdsa/src/gadgets/curve_windowed_mul.rs index dce7a0e2..39fad17c 100644 --- a/ecdsa/src/gadgets/curve_windowed_mul.rs +++ b/ecdsa/src/gadgets/curve_windowed_mul.rs @@ -1,13 +1,15 @@ +use alloc::vec; +use alloc::vec::Vec; use core::marker::PhantomData; use num::BigUint; +use plonky2::field::extension::Extendable; +use plonky2::field::types::{Field, Sample}; use plonky2::hash::hash_types::RichField; use plonky2::hash::keccak::KeccakHash; use plonky2::iop::target::{BoolTarget, Target}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::config::{GenericHashOut, Hasher}; -use plonky2_field::extension::Extendable; -use plonky2_field::types::{Field, Sample}; use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target}; use crate::curve::curve_types::{Curve, CurveScalar}; @@ -169,22 +171,18 @@ impl, const D: usize> CircuitBuilderWindowedMul Result<()> { @@ -206,7 +204,7 @@ mod tests { }) .collect(); - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let access_index = rng.gen::() % num_points; let access_index_target = builder.constant(F::from_canonical_usize(access_index)); diff --git a/ecdsa/src/gadgets/ecdsa.rs b/ecdsa/src/gadgets/ecdsa.rs index fe2cc397..657ec492 100644 --- a/ecdsa/src/gadgets/ecdsa.rs +++ b/ecdsa/src/gadgets/ecdsa.rs @@ -1,9 +1,9 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; +use plonky2::field::extension::Extendable; +use plonky2::field::secp256k1_scalar::Secp256K1Scalar; use plonky2::hash::hash_types::RichField; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::extension::Extendable; -use plonky2_field::secp256k1_scalar::Secp256K1Scalar; use crate::curve::curve_types::Curve; use crate::curve::secp256k1::Secp256K1; @@ -52,20 +52,14 @@ pub fn verify_message_circuit, const D: usize>( #[cfg(test)] mod tests { use anyhow::Result; + use plonky2::field::types::Sample; use plonky2::iop::witness::PartialWitness; - use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Sample; - use super::{ECDSAPublicKeyTarget, ECDSASignatureTarget}; - use crate::curve::curve_types::{Curve, CurveScalar}; + use super::*; + use crate::curve::curve_types::CurveScalar; use crate::curve::ecdsa::{sign_message, ECDSAPublicKey, ECDSASecretKey, ECDSASignature}; - use crate::curve::secp256k1::Secp256K1; - use crate::gadgets::curve::CircuitBuilderCurve; - use crate::gadgets::ecdsa::verify_message_circuit; - use crate::gadgets::nonnative::CircuitBuilderNonNative; fn test_ecdsa_circuit_with_config(config: CircuitConfig) -> Result<()> { const D: usize = 2; diff --git a/ecdsa/src/gadgets/glv.rs b/ecdsa/src/gadgets/glv.rs index 00cf64d7..063dee35 100644 --- a/ecdsa/src/gadgets/glv.rs +++ b/ecdsa/src/gadgets/glv.rs @@ -1,14 +1,15 @@ -use std::marker::PhantomData; +use alloc::vec::Vec; +use core::marker::PhantomData; +use plonky2::field::extension::Extendable; +use plonky2::field::secp256k1_base::Secp256K1Base; +use plonky2::field::secp256k1_scalar::Secp256K1Scalar; +use plonky2::field::types::{Field, PrimeField}; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::{BoolTarget, Target}; use plonky2::iop::witness::PartitionWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::extension::Extendable; -use plonky2_field::secp256k1_base::Secp256K1Base; -use plonky2_field::secp256k1_scalar::Secp256K1Scalar; -use plonky2_field::types::{Field, PrimeField}; use crate::curve::glv::{decompose_secp256k1_scalar, GLV_BETA, GLV_S}; use crate::curve::secp256k1::Secp256K1; @@ -132,12 +133,12 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { use anyhow::Result; + use plonky2::field::secp256k1_scalar::Secp256K1Scalar; + use plonky2::field::types::Sample; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Sample; use crate::curve::curve_types::{Curve, CurveScalar}; use crate::curve::glv::glv_mul; diff --git a/ecdsa/src/gadgets/nonnative.rs b/ecdsa/src/gadgets/nonnative.rs index ca865807..27dd1c65 100644 --- a/ecdsa/src/gadgets/nonnative.rs +++ b/ecdsa/src/gadgets/nonnative.rs @@ -1,17 +1,19 @@ -use std::marker::PhantomData; +use alloc::vec; +use alloc::vec::Vec; +use core::marker::PhantomData; use num::{BigUint, Integer, One, Zero}; +use plonky2::field::extension::Extendable; +use plonky2::field::types::{Field, PrimeField}; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::{BoolTarget, Target}; use plonky2::iop::witness::PartitionWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::extension::Extendable; -use plonky2_field::types::{Field, PrimeField}; +use plonky2::util::ceil_div_usize; use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target}; use plonky2_u32::gadgets::range_check::range_check_u32_circuit; use plonky2_u32::witness::GeneratedValuesU32; -use plonky2_util::ceil_div_usize; use crate::gadgets::biguint::{ BigUintTarget, CircuitBuilderBiguint, GeneratedValuesBigUint, WitnessBigUint, @@ -642,12 +644,12 @@ impl, const D: usize, FF: PrimeField> SimpleGenerat #[cfg(test)] mod tests { use anyhow::Result; + use plonky2::field::secp256k1_base::Secp256K1Base; + use plonky2::field::types::{Field, PrimeField, Sample}; use plonky2::iop::witness::PartialWitness; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2_field::secp256k1_base::Secp256K1Base; - use plonky2_field::types::{Field, PrimeField, Sample}; use crate::gadgets::nonnative::CircuitBuilderNonNative; diff --git a/ecdsa/src/gadgets/split_nonnative.rs b/ecdsa/src/gadgets/split_nonnative.rs index 330c2ea1..977912e2 100644 --- a/ecdsa/src/gadgets/split_nonnative.rs +++ b/ecdsa/src/gadgets/split_nonnative.rs @@ -1,11 +1,12 @@ -use std::marker::PhantomData; +use alloc::vec::Vec; +use core::marker::PhantomData; use itertools::Itertools; +use plonky2::field::extension::Extendable; +use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::iop::target::Target; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; use plonky2_u32::gadgets::arithmetic_u32::{CircuitBuilderU32, U32Target}; use crate::gadgets::biguint::BigUintTarget; @@ -96,15 +97,14 @@ impl, const D: usize> CircuitBuilderSplit #[cfg(test)] mod tests { use anyhow::Result; + use plonky2::field::secp256k1_scalar::Secp256K1Scalar; + use plonky2::field::types::Sample; use plonky2::iop::witness::PartialWitness; - use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2_field::secp256k1_scalar::Secp256K1Scalar; - use plonky2_field::types::Sample; + use super::*; use crate::gadgets::nonnative::{CircuitBuilderNonNative, NonNativeTarget}; - use crate::gadgets::split_nonnative::CircuitBuilderSplit; #[test] fn test_split_nonnative() -> Result<()> { diff --git a/ecdsa/src/lib.rs b/ecdsa/src/lib.rs index 92bdb857..bf84913a 100644 --- a/ecdsa/src/lib.rs +++ b/ecdsa/src/lib.rs @@ -1,7 +1,7 @@ #![allow(clippy::needless_range_loop)] -// Below lint is currently broken and produces false positives. -// TODO: Remove this override when Clippy is patched. -#![allow(clippy::derive_partial_eq_without_eq)] +#![cfg_attr(not(test), no_std)] + +extern crate alloc; pub mod curve; pub mod gadgets; diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index a9ad3de2..82b82091 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -36,15 +36,15 @@ static_assertions = { version = "1.1.0", default-features = false } unroll = { version = "0.1.5", default-features = false } [dev-dependencies] -criterion = "0.3.5" -env_logger = "0.9.0" -num_cpus = "1.13.1" +criterion = { version = "0.3.5", default-features = false } +env_logger = { version = "0.9.0", default-features = false } +num_cpus = { version = "1.13.1", default-features = false } plonky2 = { path = "." } -rand = "0.8.4" -rand_chacha = "0.3.1" -rayon = "1.5.1" -structopt = "0.3.26" -tynm = "0.1.6" +rand = { version = "0.8.4", default-features = false, features = ["getrandom"] } +rand_chacha = { version = "0.3.1", default-features = false } +rayon = { version = "1.5.1", default-features = false } +structopt = { version = "0.3.26", default-features = false } +tynm = { version = "0.1.6", default-features = false } [target.'cfg(not(target_env = "msvc"))'.dev-dependencies] jemallocator = "0.3.2" diff --git a/plonky2/src/bin/generate_constants.rs b/plonky2/src/bin/generate_constants.rs index c5f8fae2..608df815 100644 --- a/plonky2/src/bin/generate_constants.rs +++ b/plonky2/src/bin/generate_constants.rs @@ -2,8 +2,8 @@ #![allow(clippy::needless_range_loop)] -use plonky2_field::goldilocks_field::GoldilocksField; -use plonky2_field::types::Field64; +use plonky2::field::goldilocks_field::GoldilocksField; +use plonky2::field::types::Field64; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; diff --git a/plonky2/src/fri/challenges.rs b/plonky2/src/fri/challenges.rs index 3a750dd6..00deda07 100644 --- a/plonky2/src/fri/challenges.rs +++ b/plonky2/src/fri/challenges.rs @@ -1,8 +1,7 @@ use alloc::vec::Vec; -use plonky2_field::extension::Extendable; -use plonky2_field::polynomial::PolynomialCoeffs; - +use crate::field::extension::Extendable; +use crate::field::polynomial::PolynomialCoeffs; use crate::fri::proof::{FriChallenges, FriChallengesTarget}; use crate::fri::structure::{FriOpenings, FriOpeningsTarget}; use crate::fri::FriConfig; diff --git a/plonky2/src/fri/oracle.rs b/plonky2/src/fri/oracle.rs index b670944d..cc114d98 100644 --- a/plonky2/src/fri/oracle.rs +++ b/plonky2/src/fri/oracle.rs @@ -3,13 +3,12 @@ use alloc::vec::Vec; use itertools::Itertools; use maybe_rayon::*; -use plonky2_field::extension::Extendable; -use plonky2_field::fft::FftRootTable; -use plonky2_field::packed::PackedField; -use plonky2_field::polynomial::{PolynomialCoeffs, PolynomialValues}; -use plonky2_field::types::Field; -use plonky2_util::{log2_strict, reverse_index_bits_in_place}; +use crate::field::extension::Extendable; +use crate::field::fft::FftRootTable; +use crate::field::packed::PackedField; +use crate::field::polynomial::{PolynomialCoeffs, PolynomialValues}; +use crate::field::types::Field; use crate::fri::proof::FriProof; use crate::fri::prover::fri_proof; use crate::fri::structure::{FriBatchInfo, FriInstanceInfo}; @@ -21,7 +20,7 @@ use crate::plonk::config::GenericConfig; use crate::timed; use crate::util::reducing::ReducingFactor; use crate::util::timing::TimingTree; -use crate::util::{reverse_bits, transpose}; +use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place, transpose}; /// Four (~64 bit) field elements gives ~128 bit security. pub const SALT_SIZE: usize = 4; diff --git a/plonky2/src/fri/proof.rs b/plonky2/src/fri/proof.rs index c3d3ecbb..4c5f65d8 100644 --- a/plonky2/src/fri/proof.rs +++ b/plonky2/src/fri/proof.rs @@ -3,10 +3,10 @@ use alloc::vec::Vec; use hashbrown::HashMap; use itertools::izip; -use plonky2_field::extension::{flatten, unflatten, Extendable}; -use plonky2_field::polynomial::PolynomialCoeffs; use serde::{Deserialize, Serialize}; +use crate::field::extension::{flatten, unflatten, Extendable}; +use crate::field::polynomial::PolynomialCoeffs; use crate::fri::FriParams; use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; use crate::hash::hash_types::{MerkleCapTarget, RichField}; diff --git a/plonky2/src/fri/prover.rs b/plonky2/src/fri/prover.rs index adbf5e29..f3c8b28e 100644 --- a/plonky2/src/fri/prover.rs +++ b/plonky2/src/fri/prover.rs @@ -2,10 +2,9 @@ use alloc::vec::Vec; use itertools::Itertools; use maybe_rayon::*; -use plonky2_field::extension::{flatten, unflatten, Extendable}; -use plonky2_field::polynomial::{PolynomialCoeffs, PolynomialValues}; -use plonky2_util::reverse_index_bits_in_place; +use crate::field::extension::{flatten, unflatten, Extendable}; +use crate::field::polynomial::{PolynomialCoeffs, PolynomialValues}; use crate::fri::proof::{FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep}; use crate::fri::{FriConfig, FriParams}; use crate::hash::hash_types::{HashOut, RichField}; @@ -14,6 +13,7 @@ use crate::iop::challenger::Challenger; use crate::plonk::config::{GenericConfig, Hasher}; use crate::plonk::plonk_common::reduce_with_powers; use crate::timed; +use crate::util::reverse_index_bits_in_place; use crate::util::timing::TimingTree; /// Builds a FRI proof. diff --git a/plonky2/src/fri/recursive_verifier.rs b/plonky2/src/fri/recursive_verifier.rs index a5b50041..822dd559 100644 --- a/plonky2/src/fri/recursive_verifier.rs +++ b/plonky2/src/fri/recursive_verifier.rs @@ -2,9 +2,8 @@ use alloc::vec::Vec; use alloc::{format, vec}; use itertools::Itertools; -use plonky2_field::extension::Extendable; -use plonky2_util::{log2_strict, reverse_index_bits_in_place}; +use crate::field::extension::Extendable; use crate::fri::proof::{ FriChallengesTarget, FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, @@ -22,6 +21,7 @@ use crate::iop::target::{BoolTarget, Target}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; use crate::util::reducing::ReducingFactorTarget; +use crate::util::{log2_strict, reverse_index_bits_in_place}; use crate::with_context; impl, const D: usize> CircuitBuilder { diff --git a/plonky2/src/fri/reduction_strategies.rs b/plonky2/src/fri/reduction_strategies.rs index 7035100d..409a0224 100644 --- a/plonky2/src/fri/reduction_strategies.rs +++ b/plonky2/src/fri/reduction_strategies.rs @@ -35,7 +35,6 @@ impl FriReductionStrategy { ) -> Vec { match self { FriReductionStrategy::Fixed(reduction_arity_bits) => reduction_arity_bits.to_vec(), - &FriReductionStrategy::ConstantArityBits(arity_bits, final_poly_bits) => { let mut result = Vec::new(); while degree_bits > final_poly_bits @@ -48,7 +47,6 @@ impl FriReductionStrategy { result.shrink_to_fit(); result } - FriReductionStrategy::MinSize(opt_max_arity_bits) => { min_size_arity_bits(degree_bits, rate_bits, num_queries, *opt_max_arity_bits) } diff --git a/plonky2/src/fri/validate_shape.rs b/plonky2/src/fri/validate_shape.rs index 0ef85c4c..526da8f7 100644 --- a/plonky2/src/fri/validate_shape.rs +++ b/plonky2/src/fri/validate_shape.rs @@ -1,6 +1,6 @@ use anyhow::ensure; -use plonky2_field::extension::Extendable; +use crate::field::extension::Extendable; use crate::fri::proof::{FriProof, FriQueryRound, FriQueryStep}; use crate::fri::structure::FriInstanceInfo; use crate::fri::FriParams; diff --git a/plonky2/src/fri/verifier.rs b/plonky2/src/fri/verifier.rs index 7060ce95..6644b971 100644 --- a/plonky2/src/fri/verifier.rs +++ b/plonky2/src/fri/verifier.rs @@ -1,11 +1,10 @@ use alloc::vec::Vec; use anyhow::{ensure, Result}; -use plonky2_field::extension::{flatten, Extendable, FieldExtension}; -use plonky2_field::interpolation::{barycentric_weights, interpolate}; -use plonky2_field::types::Field; -use plonky2_util::{log2_strict, reverse_index_bits_in_place}; +use crate::field::extension::{flatten, Extendable, FieldExtension}; +use crate::field::interpolation::{barycentric_weights, interpolate}; +use crate::field::types::Field; use crate::fri::proof::{FriChallenges, FriInitialTreeProof, FriProof, FriQueryRound}; use crate::fri::structure::{FriBatchInfo, FriInstanceInfo, FriOpenings}; use crate::fri::validate_shape::validate_fri_proof_shape; @@ -15,7 +14,7 @@ use crate::hash::merkle_proofs::verify_merkle_proof_to_cap; use crate::hash::merkle_tree::MerkleCap; use crate::plonk::config::{GenericConfig, Hasher}; use crate::util::reducing::ReducingFactor; -use crate::util::reverse_bits; +use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place}; /// Computes P'(x^arity) from {P(x*g^i)}_(i=0..arity), where g is a `arity`-th root of unity /// and P' is the FRI reduced polynomial. diff --git a/plonky2/src/fri/witness_util.rs b/plonky2/src/fri/witness_util.rs index ddf3c401..670319de 100644 --- a/plonky2/src/fri/witness_util.rs +++ b/plonky2/src/fri/witness_util.rs @@ -1,6 +1,6 @@ use itertools::Itertools; -use plonky2_field::extension::Extendable; +use crate::field::extension::Extendable; use crate::fri::proof::{FriProof, FriProofTarget}; use crate::hash::hash_types::RichField; use crate::iop::witness::Witness; diff --git a/plonky2/src/gadgets/arithmetic.rs b/plonky2/src/gadgets/arithmetic.rs index c18ea034..3e42fa11 100644 --- a/plonky2/src/gadgets/arithmetic.rs +++ b/plonky2/src/gadgets/arithmetic.rs @@ -2,9 +2,8 @@ use alloc::vec; use alloc::vec::Vec; use core::borrow::Borrow; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field64; - +use crate::field::extension::Extendable; +use crate::field::types::Field64; use crate::gates::arithmetic_base::ArithmeticGate; use crate::gates::exponentiation::ExponentiationGate; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/gadgets/arithmetic_extension.rs b/plonky2/src/gadgets/arithmetic_extension.rs index 6232d7cb..e37d4deb 100644 --- a/plonky2/src/gadgets/arithmetic_extension.rs +++ b/plonky2/src/gadgets/arithmetic_extension.rs @@ -2,10 +2,8 @@ use alloc::vec; use alloc::vec::Vec; use core::borrow::Borrow; -use plonky2_field::extension::{Extendable, FieldExtension, OEF}; -use plonky2_field::types::{Field, Field64}; -use plonky2_util::bits_u64; - +use crate::field::extension::{Extendable, FieldExtension, OEF}; +use crate::field::types::{Field, Field64}; use crate::gates::arithmetic_extension::ArithmeticExtensionGate; use crate::gates::multiplication_extension::MulExtensionGate; use crate::hash::hash_types::RichField; @@ -14,6 +12,7 @@ use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::Target; use crate::iop::witness::{PartitionWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::util::bits_u64; impl, const D: usize> CircuitBuilder { pub fn arithmetic_extension( @@ -570,9 +569,9 @@ pub(crate) struct ExtensionArithmeticOperation, const #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::extension::algebra::ExtensionAlgebra; - use plonky2_field::types::Sample; + use crate::field::extension::algebra::ExtensionAlgebra; + use crate::field::types::Sample; use crate::iop::ext_target::ExtensionAlgebraTarget; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; diff --git a/plonky2/src/gadgets/hash.rs b/plonky2/src/gadgets/hash.rs index ec235340..2b8bfac5 100644 --- a/plonky2/src/gadgets/hash.rs +++ b/plonky2/src/gadgets/hash.rs @@ -1,5 +1,4 @@ -use plonky2_field::extension::Extendable; - +use crate::field::extension::Extendable; use crate::hash::hash_types::RichField; use crate::hash::hashing::SPONGE_WIDTH; use crate::iop::target::{BoolTarget, Target}; diff --git a/plonky2/src/gadgets/polynomial.rs b/plonky2/src/gadgets/polynomial.rs index bf5c2207..f7a59192 100644 --- a/plonky2/src/gadgets/polynomial.rs +++ b/plonky2/src/gadgets/polynomial.rs @@ -1,7 +1,6 @@ use alloc::vec::Vec; -use plonky2_field::extension::Extendable; - +use crate::field::extension::Extendable; use crate::hash::hash_types::RichField; use crate::iop::ext_target::{ExtensionAlgebraTarget, ExtensionTarget}; use crate::iop::target::Target; diff --git a/plonky2/src/gadgets/random_access.rs b/plonky2/src/gadgets/random_access.rs index a3febec7..d3a3ff1b 100644 --- a/plonky2/src/gadgets/random_access.rs +++ b/plonky2/src/gadgets/random_access.rs @@ -1,13 +1,12 @@ use alloc::vec::Vec; -use plonky2_field::extension::Extendable; -use plonky2_util::log2_strict; - +use crate::field::extension::Extendable; use crate::gates::random_access::RandomAccessGate; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::util::log2_strict; impl, const D: usize> CircuitBuilder { /// Checks that a `Target` matches a vector at a non-deterministic index. @@ -57,9 +56,9 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::{Field, Sample}; use super::*; + use crate::field::types::{Field, Sample}; use crate::iop::witness::PartialWitness; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/gadgets/range_check.rs b/plonky2/src/gadgets/range_check.rs index fd22c17d..22977bc1 100644 --- a/plonky2/src/gadgets/range_check.rs +++ b/plonky2/src/gadgets/range_check.rs @@ -1,8 +1,7 @@ use alloc::vec; use alloc::vec::Vec; -use plonky2_field::extension::Extendable; - +use crate::field::extension::Extendable; use crate::hash::hash_types::RichField; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; diff --git a/plonky2/src/gadgets/select.rs b/plonky2/src/gadgets/select.rs index 03e18188..c2531488 100644 --- a/plonky2/src/gadgets/select.rs +++ b/plonky2/src/gadgets/select.rs @@ -1,5 +1,4 @@ -use plonky2_field::extension::Extendable; - +use crate::field::extension::Extendable; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::{BoolTarget, Target}; @@ -40,8 +39,8 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::Sample; + use crate::field::types::Sample; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; diff --git a/plonky2/src/gadgets/split_base.rs b/plonky2/src/gadgets/split_base.rs index 43e67cb8..3843cad3 100644 --- a/plonky2/src/gadgets/split_base.rs +++ b/plonky2/src/gadgets/split_base.rs @@ -3,9 +3,9 @@ use alloc::vec::Vec; use core::borrow::Borrow; use itertools::Itertools; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; +use crate::field::extension::Extendable; +use crate::field::types::Field; use crate::gates::base_sum::BaseSumGate; use crate::hash::hash_types::RichField; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; @@ -101,11 +101,11 @@ impl SimpleGenerator for BaseSumGenerator { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::Field; - use rand::{thread_rng, Rng}; + use rand::rngs::OsRng; + use rand::Rng; + use super::*; use crate::iop::witness::PartialWitness; - use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use crate::plonk::verifier::verify; @@ -147,7 +147,7 @@ mod tests { let pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); - let n = thread_rng().gen_range(0..(1 << 30)); + let n = OsRng.gen_range(0..(1 << 30)); let x = builder.constant(F::from_canonical_usize(n)); let zero = builder._false(); diff --git a/plonky2/src/gadgets/split_join.rs b/plonky2/src/gadgets/split_join.rs index ee4bd7ef..1a1575c0 100644 --- a/plonky2/src/gadgets/split_join.rs +++ b/plonky2/src/gadgets/split_join.rs @@ -1,15 +1,14 @@ use alloc::vec; use alloc::vec::Vec; -use plonky2_field::extension::Extendable; -use plonky2_util::ceil_div_usize; - +use crate::field::extension::Extendable; use crate::gates::base_sum::BaseSumGate; use crate::hash::hash_types::RichField; use crate::iop::generator::{GeneratedValues, SimpleGenerator}; use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::{PartitionWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::util::ceil_div_usize; impl, const D: usize> CircuitBuilder { /// Split the given integer into a list of wires, where each one represents a diff --git a/plonky2/src/gates/arithmetic_base.rs b/plonky2/src/gates/arithmetic_base.rs index 69f2c179..34d6e244 100644 --- a/plonky2/src/gates/arithmetic_base.rs +++ b/plonky2/src/gates/arithmetic_base.rs @@ -3,9 +3,8 @@ use alloc::format; use alloc::string::String; use alloc::vec::Vec; -use plonky2_field::extension::Extendable; -use plonky2_field::packed::PackedField; - +use crate::field::extension::Extendable; +use crate::field::packed::PackedField; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -214,8 +213,8 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; + use crate::field::goldilocks_field::GoldilocksField; use crate::gates::arithmetic_base::ArithmeticGate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::plonk::circuit_data::CircuitConfig; diff --git a/plonky2/src/gates/arithmetic_extension.rs b/plonky2/src/gates/arithmetic_extension.rs index da686739..ee7f96be 100644 --- a/plonky2/src/gates/arithmetic_extension.rs +++ b/plonky2/src/gates/arithmetic_extension.rs @@ -4,8 +4,7 @@ use alloc::string::String; use alloc::vec::Vec; use core::ops::Range; -use plonky2_field::extension::{Extendable, FieldExtension}; - +use crate::field::extension::{Extendable, FieldExtension}; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -207,8 +206,8 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; + use crate::field::goldilocks_field::GoldilocksField; use crate::gates::arithmetic_extension::ArithmeticExtensionGate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::plonk::circuit_data::CircuitConfig; diff --git a/plonky2/src/gates/base_sum.rs b/plonky2/src/gates/base_sum.rs index dd3542e1..27eb2c69 100644 --- a/plonky2/src/gates/base_sum.rs +++ b/plonky2/src/gates/base_sum.rs @@ -4,11 +4,9 @@ use alloc::vec::Vec; use alloc::{format, vec}; use core::ops::Range; -use plonky2_field::extension::Extendable; -use plonky2_field::packed::PackedField; -use plonky2_field::types::{Field, Field64}; -use plonky2_util::log_floor; - +use crate::field::extension::Extendable; +use crate::field::packed::PackedField; +use crate::field::types::{Field, Field64}; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -24,6 +22,7 @@ use crate::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, }; +use crate::util::log_floor; /// A gate which can decompose a number into base B little-endian limbs. #[derive(Copy, Clone, Debug)] @@ -201,8 +200,8 @@ impl SimpleGenerator for BaseSplitGenerator #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; + use crate::field::goldilocks_field::GoldilocksField; use crate::gates::base_sum::BaseSumGate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/gates/constant.rs b/plonky2/src/gates/constant.rs index dcb730af..bf365b04 100644 --- a/plonky2/src/gates/constant.rs +++ b/plonky2/src/gates/constant.rs @@ -3,9 +3,8 @@ use alloc::string::String; use alloc::vec::Vec; use alloc::{format, vec}; -use plonky2_field::extension::Extendable; -use plonky2_field::packed::PackedField; - +use crate::field::extension::Extendable; +use crate::field::packed::PackedField; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -118,8 +117,8 @@ impl, const D: usize> PackedEvaluableBase for #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; + use crate::field::goldilocks_field::GoldilocksField; use crate::gates::constant::ConstantGate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::plonk::circuit_data::CircuitConfig; diff --git a/plonky2/src/gates/exponentiation.rs b/plonky2/src/gates/exponentiation.rs index f7c2bc60..138ec3c9 100644 --- a/plonky2/src/gates/exponentiation.rs +++ b/plonky2/src/gates/exponentiation.rs @@ -4,11 +4,10 @@ use alloc::vec::Vec; use alloc::{format, vec}; use core::marker::PhantomData; -use plonky2_field::extension::Extendable; -use plonky2_field::ops::Square; -use plonky2_field::packed::PackedField; -use plonky2_field::types::Field; - +use crate::field::extension::Extendable; +use crate::field::ops::Square; +use crate::field::packed::PackedField; +use crate::field::types::Field; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -286,21 +285,17 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use core::marker::PhantomData; - use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, Sample}; - use plonky2_util::log2_ceil; + use rand::rngs::OsRng; use rand::Rng; - use crate::gates::exponentiation::ExponentiationGate; - use crate::gates::gate::Gate; + use super::*; + use crate::field::goldilocks_field::GoldilocksField; + use crate::field::types::Sample; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::hash::hash_types::HashOut; - use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use crate::plonk::vars::EvaluationVars; + use crate::util::log2_ceil; const MAX_POWER_BITS: usize = 17; @@ -383,7 +378,7 @@ mod tests { v.iter().map(|&x| x.into()).collect::>() } - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let base = F::TWO; let power = rng.gen::() % (1 << MAX_POWER_BITS); diff --git a/plonky2/src/gates/gate.rs b/plonky2/src/gates/gate.rs index 7b2db413..34950b76 100644 --- a/plonky2/src/gates/gate.rs +++ b/plonky2/src/gates/gate.rs @@ -8,10 +8,10 @@ use core::hash::{Hash, Hasher}; use core::ops::Range; use hashbrown::HashMap; -use plonky2_field::batch_util::batch_multiply_inplace; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::types::Field; +use crate::field::batch_util::batch_multiply_inplace; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::types::Field; use crate::gates::selectors::UNUSED_SELECTOR; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/gates/gate_testing.rs b/plonky2/src/gates/gate_testing.rs index 0e87c262..c6cae2bb 100644 --- a/plonky2/src/gates/gate_testing.rs +++ b/plonky2/src/gates/gate_testing.rs @@ -2,11 +2,10 @@ use alloc::vec; use alloc::vec::Vec; use anyhow::{ensure, Result}; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::polynomial::{PolynomialCoeffs, PolynomialValues}; -use plonky2_field::types::{Field, Sample}; -use plonky2_util::log2_ceil; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::polynomial::{PolynomialCoeffs, PolynomialValues}; +use crate::field::types::{Field, Sample}; use crate::gates::gate::Gate; use crate::hash::hash_types::{HashOut, RichField}; use crate::iop::witness::{PartialWitness, Witness}; @@ -15,7 +14,7 @@ use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::GenericConfig; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch}; use crate::plonk::verifier::verify; -use crate::util::transpose; +use crate::util::{log2_ceil, transpose}; const WITNESS_SIZE: usize = 1 << 5; const WITNESS_DEGREE: usize = WITNESS_SIZE - 1; diff --git a/plonky2/src/gates/high_degree_interpolation.rs b/plonky2/src/gates/high_degree_interpolation.rs index 110ea167..65573898 100644 --- a/plonky2/src/gates/high_degree_interpolation.rs +++ b/plonky2/src/gates/high_degree_interpolation.rs @@ -5,11 +5,10 @@ use alloc::{format, vec}; use core::marker::PhantomData; use core::ops::Range; -use plonky2_field::extension::algebra::PolynomialCoeffsAlgebra; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::interpolation::interpolant; -use plonky2_field::polynomial::PolynomialCoeffs; - +use crate::field::extension::algebra::PolynomialCoeffsAlgebra; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::interpolation::interpolant; +use crate::field::polynomial::PolynomialCoeffs; use crate::gadgets::polynomial::PolynomialCoeffsExtAlgebraTarget; use crate::gates::gate::Gate; use crate::gates::interpolation::InterpolationGate; @@ -274,20 +273,14 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use core::marker::PhantomData; - use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::polynomial::PolynomialCoeffs; - use plonky2_field::types::{Field, Sample}; - use crate::gates::gate::Gate; + use super::*; + use crate::field::goldilocks_field::GoldilocksField; + use crate::field::types::{Field, Sample}; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; - use crate::gates::high_degree_interpolation::HighDegreeInterpolationGate; - use crate::gates::interpolation::InterpolationGate; use crate::hash::hash_types::HashOut; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use crate::plonk::vars::EvaluationVars; #[test] fn wire_indices() { diff --git a/plonky2/src/gates/interpolation.rs b/plonky2/src/gates/interpolation.rs index 7f4953d5..07179006 100644 --- a/plonky2/src/gates/interpolation.rs +++ b/plonky2/src/gates/interpolation.rs @@ -1,8 +1,7 @@ use alloc::vec; use core::ops::Range; -use plonky2_field::extension::Extendable; - +use crate::field::extension::Extendable; use crate::gates::gate::Gate; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; @@ -106,10 +105,10 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::extension::FieldExtension; - use plonky2_field::interpolation::interpolant; - use plonky2_field::types::{Field, Sample}; + use crate::field::extension::FieldExtension; + use crate::field::interpolation::interpolant; + use crate::field::types::{Field, Sample}; use crate::gates::high_degree_interpolation::HighDegreeInterpolationGate; use crate::gates::low_degree_interpolation::LowDegreeInterpolationGate; use crate::iop::witness::PartialWitness; diff --git a/plonky2/src/gates/low_degree_interpolation.rs b/plonky2/src/gates/low_degree_interpolation.rs index 77a84484..f4f3286c 100644 --- a/plonky2/src/gates/low_degree_interpolation.rs +++ b/plonky2/src/gates/low_degree_interpolation.rs @@ -5,12 +5,11 @@ use alloc::{format, vec}; use core::marker::PhantomData; use core::ops::Range; -use plonky2_field::extension::algebra::PolynomialCoeffsAlgebra; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::interpolation::interpolant; -use plonky2_field::polynomial::PolynomialCoeffs; -use plonky2_field::types::Field; - +use crate::field::extension::algebra::PolynomialCoeffsAlgebra; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::interpolation::interpolant; +use crate::field::polynomial::PolynomialCoeffs; +use crate::field::types::Field; use crate::gadgets::polynomial::PolynomialCoeffsExtAlgebraTarget; use crate::gates::gate::Gate; use crate::gates::interpolation::InterpolationGate; @@ -387,11 +386,11 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::extension::quadratic::QuadraticExtension; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::polynomial::PolynomialCoeffs; - use plonky2_field::types::{Field, Sample}; + use crate::field::extension::quadratic::QuadraticExtension; + use crate::field::goldilocks_field::GoldilocksField; + use crate::field::polynomial::PolynomialCoeffs; + use crate::field::types::{Field, Sample}; use crate::gates::gate::Gate; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::gates::interpolation::InterpolationGate; diff --git a/plonky2/src/gates/multiplication_extension.rs b/plonky2/src/gates/multiplication_extension.rs index 5941f978..02243450 100644 --- a/plonky2/src/gates/multiplication_extension.rs +++ b/plonky2/src/gates/multiplication_extension.rs @@ -4,8 +4,7 @@ use alloc::string::String; use alloc::vec::Vec; use core::ops::Range; -use plonky2_field::extension::{Extendable, FieldExtension}; - +use crate::field::extension::{Extendable, FieldExtension}; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -184,11 +183,10 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; + use super::*; + use crate::field::goldilocks_field::GoldilocksField; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; - use crate::gates::multiplication_extension::MulExtensionGate; - use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; #[test] diff --git a/plonky2/src/gates/noop.rs b/plonky2/src/gates/noop.rs index a4d41a5c..f6f9853a 100644 --- a/plonky2/src/gates/noop.rs +++ b/plonky2/src/gates/noop.rs @@ -2,8 +2,7 @@ use alloc::boxed::Box; use alloc::string::String; use alloc::vec::Vec; -use plonky2_field::extension::Extendable; - +use crate::field::extension::Extendable; use crate::gates::gate::Gate; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; @@ -58,8 +57,7 @@ impl, const D: usize> Gate for NoopGate { #[cfg(test)] mod tests { - use plonky2_field::goldilocks_field::GoldilocksField; - + use crate::field::goldilocks_field::GoldilocksField; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::gates::noop::NoopGate; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/gates/packed_util.rs b/plonky2/src/gates/packed_util.rs index 62bc2d54..361eb3a2 100644 --- a/plonky2/src/gates/packed_util.rs +++ b/plonky2/src/gates/packed_util.rs @@ -1,10 +1,9 @@ use alloc::vec; use alloc::vec::Vec; -use plonky2_field::extension::Extendable; -use plonky2_field::packable::Packable; -use plonky2_field::packed::PackedField; - +use crate::field::extension::Extendable; +use crate::field::packable::Packable; +use crate::field::packed::PackedField; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/gates/poseidon.rs b/plonky2/src/gates/poseidon.rs index d491cce6..c644ada5 100644 --- a/plonky2/src/gates/poseidon.rs +++ b/plonky2/src/gates/poseidon.rs @@ -4,9 +4,8 @@ use alloc::vec::Vec; use alloc::{format, vec}; use core::marker::PhantomData; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; - +use crate::field::extension::Extendable; +use crate::field::types::Field; use crate::gates::gate::Gate; use crate::gates::poseidon_mds::PoseidonMdsGate; use crate::gates::util::StridedConstraintConsumer; @@ -507,9 +506,9 @@ impl + Poseidon, const D: usize> SimpleGenerator #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::Field; + use crate::field::goldilocks_field::GoldilocksField; + use crate::field::types::Field; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::gates::poseidon::PoseidonGate; use crate::hash::hashing::SPONGE_WIDTH; diff --git a/plonky2/src/gates/poseidon_mds.rs b/plonky2/src/gates/poseidon_mds.rs index 880a21ff..dd494328 100644 --- a/plonky2/src/gates/poseidon_mds.rs +++ b/plonky2/src/gates/poseidon_mds.rs @@ -5,10 +5,9 @@ use alloc::{format, vec}; use core::marker::PhantomData; use core::ops::Range; -use plonky2_field::extension::algebra::ExtensionAlgebra; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::types::Field; - +use crate::field::extension::algebra::ExtensionAlgebra; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::types::Field; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/gates/public_input.rs b/plonky2/src/gates/public_input.rs index d2ab2568..10c42f00 100644 --- a/plonky2/src/gates/public_input.rs +++ b/plonky2/src/gates/public_input.rs @@ -3,9 +3,8 @@ use alloc::string::String; use alloc::vec::Vec; use core::ops::Range; -use plonky2_field::extension::Extendable; -use plonky2_field::packed::PackedField; - +use crate::field::extension::Extendable; +use crate::field::packed::PackedField; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -102,8 +101,7 @@ impl, const D: usize> PackedEvaluableBase for #[cfg(test)] mod tests { - use plonky2_field::goldilocks_field::GoldilocksField; - + use crate::field::goldilocks_field::GoldilocksField; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::gates::public_input::PublicInputGate; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/gates/random_access.rs b/plonky2/src/gates/random_access.rs index dbc3a947..52972cd3 100644 --- a/plonky2/src/gates/random_access.rs +++ b/plonky2/src/gates/random_access.rs @@ -5,10 +5,10 @@ use alloc::{format, vec}; use core::marker::PhantomData; use itertools::Itertools; -use plonky2_field::extension::Extendable; -use plonky2_field::packed::PackedField; -use plonky2_field::types::Field; +use crate::field::extension::Extendable; +use crate::field::packed::PackedField; +use crate::field::types::Field; use crate::gates::gate::Gate; use crate::gates::packed_util::PackedEvaluableBase; use crate::gates::util::StridedConstraintConsumer; @@ -380,19 +380,16 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use core::marker::PhantomData; - use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, Sample}; - use rand::{thread_rng, Rng}; + use rand::rngs::OsRng; + use rand::Rng; - use crate::gates::gate::Gate; + use super::*; + use crate::field::goldilocks_field::GoldilocksField; + use crate::field::types::Sample; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; - use crate::gates::random_access::RandomAccessGate; use crate::hash::hash_types::HashOut; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use crate::plonk::vars::EvaluationVars; #[test] fn low_degree() { @@ -453,7 +450,7 @@ mod tests { .map(|_| F::rand_vec(vec_size)) .collect::>(); let access_indices = (0..num_copies) - .map(|_| thread_rng().gen_range(0..vec_size)) + .map(|_| OsRng.gen_range(0..vec_size)) .collect::>(); let gate = RandomAccessGate:: { bits, diff --git a/plonky2/src/gates/reducing.rs b/plonky2/src/gates/reducing.rs index 12880b28..64a1a986 100644 --- a/plonky2/src/gates/reducing.rs +++ b/plonky2/src/gates/reducing.rs @@ -4,8 +4,7 @@ use alloc::vec::Vec; use alloc::{format, vec}; use core::ops::Range; -use plonky2_field::extension::{Extendable, FieldExtension}; - +use crate::field::extension::{Extendable, FieldExtension}; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -213,8 +212,8 @@ impl, const D: usize> SimpleGenerator for Reduci #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; + use crate::field::goldilocks_field::GoldilocksField; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::gates::reducing::ReducingGate; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/gates/reducing_extension.rs b/plonky2/src/gates/reducing_extension.rs index f952c0c8..27483e1f 100644 --- a/plonky2/src/gates/reducing_extension.rs +++ b/plonky2/src/gates/reducing_extension.rs @@ -4,8 +4,7 @@ use alloc::vec::Vec; use alloc::{format, vec}; use core::ops::Range; -use plonky2_field::extension::{Extendable, FieldExtension}; - +use crate::field::extension::{Extendable, FieldExtension}; use crate::gates::gate::Gate; use crate::gates::util::StridedConstraintConsumer; use crate::hash::hash_types::RichField; @@ -207,8 +206,8 @@ impl, const D: usize> SimpleGenerator for Reduci #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::goldilocks_field::GoldilocksField; + use crate::field::goldilocks_field::GoldilocksField; use crate::gates::gate_testing::{test_eval_fns, test_low_degree}; use crate::gates::reducing_extension::ReducingExtensionGate; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/gates/selectors.rs b/plonky2/src/gates/selectors.rs index bfd13073..7c5c6f34 100644 --- a/plonky2/src/gates/selectors.rs +++ b/plonky2/src/gates/selectors.rs @@ -2,9 +2,8 @@ use alloc::vec; use alloc::vec::Vec; use core::ops::Range; -use plonky2_field::extension::Extendable; -use plonky2_field::polynomial::PolynomialValues; - +use crate::field::extension::Extendable; +use crate::field::polynomial::PolynomialValues; use crate::gates::gate::{GateInstance, GateRef}; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/gates/util.rs b/plonky2/src/gates/util.rs index cd6dc9e1..88d77471 100644 --- a/plonky2/src/gates/util.rs +++ b/plonky2/src/gates/util.rs @@ -1,6 +1,6 @@ use core::marker::PhantomData; -use plonky2_field::packed::PackedField; +use crate::field::packed::PackedField; /// Writes constraints yielded by a gate to a buffer, with a given stride. /// Permits us to abstract the underlying memory layout. In particular, we can make a matrix of diff --git a/plonky2/src/hash/arch/aarch64/poseidon_goldilocks_neon.rs b/plonky2/src/hash/arch/aarch64/poseidon_goldilocks_neon.rs index 5cf25dce..10d81f28 100644 --- a/plonky2/src/hash/arch/aarch64/poseidon_goldilocks_neon.rs +++ b/plonky2/src/hash/arch/aarch64/poseidon_goldilocks_neon.rs @@ -4,12 +4,12 @@ use core::arch::aarch64::*; use core::arch::asm; use core::mem::transmute; -use plonky2_field::goldilocks_field::GoldilocksField; -use plonky2_util::branch_hint; use static_assertions::const_assert; use unroll::unroll_for_loops; +use crate::field::goldilocks_field::GoldilocksField; use crate::hash::poseidon::Poseidon; +use crate::util::branch_hint; // ========================================== CONSTANTS =========================================== diff --git a/plonky2/src/hash/arch/x86_64/poseidon_goldilocks_avx2_bmi2.rs b/plonky2/src/hash/arch/x86_64/poseidon_goldilocks_avx2_bmi2.rs index ae08f568..c7a65f90 100644 --- a/plonky2/src/hash/arch/x86_64/poseidon_goldilocks_avx2_bmi2.rs +++ b/plonky2/src/hash/arch/x86_64/poseidon_goldilocks_avx2_bmi2.rs @@ -2,14 +2,14 @@ use core::arch::asm; use core::arch::x86_64::*; use core::mem::size_of; -use plonky2_field::goldilocks_field::GoldilocksField; -use plonky2_field::types::Field; -use plonky2_util::branch_hint; use static_assertions::const_assert; +use crate::field::goldilocks_field::GoldilocksField; +use crate::field::types::Field; use crate::hash::poseidon::{ Poseidon, ALL_ROUND_CONSTANTS, HALF_N_FULL_ROUNDS, N_PARTIAL_ROUNDS, N_ROUNDS, }; +use crate::util::branch_hint; // WARNING: This code contains tricks that work for the current MDS matrix and round constants, but // are not guaranteed to work if those are changed. diff --git a/plonky2/src/hash/hash_types.rs b/plonky2/src/hash/hash_types.rs index e7f29044..b95a2113 100644 --- a/plonky2/src/hash/hash_types.rs +++ b/plonky2/src/hash/hash_types.rs @@ -1,9 +1,9 @@ use alloc::vec::Vec; -use plonky2_field::goldilocks_field::GoldilocksField; -use plonky2_field::types::{Field, PrimeField64, Sample}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use crate::field::goldilocks_field::GoldilocksField; +use crate::field::types::{Field, PrimeField64, Sample}; use crate::hash::poseidon::Poseidon; use crate::iop::target::Target; use crate::plonk::config::GenericHashOut; diff --git a/plonky2/src/hash/hashing.rs b/plonky2/src/hash/hashing.rs index ac115152..3e93447a 100644 --- a/plonky2/src/hash/hashing.rs +++ b/plonky2/src/hash/hashing.rs @@ -2,8 +2,7 @@ use alloc::vec::Vec; -use plonky2_field::extension::Extendable; - +use crate::field::extension::Extendable; use crate::hash::hash_types::{HashOut, HashOutTarget, RichField}; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; diff --git a/plonky2/src/hash/merkle_proofs.rs b/plonky2/src/hash/merkle_proofs.rs index 01a4a395..69d7299f 100644 --- a/plonky2/src/hash/merkle_proofs.rs +++ b/plonky2/src/hash/merkle_proofs.rs @@ -2,9 +2,9 @@ use alloc::vec; use alloc::vec::Vec; use anyhow::{ensure, Result}; -use plonky2_field::extension::Extendable; use serde::{Deserialize, Serialize}; +use crate::field::extension::Extendable; use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::hashing::SPONGE_WIDTH; use crate::hash::merkle_tree::MerkleCap; @@ -150,10 +150,11 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::Field; - use rand::{thread_rng, Rng}; + use rand::rngs::OsRng; + use rand::Rng; use super::*; + use crate::field::types::Field; use crate::hash::merkle_tree::MerkleTree; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; @@ -179,7 +180,7 @@ mod tests { let cap_height = 1; let leaves = random_data::(n, 7); let tree = MerkleTree::>::Hasher>::new(leaves, cap_height); - let i: usize = thread_rng().gen_range(0..n); + let i: usize = OsRng.gen_range(0..n); let proof = tree.prove(i); let proof_t = MerkleProofTarget { diff --git a/plonky2/src/hash/merkle_tree.rs b/plonky2/src/hash/merkle_tree.rs index 6958bb9c..92f1dca0 100644 --- a/plonky2/src/hash/merkle_tree.rs +++ b/plonky2/src/hash/merkle_tree.rs @@ -3,12 +3,12 @@ use core::mem::MaybeUninit; use core::slice; use maybe_rayon::*; -use plonky2_util::log2_strict; use serde::{Deserialize, Serialize}; use crate::hash::hash_types::RichField; use crate::hash::merkle_proofs::MerkleProof; use crate::plonk::config::{GenericHashOut, Hasher}; +use crate::util::log2_strict; /// The Merkle cap of height `h` of a Merkle tree is the `h`-th layer (from the root) of the tree. /// It can be used in place of the root to verify Merkle paths, which are `h` elements shorter. @@ -208,9 +208,9 @@ impl> MerkleTree { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::extension::Extendable; use super::*; + use crate::field::extension::Extendable; use crate::hash::merkle_proofs::verify_merkle_proof_to_cap; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/hash/path_compression.rs b/plonky2/src/hash/path_compression.rs index 7efe3a67..d4f7d5eb 100644 --- a/plonky2/src/hash/path_compression.rs +++ b/plonky2/src/hash/path_compression.rs @@ -114,10 +114,11 @@ pub(crate) fn decompress_merkle_proofs>( #[cfg(test)] mod tests { - use plonky2_field::types::Sample; - use rand::{thread_rng, Rng}; + use rand::rngs::OsRng; + use rand::Rng; use super::*; + use crate::field::types::Sample; use crate::hash::merkle_tree::MerkleTree; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; @@ -131,7 +132,7 @@ mod tests { let vs = (0..1 << h).map(|_| vec![F::rand()]).collect::>(); let mt = MerkleTree::>::Hasher>::new(vs.clone(), cap_height); - let mut rng = thread_rng(); + let mut rng = OsRng; let k = rng.gen_range(1..=1 << h); let indices = (0..k).map(|_| rng.gen_range(0..1 << h)).collect::>(); let proofs = indices.iter().map(|&i| mt.prove(i)).collect::>(); diff --git a/plonky2/src/hash/poseidon.rs b/plonky2/src/hash/poseidon.rs index 6a30c2bd..e7436018 100644 --- a/plonky2/src/hash/poseidon.rs +++ b/plonky2/src/hash/poseidon.rs @@ -4,10 +4,10 @@ use alloc::vec; use alloc::vec::Vec; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::types::{Field, PrimeField64}; use unroll::unroll_for_loops; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::types::{Field, PrimeField64}; use crate::gates::gate::Gate; use crate::gates::poseidon::PoseidonGate; use crate::gates::poseidon_mds::PoseidonMdsGate; @@ -687,8 +687,7 @@ impl AlgebraicHasher for PoseidonHash { #[cfg(test)] pub(crate) mod test_helpers { - use plonky2_field::types::Field; - + use crate::field::types::Field; use crate::hash::hashing::SPONGE_WIDTH; use crate::hash::poseidon::Poseidon; diff --git a/plonky2/src/hash/poseidon_goldilocks.rs b/plonky2/src/hash/poseidon_goldilocks.rs index 001c5900..b6e9bc74 100644 --- a/plonky2/src/hash/poseidon_goldilocks.rs +++ b/plonky2/src/hash/poseidon_goldilocks.rs @@ -4,8 +4,7 @@ //! `poseidon_constants.sage` script in the `mir-protocol/hash-constants` //! repository. -use plonky2_field::goldilocks_field::GoldilocksField; - +use crate::field::goldilocks_field::GoldilocksField; use crate::hash::poseidon::{Poseidon, N_PARTIAL_ROUNDS}; #[rustfmt::skip] @@ -271,9 +270,8 @@ impl Poseidon for GoldilocksField { #[cfg(test)] mod tests { - use plonky2_field::goldilocks_field::GoldilocksField as F; - use plonky2_field::types::{Field, PrimeField64}; - + use crate::field::goldilocks_field::GoldilocksField as F; + use crate::field::types::{Field, PrimeField64}; use crate::hash::poseidon::test_helpers::{check_consistency, check_test_vectors}; #[test] diff --git a/plonky2/src/iop/challenger.rs b/plonky2/src/iop/challenger.rs index 7b666494..49b30559 100644 --- a/plonky2/src/iop/challenger.rs +++ b/plonky2/src/iop/challenger.rs @@ -2,8 +2,7 @@ use alloc::vec; use alloc::vec::Vec; use core::marker::PhantomData; -use plonky2_field::extension::{Extendable, FieldExtension}; - +use crate::field::extension::{Extendable, FieldExtension}; use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::hashing::{PlonkyPermutation, SPONGE_RATE, SPONGE_WIDTH}; use crate::hash::merkle_tree::MerkleCap; @@ -301,8 +300,7 @@ impl, H: AlgebraicHasher, const D: usize> #[cfg(test)] mod tests { - use plonky2_field::types::Sample; - + use crate::field::types::Sample; use crate::iop::challenger::{Challenger, RecursiveChallenger}; use crate::iop::generator::generate_partial_witness; use crate::iop::target::Target; diff --git a/plonky2/src/iop/ext_target.rs b/plonky2/src/iop/ext_target.rs index 73effa8e..c9929b21 100644 --- a/plonky2/src/iop/ext_target.rs +++ b/plonky2/src/iop/ext_target.rs @@ -1,10 +1,9 @@ use alloc::vec::Vec; use core::ops::Range; -use plonky2_field::extension::algebra::ExtensionAlgebra; -use plonky2_field::extension::{Extendable, FieldExtension, OEF}; -use plonky2_field::types::Field; - +use crate::field::extension::algebra::ExtensionAlgebra; +use crate::field::extension::{Extendable, FieldExtension, OEF}; +use crate::field::types::Field; use crate::hash::hash_types::RichField; use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; diff --git a/plonky2/src/iop/generator.rs b/plonky2/src/iop/generator.rs index 522cee18..86a4d923 100644 --- a/plonky2/src/iop/generator.rs +++ b/plonky2/src/iop/generator.rs @@ -3,9 +3,8 @@ use alloc::vec::Vec; use core::fmt::Debug; use core::marker::PhantomData; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::types::Field; - +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::types::Field; use crate::hash::hash_types::{HashOut, HashOutTarget, RichField}; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::{BoolTarget, Target}; diff --git a/plonky2/src/iop/witness.rs b/plonky2/src/iop/witness.rs index a7cdf1f4..218008ac 100644 --- a/plonky2/src/iop/witness.rs +++ b/plonky2/src/iop/witness.rs @@ -3,9 +3,9 @@ use alloc::vec::Vec; use hashbrown::HashMap; use itertools::Itertools; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::types::Field; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::types::Field; use crate::fri::structure::{FriOpenings, FriOpeningsTarget}; use crate::fri::witness_util::set_fri_proof_target; use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget, RichField}; diff --git a/plonky2/src/lib.rs b/plonky2/src/lib.rs index 49bc8248..c357c27a 100644 --- a/plonky2/src/lib.rs +++ b/plonky2/src/lib.rs @@ -4,6 +4,7 @@ extern crate alloc; +#[doc(inline)] pub use plonky2_field as field; pub mod fri; diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index deb46442..f84378b8 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -9,13 +9,12 @@ use std::time::Instant; use hashbrown::{HashMap, HashSet}; use itertools::Itertools; use log::{debug, info, Level}; -use plonky2_field::cosets::get_unique_coset_shifts; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::fft::fft_root_table; -use plonky2_field::polynomial::PolynomialValues; -use plonky2_field::types::Field; -use plonky2_util::{log2_ceil, log2_strict}; +use crate::field::cosets::get_unique_coset_shifts; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::fft::fft_root_table; +use crate::field::polynomial::PolynomialValues; +use crate::field::types::Field; use crate::fri::oracle::PolynomialBatch; use crate::fri::{FriConfig, FriParams}; use crate::gadgets::arithmetic::BaseArithmeticOperation; @@ -49,7 +48,7 @@ use crate::timed; use crate::util::context_tree::ContextTree; use crate::util::partial_products::num_partial_products; use crate::util::timing::TimingTree; -use crate::util::{transpose, transpose_poly_values}; +use crate::util::{log2_ceil, log2_strict, transpose, transpose_poly_values}; pub struct CircuitBuilder, const D: usize> { pub config: CircuitConfig, diff --git a/plonky2/src/plonk/circuit_data.rs b/plonky2/src/plonk/circuit_data.rs index 791160ad..df455a3a 100644 --- a/plonky2/src/plonk/circuit_data.rs +++ b/plonky2/src/plonk/circuit_data.rs @@ -5,9 +5,9 @@ use alloc::vec::Vec; use core::ops::{Range, RangeFrom}; use anyhow::Result; -use plonky2_field::extension::Extendable; -use plonky2_field::fft::FftRootTable; +use crate::field::extension::Extendable; +use crate::field::fft::FftRootTable; use crate::field::types::Field; use crate::fri::oracle::PolynomialBatch; use crate::fri::reduction_strategies::FriReductionStrategy; diff --git a/plonky2/src/plonk/config.rs b/plonky2/src/plonk/config.rs index ac7399f7..36d29cff 100644 --- a/plonky2/src/plonk/config.rs +++ b/plonky2/src/plonk/config.rs @@ -2,12 +2,12 @@ use alloc::vec; use alloc::vec::Vec; use core::fmt::Debug; -use plonky2_field::extension::quadratic::QuadraticExtension; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::goldilocks_field::GoldilocksField; use serde::de::DeserializeOwned; use serde::Serialize; +use crate::field::extension::quadratic::QuadraticExtension; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::goldilocks_field::GoldilocksField; use crate::hash::hash_types::{HashOut, RichField}; use crate::hash::hashing::{PlonkyPermutation, SPONGE_WIDTH}; use crate::hash::keccak::KeccakHash; diff --git a/plonky2/src/plonk/get_challenges.rs b/plonky2/src/plonk/get_challenges.rs index 4c4785f8..240d9047 100644 --- a/plonky2/src/plonk/get_challenges.rs +++ b/plonky2/src/plonk/get_challenges.rs @@ -2,9 +2,9 @@ use alloc::vec; use alloc::vec::Vec; use hashbrown::HashSet; -use plonky2_field::extension::Extendable; -use plonky2_field::polynomial::PolynomialCoeffs; +use crate::field::extension::Extendable; +use crate::field::polynomial::PolynomialCoeffs; use crate::fri::proof::{CompressedFriProof, FriChallenges, FriProof, FriProofTarget}; use crate::fri::verifier::{compute_evaluation, fri_combine_initial, PrecomputedReducedOpenings}; use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; diff --git a/plonky2/src/plonk/permutation_argument.rs b/plonky2/src/plonk/permutation_argument.rs index 2400516a..7052cabe 100644 --- a/plonky2/src/plonk/permutation_argument.rs +++ b/plonky2/src/plonk/permutation_argument.rs @@ -2,9 +2,9 @@ use alloc::vec::Vec; use hashbrown::HashMap; use maybe_rayon::*; -use plonky2_field::polynomial::PolynomialValues; -use plonky2_field::types::Field; +use crate::field::polynomial::PolynomialValues; +use crate::field::types::Field; use crate::iop::target::Target; use crate::iop::wire::Wire; diff --git a/plonky2/src/plonk/plonk_common.rs b/plonky2/src/plonk/plonk_common.rs index fdd53035..53c75af1 100644 --- a/plonky2/src/plonk/plonk_common.rs +++ b/plonky2/src/plonk/plonk_common.rs @@ -1,10 +1,9 @@ use alloc::vec; use alloc::vec::Vec; -use plonky2_field::extension::Extendable; -use plonky2_field::packed::PackedField; -use plonky2_field::types::Field; - +use crate::field::extension::Extendable; +use crate::field::packed::PackedField; +use crate::field::types::Field; use crate::fri::oracle::SALT_SIZE; use crate::gates::arithmetic_base::ArithmeticGate; use crate::hash::hash_types::RichField; diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index 065e2328..a5a66e26 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -3,9 +3,9 @@ use alloc::vec::Vec; use anyhow::ensure; use maybe_rayon::*; -use plonky2_field::extension::Extendable; use serde::{Deserialize, Serialize}; +use crate::field::extension::Extendable; use crate::fri::oracle::PolynomialBatch; use crate::fri::proof::{ CompressedFriProof, FriChallenges, FriChallengesTarget, FriProof, FriProofTarget, @@ -383,8 +383,8 @@ impl OpeningSetTarget { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::Sample; + use crate::field::types::Sample; use crate::fri::reduction_strategies::FriReductionStrategy; use crate::gates::noop::NoopGate; use crate::iop::witness::PartialWitness; diff --git a/plonky2/src/plonk/prover.rs b/plonky2/src/plonk/prover.rs index 35490d7f..d45fa573 100644 --- a/plonky2/src/plonk/prover.rs +++ b/plonky2/src/plonk/prover.rs @@ -4,12 +4,11 @@ use core::mem::swap; use anyhow::{ensure, Result}; use maybe_rayon::*; -use plonky2_field::extension::Extendable; -use plonky2_field::polynomial::{PolynomialCoeffs, PolynomialValues}; -use plonky2_field::zero_poly_coset::ZeroPolyOnCoset; -use plonky2_util::{ceil_div_usize, log2_ceil}; +use crate::field::extension::Extendable; +use crate::field::polynomial::{PolynomialCoeffs, PolynomialValues}; use crate::field::types::Field; +use crate::field::zero_poly_coset::ZeroPolyOnCoset; use crate::fri::oracle::PolynomialBatch; use crate::hash::hash_types::RichField; use crate::iop::challenger::Challenger; @@ -24,7 +23,7 @@ use crate::plonk::vars::EvaluationVarsBaseBatch; use crate::timed; use crate::util::partial_products::{partial_products_and_z_gx, quotient_chunk_products}; use crate::util::timing::TimingTree; -use crate::util::transpose; +use crate::util::{ceil_div_usize, log2_ceil, transpose}; pub fn prove, C: GenericConfig, const D: usize>( prover_data: &ProverOnlyCircuitData, diff --git a/plonky2/src/plonk/validate_shape.rs b/plonky2/src/plonk/validate_shape.rs index 81f43332..0b4bf4a8 100644 --- a/plonky2/src/plonk/validate_shape.rs +++ b/plonky2/src/plonk/validate_shape.rs @@ -1,6 +1,6 @@ use anyhow::ensure; -use plonky2_field::extension::Extendable; +use crate::field::extension::Extendable; use crate::hash::hash_types::RichField; use crate::plonk::circuit_data::CommonCircuitData; use crate::plonk::config::GenericConfig; diff --git a/plonky2/src/plonk/vanishing_poly.rs b/plonky2/src/plonk/vanishing_poly.rs index f27eba48..30473650 100644 --- a/plonky2/src/plonk/vanishing_poly.rs +++ b/plonky2/src/plonk/vanishing_poly.rs @@ -1,11 +1,10 @@ use alloc::vec::Vec; use alloc::{format, vec}; -use plonky2_field::batch_util::batch_add_inplace; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::types::Field; -use plonky2_field::zero_poly_coset::ZeroPolyOnCoset; - +use crate::field::batch_util::batch_add_inplace; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::types::Field; +use crate::field::zero_poly_coset::ZeroPolyOnCoset; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::Target; diff --git a/plonky2/src/plonk/vars.rs b/plonky2/src/plonk/vars.rs index 722ebdf1..758018f5 100644 --- a/plonky2/src/plonk/vars.rs +++ b/plonky2/src/plonk/vars.rs @@ -1,10 +1,9 @@ use core::ops::Range; -use plonky2_field::extension::algebra::ExtensionAlgebra; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::packed::PackedField; -use plonky2_field::types::Field; - +use crate::field::extension::algebra::ExtensionAlgebra; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::packed::PackedField; +use crate::field::types::Field; use crate::hash::hash_types::{HashOut, HashOutTarget, RichField}; use crate::iop::ext_target::{ExtensionAlgebraTarget, ExtensionTarget}; use crate::util::strided_view::PackedStridedView; diff --git a/plonky2/src/plonk/verifier.rs b/plonky2/src/plonk/verifier.rs index ba477264..893720c6 100644 --- a/plonky2/src/plonk/verifier.rs +++ b/plonky2/src/plonk/verifier.rs @@ -1,7 +1,7 @@ use anyhow::{ensure, Result}; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; +use crate::field::extension::Extendable; +use crate::field::types::Field; use crate::fri::verifier::verify_fri_proof; use crate::hash::hash_types::RichField; use crate::plonk::circuit_data::{CommonCircuitData, VerifierOnlyCircuitData}; diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index fdbff5a0..6cbce94a 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -3,9 +3,8 @@ use alloc::vec::Vec; use anyhow::{ensure, Result}; use itertools::Itertools; -use plonky2_field::extension::Extendable; -use plonky2_util::ceil_div_usize; +use crate::field::extension::Extendable; use crate::fri::proof::{ FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, }; @@ -24,6 +23,7 @@ use crate::plonk::config::{AlgebraicHasher, GenericConfig}; use crate::plonk::proof::{ OpeningSetTarget, ProofTarget, ProofWithPublicInputs, ProofWithPublicInputsTarget, }; +use crate::util::ceil_div_usize; use crate::with_context; /// Generate a proof having a given `CommonCircuitData`. @@ -369,9 +369,9 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::Sample; use super::*; + use crate::field::types::Sample; use crate::gates::noop::NoopGate; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_data::CircuitConfig; diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index ab569d27..efc336bc 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -4,8 +4,8 @@ use alloc::vec; use anyhow::{ensure, Result}; use itertools::Itertools; -use plonky2_field::extension::Extendable; +use crate::field::extension::Extendable; use crate::gates::noop::NoopGate; use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_tree::MerkleCap; @@ -254,12 +254,10 @@ where #[cfg(test)] mod tests { - use anyhow::Result; - use plonky2_field::extension::Extendable; - use plonky2_field::types::PrimeField64; - use crate::field::types::Field; + use crate::field::extension::Extendable; + use crate::field::types::{Field, PrimeField64}; use crate::gates::noop::NoopGate; use crate::hash::hash_types::RichField; use crate::hash::hashing::hash_n_to_hash_no_pad; diff --git a/plonky2/src/recursion/recursive_verifier.rs b/plonky2/src/recursion/recursive_verifier.rs index a42494f4..0854dad8 100644 --- a/plonky2/src/recursion/recursive_verifier.rs +++ b/plonky2/src/recursion/recursive_verifier.rs @@ -1,5 +1,4 @@ -use plonky2_field::extension::Extendable; - +use crate::field::extension::Extendable; use crate::hash::hash_types::{HashOutTarget, RichField}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{CommonCircuitData, VerifierCircuitTarget}; diff --git a/plonky2/src/util/mod.rs b/plonky2/src/util/mod.rs index 2c61b399..19f3cb74 100644 --- a/plonky2/src/util/mod.rs +++ b/plonky2/src/util/mod.rs @@ -1,8 +1,11 @@ use alloc::vec; use alloc::vec::Vec; -use plonky2_field::polynomial::PolynomialValues; -use plonky2_field::types::Field; +#[doc(inline)] +pub use plonky2_util::*; + +use crate::field::polynomial::PolynomialValues; +use crate::field::types::Field; pub(crate) mod context_tree; pub(crate) mod partial_products; @@ -61,9 +64,7 @@ pub(crate) fn reverse_bits(n: usize, num_bits: usize) -> usize { #[cfg(test)] mod tests { - use plonky2_util::{reverse_index_bits, reverse_index_bits_in_place}; - - use crate::util::reverse_bits; + use super::*; #[test] fn test_reverse_bits() { diff --git a/plonky2/src/util/partial_products.rs b/plonky2/src/util/partial_products.rs index c1b2e979..ff2261b8 100644 --- a/plonky2/src/util/partial_products.rs +++ b/plonky2/src/util/partial_products.rs @@ -2,13 +2,13 @@ use alloc::vec::Vec; use core::iter; use itertools::Itertools; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; -use plonky2_util::ceil_div_usize; +use crate::field::extension::Extendable; +use crate::field::types::Field; use crate::hash::hash_types::RichField; use crate::iop::ext_target::ExtensionTarget; use crate::plonk::circuit_builder::CircuitBuilder; +use crate::util::ceil_div_usize; pub(crate) fn quotient_chunk_products( quotient_values: &[F], @@ -108,9 +108,8 @@ pub(crate) fn check_partial_products_circuit, const #[cfg(test)] mod tests { - use plonky2_field::goldilocks_field::GoldilocksField; - use super::*; + use crate::field::goldilocks_field::GoldilocksField; #[test] fn test_partial_products() { diff --git a/plonky2/src/util/reducing.rs b/plonky2/src/util/reducing.rs index b1a179b7..0bed0b84 100644 --- a/plonky2/src/util/reducing.rs +++ b/plonky2/src/util/reducing.rs @@ -2,11 +2,10 @@ use alloc::vec; use alloc::vec::Vec; use core::borrow::Borrow; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::packed::PackedField; -use plonky2_field::polynomial::PolynomialCoeffs; -use plonky2_field::types::Field; - +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::packed::PackedField; +use crate::field::polynomial::PolynomialCoeffs; +use crate::field::types::Field; use crate::gates::arithmetic_extension::ArithmeticExtensionGate; use crate::gates::reducing::ReducingGate; use crate::gates::reducing_extension::ReducingExtensionGate; @@ -276,9 +275,9 @@ impl ReducingFactorTarget { #[cfg(test)] mod tests { use anyhow::Result; - use plonky2_field::types::Sample; use super::*; + use crate::field::types::Sample; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; diff --git a/plonky2/src/util/serialization.rs b/plonky2/src/util/serialization.rs index b5c7ef5c..1cdfc39c 100644 --- a/plonky2/src/util/serialization.rs +++ b/plonky2/src/util/serialization.rs @@ -5,10 +5,10 @@ use core::convert::Infallible; use std::io::{self, Cursor, Read as _, Write as _}; use hashbrown::HashMap; -use plonky2_field::extension::{Extendable, FieldExtension}; -use plonky2_field::polynomial::PolynomialCoeffs; -use plonky2_field::types::{Field64, PrimeField64}; +use crate::field::extension::{Extendable, FieldExtension}; +use crate::field::polynomial::PolynomialCoeffs; +use crate::field::types::{Field64, PrimeField64}; use crate::fri::proof::{ CompressedFriProof, CompressedFriQueryRounds, FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep, diff --git a/plonky2/src/util/strided_view.rs b/plonky2/src/util/strided_view.rs index 43fd4894..c165da2c 100644 --- a/plonky2/src/util/strided_view.rs +++ b/plonky2/src/util/strided_view.rs @@ -2,7 +2,7 @@ use core::marker::PhantomData; use core::mem::size_of; use core::ops::{Index, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}; -use plonky2_field::packed::PackedField; +use crate::field::packed::PackedField; /// Imagine a slice, but with a stride (a la a NumPy array). /// diff --git a/u32/Cargo.toml b/u32/Cargo.toml index f0a1d349..af7676ed 100644 --- a/u32/Cargo.toml +++ b/u32/Cargo.toml @@ -3,13 +3,13 @@ name = "plonky2_u32" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -anyhow = "1.0.40" -rand = "0.8.4" -num = { version = "0.4", features = [ "rand" ] } -itertools = "0.10.0" -plonky2 = { path = "../plonky2" } -plonky2_util = { path = "../util" } -plonky2_field = { path = "../field" } +anyhow = { version = "1.0.40", default-features = false } +itertools = { version = "0.10.0", default-features = false } +num = { version = "0.4", default-features = false } +plonky2 = { path = "../plonky2", default-features = false } + +[dev-dependencies] +plonky2 = { path = "../plonky2", default-features = false, features = ["gate_testing"] } +rand = { version = "0.8.4", default-features = false, features = ["getrandom"] } + diff --git a/u32/src/gadgets/arithmetic_u32.rs b/u32/src/gadgets/arithmetic_u32.rs index 7475681c..65f5ac07 100644 --- a/u32/src/gadgets/arithmetic_u32.rs +++ b/u32/src/gadgets/arithmetic_u32.rs @@ -1,11 +1,13 @@ -use std::marker::PhantomData; +use alloc::vec; +use alloc::vec::Vec; +use core::marker::PhantomData; +use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::Target; use plonky2::iop::witness::{PartitionWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::extension::Extendable; use crate::gates::add_many_u32::U32AddManyGate; use crate::gates::arithmetic_u32::U32ArithmeticGate; @@ -258,12 +260,12 @@ impl, const D: usize> SimpleGenerator mod tests { use anyhow::Result; use plonky2::iop::witness::PartialWitness; - use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use rand::{thread_rng, Rng}; + use rand::rngs::OsRng; + use rand::Rng; - use crate::gadgets::arithmetic_u32::CircuitBuilderU32; + use super::*; #[test] pub fn test_add_many_u32s() -> Result<()> { @@ -278,7 +280,7 @@ mod tests { let pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); - let mut rng = thread_rng(); + let mut rng = OsRng; let mut to_add = Vec::new(); let mut sum = 0u64; for _ in 0..NUM_ADDENDS { diff --git a/u32/src/gadgets/multiple_comparison.rs b/u32/src/gadgets/multiple_comparison.rs index 09ad2eb5..8d82c296 100644 --- a/u32/src/gadgets/multiple_comparison.rs +++ b/u32/src/gadgets/multiple_comparison.rs @@ -1,10 +1,13 @@ +use alloc::vec; +use alloc::vec::Vec; + +use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2::iop::target::{BoolTarget, Target}; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::extension::Extendable; -use plonky2_util::ceil_div_usize; +use plonky2::util::ceil_div_usize; -use super::arithmetic_u32::U32Target; +use crate::gadgets::arithmetic_u32::U32Target; use crate::gates::comparison::ComparisonGate; /// Returns true if a is less than or equal to b, considered as base-`2^num_bits` limbs of a large value. @@ -78,14 +81,14 @@ pub fn list_le_u32_circuit, const D: usize>( mod tests { use anyhow::Result; use num::BigUint; + use plonky2::field::types::Field; use plonky2::iop::witness::PartialWitness; - use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2_field::types::Field; + use rand::rngs::OsRng; use rand::Rng; - use crate::gadgets::multiple_comparison::list_le_circuit; + use super::*; fn test_list_le(size: usize, num_bits: usize) -> Result<()> { const D: usize = 2; @@ -95,7 +98,7 @@ mod tests { let pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let lst1: Vec = (0..size) .map(|_| rng.gen_range(0..(1 << num_bits))) diff --git a/u32/src/gadgets/range_check.rs b/u32/src/gadgets/range_check.rs index fb6a9b1e..9e8cf2ad 100644 --- a/u32/src/gadgets/range_check.rs +++ b/u32/src/gadgets/range_check.rs @@ -1,7 +1,10 @@ +use alloc::vec; +use alloc::vec::Vec; + +use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2::iop::target::Target; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_field::extension::Extendable; use crate::gadgets::arithmetic_u32::U32Target; use crate::gates::range_check_u32::U32RangeCheckGate; diff --git a/u32/src/gates/add_many_u32.rs b/u32/src/gates/add_many_u32.rs index 8928b74d..a2bd2dac 100644 --- a/u32/src/gates/add_many_u32.rs +++ b/u32/src/gates/add_many_u32.rs @@ -1,6 +1,12 @@ -use std::marker::PhantomData; +use alloc::boxed::Box; +use alloc::format; +use alloc::string::String; +use alloc::vec::Vec; +use core::marker::PhantomData; use itertools::unfold; +use plonky2::field::extension::Extendable; +use plonky2::field::types::Field; use plonky2::gates::gate::Gate; use plonky2::gates::util::StridedConstraintConsumer; use plonky2::hash::hash_types::RichField; @@ -12,9 +18,7 @@ use plonky2::iop::witness::{PartitionWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; -use plonky2_util::ceil_div_usize; +use plonky2::util::ceil_div_usize; const LOG2_MAX_NUM_ADDENDS: usize = 4; const MAX_NUM_ADDENDS: usize = 16; @@ -340,21 +344,17 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use core::marker::PhantomData; - use anyhow::Result; - use itertools::unfold; - use plonky2::gates::gate::Gate; + use plonky2::field::extension::quartic::QuarticExtension; + use plonky2::field::goldilocks_field::GoldilocksField; + use plonky2::field::types::Sample; use plonky2::gates::gate_testing::{test_eval_fns, test_low_degree}; use plonky2::hash::hash_types::HashOut; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2::plonk::vars::EvaluationVars; - use plonky2_field::extension::quartic::QuarticExtension; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, Sample}; + use rand::rngs::OsRng; use rand::Rng; - use crate::gates::add_many_u32::U32AddManyGate; + use super::*; #[test] fn low_degree() { @@ -428,7 +428,7 @@ mod tests { v0.iter().chain(v1.iter()).map(|&x| x.into()).collect() } - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let addends: Vec> = (0..NUM_U32_ADD_MANY_OPS) .map(|_| (0..NUM_ADDENDS).map(|_| rng.gen::() as u64).collect()) .collect(); diff --git a/u32/src/gates/arithmetic_u32.rs b/u32/src/gates/arithmetic_u32.rs index 8946f9de..3f249d29 100644 --- a/u32/src/gates/arithmetic_u32.rs +++ b/u32/src/gates/arithmetic_u32.rs @@ -1,6 +1,13 @@ -use std::marker::PhantomData; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; +use core::marker::PhantomData; use itertools::unfold; +use plonky2::field::extension::Extendable; +use plonky2::field::packed::PackedField; +use plonky2::field::types::Field; use plonky2::gates::gate::Gate; use plonky2::gates::packed_util::PackedEvaluableBase; use plonky2::gates::util::StridedConstraintConsumer; @@ -16,9 +23,6 @@ use plonky2::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, }; -use plonky2_field::extension::Extendable; -use plonky2_field::packed::PackedField; -use plonky2_field::types::Field; /// A gate to perform a basic mul-add on 32-bit values (we assume they are range-checked beforehand). #[derive(Copy, Clone, Debug)] @@ -411,20 +415,16 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use core::marker::PhantomData; - use anyhow::Result; - use plonky2::gates::gate::Gate; + use plonky2::field::goldilocks_field::GoldilocksField; + use plonky2::field::types::Sample; use plonky2::gates::gate_testing::{test_eval_fns, test_low_degree}; - use plonky2::hash::hash_types::{HashOut, RichField}; + use plonky2::hash::hash_types::HashOut; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2::plonk::vars::EvaluationVars; - use plonky2_field::extension::Extendable; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, Sample}; + use rand::rngs::OsRng; use rand::Rng; - use crate::gates::arithmetic_u32::U32ArithmeticGate; + use super::*; #[test] fn low_degree() { @@ -506,7 +506,7 @@ mod tests { type FF = >::FE; const NUM_U32_ARITHMETIC_OPS: usize = 3; - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let multiplicands_0: Vec<_> = (0..NUM_U32_ARITHMETIC_OPS) .map(|_| rng.gen::() as u64) .collect(); diff --git a/u32/src/gates/comparison.rs b/u32/src/gates/comparison.rs index b7dc74a8..6cb67106 100644 --- a/u32/src/gates/comparison.rs +++ b/u32/src/gates/comparison.rs @@ -1,5 +1,12 @@ -use std::marker::PhantomData; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; +use core::marker::PhantomData; +use plonky2::field::extension::Extendable; +use plonky2::field::packed::PackedField; +use plonky2::field::types::{Field, Field64}; use plonky2::gates::gate::Gate; use plonky2::gates::packed_util::PackedEvaluableBase; use plonky2::gates::util::StridedConstraintConsumer; @@ -15,10 +22,7 @@ use plonky2::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, }; -use plonky2_field::extension::Extendable; -use plonky2_field::packed::PackedField; -use plonky2_field::types::{Field, Field64}; -use plonky2_util::{bits_u64, ceil_div_usize}; +use plonky2::util::{bits_u64, ceil_div_usize}; /// A gate for checking that one value is less than or equal to another. #[derive(Clone, Debug)] @@ -512,19 +516,16 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use core::marker::PhantomData; - use anyhow::Result; - use plonky2::gates::gate::Gate; + use plonky2::field::goldilocks_field::GoldilocksField; + use plonky2::field::types::{PrimeField64, Sample}; use plonky2::gates::gate_testing::{test_eval_fns, test_low_degree}; use plonky2::hash::hash_types::HashOut; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2::plonk::vars::EvaluationVars; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, PrimeField64, Sample}; + use rand::rngs::OsRng; use rand::Rng; - use crate::gates::comparison::ComparisonGate; + use super::*; #[test] fn wire_indices() { @@ -656,7 +657,7 @@ mod tests { v.iter().map(|&x| x.into()).collect() }; - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let max: u64 = 1 << (num_bits - 1); let first_input_u64 = rng.gen_range(0..max); let second_input_u64 = { diff --git a/u32/src/gates/range_check_u32.rs b/u32/src/gates/range_check_u32.rs index ff99e492..6dd20d48 100644 --- a/u32/src/gates/range_check_u32.rs +++ b/u32/src/gates/range_check_u32.rs @@ -1,5 +1,11 @@ -use std::marker::PhantomData; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; +use core::marker::PhantomData; +use plonky2::field::extension::Extendable; +use plonky2::field::types::Field; use plonky2::gates::gate::Gate; use plonky2::gates::util::StridedConstraintConsumer; use plonky2::hash::hash_types::RichField; @@ -10,9 +16,7 @@ use plonky2::iop::witness::{PartitionWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::plonk_common::{reduce_with_powers, reduce_with_powers_ext_circuit}; use plonky2::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; -use plonky2_field::extension::Extendable; -use plonky2_field::types::Field; -use plonky2_util::ceil_div_usize; +use plonky2::util::ceil_div_usize; /// A gate which can decompose a number into base B little-endian limbs. #[derive(Copy, Clone, Debug)] @@ -201,22 +205,18 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use core::marker::PhantomData; - use anyhow::Result; use itertools::unfold; - use plonky2::gates::gate::Gate; + use plonky2::field::extension::quartic::QuarticExtension; + use plonky2::field::goldilocks_field::GoldilocksField; + use plonky2::field::types::{Field, Sample}; use plonky2::gates::gate_testing::{test_eval_fns, test_low_degree}; use plonky2::hash::hash_types::HashOut; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2::plonk::vars::EvaluationVars; - use plonky2_field::extension::quartic::QuarticExtension; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, Sample}; - use plonky2_util::ceil_div_usize; + use rand::rngs::OsRng; use rand::Rng; - use crate::gates::range_check_u32::U32RangeCheckGate; + use super::*; #[test] fn low_degree() { @@ -290,7 +290,7 @@ mod tests { #[test] fn test_gate_constraint_good() { - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let input_limbs: Vec<_> = (0..8).map(|_| rng.gen::() as u64).collect(); test_gate_constraint(input_limbs); @@ -299,7 +299,7 @@ mod tests { #[test] #[should_panic] fn test_gate_constraint_bad() { - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let input_limbs: Vec<_> = (0..8).map(|_| rng.gen()).collect(); test_gate_constraint(input_limbs); diff --git a/u32/src/gates/subtraction_u32.rs b/u32/src/gates/subtraction_u32.rs index 1657aec1..9a3b1db6 100644 --- a/u32/src/gates/subtraction_u32.rs +++ b/u32/src/gates/subtraction_u32.rs @@ -1,5 +1,12 @@ -use std::marker::PhantomData; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; +use core::marker::PhantomData; +use plonky2::field::extension::Extendable; +use plonky2::field::packed::PackedField; +use plonky2::field::types::Field; use plonky2::gates::gate::Gate; use plonky2::gates::packed_util::PackedEvaluableBase; use plonky2::gates::util::StridedConstraintConsumer; @@ -15,9 +22,6 @@ use plonky2::plonk::vars::{ EvaluationTargets, EvaluationVars, EvaluationVarsBase, EvaluationVarsBaseBatch, EvaluationVarsBasePacked, }; -use plonky2_field::extension::Extendable; -use plonky2_field::packed::PackedField; -use plonky2_field::types::Field; /// A gate to perform a subtraction on 32-bit limbs: given `x`, `y`, and `borrow`, it returns /// the result `x - y - borrow` and, if this underflows, a new `borrow`. Inputs are not range-checked. @@ -329,20 +333,17 @@ impl, const D: usize> SimpleGenerator #[cfg(test)] mod tests { - use core::marker::PhantomData; - use anyhow::Result; - use plonky2::gates::gate::Gate; + use plonky2::field::extension::quartic::QuarticExtension; + use plonky2::field::goldilocks_field::GoldilocksField; + use plonky2::field::types::{PrimeField64, Sample}; use plonky2::gates::gate_testing::{test_eval_fns, test_low_degree}; use plonky2::hash::hash_types::HashOut; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2::plonk::vars::EvaluationVars; - use plonky2_field::extension::quartic::QuarticExtension; - use plonky2_field::goldilocks_field::GoldilocksField; - use plonky2_field::types::{Field, PrimeField64, Sample}; + use rand::rngs::OsRng; use rand::Rng; - use crate::gates::subtraction_u32::U32SubtractionGate; + use super::*; #[test] fn low_degree() { @@ -414,7 +415,7 @@ mod tests { v0.iter().chain(v1.iter()).map(|&x| x.into()).collect() } - let mut rng = rand::thread_rng(); + let mut rng = OsRng; let inputs_x = (0..NUM_U32_SUBTRACTION_OPS) .map(|_| rng.gen::() as u64) .collect(); diff --git a/u32/src/lib.rs b/u32/src/lib.rs index 0957c7bc..2d8d07f3 100644 --- a/u32/src/lib.rs +++ b/u32/src/lib.rs @@ -1,4 +1,7 @@ #![allow(clippy::needless_range_loop)] +#![no_std] + +extern crate alloc; pub mod gadgets; pub mod gates; diff --git a/u32/src/witness.rs b/u32/src/witness.rs index ddc3432f..004fedc6 100644 --- a/u32/src/witness.rs +++ b/u32/src/witness.rs @@ -1,6 +1,6 @@ +use plonky2::field::types::{Field, PrimeField64}; use plonky2::iop::generator::GeneratedValues; use plonky2::iop::witness::Witness; -use plonky2_field::types::{Field, PrimeField64}; use crate::gadgets::arithmetic_u32::U32Target; From 38e467f1c0d9f8a18244745a5cb9b29b91083003 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 3 Nov 2022 11:41:12 -0700 Subject: [PATCH 07/49] chore: fix serde-cbor and run cargo-sort Signed-off-by: Brandon H. Gomes --- Cargo.toml | 2 +- evm/Cargo.toml | 8 ++++---- insertion/Cargo.toml | 2 +- plonky2/Cargo.toml | 6 +++--- starky/Cargo.toml | 6 +++--- system_zero/Cargo.toml | 6 +++--- waksman/Cargo.toml | 8 ++++---- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a78d0a96..82fb725e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["field", "insertion", "plonky2", "starky", "system_zero", "util", "waksman", "ecdsa", "u32", "evm", "maybe_rayon"] +members = ["ecdsa", "evm", "field", "insertion", "maybe_rayon", "plonky2", "starky", "system_zero", "u32", "util", "waksman"] [profile.release] opt-level = 3 diff --git a/evm/Cargo.toml b/evm/Cargo.toml index 314a2b50..2c9a5ce2 100644 --- a/evm/Cargo.toml +++ b/evm/Cargo.toml @@ -5,22 +5,22 @@ version = "0.1.0" edition = "2021" [dependencies] -plonky2 = { path = "../plonky2", default-features = false, features = ["timing"] } -plonky2_util = { path = "../util" } -eth_trie_utils = "0.4.0" anyhow = "1.0.40" env_logger = "0.9.0" +eth_trie_utils = "0.4.0" ethereum-types = "0.14.0" hex = { version = "0.4.3", optional = true } hex-literal = "0.3.4" itertools = "0.10.3" keccak-hash = "0.10.0" log = "0.4.14" -num = "0.4.0" maybe_rayon = { path = "../maybe_rayon" } +num = "0.4.0" once_cell = "1.13.0" pest = "2.1.3" pest_derive = "2.1.0" +plonky2 = { path = "../plonky2", default-features = false, features = ["timing"] } +plonky2_util = { path = "../util" } rand = "0.8.5" rand_chacha = "0.3.1" ripemd = "0.1.3" diff --git a/insertion/Cargo.toml b/insertion/Cargo.toml index 481c2d5d..afaefd4f 100644 --- a/insertion/Cargo.toml +++ b/insertion/Cargo.toml @@ -5,5 +5,5 @@ version = "0.1.0" edition = "2021" [dependencies] -plonky2 = { path = "../plonky2" } anyhow = "1.0.40" +plonky2 = { path = "../plonky2" } diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index 82b82091..25fe16c7 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -31,18 +31,18 @@ plonky2_util = { path = "../util", default-features = false } rand = { version = "0.8.4", default-features = false } rand_chacha = { version = "0.3.1", optional = true, default-features = false } serde = { version = "1.0", default-features = false, features = ["derive"] } -serde_cbor = { version = "0.11.1", default-features = false } static_assertions = { version = "1.1.0", default-features = false } unroll = { version = "0.1.5", default-features = false } [dev-dependencies] -criterion = { version = "0.3.5", default-features = false } +criterion = { version = "0.4.0", default-features = false } env_logger = { version = "0.9.0", default-features = false } -num_cpus = { version = "1.13.1", default-features = false } +num_cpus = { version = "1.14.0", default-features = false } plonky2 = { path = "." } rand = { version = "0.8.4", default-features = false, features = ["getrandom"] } rand_chacha = { version = "0.3.1", default-features = false } rayon = { version = "1.5.1", default-features = false } +serde_cbor = { version = "0.11.2" } structopt = { version = "0.3.26", default-features = false } tynm = { version = "0.1.6", default-features = false } diff --git a/starky/Cargo.toml b/starky/Cargo.toml index fd39d098..a33d03cf 100644 --- a/starky/Cargo.toml +++ b/starky/Cargo.toml @@ -9,10 +9,10 @@ default = ["parallel"] parallel = ["plonky2/parallel", "maybe_rayon/parallel"] [dependencies] -plonky2 = { path = "../plonky2", default-features = false, features = ["timing"] } -plonky2_util = { path = "../util" } -maybe_rayon = { path = "../maybe_rayon"} anyhow = "1.0.40" env_logger = "0.9.0" itertools = "0.10.0" log = "0.4.14" +maybe_rayon = { path = "../maybe_rayon" } +plonky2 = { path = "../plonky2", default-features = false, features = ["timing"] } +plonky2_util = { path = "../util" } diff --git a/system_zero/Cargo.toml b/system_zero/Cargo.toml index f1cb5729..00765dcc 100644 --- a/system_zero/Cargo.toml +++ b/system_zero/Cargo.toml @@ -5,15 +5,15 @@ version = "0.1.0" edition = "2021" [dependencies] -plonky2 = { path = "../plonky2" } -plonky2_util = { path = "../util" } -starky = { path = "../starky" } anyhow = "1.0.40" env_logger = "0.9.0" itertools = "0.10.0" log = "0.4.14" +plonky2 = { path = "../plonky2" } +plonky2_util = { path = "../util" } rand = "0.8.4" rand_chacha = "0.3.1" +starky = { path = "../starky" } [dev-dependencies] criterion = "0.3.5" diff --git a/waksman/Cargo.toml b/waksman/Cargo.toml index 5aa25dc9..7be3f414 100644 --- a/waksman/Cargo.toml +++ b/waksman/Cargo.toml @@ -5,11 +5,11 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow = "1.0.40" +array_tool = "1.0.3" +bimap = "0.6.1" +itertools = "0.10.0" "plonky2" = { path = "../plonky2" } "plonky2_field" = { path = "../field" } "plonky2_util" = { path = "../util" } -anyhow = "1.0.40" -bimap = "0.6.1" -itertools = "0.10.0" rand = "0.8.4" -array_tool = "1.0.3" From fc3f63398dd2dd5d9bd6d1d04f7b83d073386fec Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 3 Nov 2022 12:17:03 -0700 Subject: [PATCH 08/49] wip: start moving starky to no-std Signed-off-by: Brandon H. Gomes --- ecdsa/Cargo.toml | 3 +++ ecdsa/src/curve/curve_msm.rs | 2 +- field/src/lib.rs | 1 - insertion/src/insertion_gate.rs | 4 ++-- maybe_rayon/Cargo.toml | 1 - maybe_rayon/src/lib.rs | 11 +++++++---- plonky2/Cargo.toml | 1 - plonky2/benches/hashing.rs | 3 --- plonky2/benches/merkle.rs | 8 +------- plonky2/examples/bench_recursion.rs | 16 ++++------------ starky/src/constraint_consumer.rs | 2 +- starky/src/fibonacci_stark.rs | 2 +- starky/src/prover.rs | 2 +- starky/src/recursive_verifier.rs | 2 +- starky/src/verifier.rs | 2 +- 15 files changed, 23 insertions(+), 37 deletions(-) diff --git a/ecdsa/Cargo.toml b/ecdsa/Cargo.toml index 522856ef..602fbb09 100644 --- a/ecdsa/Cargo.toml +++ b/ecdsa/Cargo.toml @@ -3,6 +3,9 @@ name = "plonky2_ecdsa" version = "0.1.0" edition = "2021" +[features] +parallel = ["maybe_rayon/parallel", "plonky2/parallel"] + [dependencies] anyhow = { version = "1.0.40", default-features = false } itertools = { version = "0.10.0", default-features = false } diff --git a/ecdsa/src/curve/curve_msm.rs b/ecdsa/src/curve/curve_msm.rs index bc04b6cc..21bcc404 100644 --- a/ecdsa/src/curve/curve_msm.rs +++ b/ecdsa/src/curve/curve_msm.rs @@ -1,7 +1,7 @@ use alloc::vec::Vec; use itertools::Itertools; -use maybe_rayon::{MaybeIntoParIter, MaybeParChunks}; +use maybe_rayon::*; use plonky2::field::types::{Field, PrimeField}; use crate::curve::curve_summation::affine_multisummation_best; diff --git a/field/src/lib.rs b/field/src/lib.rs index 33db5c27..dd4fc433 100644 --- a/field/src/lib.rs +++ b/field/src/lib.rs @@ -7,7 +7,6 @@ #![allow(clippy::return_self_not_must_use)] #![feature(generic_const_exprs)] #![feature(specialization)] -#![feature(stdsimd)] #![cfg_attr(not(test), no_std)] extern crate alloc; diff --git a/insertion/src/insertion_gate.rs b/insertion/src/insertion_gate.rs index 5694c2b4..a476002b 100644 --- a/insertion/src/insertion_gate.rs +++ b/insertion/src/insertion_gate.rs @@ -1,5 +1,5 @@ -use std::marker::PhantomData; -use std::ops::Range; +use core::marker::PhantomData; +use core::ops::Range; use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::types::Field; diff --git a/maybe_rayon/Cargo.toml b/maybe_rayon/Cargo.toml index f8cc95fb..b3c1e78a 100644 --- a/maybe_rayon/Cargo.toml +++ b/maybe_rayon/Cargo.toml @@ -3,7 +3,6 @@ name = "maybe_rayon" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] parallel = ["rayon"] diff --git a/maybe_rayon/src/lib.rs b/maybe_rayon/src/lib.rs index d24ba2e5..c4bfb2e9 100644 --- a/maybe_rayon/src/lib.rs +++ b/maybe_rayon/src/lib.rs @@ -1,13 +1,16 @@ #[cfg(not(feature = "parallel"))] -use std::{ +use core::{ iter::{FlatMap, IntoIterator, Iterator}, slice::{Chunks, ChunksExact, ChunksExactMut, ChunksMut}, }; #[cfg(feature = "parallel")] -pub use rayon::prelude::{ - IndexedParallelIterator, ParallelDrainFull, ParallelDrainRange, ParallelExtend, - ParallelIterator, +pub use rayon::{ + self, + prelude::{ + IndexedParallelIterator, ParallelDrainFull, ParallelDrainRange, ParallelExtend, + ParallelIterator, + }, }; #[cfg(feature = "parallel")] use rayon::{ diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index 25fe16c7..88217d2d 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -41,7 +41,6 @@ num_cpus = { version = "1.14.0", default-features = false } plonky2 = { path = "." } rand = { version = "0.8.4", default-features = false, features = ["getrandom"] } rand_chacha = { version = "0.3.1", default-features = false } -rayon = { version = "1.5.1", default-features = false } serde_cbor = { version = "0.11.2" } structopt = { version = "0.3.26", default-features = false } tynm = { version = "0.1.6", default-features = false } diff --git a/plonky2/benches/hashing.rs b/plonky2/benches/hashing.rs index fd2e0991..485a6361 100644 --- a/plonky2/benches/hashing.rs +++ b/plonky2/benches/hashing.rs @@ -1,6 +1,3 @@ -#![allow(incomplete_features)] -#![feature(generic_const_exprs)] - mod allocator; use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; diff --git a/plonky2/benches/merkle.rs b/plonky2/benches/merkle.rs index 27f23966..f9bae127 100644 --- a/plonky2/benches/merkle.rs +++ b/plonky2/benches/merkle.rs @@ -1,6 +1,3 @@ -#![allow(incomplete_features)] -#![feature(generic_const_exprs)] - mod allocator; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; @@ -14,10 +11,7 @@ use tynm::type_name; const ELEMS_PER_LEAF: usize = 135; -pub(crate) fn bench_merkle_tree>(c: &mut Criterion) -where - [(); H::HASH_SIZE]:, -{ +pub(crate) fn bench_merkle_tree>(c: &mut Criterion) { let mut group = c.benchmark_group(&format!( "merkle-tree<{}, {}>", type_name::(), diff --git a/plonky2/examples/bench_recursion.rs b/plonky2/examples/bench_recursion.rs index dc88f764..27101d1a 100644 --- a/plonky2/examples/bench_recursion.rs +++ b/plonky2/examples/bench_recursion.rs @@ -2,8 +2,6 @@ // custom CLI argument parsing (even with harness disabled). We could also have // put it in `src/bin/`, but then we wouldn't have access to // `[dev-dependencies]`. -#![allow(incomplete_features)] -#![feature(generic_const_exprs)] use core::num::ParseIntError; use core::ops::RangeInclusive; @@ -11,6 +9,7 @@ use core::str::FromStr; use anyhow::{anyhow, Context as _, Result}; use log::{info, Level, LevelFilter}; +use maybe_rayon::rayon; use plonky2::gates::noop::NoopGate; use plonky2::hash::hash_types::RichField; use plonky2::iop::witness::{PartialWitness, Witness}; @@ -18,7 +17,7 @@ use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::{ CircuitConfig, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; -use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, Hasher, PoseidonGoldilocksConfig}; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig, PoseidonGoldilocksConfig}; use plonky2::plonk::proof::{CompressedProofWithPublicInputs, ProofWithPublicInputs}; use plonky2::plonk::prover::prove; use plonky2::util::timing::TimingTree; @@ -65,10 +64,7 @@ struct Options { fn dummy_proof, C: GenericConfig, const D: usize>( config: &CircuitConfig, log2_size: usize, -) -> Result> -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> Result> { // 'size' is in degree, but we want number of noop gates. A non-zero amount of padding will be added and size will be rounded to the next power of two. To hit our target size, we go just under the previous power of two and hope padding is less than half the proof. let num_dummy_gates = match log2_size { 0 => return Err(anyhow!("size must be at least 1")), @@ -106,7 +102,6 @@ fn recursive_proof< ) -> Result> where InnerC::Hasher: AlgebraicHasher, - [(); C::Hasher::HASH_SIZE]:, { let (inner_proof, inner_vd, inner_cd) = inner; let mut builder = CircuitBuilder::::new(config.clone()); @@ -150,10 +145,7 @@ fn test_serialization, C: GenericConfig, proof: &ProofWithPublicInputs, vd: &VerifierOnlyCircuitData, cd: &CommonCircuitData, -) -> Result<()> -where - [(); C::Hasher::HASH_SIZE]:, -{ +) -> Result<()> { let proof_bytes = proof.to_bytes(); info!("Proof length: {} bytes", proof_bytes.len()); let proof_from_bytes = ProofWithPublicInputs::from_bytes(proof_bytes, cd)?; diff --git a/starky/src/constraint_consumer.rs b/starky/src/constraint_consumer.rs index 1a061c20..4cd8c0cd 100644 --- a/starky/src/constraint_consumer.rs +++ b/starky/src/constraint_consumer.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use plonky2::field::extension::Extendable; use plonky2::field::packed::PackedField; diff --git a/starky/src/fibonacci_stark.rs b/starky/src/fibonacci_stark.rs index b8c8c01e..260e2c54 100644 --- a/starky/src/fibonacci_stark.rs +++ b/starky/src/fibonacci_stark.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::packed::PackedField; diff --git a/starky/src/prover.rs b/starky/src/prover.rs index c9191f1d..4d69e838 100644 --- a/starky/src/prover.rs +++ b/starky/src/prover.rs @@ -1,4 +1,4 @@ -use std::iter::once; +use core::iter::once; use anyhow::{ensure, Result}; use itertools::Itertools; diff --git a/starky/src/recursive_verifier.rs b/starky/src/recursive_verifier.rs index 04858d55..be3b6bc6 100644 --- a/starky/src/recursive_verifier.rs +++ b/starky/src/recursive_verifier.rs @@ -1,4 +1,4 @@ -use std::iter::once; +use core::iter::once; use anyhow::{ensure, Result}; use itertools::Itertools; diff --git a/starky/src/verifier.rs b/starky/src/verifier.rs index fe0e41d2..78c6b63e 100644 --- a/starky/src/verifier.rs +++ b/starky/src/verifier.rs @@ -1,4 +1,4 @@ -use std::iter::once; +use core::iter::once; use anyhow::{anyhow, ensure, Result}; use itertools::Itertools; From 9f4dc3464e7e95b3e56f3bb2b6f65a416ce50d50 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Thu, 3 Nov 2022 20:04:57 -0700 Subject: [PATCH 09/49] fix: add architecture gating for inline-assembly Signed-off-by: Brandon H. Gomes --- field/src/goldilocks_field.rs | 3 +-- util/Cargo.toml | 2 -- util/src/lib.rs | 24 ++++++++++++------------ 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/field/src/goldilocks_field.rs b/field/src/goldilocks_field.rs index 12c8da3a..9f0b0519 100644 --- a/field/src/goldilocks_field.rs +++ b/field/src/goldilocks_field.rs @@ -305,10 +305,9 @@ impl DivAssign for GoldilocksField { #[inline(always)] #[cfg(target_arch = "x86_64")] unsafe fn add_no_canonicalize_trashing_input(x: u64, y: u64) -> u64 { - use core::arch::asm; let res_wrapped: u64; let adjustment: u64; - asm!( + core::arch::asm!( "add {0}, {1}", // Trick. The carry flag is set iff the addition overflowed. // sbb x, y does x := x - y - CF. In our case, x and y are both {1:e}, so it simply does diff --git a/util/Cargo.toml b/util/Cargo.toml index a1ab402a..0e3a68f0 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -3,5 +3,3 @@ name = "plonky2_util" description = "Utilities used by Plonky2" version = "0.1.0" edition = "2021" - -[dependencies] diff --git a/util/src/lib.rs b/util/src/lib.rs index c840bc69..ab1e8d8d 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -9,8 +9,6 @@ extern crate alloc; use alloc::vec::Vec; -use core::arch::asm; -use core::convert::Infallible; use core::hint::unreachable_unchecked; use core::mem::size_of; use core::ptr::{swap, swap_nonoverlapping}; @@ -19,15 +17,6 @@ use crate::transpose_util::transpose_in_place_square; mod transpose_util; -/// Converts `result` into the [`Ok`] variant of [`Result`]. -#[inline] -pub fn into_ok(result: Result) -> T { - match result { - Ok(value) => value, - _ => unreachable!("The `Infallible` value cannot be constructed."), - } -} - pub fn bits_u64(n: u64) -> usize { (64 - n.leading_zeros()) as usize } @@ -281,8 +270,19 @@ pub fn assume(p: bool) { /// This function has no semantics. It is a hint only. #[inline(always)] pub fn branch_hint() { + // NOTE: These are the currently supported assembly architectures. See the + // [nightly reference](https://doc.rust-lang.org/nightly/reference/inline-assembly.html) for + // the most up-to-date list. + #[cfg(any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "riscv32", + target_arch = "riscv64", + target_arch = "x86", + target_arch = "x86_64", + ))] unsafe { - asm!("", options(nomem, nostack, preserves_flags)); + core::arch::asm!("", options(nomem, nostack, preserves_flags)); } } From 5dfe1b412e84e0d9a13508dd3df5b0af4ff25084 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Fri, 4 Nov 2022 16:04:10 -0700 Subject: [PATCH 10/49] feat: add no-std support for starky Signed-off-by: Brandon H. Gomes --- starky/Cargo.toml | 19 +++++++++++-------- starky/src/constraint_consumer.rs | 2 ++ starky/src/fibonacci_stark.rs | 2 ++ starky/src/get_challenges.rs | 2 ++ starky/src/lib.rs | 6 +++++- starky/src/permutation.rs | 3 +++ starky/src/proof.rs | 3 +++ starky/src/prover.rs | 4 ++-- starky/src/recursive_verifier.rs | 1 + starky/src/stark.rs | 5 ++++- starky/src/stark_testing.rs | 6 ++++-- starky/src/util.rs | 2 ++ starky/src/verifier.rs | 1 + 13 files changed, 42 insertions(+), 14 deletions(-) diff --git a/starky/Cargo.toml b/starky/Cargo.toml index a33d03cf..cdeb189a 100644 --- a/starky/Cargo.toml +++ b/starky/Cargo.toml @@ -5,14 +5,17 @@ version = "0.1.0" edition = "2021" [features] -default = ["parallel"] +default = ["parallel", "std", "timing"] parallel = ["plonky2/parallel", "maybe_rayon/parallel"] +std = ["anyhow/std", "plonky2/std"] +timing = ["plonky2/timing"] [dependencies] -anyhow = "1.0.40" -env_logger = "0.9.0" -itertools = "0.10.0" -log = "0.4.14" -maybe_rayon = { path = "../maybe_rayon" } -plonky2 = { path = "../plonky2", default-features = false, features = ["timing"] } -plonky2_util = { path = "../util" } +anyhow = { version = "1.0.40", default-features = false } +itertools = { version = "0.10.0", default-features = false } +log = { version = "0.4.14", default-features = false } +maybe_rayon = { path = "../maybe_rayon", default-features = false } +plonky2 = { path = "../plonky2", default-features = false } + +[dev-dependencies] +env_logger = { version = "0.9.0", default-features = false } diff --git a/starky/src/constraint_consumer.rs b/starky/src/constraint_consumer.rs index 4cd8c0cd..03548935 100644 --- a/starky/src/constraint_consumer.rs +++ b/starky/src/constraint_consumer.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::marker::PhantomData; use plonky2::field::extension::Extendable; diff --git a/starky/src/fibonacci_stark.rs b/starky/src/fibonacci_stark.rs index 260e2c54..9397d6d7 100644 --- a/starky/src/fibonacci_stark.rs +++ b/starky/src/fibonacci_stark.rs @@ -1,3 +1,5 @@ +use alloc::vec; +use alloc::vec::Vec; use core::marker::PhantomData; use plonky2::field::extension::{Extendable, FieldExtension}; diff --git a/starky/src/get_challenges.rs b/starky/src/get_challenges.rs index e84f5599..2f1a9064 100644 --- a/starky/src/get_challenges.rs +++ b/starky/src/get_challenges.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use plonky2::field::extension::Extendable; use plonky2::field::polynomial::PolynomialCoeffs; use plonky2::fri::proof::{FriProof, FriProofTarget}; diff --git a/starky/src/lib.rs b/starky/src/lib.rs index 4e4b2eb6..89a57d77 100644 --- a/starky/src/lib.rs +++ b/starky/src/lib.rs @@ -2,10 +2,14 @@ #![allow(clippy::too_many_arguments)] #![allow(clippy::type_complexity)] #![feature(generic_const_exprs)] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +mod get_challenges; pub mod config; pub mod constraint_consumer; -mod get_challenges; pub mod permutation; pub mod proof; pub mod prover; diff --git a/starky/src/permutation.rs b/starky/src/permutation.rs index 7d422171..ee4225f3 100644 --- a/starky/src/permutation.rs +++ b/starky/src/permutation.rs @@ -1,5 +1,8 @@ //! Permutation arguments. +use alloc::vec; +use alloc::vec::Vec; + use itertools::Itertools; use maybe_rayon::*; use plonky2::field::batch_util::batch_multiply_inplace; diff --git a/starky/src/proof.rs b/starky/src/proof.rs index c9900c08..86093857 100644 --- a/starky/src/proof.rs +++ b/starky/src/proof.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use itertools::Itertools; use maybe_rayon::*; use plonky2::field::extension::{Extendable, FieldExtension}; diff --git a/starky/src/prover.rs b/starky/src/prover.rs index 4d69e838..dc445f24 100644 --- a/starky/src/prover.rs +++ b/starky/src/prover.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use core::iter::once; use anyhow::{ensure, Result}; @@ -15,8 +16,7 @@ use plonky2::iop::challenger::Challenger; use plonky2::plonk::config::{GenericConfig, Hasher}; use plonky2::timed; use plonky2::util::timing::TimingTree; -use plonky2::util::transpose; -use plonky2_util::{log2_ceil, log2_strict}; +use plonky2::util::{log2_ceil, log2_strict, transpose}; use crate::config::StarkConfig; use crate::constraint_consumer::ConstraintConsumer; diff --git a/starky/src/recursive_verifier.rs b/starky/src/recursive_verifier.rs index be3b6bc6..d080f80f 100644 --- a/starky/src/recursive_verifier.rs +++ b/starky/src/recursive_verifier.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use core::iter::once; use anyhow::{ensure, Result}; diff --git a/starky/src/stark.rs b/starky/src/stark.rs index 668fc4a2..b223d107 100644 --- a/starky/src/stark.rs +++ b/starky/src/stark.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::packed::PackedField; use plonky2::fri::structure::{ @@ -7,7 +10,7 @@ use plonky2::fri::structure::{ use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; use plonky2::plonk::circuit_builder::CircuitBuilder; -use plonky2_util::ceil_div_usize; +use plonky2::util::ceil_div_usize; use crate::config::StarkConfig; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; diff --git a/starky/src/stark_testing.rs b/starky/src/stark_testing.rs index f9f57828..7adcacc4 100644 --- a/starky/src/stark_testing.rs +++ b/starky/src/stark_testing.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use anyhow::{ensure, Result}; use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::polynomial::{PolynomialCoeffs, PolynomialValues}; @@ -7,8 +10,7 @@ use plonky2::iop::witness::{PartialWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; use plonky2::plonk::circuit_data::CircuitConfig; use plonky2::plonk::config::{GenericConfig, Hasher}; -use plonky2::util::transpose; -use plonky2_util::{log2_ceil, log2_strict}; +use plonky2::util::{log2_ceil, log2_strict, transpose}; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::stark::Stark; diff --git a/starky/src/util.rs b/starky/src/util.rs index 297978ee..1adee000 100644 --- a/starky/src/util.rs +++ b/starky/src/util.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use itertools::Itertools; use plonky2::field::polynomial::PolynomialValues; use plonky2::field::types::Field; diff --git a/starky/src/verifier.rs b/starky/src/verifier.rs index 78c6b63e..443fcb31 100644 --- a/starky/src/verifier.rs +++ b/starky/src/verifier.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use core::iter::once; use anyhow::{anyhow, ensure, Result}; From 9e33310ee741f009c35bdaad963768a290b5c43f Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Fri, 4 Nov 2022 16:26:22 -0700 Subject: [PATCH 11/49] feat: add no-std support for insertion gate Signed-off-by: Brandon H. Gomes --- ecdsa/Cargo.toml | 1 - insertion/Cargo.toml | 6 +++++- insertion/src/insert_gadget.rs | 3 +++ insertion/src/insertion_gate.rs | 12 ++++++------ insertion/src/lib.rs | 3 +++ u32/Cargo.toml | 1 - 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/ecdsa/Cargo.toml b/ecdsa/Cargo.toml index 602fbb09..ed84d5de 100644 --- a/ecdsa/Cargo.toml +++ b/ecdsa/Cargo.toml @@ -17,4 +17,3 @@ serde = { version = "1.0", default-features = false, features = ["derive"] } [dev-dependencies] rand = { version = "0.8.4", default-features = false, features = ["getrandom"] } - diff --git a/insertion/Cargo.toml b/insertion/Cargo.toml index afaefd4f..c007a975 100644 --- a/insertion/Cargo.toml +++ b/insertion/Cargo.toml @@ -5,5 +5,9 @@ version = "0.1.0" edition = "2021" [dependencies] -anyhow = "1.0.40" +anyhow = { version = "1.0.40", default-features = false } +plonky2 = { path = "../plonky2", default-features = false } + +[dev-dependencies] plonky2 = { path = "../plonky2" } + diff --git a/insertion/src/insert_gadget.rs b/insertion/src/insert_gadget.rs index dde8e940..1574d8fb 100644 --- a/insertion/src/insert_gadget.rs +++ b/insertion/src/insert_gadget.rs @@ -1,3 +1,6 @@ +use alloc::vec; +use alloc::vec::Vec; + use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; diff --git a/insertion/src/insertion_gate.rs b/insertion/src/insertion_gate.rs index a476002b..8019649a 100644 --- a/insertion/src/insertion_gate.rs +++ b/insertion/src/insertion_gate.rs @@ -1,3 +1,7 @@ +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; +use alloc::{format, vec}; use core::marker::PhantomData; use core::ops::Range; @@ -317,18 +321,14 @@ impl, const D: usize> SimpleGenerator for Insert #[cfg(test)] mod tests { - use core::marker::PhantomData; - use anyhow::Result; use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::{Field, Sample}; - use plonky2::gates::gate::Gate; + use plonky2::field::types::Sample; use plonky2::gates::gate_testing::{test_eval_fns, test_low_degree}; use plonky2::hash::hash_types::HashOut; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; - use plonky2::plonk::vars::EvaluationVars; - use crate::insertion_gate::InsertionGate; + use super::*; #[test] fn wire_indices() { diff --git a/insertion/src/lib.rs b/insertion/src/lib.rs index 15c91253..e71919dd 100644 --- a/insertion/src/lib.rs +++ b/insertion/src/lib.rs @@ -4,6 +4,9 @@ #![allow(clippy::len_without_is_empty)] #![allow(clippy::needless_range_loop)] #![allow(clippy::return_self_not_must_use)] +#![no_std] + +extern crate alloc; pub mod insert_gadget; pub mod insertion_gate; diff --git a/u32/Cargo.toml b/u32/Cargo.toml index af7676ed..273db263 100644 --- a/u32/Cargo.toml +++ b/u32/Cargo.toml @@ -12,4 +12,3 @@ plonky2 = { path = "../plonky2", default-features = false } [dev-dependencies] plonky2 = { path = "../plonky2", default-features = false, features = ["gate_testing"] } rand = { version = "0.8.4", default-features = false, features = ["getrandom"] } - From 7e432bd6cc67e6dae66844fac3359c29a89db8f7 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Fri, 4 Nov 2022 16:47:02 -0700 Subject: [PATCH 12/49] feat: add serialization documentation Signed-off-by: Brandon H. Gomes --- plonky2/src/util/serialization.rs | 207 +++++++++++++++--------------- 1 file changed, 104 insertions(+), 103 deletions(-) diff --git a/plonky2/src/util/serialization.rs b/plonky2/src/util/serialization.rs index 1cdfc39c..5291ba00 100644 --- a/plonky2/src/util/serialization.rs +++ b/plonky2/src/util/serialization.rs @@ -48,15 +48,15 @@ impl Size for Vec { } } -/// +/// Reading pub trait Read { - /// + /// Error Type type Error; - /// + /// Reads exactly the length of `bytes` from `self` and writes it to `bytes`. fn read_exact(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error>; - /// + /// Reads a `u8` value from `self`. #[inline] fn read_u8(&mut self) -> Result { let mut buf = [0; core::mem::size_of::()]; @@ -64,7 +64,7 @@ pub trait Read { Ok(buf[0]) } - /// + /// Reads a `u32` value from `self`. #[inline] fn read_u32(&mut self) -> Result { let mut buf = [0; core::mem::size_of::()]; @@ -72,7 +72,7 @@ pub trait Read { Ok(u32::from_le_bytes(buf)) } - /// + /// Reads a element from the field `F` with size less than `2^64` from `self.` #[inline] fn read_field(&mut self) -> Result where @@ -83,11 +83,22 @@ pub trait Read { Ok(F::from_canonical_u64(u64::from_le_bytes(buf))) } - /// + /// Reads a vector of elements from the field `F` from `self`. + #[inline] + fn read_field_vec(&mut self, length: usize) -> Result, Self::Error> + where + F: Field64, + { + (0..length) + .map(|_| self.read_field()) + .collect::, _>>() + } + + /// Reads an element from the field extension of `F` from `self.` #[inline] fn read_field_ext(&mut self) -> Result where - F: RichField + Extendable, + F: Field64 + Extendable, { let mut arr = [F::ZERO; D]; for a in arr.iter_mut() { @@ -98,7 +109,19 @@ pub trait Read { )) } - /// + /// Reads a vector of elements from the field extension of `F` from `self`. + #[inline] + fn read_field_ext_vec( + &mut self, + length: usize, + ) -> Result, Self::Error> + where + F: RichField + Extendable, + { + (0..length).map(|_| self.read_field_ext::()).collect() + } + + /// Reads a hash value from `self`. #[inline] fn read_hash(&mut self) -> Result where @@ -110,7 +133,7 @@ pub trait Read { Ok(H::Hash::from_bytes(&buf)) } - /// + /// Reads a value of type [`MerkleCap`] from `self` with the given `cap_height`. #[inline] fn read_merkle_cap(&mut self, cap_height: usize) -> Result, Self::Error> where @@ -125,30 +148,7 @@ pub trait Read { )) } - /// - #[inline] - fn read_field_vec(&mut self, length: usize) -> Result, Self::Error> - where - F: Field64, - { - (0..length) - .map(|_| self.read_field()) - .collect::, _>>() - } - - /// - #[inline] - fn read_field_ext_vec( - &mut self, - length: usize, - ) -> Result, Self::Error> - where - F: RichField + Extendable, - { - (0..length).map(|_| self.read_field_ext::()).collect() - } - - /// + /// Reads a value of type [`OpeningSet`] from `self` with the given `common_data`. #[inline] fn read_opening_set( &mut self, @@ -180,7 +180,7 @@ pub trait Read { }) } - /// + /// Reads a value of type [`MerkleProof`] from `self`. #[inline] fn read_merkle_proof(&mut self) -> Result, Self::Error> where @@ -191,11 +191,11 @@ pub trait Read { Ok(MerkleProof { siblings: (0..length) .map(|_| self.read_hash::()) - .collect::, _>>()?, + .collect::>()?, }) } - /// + /// Reads a value of type [`FriInitialTreeProof`] from `self` with the given `common_data`. #[inline] fn read_fri_initial_proof( &mut self, @@ -232,7 +232,8 @@ pub trait Read { Ok(FriInitialTreeProof { evals_proofs }) } - /// + /// Reads a value of type [`FriQueryStep`] from `self` with the given `arity` and `compressed` + /// flag. #[inline] fn read_fri_query_step( &mut self, @@ -251,7 +252,7 @@ pub trait Read { }) } - /// + /// Reads a vector of [`FriQueryRound`]s from `self` with `common_data`. #[inline] fn read_fri_query_rounds( &mut self, @@ -279,7 +280,7 @@ pub trait Read { Ok(fqrs) } - /// + /// Reads a value of type [`FriProof`] from `self` with `common_data`. #[inline] fn read_fri_proof( &mut self, @@ -306,7 +307,7 @@ pub trait Read { }) } - /// + /// Reads a value of type [`Proof`] from `self` with `common_data`. #[inline] fn read_proof( &mut self, @@ -331,7 +332,7 @@ pub trait Read { }) } - /// + /// Reads a value of type [`ProofWithPublicInputs`] from `self` with `common_data`. #[inline] fn read_proof_with_public_inputs( &mut self, @@ -352,7 +353,7 @@ pub trait Read { }) } - /// + /// Reads a value of type [`CompressedFriQueryRounds`] from `self` with `common_data`. #[inline] fn read_compressed_fri_query_rounds( &mut self, @@ -400,7 +401,7 @@ pub trait Read { }) } - /// + /// Reads a value of type [`CompressedFriProof`] from `self` with `common_data`. #[inline] fn read_compressed_fri_proof( &mut self, @@ -427,7 +428,7 @@ pub trait Read { }) } - /// + /// Reads a value of type [`CompressedProof`] from `self` with `common_data`. #[inline] fn read_compressed_proof( &mut self, @@ -452,7 +453,7 @@ pub trait Read { }) } - /// + /// Reads a value of type [`CompressedProofWithPublicInputs`] from `self` with `common_data`. #[inline] fn read_compressed_proof_with_public_inputs( &mut self, @@ -474,27 +475,27 @@ pub trait Read { } } -/// +/// Writing pub trait Write { - /// + /// Error Type type Error; - /// + /// Writes all `bytes` to `self`. fn write_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error>; - /// + /// Writes a byte `x` to `self`. #[inline] fn write_u8(&mut self, x: u8) -> Result<(), Self::Error> { self.write_all(&[x]) } - /// + /// Writes a word `x` to `self.` #[inline] fn write_u32(&mut self, x: u32) -> Result<(), Self::Error> { self.write_all(&x.to_le_bytes()) } - /// + /// Writes an element `x` from the field `F` to `self`. #[inline] fn write_field(&mut self, x: F) -> Result<(), Self::Error> where @@ -503,42 +504,7 @@ pub trait Write { self.write_all(&x.to_canonical_u64().to_le_bytes()) } - /// - #[inline] - fn write_field_ext(&mut self, x: F::Extension) -> Result<(), Self::Error> - where - F: RichField + Extendable, - { - for &a in &x.to_basefield_array() { - self.write_field(a)?; - } - Ok(()) - } - - /// - #[inline] - fn write_hash(&mut self, h: H::Hash) -> Result<(), Self::Error> - where - F: RichField, - H: Hasher, - { - self.write_all(&h.to_bytes()) - } - - /// - #[inline] - fn write_merkle_cap(&mut self, cap: &MerkleCap) -> Result<(), Self::Error> - where - F: RichField, - H: Hasher, - { - for &a in &cap.0 { - self.write_hash::(a)?; - } - Ok(()) - } - - /// + /// Writes a vector of elements #[inline] fn write_field_vec(&mut self, v: &[F]) -> Result<(), Self::Error> where @@ -550,6 +516,18 @@ pub trait Write { Ok(()) } + /// Writes an element `x` from the field extension of `F` to `self`. + #[inline] + fn write_field_ext(&mut self, x: F::Extension) -> Result<(), Self::Error> + where + F: RichField + Extendable, + { + for &a in &x.to_basefield_array() { + self.write_field(a)?; + } + Ok(()) + } + /// #[inline] fn write_field_ext_vec( @@ -565,7 +543,30 @@ pub trait Write { Ok(()) } - /// + /// Writes a hash `h` to `self`. + #[inline] + fn write_hash(&mut self, h: H::Hash) -> Result<(), Self::Error> + where + F: RichField, + H: Hasher, + { + self.write_all(&h.to_bytes()) + } + + /// Writes `cap`, a value of type [`MerkleCap`], to `self`. + #[inline] + fn write_merkle_cap(&mut self, cap: &MerkleCap) -> Result<(), Self::Error> + where + F: RichField, + H: Hasher, + { + for &a in &cap.0 { + self.write_hash::(a)?; + } + Ok(()) + } + + /// Writes a value `os` of type [`OpeningSet`] to `self.` #[inline] fn write_opening_set( &mut self, @@ -583,7 +584,7 @@ pub trait Write { self.write_field_ext_vec::(&os.quotient_polys) } - /// + /// Writes a value `p` of type [`MerkleProof`] to `self.` #[inline] fn write_merkle_proof(&mut self, p: &MerkleProof) -> Result<(), Self::Error> where @@ -602,7 +603,7 @@ pub trait Write { Ok(()) } - /// + /// Writes a value `fitp` of type [`FriInitialTreeProof`] to `self.` #[inline] fn write_fri_initial_proof( &mut self, @@ -619,7 +620,7 @@ pub trait Write { Ok(()) } - /// + /// Writes a value `fqs` of type [`FriQueryStep`] to `self.` #[inline] fn write_fri_query_step( &mut self, @@ -633,7 +634,7 @@ pub trait Write { self.write_merkle_proof(&fqs.merkle_proof) } - /// + /// Writes a value `fqrs` of type [`FriQueryRound`] to `self.` #[inline] fn write_fri_query_rounds( &mut self, @@ -652,7 +653,7 @@ pub trait Write { Ok(()) } - /// + /// Writes a value `fq` of type [`FriProof`] to `self.` #[inline] fn write_fri_proof( &mut self, @@ -670,7 +671,7 @@ pub trait Write { self.write_field(fp.pow_witness) } - /// + /// Writes a value `proof` of type [`Proof`] to `self.` #[inline] fn write_proof( &mut self, @@ -687,7 +688,7 @@ pub trait Write { self.write_fri_proof::(&proof.opening_proof) } - /// + /// Writes a value `proof_with_pis` of type [`ProofWithPublicInputs`] to `self.` #[inline] fn write_proof_with_public_inputs( &mut self, @@ -705,7 +706,7 @@ pub trait Write { self.write_field_vec(public_inputs) } - /// + /// Writes a value `cfqrs` of type [`CompressedFriQueryRounds`] to `self.` #[inline] fn write_compressed_fri_query_rounds( &mut self, @@ -733,7 +734,7 @@ pub trait Write { Ok(()) } - /// + /// Writes a value `fq` of type [`CompressedFriProof`] to `self.` #[inline] fn write_compressed_fri_proof( &mut self, @@ -751,7 +752,7 @@ pub trait Write { self.write_field(fp.pow_witness) } - /// + /// Writes a value `proof` of type [`CompressedProof`] to `self.` #[inline] fn write_compressed_proof( &mut self, @@ -768,7 +769,7 @@ pub trait Write { self.write_compressed_fri_proof::(&proof.opening_proof) } - /// + /// Writes a value `proof_with_pis` of type [`CompressedProofWithPublicInputs`] to `self.` #[inline] fn write_compressed_proof_with_public_inputs( &mut self, @@ -797,20 +798,20 @@ impl Write for Vec { } } -/// +/// Buffer #[cfg(feature = "std")] #[derive(Debug)] pub struct Buffer(Cursor>); #[cfg(feature = "std")] impl Buffer { - /// + /// Builds a new [`Buffer`] over `buffer`. #[inline] pub fn new(buffer: Vec) -> Self { Self(Cursor::new(buffer)) } - /// + /// Returns the inner buffer. #[inline] pub fn bytes(self) -> Vec { self.0.into_inner() From 9431fd74483fbdd301b5c88028aec473a378a748 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Sat, 5 Nov 2022 10:59:46 -0700 Subject: [PATCH 13/49] chore: add missing documentation in serialization trait Signed-off-by: Brandon H. Gomes --- plonky2/src/util/serialization.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plonky2/src/util/serialization.rs b/plonky2/src/util/serialization.rs index 5291ba00..ce56709d 100644 --- a/plonky2/src/util/serialization.rs +++ b/plonky2/src/util/serialization.rs @@ -504,7 +504,7 @@ pub trait Write { self.write_all(&x.to_canonical_u64().to_le_bytes()) } - /// Writes a vector of elements + /// Writes a vector `v` of elements from the field `F` to `self`. #[inline] fn write_field_vec(&mut self, v: &[F]) -> Result<(), Self::Error> where @@ -528,7 +528,7 @@ pub trait Write { Ok(()) } - /// + /// Writes a vector `v` of elements from the field extension of `F` to `self`. #[inline] fn write_field_ext_vec( &mut self, From cab6c18ed6433e741a824dfa9cbe9d2995158feb Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 8 Nov 2022 11:55:02 -0800 Subject: [PATCH 14/49] Check that `le_sum` won't overflow --- plonky2/src/gadgets/split_base.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plonky2/src/gadgets/split_base.rs b/plonky2/src/gadgets/split_base.rs index c539d784..9c85863f 100644 --- a/plonky2/src/gadgets/split_base.rs +++ b/plonky2/src/gadgets/split_base.rs @@ -3,6 +3,7 @@ use std::borrow::Borrow; use itertools::Itertools; use plonky2_field::extension::Extendable; use plonky2_field::types::Field; +use plonky2_util::log_floor; use crate::gates::base_sum::BaseSumGate; use crate::hash::hash_types::RichField; @@ -33,6 +34,11 @@ impl, const D: usize> CircuitBuilder { pub(crate) fn le_sum(&mut self, bits: impl Iterator>) -> Target { let bits = bits.map(|b| *b.borrow()).collect_vec(); let num_bits = bits.len(); + assert!( + num_bits <= log_floor(F::ORDER, 2), + "{} bits may overflow the field", + num_bits + ); if num_bits == 0 { return self.zero(); } From 882297877cfc2156f3541126f418a554e86632db Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 8 Nov 2022 12:03:58 -0800 Subject: [PATCH 15/49] security notes --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b924698..59fc4d09 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,11 @@ Jemalloc is known to cause crashes when a binary compiled for x86 is run on an A As this is a monorepo, see the individual crates within for license information. -## Disclaimer +## Security This code has not yet been audited, and should not be used in any production systems. +While Plonky2 is configurable, its defaults generally target 100 bits of security. The default FRI configuration targets 100 bits of *conjectured* security based on the conjecture in [ethSTARK](https://eprint.iacr.org/2021/582). + +Plonky2's default hash function is Poseidon, configured with 8 full rounds, 22 partial rounds, a width of 12 field elements (each ~64 bits), and an S-box of `x^7`. [BBLP22](https://tosc.iacr.org/index.php/ToSC/article/view/9850) suggests that this configuration may have around 95 bits of security, falling a bit short of our 100 bit target. + From c622e4524620e58aeb931f90bfc916a281e88d05 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 8 Nov 2022 12:26:52 -0800 Subject: [PATCH 16/49] Test reverse_index_bits Thanks to Least Authority for this --- util/Cargo.toml | 1 + util/src/lib.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/util/Cargo.toml b/util/Cargo.toml index a1ab402a..4e0b4b15 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -5,3 +5,4 @@ version = "0.1.0" edition = "2021" [dependencies] +rand = { version = "0.8.5", default-features = false, features = ["getrandom"] } diff --git a/util/src/lib.rs b/util/src/lib.rs index b22a4236..972c8372 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -274,8 +274,50 @@ pub fn branch_hint() { #[cfg(test)] mod tests { + use rand::rngs::OsRng; + use rand::Rng; + use crate::{log2_ceil, log2_strict}; + #[test] + fn test_reverse_index_bits() { + let lengths = [32, 128, 1 << 16]; + let mut rng = OsRng; + for _ in 0..32 { + for length in lengths { + let mut rand_list: Vec = Vec::with_capacity(length); + rand_list.resize_with(length, || rng.gen()); + + let out = super::reverse_index_bits(&rand_list); + let expect = reverse_index_bits_naive(&rand_list); + + for (out, expect) in out.iter().zip(&expect) { + assert_eq!(out, expect); + } + } + } + } + + #[test] + fn test_reverse_index_bits_in_place() { + let lengths = [32, 128, 1 << 16]; + let mut rng = OsRng; + for _ in 0..32 { + for length in lengths { + let mut rand_list: Vec = Vec::with_capacity(length); + rand_list.resize_with(length, || rng.gen()); + + let expect = reverse_index_bits_naive(&rand_list); + + super::reverse_index_bits_in_place(&mut rand_list); + + for (got, expect) in rand_list.iter().zip(&expect) { + assert_eq!(got, expect); + } + } + } + } + #[test] fn test_log2_strict() { assert_eq!(log2_strict(1), 0); @@ -326,4 +368,17 @@ mod tests { assert_eq!(log2_ceil(usize::MAX - 1), usize::BITS as usize); assert_eq!(log2_ceil(usize::MAX), usize::BITS as usize); } + + fn reverse_index_bits_naive(arr: &[T]) -> Vec { + let n = arr.len(); + let n_power = log2_strict(n); + + let mut out = vec![None; n]; + for (i, v) in arr.iter().enumerate() { + let dst = i.reverse_bits() >> 64 - n_power; + out[dst] = Some(*v); + } + + out.into_iter().map(|x| x.unwrap()).collect() + } } From 624dabb9e349d780693a3c8f8c7075ccc221abfe Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 8 Nov 2022 13:06:01 -0800 Subject: [PATCH 17/49] clippy --- util/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/src/lib.rs b/util/src/lib.rs index 972c8372..eb297bd8 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -375,7 +375,7 @@ mod tests { let mut out = vec![None; n]; for (i, v) in arr.iter().enumerate() { - let dst = i.reverse_bits() >> 64 - n_power; + let dst = i.reverse_bits() >> (64 - n_power); out[dst] = Some(*v); } From 1c87fbb712be993cf51b604d1dfda54eb05ebe7d Mon Sep 17 00:00:00 2001 From: Hamish Ivey-Law <426294+unzvfu@users.noreply.github.com> Date: Wed, 9 Nov 2022 10:47:15 +1100 Subject: [PATCH 18/49] EVM shift left/right operations (#801) * First parts of shift implementation. * Disable range check errors. * Tidy up ASM. * Update comments; fix some .sum() expressions. * First full draft of shift left/right. * Missed a +1. * Clippy. * Address Jacqui's comments. * Add comment. * Fix missing filter. * Address second round of comments from Jacqui. --- evm/src/arithmetic/utils.rs | 30 +++++---- evm/src/cpu/columns/general.rs | 18 ++++++ evm/src/cpu/cpu_stark.rs | 6 +- evm/src/cpu/kernel/aggregator.rs | 1 + evm/src/cpu/kernel/asm/main.asm | 4 +- evm/src/cpu/kernel/asm/shift.asm | 25 +++++++ evm/src/cpu/mod.rs | 1 + evm/src/cpu/shift.rs | 108 +++++++++++++++++++++++++++++++ evm/src/memory/segments.rs | 8 ++- 9 files changed, 183 insertions(+), 18 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/shift.asm create mode 100644 evm/src/cpu/shift.rs diff --git a/evm/src/arithmetic/utils.rs b/evm/src/arithmetic/utils.rs index 74999ab4..ec989c94 100644 --- a/evm/src/arithmetic/utils.rs +++ b/evm/src/arithmetic/utils.rs @@ -1,6 +1,5 @@ use std::ops::{Add, AddAssign, Mul, Neg, Range, Shr, Sub, SubAssign}; -use log::error; use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; @@ -11,21 +10,24 @@ use crate::arithmetic::columns::{NUM_ARITH_COLUMNS, N_LIMBS}; /// Emit an error message regarding unchecked range assumptions. /// Assumes the values in `cols` are `[cols[0], cols[0] + 1, ..., /// cols[0] + cols.len() - 1]`. +/// +/// TODO: Hamish to delete this when he has implemented and integrated +/// range checks. pub(crate) fn _range_check_error( - file: &str, - line: u32, - cols: Range, - signedness: &str, + _file: &str, + _line: u32, + _cols: Range, + _signedness: &str, ) { - error!( - "{}:{}: arithmetic unit skipped {}-bit {} range-checks on columns {}--{}: not yet implemented", - line, - file, - RC_BITS, - signedness, - cols.start, - cols.end - 1, - ); + // error!( + // "{}:{}: arithmetic unit skipped {}-bit {} range-checks on columns {}--{}: not yet implemented", + // line, + // file, + // RC_BITS, + // signedness, + // cols.start, + // cols.end - 1, + // ); } #[macro_export] diff --git a/evm/src/cpu/columns/general.rs b/evm/src/cpu/columns/general.rs index 134788dc..5a2c9426 100644 --- a/evm/src/cpu/columns/general.rs +++ b/evm/src/cpu/columns/general.rs @@ -9,6 +9,7 @@ pub(crate) union CpuGeneralColumnsView { arithmetic: CpuArithmeticView, logic: CpuLogicView, jumps: CpuJumpsView, + shift: CpuShiftView, } impl CpuGeneralColumnsView { @@ -51,6 +52,16 @@ impl CpuGeneralColumnsView { pub(crate) fn jumps_mut(&mut self) -> &mut CpuJumpsView { unsafe { &mut self.jumps } } + + // SAFETY: Each view is a valid interpretation of the underlying array. + pub(crate) fn shift(&self) -> &CpuShiftView { + unsafe { &self.shift } + } + + // SAFETY: Each view is a valid interpretation of the underlying array. + pub(crate) fn shift_mut(&mut self) -> &mut CpuShiftView { + unsafe { &mut self.shift } + } } impl PartialEq for CpuGeneralColumnsView { @@ -144,5 +155,12 @@ pub(crate) struct CpuJumpsView { pub(crate) should_trap: T, } +#[derive(Copy, Clone)] +pub(crate) struct CpuShiftView { + // For a shift amount of displacement: [T], this is the inverse of + // sum(displacement[1..]) or zero if the sum is zero. + pub(crate) high_limb_sum_inv: T, +} + // `u8` is guaranteed to have a `size_of` of 1. pub const NUM_SHARED_COLUMNS: usize = size_of::>(); diff --git a/evm/src/cpu/cpu_stark.rs b/evm/src/cpu/cpu_stark.rs index 7b34cc4f..4cc38823 100644 --- a/evm/src/cpu/cpu_stark.rs +++ b/evm/src/cpu/cpu_stark.rs @@ -11,8 +11,8 @@ use plonky2::hash::hash_types::RichField; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::cpu::columns::{CpuColumnsView, COL_MAP, NUM_CPU_COLUMNS}; use crate::cpu::{ - bootstrap_kernel, control_flow, decode, dup_swap, jumps, membus, modfp254, simple_logic, stack, - stack_bounds, syscalls, + bootstrap_kernel, control_flow, decode, dup_swap, jumps, membus, modfp254, shift, simple_logic, + stack, stack_bounds, syscalls, }; use crate::cross_table_lookup::Column; use crate::memory::segments::Segment; @@ -151,6 +151,7 @@ impl, const D: usize> Stark for CpuStark, const D: usize> Stark for CpuStark Kernel { include_str!("asm/sha2/store_pad.asm"), include_str!("asm/sha2/temp_words.asm"), include_str!("asm/sha2/write_length.asm"), + include_str!("asm/shift.asm"), include_str!("asm/transactions/router.asm"), include_str!("asm/transactions/type_0.asm"), include_str!("asm/transactions/type_1.asm"), diff --git a/evm/src/cpu/kernel/asm/main.asm b/evm/src/cpu/kernel/asm/main.asm index e8c8e3e4..41cb8079 100644 --- a/evm/src/cpu/kernel/asm/main.asm +++ b/evm/src/cpu/kernel/asm/main.asm @@ -1,5 +1,7 @@ global main: - // First, load all MPT data from the prover. + // First, initialise the shift table + %shift_table_init + // Second, load all MPT data from the prover. PUSH txn_loop %jump(load_all_mpts) diff --git a/evm/src/cpu/kernel/asm/shift.asm b/evm/src/cpu/kernel/asm/shift.asm new file mode 100644 index 00000000..ce481ea2 --- /dev/null +++ b/evm/src/cpu/kernel/asm/shift.asm @@ -0,0 +1,25 @@ +/// Initialise the lookup table of binary powers for doing left/right shifts +/// +/// Specifically, set SHIFT_TABLE_SEGMENT[i] = 2^i for i = 0..255. +%macro shift_table_init + push 1 // 2^0 + push 0 // initial offset is zero + push @SEGMENT_SHIFT_TABLE // segment + dup2 // kernel context is 0 + %rep 255 + // stack: context, segment, ost_i, 2^i + dup4 + dup1 + add + // stack: 2^(i+1), context, segment, ost_i, 2^i + dup4 + %increment + // stack: ost_(i+1), 2^(i+1), context, segment, ost_i, 2^i + dup4 + dup4 + // stack: context, segment, ost_(i+1), 2^(i+1), context, segment, ost_i, 2^i + %endrep + %rep 256 + mstore_general + %endrep +%endmacro diff --git a/evm/src/cpu/mod.rs b/evm/src/cpu/mod.rs index fda5db80..ece07c1c 100644 --- a/evm/src/cpu/mod.rs +++ b/evm/src/cpu/mod.rs @@ -8,6 +8,7 @@ mod jumps; pub mod kernel; pub(crate) mod membus; mod modfp254; +mod shift; mod simple_logic; mod stack; mod stack_bounds; diff --git a/evm/src/cpu/shift.rs b/evm/src/cpu/shift.rs new file mode 100644 index 00000000..d383b6b2 --- /dev/null +++ b/evm/src/cpu/shift.rs @@ -0,0 +1,108 @@ +use plonky2::field::extension::Extendable; +use plonky2::field::packed::PackedField; +use plonky2::field::types::Field; +use plonky2::hash::hash_types::RichField; +use plonky2::iop::ext_target::ExtensionTarget; + +use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; +use crate::cpu::columns::CpuColumnsView; +use crate::cpu::membus::NUM_GP_CHANNELS; +use crate::memory::segments::Segment; + +pub(crate) fn eval_packed( + lv: &CpuColumnsView

, + yield_constr: &mut ConstraintConsumer

, +) { + let is_shift = lv.op.shl + lv.op.shr; + let displacement = lv.mem_channels[1]; // holds the shift displacement d + let two_exp = lv.mem_channels[2]; // holds 2^d + + // Not needed here; val is the input and we're verifying that output is + // val * 2^d (mod 2^256) + //let val = lv.mem_channels[0]; + //let output = lv.mem_channels[NUM_GP_CHANNELS - 1]; + + let shift_table_segment = P::Scalar::from_canonical_u64(Segment::ShiftTable as u64); + + // Only lookup the shifting factor when displacement is < 2^32. + // two_exp.used is true (1) if the high limbs of the displacement are + // zero and false (0) otherwise. + let high_limbs_are_zero = two_exp.used; + yield_constr.constraint(is_shift * (two_exp.is_read - P::ONES)); + + let high_limbs_sum: P = displacement.value[1..].iter().copied().sum(); + let high_limbs_sum_inv = lv.general.shift().high_limb_sum_inv; + // Verify that high_limbs_are_zero = 0 implies high_limbs_sum != 0 and + // high_limbs_are_zero = 1 implies high_limbs_sum = 0. + let t = high_limbs_sum * high_limbs_sum_inv - (P::ONES - high_limbs_are_zero); + yield_constr.constraint(is_shift * t); + yield_constr.constraint(is_shift * high_limbs_sum * high_limbs_are_zero); + + // When the shift displacement is < 2^32, constrain the two_exp + // mem_channel to be the entry corresponding to `displacement` in + // the shift table lookup (will be zero if displacement >= 256). + yield_constr.constraint(is_shift * two_exp.addr_context); // read from kernel memory + yield_constr.constraint(is_shift * (two_exp.addr_segment - shift_table_segment)); + yield_constr.constraint(is_shift * (two_exp.addr_virtual - displacement.value[0])); + + // Other channels must be unused + for chan in &lv.mem_channels[3..NUM_GP_CHANNELS - 1] { + yield_constr.constraint(is_shift * chan.used); // channel is not used + } + + // Cross-table lookup must connect the memory channels here to MUL + // (in the case of left shift) or DIV (in the case of right shift) + // in the arithmetic table. Specifically, the mapping is + // + // 0 -> 0 (value to be shifted is the same) + // 2 -> 1 (two_exp becomes the multiplicand (resp. divisor)) + // last -> last (output is the same) +} + +pub(crate) fn eval_ext_circuit, const D: usize>( + builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder, + lv: &CpuColumnsView>, + yield_constr: &mut RecursiveConstraintConsumer, +) { + let is_shift = builder.add_extension(lv.op.shl, lv.op.shr); + let displacement = lv.mem_channels[1]; + let two_exp = lv.mem_channels[2]; + + let shift_table_segment = F::from_canonical_u64(Segment::ShiftTable as u64); + + let high_limbs_are_zero = two_exp.used; + let one = builder.one_extension(); + let t = builder.sub_extension(two_exp.is_read, one); + let t = builder.mul_extension(is_shift, t); + yield_constr.constraint(builder, t); + + let high_limbs_sum = builder.add_many_extension(&displacement.value[1..]); + let high_limbs_sum_inv = lv.general.shift().high_limb_sum_inv; + let t = builder.one_extension(); + let t = builder.sub_extension(t, high_limbs_are_zero); + let t = builder.mul_sub_extension(high_limbs_sum, high_limbs_sum_inv, t); + let t = builder.mul_extension(is_shift, t); + yield_constr.constraint(builder, t); + + let t = builder.mul_many_extension([is_shift, high_limbs_sum, high_limbs_are_zero]); + yield_constr.constraint(builder, t); + + let t = builder.mul_extension(is_shift, two_exp.addr_context); + yield_constr.constraint(builder, t); + let t = builder.arithmetic_extension( + F::ONE, + -shift_table_segment, + is_shift, + two_exp.addr_segment, + is_shift, + ); + yield_constr.constraint(builder, t); + let t = builder.sub_extension(two_exp.addr_virtual, displacement.value[0]); + let t = builder.mul_extension(is_shift, t); + yield_constr.constraint(builder, t); + + for chan in &lv.mem_channels[3..NUM_GP_CHANNELS - 1] { + let t = builder.mul_extension(is_shift, chan.used); + yield_constr.constraint(builder, t); + } +} diff --git a/evm/src/memory/segments.rs b/evm/src/memory/segments.rs index f8d536e9..7a28cb96 100644 --- a/evm/src/memory/segments.rs +++ b/evm/src/memory/segments.rs @@ -35,10 +35,13 @@ pub(crate) enum Segment { TrieEncodedChild = 14, /// A buffer used to store the lengths of the encodings of a branch node's children. TrieEncodedChildLen = 15, + /// A table of values 2^i for i=0..255 for use with shift + /// instructions; initialised by `kernel/asm/shift.asm::init_shift_table()`. + ShiftTable = 16, } impl Segment { - pub(crate) const COUNT: usize = 16; + pub(crate) const COUNT: usize = 17; pub(crate) fn all() -> [Self; Self::COUNT] { [ @@ -58,6 +61,7 @@ impl Segment { Self::TrieData, Self::TrieEncodedChild, Self::TrieEncodedChildLen, + Self::ShiftTable, ] } @@ -80,6 +84,7 @@ impl Segment { Segment::TrieData => "SEGMENT_TRIE_DATA", Segment::TrieEncodedChild => "SEGMENT_TRIE_ENCODED_CHILD", Segment::TrieEncodedChildLen => "SEGMENT_TRIE_ENCODED_CHILD_LEN", + Segment::ShiftTable => "SEGMENT_SHIFT_TABLE", } } @@ -102,6 +107,7 @@ impl Segment { Segment::TrieData => 256, Segment::TrieEncodedChild => 256, Segment::TrieEncodedChildLen => 6, + Segment::ShiftTable => 256, } } } From 56e291cf4ee8ff7061978c5bdf01dad66a7801f6 Mon Sep 17 00:00:00 2001 From: Hamish Ivey-Law <426294+unzvfu@users.noreply.github.com> Date: Fri, 11 Nov 2022 15:09:56 +1100 Subject: [PATCH 19/49] Remove signed operation placeholders from arithmetic table. (#812) --- evm/src/arithmetic/columns.rs | 19 +++++++------------ evm/src/arithmetic/compare.rs | 2 -- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/evm/src/arithmetic/columns.rs b/evm/src/arithmetic/columns.rs index 10bf72d9..923fbc73 100644 --- a/evm/src/arithmetic/columns.rs +++ b/evm/src/arithmetic/columns.rs @@ -22,25 +22,20 @@ pub const IS_ADD: usize = 0; pub const IS_MUL: usize = IS_ADD + 1; pub const IS_SUB: usize = IS_MUL + 1; pub const IS_DIV: usize = IS_SUB + 1; -pub const IS_SDIV: usize = IS_DIV + 1; -pub const IS_MOD: usize = IS_SDIV + 1; -pub const IS_SMOD: usize = IS_MOD + 1; -pub const IS_ADDMOD: usize = IS_SMOD + 1; +pub const IS_MOD: usize = IS_DIV + 1; +pub const IS_ADDMOD: usize = IS_MOD + 1; pub const IS_SUBMOD: usize = IS_ADDMOD + 1; pub const IS_MULMOD: usize = IS_SUBMOD + 1; pub const IS_LT: usize = IS_MULMOD + 1; pub const IS_GT: usize = IS_LT + 1; -pub const IS_SLT: usize = IS_GT + 1; -pub const IS_SGT: usize = IS_SLT + 1; -pub const IS_SHL: usize = IS_SGT + 1; +pub const IS_SHL: usize = IS_GT + 1; pub const IS_SHR: usize = IS_SHL + 1; -pub const IS_SAR: usize = IS_SHR + 1; -const START_SHARED_COLS: usize = IS_SAR + 1; +const START_SHARED_COLS: usize = IS_SHR + 1; -pub(crate) const ALL_OPERATIONS: [usize; 17] = [ - IS_ADD, IS_MUL, IS_SUB, IS_DIV, IS_SDIV, IS_MOD, IS_SMOD, IS_ADDMOD, IS_SUBMOD, IS_MULMOD, - IS_LT, IS_GT, IS_SLT, IS_SGT, IS_SHL, IS_SHR, IS_SAR, +pub(crate) const ALL_OPERATIONS: [usize; 12] = [ + IS_ADD, IS_MUL, IS_SUB, IS_DIV, IS_MOD, IS_ADDMOD, IS_SUBMOD, IS_MULMOD, IS_LT, IS_GT, IS_SHL, + IS_SHR, ]; /// Within the Arithmetic Unit, there are shared columns which can be diff --git a/evm/src/arithmetic/compare.rs b/evm/src/arithmetic/compare.rs index 55dc5764..a9dd785d 100644 --- a/evm/src/arithmetic/compare.rs +++ b/evm/src/arithmetic/compare.rs @@ -35,8 +35,6 @@ pub(crate) fn generate(lv: &mut [F; NUM_ARITH_COLUMNS], op: usize) IS_LT => u256_sub_br(input0, input1), // input1 - input0 == diff + br*2^256 IS_GT => u256_sub_br(input1, input0), - IS_SLT => todo!(), - IS_SGT => todo!(), _ => panic!("op code not a comparison"), }; From 7eb0c74166e54ca6421a5ecf3db70c3c208f14f6 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Mon, 14 Nov 2022 14:53:06 -0800 Subject: [PATCH 20/49] Randomize unused wires of PublicInputGate --- plonky2/src/plonk/circuit_builder.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index dfd23426..297358ea 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -685,6 +685,18 @@ impl, const D: usize> CircuitBuilder { } } + /// In PLONK's permutation argument, there's a slight chance of division by zero. We can + /// mitigate this by randomizing some unused witness elements, so if proving fails with + /// division by zero, the next attempt will have an (almost) independent chance of success. + /// See https://github.com/mir-protocol/plonky2/issues/456 + fn randomize_unused_pi_wires(&mut self, pi_gate: usize) { + for wire in PublicInputGate::wires_public_inputs_hash().end..self.config.num_wires { + self.add_simple_generator(RandomValueGenerator { + target: Target::wire(pi_gate, wire), + }); + } + } + /// Builds a "full circuit", with both prover and verifier data. pub fn build>(mut self) -> CircuitData where @@ -708,6 +720,7 @@ impl, const D: usize> CircuitBuilder { { self.connect(hash_part, Target::wire(pi_gate, wire)) } + self.randomize_unused_pi_wires(pi_gate); // Make sure we have enough constant generators. If not, add a `ConstantGate`. while self.constants_to_targets.len() > self.constant_generators.len() { From 14c2a6dd1ff0f7c08c934373ed47f1910930db7a Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 15 Nov 2022 01:51:29 -0500 Subject: [PATCH 21/49] Fork Update (#3) * Use static `KERNEL` in tests * Print opcode count * Update criterion * Combine all syscalls into one flag (#802) * Combine all syscalls into one flag * Minor: typo * Daniel PR comments * Check that `le_sum` won't overflow * security notes * Test reverse_index_bits Thanks to Least Authority for this * clippy * EVM shift left/right operations (#801) * First parts of shift implementation. * Disable range check errors. * Tidy up ASM. * Update comments; fix some .sum() expressions. * First full draft of shift left/right. * Missed a +1. * Clippy. * Address Jacqui's comments. * Add comment. * Fix missing filter. * Address second round of comments from Jacqui. * Remove signed operation placeholders from arithmetic table. (#812) Co-authored-by: wborgeaud Co-authored-by: Daniel Lubarov Co-authored-by: Jacqueline Nabaglo Co-authored-by: Hamish Ivey-Law <426294+unzvfu@users.noreply.github.com> --- README.md | 6 +- evm/Cargo.toml | 3 +- evm/src/arithmetic/columns.rs | 19 +- evm/src/arithmetic/compare.rs | 2 - evm/src/arithmetic/utils.rs | 30 +-- evm/src/cpu/columns/general.rs | 18 ++ evm/src/cpu/columns/ops.rs | 67 +----- evm/src/cpu/control_flow.rs | 31 ++- evm/src/cpu/cpu_stark.rs | 6 +- evm/src/cpu/decode.rs | 87 +------- evm/src/cpu/kernel/aggregator.rs | 3 + evm/src/cpu/kernel/asm/core/syscall.asm | 160 ++++++++++++++ evm/src/cpu/kernel/asm/core/syscall_stubs.asm | 53 +++++ evm/src/cpu/kernel/asm/main.asm | 4 +- evm/src/cpu/kernel/asm/shift.asm | 25 +++ evm/src/cpu/kernel/assembler.rs | 37 ++-- evm/src/cpu/kernel/ast.rs | 2 + evm/src/cpu/kernel/evm_asm.pest | 3 +- evm/src/cpu/kernel/interpreter.rs | 184 +++++++++++++++- evm/src/cpu/kernel/parser.rs | 3 + evm/src/cpu/kernel/tests/curve_ops.rs | 133 ++++-------- evm/src/cpu/kernel/tests/ecrecover.rs | 37 +--- evm/src/cpu/kernel/tests/exp.rs | 25 +-- evm/src/cpu/kernel/tests/fields.rs | 9 +- evm/src/cpu/kernel/tests/hash.rs | 11 +- evm/src/cpu/kernel/tests/ripemd.rs | 9 +- evm/src/cpu/mod.rs | 1 + evm/src/cpu/shift.rs | 108 ++++++++++ evm/src/cpu/stack.rs | 62 +----- evm/src/cpu/syscalls.rs | 204 ++++++++++++------ evm/src/memory/segments.rs | 8 +- plonky2/Cargo.toml | 2 +- plonky2/src/gadgets/split_base.rs | 6 + system_zero/Cargo.toml | 2 +- util/Cargo.toml | 1 + util/src/lib.rs | 55 +++++ 36 files changed, 942 insertions(+), 474 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/core/syscall.asm create mode 100644 evm/src/cpu/kernel/asm/core/syscall_stubs.asm create mode 100644 evm/src/cpu/kernel/asm/shift.asm create mode 100644 evm/src/cpu/shift.rs diff --git a/README.md b/README.md index 7b924698..59fc4d09 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,11 @@ Jemalloc is known to cause crashes when a binary compiled for x86 is run on an A As this is a monorepo, see the individual crates within for license information. -## Disclaimer +## Security This code has not yet been audited, and should not be used in any production systems. +While Plonky2 is configurable, its defaults generally target 100 bits of security. The default FRI configuration targets 100 bits of *conjectured* security based on the conjecture in [ethSTARK](https://eprint.iacr.org/2021/582). + +Plonky2's default hash function is Poseidon, configured with 8 full rounds, 22 partial rounds, a width of 12 field elements (each ~64 bits), and an S-box of `x^7`. [BBLP22](https://tosc.iacr.org/index.php/ToSC/article/view/9850) suggests that this configuration may have around 95 bits of security, falling a bit short of our 100 bit target. + diff --git a/evm/Cargo.toml b/evm/Cargo.toml index cdb8b5d6..5b48f524 100644 --- a/evm/Cargo.toml +++ b/evm/Cargo.toml @@ -28,10 +28,11 @@ rlp = "0.5.1" rlp-derive = "0.1.0" serde = { version = "1.0.144", features = ["derive"] } sha2 = "0.10.2" +static_assertions = "1.1.0" tiny-keccak = "2.0.2" [dev-dependencies] -criterion = "0.3.5" +criterion = "0.4.0" hex = "0.4.3" [features] diff --git a/evm/src/arithmetic/columns.rs b/evm/src/arithmetic/columns.rs index 10bf72d9..923fbc73 100644 --- a/evm/src/arithmetic/columns.rs +++ b/evm/src/arithmetic/columns.rs @@ -22,25 +22,20 @@ pub const IS_ADD: usize = 0; pub const IS_MUL: usize = IS_ADD + 1; pub const IS_SUB: usize = IS_MUL + 1; pub const IS_DIV: usize = IS_SUB + 1; -pub const IS_SDIV: usize = IS_DIV + 1; -pub const IS_MOD: usize = IS_SDIV + 1; -pub const IS_SMOD: usize = IS_MOD + 1; -pub const IS_ADDMOD: usize = IS_SMOD + 1; +pub const IS_MOD: usize = IS_DIV + 1; +pub const IS_ADDMOD: usize = IS_MOD + 1; pub const IS_SUBMOD: usize = IS_ADDMOD + 1; pub const IS_MULMOD: usize = IS_SUBMOD + 1; pub const IS_LT: usize = IS_MULMOD + 1; pub const IS_GT: usize = IS_LT + 1; -pub const IS_SLT: usize = IS_GT + 1; -pub const IS_SGT: usize = IS_SLT + 1; -pub const IS_SHL: usize = IS_SGT + 1; +pub const IS_SHL: usize = IS_GT + 1; pub const IS_SHR: usize = IS_SHL + 1; -pub const IS_SAR: usize = IS_SHR + 1; -const START_SHARED_COLS: usize = IS_SAR + 1; +const START_SHARED_COLS: usize = IS_SHR + 1; -pub(crate) const ALL_OPERATIONS: [usize; 17] = [ - IS_ADD, IS_MUL, IS_SUB, IS_DIV, IS_SDIV, IS_MOD, IS_SMOD, IS_ADDMOD, IS_SUBMOD, IS_MULMOD, - IS_LT, IS_GT, IS_SLT, IS_SGT, IS_SHL, IS_SHR, IS_SAR, +pub(crate) const ALL_OPERATIONS: [usize; 12] = [ + IS_ADD, IS_MUL, IS_SUB, IS_DIV, IS_MOD, IS_ADDMOD, IS_SUBMOD, IS_MULMOD, IS_LT, IS_GT, IS_SHL, + IS_SHR, ]; /// Within the Arithmetic Unit, there are shared columns which can be diff --git a/evm/src/arithmetic/compare.rs b/evm/src/arithmetic/compare.rs index 55dc5764..a9dd785d 100644 --- a/evm/src/arithmetic/compare.rs +++ b/evm/src/arithmetic/compare.rs @@ -35,8 +35,6 @@ pub(crate) fn generate(lv: &mut [F; NUM_ARITH_COLUMNS], op: usize) IS_LT => u256_sub_br(input0, input1), // input1 - input0 == diff + br*2^256 IS_GT => u256_sub_br(input1, input0), - IS_SLT => todo!(), - IS_SGT => todo!(), _ => panic!("op code not a comparison"), }; diff --git a/evm/src/arithmetic/utils.rs b/evm/src/arithmetic/utils.rs index 74999ab4..ec989c94 100644 --- a/evm/src/arithmetic/utils.rs +++ b/evm/src/arithmetic/utils.rs @@ -1,6 +1,5 @@ use std::ops::{Add, AddAssign, Mul, Neg, Range, Shr, Sub, SubAssign}; -use log::error; use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; @@ -11,21 +10,24 @@ use crate::arithmetic::columns::{NUM_ARITH_COLUMNS, N_LIMBS}; /// Emit an error message regarding unchecked range assumptions. /// Assumes the values in `cols` are `[cols[0], cols[0] + 1, ..., /// cols[0] + cols.len() - 1]`. +/// +/// TODO: Hamish to delete this when he has implemented and integrated +/// range checks. pub(crate) fn _range_check_error( - file: &str, - line: u32, - cols: Range, - signedness: &str, + _file: &str, + _line: u32, + _cols: Range, + _signedness: &str, ) { - error!( - "{}:{}: arithmetic unit skipped {}-bit {} range-checks on columns {}--{}: not yet implemented", - line, - file, - RC_BITS, - signedness, - cols.start, - cols.end - 1, - ); + // error!( + // "{}:{}: arithmetic unit skipped {}-bit {} range-checks on columns {}--{}: not yet implemented", + // line, + // file, + // RC_BITS, + // signedness, + // cols.start, + // cols.end - 1, + // ); } #[macro_export] diff --git a/evm/src/cpu/columns/general.rs b/evm/src/cpu/columns/general.rs index 134788dc..5a2c9426 100644 --- a/evm/src/cpu/columns/general.rs +++ b/evm/src/cpu/columns/general.rs @@ -9,6 +9,7 @@ pub(crate) union CpuGeneralColumnsView { arithmetic: CpuArithmeticView, logic: CpuLogicView, jumps: CpuJumpsView, + shift: CpuShiftView, } impl CpuGeneralColumnsView { @@ -51,6 +52,16 @@ impl CpuGeneralColumnsView { pub(crate) fn jumps_mut(&mut self) -> &mut CpuJumpsView { unsafe { &mut self.jumps } } + + // SAFETY: Each view is a valid interpretation of the underlying array. + pub(crate) fn shift(&self) -> &CpuShiftView { + unsafe { &self.shift } + } + + // SAFETY: Each view is a valid interpretation of the underlying array. + pub(crate) fn shift_mut(&mut self) -> &mut CpuShiftView { + unsafe { &mut self.shift } + } } impl PartialEq for CpuGeneralColumnsView { @@ -144,5 +155,12 @@ pub(crate) struct CpuJumpsView { pub(crate) should_trap: T, } +#[derive(Copy, Clone)] +pub(crate) struct CpuShiftView { + // For a shift amount of displacement: [T], this is the inverse of + // sum(displacement[1..]) or zero if the sum is zero. + pub(crate) high_limb_sum_inv: T, +} + // `u8` is guaranteed to have a `size_of` of 1. pub const NUM_SHARED_COLUMNS: usize = size_of::>(); diff --git a/evm/src/cpu/columns/ops.rs b/evm/src/cpu/columns/ops.rs index 04d4d0f2..c265be44 100644 --- a/evm/src/cpu/columns/ops.rs +++ b/evm/src/cpu/columns/ops.rs @@ -7,106 +7,59 @@ use crate::util::{indices_arr, transmute_no_compile_time_size_checks}; #[repr(C)] #[derive(Eq, PartialEq, Debug)] pub struct OpsColumnsView { - pub stop: T, + // TODO: combine ADD, MUL, SUB, DIV, MOD, ADDFP254, MULFP254, SUBFP254, LT, and GT into one flag pub add: T, pub mul: T, pub sub: T, pub div: T, - pub sdiv: T, pub mod_: T, - pub smod: T, + // TODO: combine ADDMOD, MULMOD into one flag pub addmod: T, pub mulmod: T, - pub exp: T, - pub signextend: T, pub addfp254: T, pub mulfp254: T, pub subfp254: T, pub lt: T, pub gt: T, - pub slt: T, - pub sgt: T, pub eq: T, // Note: This column must be 0 when is_cpu_cycle = 0. pub iszero: T, // Note: This column must be 0 when is_cpu_cycle = 0. + // TODO: combine AND, OR, and XOR into one flag pub and: T, pub or: T, pub xor: T, pub not: T, pub byte: T, + // TODO: combine SHL and SHR into one flag pub shl: T, pub shr: T, - pub sar: T, - pub keccak256: T, pub keccak_general: T, - pub address: T, - pub balance: T, - pub origin: T, - pub caller: T, - pub callvalue: T, - pub calldataload: T, - pub calldatasize: T, - pub calldatacopy: T, - pub codesize: T, - pub codecopy: T, - pub gasprice: T, - pub extcodesize: T, - pub extcodecopy: T, - pub returndatasize: T, - pub returndatacopy: T, - pub extcodehash: T, - pub blockhash: T, - pub coinbase: T, - pub timestamp: T, - pub number: T, - pub difficulty: T, - pub gaslimit: T, - pub chainid: T, - pub selfbalance: T, - pub basefee: T, pub prover_input: T, pub pop: T, - pub mload: T, - pub mstore: T, - pub mstore8: T, - pub sload: T, - pub sstore: T, + // TODO: combine JUMP and JUMPI into one flag pub jump: T, // Note: This column must be 0 when is_cpu_cycle = 0. pub jumpi: T, // Note: This column must be 0 when is_cpu_cycle = 0. pub pc: T, - pub msize: T, pub gas: T, pub jumpdest: T, + // TODO: combine GET_STATE_ROOT and SET_STATE_ROOT into one flag pub get_state_root: T, pub set_state_root: T, + // TODO: combine GET_RECEIPT_ROOT and SET_RECEIPT_ROOT into one flag pub get_receipt_root: T, pub set_receipt_root: T, pub push: T, pub dup: T, pub swap: T, - pub log0: T, - pub log1: T, - pub log2: T, - pub log3: T, - pub log4: T, - // PANIC does not get a flag; it fails at the decode stage. - pub create: T, - pub call: T, - pub callcode: T, - pub return_: T, - pub delegatecall: T, - pub create2: T, + // TODO: combine GET_CONTEXT and SET_CONTEXT into one flag pub get_context: T, pub set_context: T, pub consume_gas: T, pub exit_kernel: T, - pub staticcall: T, + // TODO: combine MLOAD_GENERAL and MSTORE_GENERAL into one flag pub mload_general: T, pub mstore_general: T, - pub revert: T, - pub selfdestruct: T, - // TODO: this doesn't actually need its own flag. We can just do `1 - sum(all other flags)`. - pub invalid: T, + pub syscall: T, } // `u8` is guaranteed to have a `size_of` of 1. diff --git a/evm/src/cpu/control_flow.rs b/evm/src/cpu/control_flow.rs index c7b7c6bb..ba0bbd3b 100644 --- a/evm/src/cpu/control_flow.rs +++ b/evm/src/cpu/control_flow.rs @@ -8,36 +8,49 @@ use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer use crate::cpu::columns::{CpuColumnsView, COL_MAP}; use crate::cpu::kernel::aggregator::KERNEL; -// TODO: This list is incomplete. -const NATIVE_INSTRUCTIONS: [usize; 28] = [ +const NATIVE_INSTRUCTIONS: [usize; 37] = [ COL_MAP.op.add, COL_MAP.op.mul, COL_MAP.op.sub, COL_MAP.op.div, - COL_MAP.op.sdiv, COL_MAP.op.mod_, - COL_MAP.op.smod, COL_MAP.op.addmod, COL_MAP.op.mulmod, - COL_MAP.op.signextend, COL_MAP.op.addfp254, COL_MAP.op.mulfp254, COL_MAP.op.subfp254, COL_MAP.op.lt, COL_MAP.op.gt, - COL_MAP.op.slt, - COL_MAP.op.sgt, COL_MAP.op.eq, COL_MAP.op.iszero, COL_MAP.op.and, COL_MAP.op.or, COL_MAP.op.xor, COL_MAP.op.not, - COL_MAP.op.byte, COL_MAP.op.shl, COL_MAP.op.shr, - COL_MAP.op.sar, + COL_MAP.op.keccak_general, + COL_MAP.op.prover_input, COL_MAP.op.pop, + // not JUMP (need to jump) + // not JUMPI (possible need to jump) + COL_MAP.op.pc, + COL_MAP.op.gas, + COL_MAP.op.jumpdest, + COL_MAP.op.get_state_root, + COL_MAP.op.set_state_root, + COL_MAP.op.get_receipt_root, + COL_MAP.op.set_receipt_root, + // not PUSH (need to increment by more than 1) + COL_MAP.op.dup, + COL_MAP.op.swap, + COL_MAP.op.get_context, + COL_MAP.op.set_context, + COL_MAP.op.consume_gas, + // not EXIT_KERNEL (performs a jump) + COL_MAP.op.mload_general, + COL_MAP.op.mstore_general, + // not SYSCALL (performs a jump) ]; fn get_halt_pcs() -> (F, F) { diff --git a/evm/src/cpu/cpu_stark.rs b/evm/src/cpu/cpu_stark.rs index 7b34cc4f..4cc38823 100644 --- a/evm/src/cpu/cpu_stark.rs +++ b/evm/src/cpu/cpu_stark.rs @@ -11,8 +11,8 @@ use plonky2::hash::hash_types::RichField; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::cpu::columns::{CpuColumnsView, COL_MAP, NUM_CPU_COLUMNS}; use crate::cpu::{ - bootstrap_kernel, control_flow, decode, dup_swap, jumps, membus, modfp254, simple_logic, stack, - stack_bounds, syscalls, + bootstrap_kernel, control_flow, decode, dup_swap, jumps, membus, modfp254, shift, simple_logic, + stack, stack_bounds, syscalls, }; use crate::cross_table_lookup::Column; use crate::memory::segments::Segment; @@ -151,6 +151,7 @@ impl, const D: usize> Stark for CpuStark, const D: usize> Stark for CpuStark(lv: &mut CpuColumnsView) { assert!(kernel <= 1); let kernel = kernel != 0; - let mut any_flag_set = false; for (oc, block_length, kernel_only, col) in OPCODES { let available = !kernel_only || kernel; let opcode_match = top_bits[8 - block_length] == oc; let flag = available && opcode_match; lv[col] = F::from_bool(flag); - if flag && any_flag_set { - panic!("opcode matched multiple flags"); - } - any_flag_set = any_flag_set || flag; } - // is_invalid is a catch-all for opcodes we can't decode. - lv.op.invalid = F::from_bool(!any_flag_set); } /// Break up an opcode (which is 8 bits long) into its eight bits. @@ -238,14 +176,12 @@ pub fn eval_packed_generic( let flag = lv[flag_col]; yield_constr.constraint(cycle_filter * flag * (flag - P::ONES)); } - yield_constr.constraint(cycle_filter * lv.op.invalid * (lv.op.invalid - P::ONES)); - // Now check that exactly one is 1. + // Now check that they sum to 0 or 1. let flag_sum: P = OPCODES .into_iter() .map(|(_, _, _, flag_col)| lv[flag_col]) - .sum::

() - + lv.op.invalid; - yield_constr.constraint(cycle_filter * (P::ONES - flag_sum)); + .sum::

(); + yield_constr.constraint(cycle_filter * flag_sum * (flag_sum - P::ONES)); // Finally, classify all opcodes, together with the kernel flag, into blocks for (oc, block_length, kernel_only, col) in OPCODES { @@ -308,20 +244,15 @@ pub fn eval_ext_circuit, const D: usize>( let constr = builder.mul_extension(cycle_filter, constr); yield_constr.constraint(builder, constr); } + // Now check that they sum to 0 or 1. { - let constr = builder.mul_sub_extension(lv.op.invalid, lv.op.invalid, lv.op.invalid); - let constr = builder.mul_extension(cycle_filter, constr); - yield_constr.constraint(builder, constr); - } - // Now check that exactly one is 1. - { - let mut constr = builder.one_extension(); + let mut flag_sum = builder.zero_extension(); for (_, _, _, flag_col) in OPCODES { let flag = lv[flag_col]; - constr = builder.sub_extension(constr, flag); + flag_sum = builder.add_extension(flag_sum, flag); } - constr = builder.sub_extension(constr, lv.op.invalid); - constr = builder.mul_extension(cycle_filter, constr); + let constr = builder.mul_sub_extension(flag_sum, flag_sum, flag_sum); + let constr = builder.mul_extension(cycle_filter, constr); yield_constr.constraint(builder, constr); } diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 49398288..9ccfcd15 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -18,6 +18,8 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/core/invalid.asm"), include_str!("asm/core/nonce.asm"), include_str!("asm/core/process_txn.asm"), + include_str!("asm/core/syscall.asm"), + include_str!("asm/core/syscall_stubs.asm"), include_str!("asm/core/terminate.asm"), include_str!("asm/core/transfer.asm"), include_str!("asm/core/util.asm"), @@ -75,6 +77,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/sha2/store_pad.asm"), include_str!("asm/sha2/temp_words.asm"), include_str!("asm/sha2/write_length.asm"), + include_str!("asm/shift.asm"), include_str!("asm/transactions/router.asm"), include_str!("asm/transactions/type_0.asm"), include_str!("asm/transactions/type_1.asm"), diff --git a/evm/src/cpu/kernel/asm/core/syscall.asm b/evm/src/cpu/kernel/asm/core/syscall.asm new file mode 100644 index 00000000..2de50993 --- /dev/null +++ b/evm/src/cpu/kernel/asm/core/syscall.asm @@ -0,0 +1,160 @@ +global syscall_jumptable: + // 0x00-0x0f + JUMPTABLE sys_stop + JUMPTABLE panic // add is implemented natively + JUMPTABLE panic // mul is implemented natively + JUMPTABLE panic // sub is implemented natively + JUMPTABLE panic // div is implemented natively + JUMPTABLE sys_sdiv + JUMPTABLE panic // mod is implemented natively + JUMPTABLE sys_smod + JUMPTABLE panic // addmod is implemented natively + JUMPTABLE panic // mulmod is implemented natively + JUMPTABLE sys_exp + JUMPTABLE sys_signextend + JUMPTABLE panic // 0x0c is an invalid opcode + JUMPTABLE panic // 0x0d is an invalid opcode + JUMPTABLE panic // 0x0e is an invalid opcode + JUMPTABLE panic // 0x0f is an invalid opcode + + // 0x10-0x1f + JUMPTABLE panic // lt is implemented natively + JUMPTABLE panic // gt is implemented natively + JUMPTABLE sys_slt + JUMPTABLE sys_sgt + JUMPTABLE panic // eq is implemented natively + JUMPTABLE panic // iszero is implemented natively + JUMPTABLE panic // and is implemented natively + JUMPTABLE panic // or is implemented natively + JUMPTABLE panic // xor is implemented natively + JUMPTABLE panic // not is implemented natively + JUMPTABLE panic // byte is implemented natively + JUMPTABLE panic // shl is implemented natively + JUMPTABLE panic // shr is implemented natively + JUMPTABLE sys_sar + JUMPTABLE panic // 0x1e is an invalid opcode + JUMPTABLE panic // 0x1f is an invalid opcode + + // 0x20-0x2f + JUMPTABLE sys_keccak256 + %rep 15 + JUMPTABLE panic // 0x21-0x2f are invalid opcodes + %endrep + + // 0x30-0x3f + JUMPTABLE sys_address + JUMPTABLE sys_balance + JUMPTABLE sys_origin + JUMPTABLE sys_caller + JUMPTABLE sys_callvalue + JUMPTABLE sys_calldataload + JUMPTABLE sys_calldatasize + JUMPTABLE sys_calldatacopy + JUMPTABLE sys_codesize + JUMPTABLE sys_codecopy + JUMPTABLE sys_gasprice + JUMPTABLE sys_extcodesize + JUMPTABLE sys_extcodecopy + JUMPTABLE sys_returndatasize + JUMPTABLE sys_returndatacopy + JUMPTABLE sys_extcodehash + + // 0x40-0x4f + JUMPTABLE sys_blockhash + JUMPTABLE sys_coinbase + JUMPTABLE sys_timestamp + JUMPTABLE sys_number + JUMPTABLE sys_prevrandao + JUMPTABLE sys_gaslimit + JUMPTABLE sys_chainid + JUMPTABLE sys_selfbalance + JUMPTABLE sys_basefee + %rep 7 + JUMPTABLE panic // 0x49-0x4f are invalid opcodes + %endrep + + // 0x50-0x5f + JUMPTABLE panic // pop is implemented natively + JUMPTABLE sys_mload + JUMPTABLE sys_mstore + JUMPTABLE sys_mstore8 + JUMPTABLE sys_sload + JUMPTABLE sys_sstore + JUMPTABLE panic // jump is implemented natively + JUMPTABLE panic // jumpi is implemented natively + JUMPTABLE panic // pc is implemented natively + JUMPTABLE sys_msize + JUMPTABLE panic // gas is implemented natively + JUMPTABLE panic // jumpdest is implemented natively + JUMPTABLE panic // 0x5c is an invalid opcode + JUMPTABLE panic // 0x5d is an invalid opcode + JUMPTABLE panic // 0x5e is an invalid opcode + JUMPTABLE panic // 0x5f is an invalid opcode + + // 0x60-0x6f + %rep 16 + JUMPTABLE panic // push1-push16 are implemented natively + %endrep + + // 0x70-0x7f + %rep 16 + JUMPTABLE panic // push17-push32 are implemented natively + %endrep + + // 0x80-0x8f + %rep 16 + JUMPTABLE panic // dup1-dup16 are implemented natively + %endrep + + // 0x90-0x9f + %rep 16 + JUMPTABLE panic // swap1-swap16 are implemented natively + %endrep + + // 0xa0-0xaf + JUMPTABLE sys_log0 + JUMPTABLE sys_log1 + JUMPTABLE sys_log2 + JUMPTABLE sys_log3 + JUMPTABLE sys_log4 + %rep 11 + JUMPTABLE panic // 0xa5-0xaf are invalid opcodes + %endrep + + // 0xb0-0xbf + %rep 16 + JUMPTABLE panic // 0xb0-0xbf are invalid opcodes + %endrep + + // 0xc0-0xcf + %rep 16 + JUMPTABLE panic // 0xc0-0xcf are invalid opcodes + %endrep + + // 0xd0-0xdf + %rep 16 + JUMPTABLE panic // 0xd0-0xdf are invalid opcodes + %endrep + + // 0xe0-0xef + %rep 16 + JUMPTABLE panic // 0xe0-0xef are invalid opcodes + %endrep + + // 0xf0-0xff + JUMPTABLE sys_create + JUMPTABLE sys_call + JUMPTABLE sys_callcode + JUMPTABLE sys_return + JUMPTABLE sys_delegatecall + JUMPTABLE sys_create2 + JUMPTABLE panic // 0xf6 is an invalid opcode + JUMPTABLE panic // 0xf7 is an invalid opcode + JUMPTABLE panic // 0xf8 is an invalid opcode + JUMPTABLE panic // 0xf9 is an invalid opcode + JUMPTABLE sys_staticcall + JUMPTABLE panic // 0xfb is an invalid opcode + JUMPTABLE panic // 0xfc is an invalid opcode + JUMPTABLE sys_revert + JUMPTABLE panic // 0xfe is an invalid opcode + JUMPTABLE sys_selfdestruct diff --git a/evm/src/cpu/kernel/asm/core/syscall_stubs.asm b/evm/src/cpu/kernel/asm/core/syscall_stubs.asm new file mode 100644 index 00000000..d39d8145 --- /dev/null +++ b/evm/src/cpu/kernel/asm/core/syscall_stubs.asm @@ -0,0 +1,53 @@ +// Labels for unimplemented syscalls to make the kernel assemble. +// Each label should be removed from this file once it is implemented. + +global sys_sdiv: +global sys_smod: +global sys_signextend: +global sys_slt: +global sys_sgt: +global sys_sar: +global sys_keccak256: +global sys_address: +global sys_balance: +global sys_origin: +global sys_caller: +global sys_callvalue: +global sys_calldataload: +global sys_calldatasize: +global sys_calldatacopy: +global sys_codesize: +global sys_codecopy: +global sys_gasprice: +global sys_extcodesize: +global sys_extcodecopy: +global sys_returndatasize: +global sys_returndatacopy: +global sys_extcodehash: +global sys_blockhash: +global sys_coinbase: +global sys_timestamp: +global sys_number: +global sys_prevrandao: +global sys_gaslimit: +global sys_chainid: +global sys_selfbalance: +global sys_basefee: +global sys_mload: +global sys_mstore: +global sys_mstore8: +global sys_sload: +global sys_sstore: +global sys_msize: +global sys_log0: +global sys_log1: +global sys_log2: +global sys_log3: +global sys_log4: +global sys_create: +global sys_call: +global sys_callcode: +global sys_delegatecall: +global sys_create2: +global sys_staticcall: + PANIC diff --git a/evm/src/cpu/kernel/asm/main.asm b/evm/src/cpu/kernel/asm/main.asm index e8c8e3e4..41cb8079 100644 --- a/evm/src/cpu/kernel/asm/main.asm +++ b/evm/src/cpu/kernel/asm/main.asm @@ -1,5 +1,7 @@ global main: - // First, load all MPT data from the prover. + // First, initialise the shift table + %shift_table_init + // Second, load all MPT data from the prover. PUSH txn_loop %jump(load_all_mpts) diff --git a/evm/src/cpu/kernel/asm/shift.asm b/evm/src/cpu/kernel/asm/shift.asm new file mode 100644 index 00000000..ce481ea2 --- /dev/null +++ b/evm/src/cpu/kernel/asm/shift.asm @@ -0,0 +1,25 @@ +/// Initialise the lookup table of binary powers for doing left/right shifts +/// +/// Specifically, set SHIFT_TABLE_SEGMENT[i] = 2^i for i = 0..255. +%macro shift_table_init + push 1 // 2^0 + push 0 // initial offset is zero + push @SEGMENT_SHIFT_TABLE // segment + dup2 // kernel context is 0 + %rep 255 + // stack: context, segment, ost_i, 2^i + dup4 + dup1 + add + // stack: 2^(i+1), context, segment, ost_i, 2^i + dup4 + %increment + // stack: ost_(i+1), 2^(i+1), context, segment, ost_i, 2^i + dup4 + dup4 + // stack: context, segment, ost_(i+1), 2^(i+1), context, segment, ost_i, 2^i + %endrep + %rep 256 + mstore_general + %endrep +%endmacro diff --git a/evm/src/cpu/kernel/assembler.rs b/evm/src/cpu/kernel/assembler.rs index aad2dd53..5f9584ba 100644 --- a/evm/src/cpu/kernel/assembler.rs +++ b/evm/src/cpu/kernel/assembler.rs @@ -300,11 +300,29 @@ fn find_labels( } Item::StandardOp(_) => *offset += 1, Item::Bytes(bytes) => *offset += bytes.len(), + Item::Jumptable(labels) => *offset += labels.len() * (BYTES_PER_OFFSET as usize), } } local_labels } +fn look_up_label( + label: &String, + local_labels: &HashMap, + global_labels: &HashMap, +) -> Vec { + let offset = local_labels + .get(label) + .or_else(|| global_labels.get(label)) + .unwrap_or_else(|| panic!("No such label: {label}")); + // We want the BYTES_PER_OFFSET least significant bytes in BE order. + // It's easiest to rev the first BYTES_PER_OFFSET bytes of the LE encoding. + (0..BYTES_PER_OFFSET) + .rev() + .map(|i| offset.to_le_bytes()[i as usize]) + .collect() +} + fn assemble_file( body: Vec, code: &mut Vec, @@ -327,18 +345,7 @@ fn assemble_file( Item::Push(target) => { let target_bytes: Vec = match target { PushTarget::Literal(n) => u256_to_trimmed_be_bytes(&n), - PushTarget::Label(label) => { - let offset = local_labels - .get(&label) - .or_else(|| global_labels.get(&label)) - .unwrap_or_else(|| panic!("No such label: {label}")); - // We want the BYTES_PER_OFFSET least significant bytes in BE order. - // It's easiest to rev the first BYTES_PER_OFFSET bytes of the LE encoding. - (0..BYTES_PER_OFFSET) - .rev() - .map(|i| offset.to_le_bytes()[i as usize]) - .collect() - } + PushTarget::Label(label) => look_up_label(&label, &local_labels, global_labels), PushTarget::MacroLabel(v) => panic!("Macro label not in a macro: {v}"), PushTarget::MacroVar(v) => panic!("Variable not in a macro: {v}"), PushTarget::Constant(c) => panic!("Constant wasn't inlined: {c}"), @@ -353,6 +360,12 @@ fn assemble_file( code.push(get_opcode(&opcode)); } Item::Bytes(bytes) => code.extend(bytes), + Item::Jumptable(labels) => { + for label in labels { + let bytes = look_up_label(&label, &local_labels, global_labels); + code.extend(bytes); + } + } } } } diff --git a/evm/src/cpu/kernel/ast.rs b/evm/src/cpu/kernel/ast.rs index 6180b1c8..ed4f6dbb 100644 --- a/evm/src/cpu/kernel/ast.rs +++ b/evm/src/cpu/kernel/ast.rs @@ -34,6 +34,8 @@ pub(crate) enum Item { StandardOp(String), /// Literal hex data; should contain an even number of hex chars. Bytes(Vec), + /// Creates a table of addresses from a list of labels. + Jumptable(Vec), } /// The left hand side of a %stack stack-manipulation macro. diff --git a/evm/src/cpu/kernel/evm_asm.pest b/evm/src/cpu/kernel/evm_asm.pest index 9b8721f4..e7337430 100644 --- a/evm/src/cpu/kernel/evm_asm.pest +++ b/evm/src/cpu/kernel/evm_asm.pest @@ -15,7 +15,7 @@ literal = { literal_hex | literal_decimal } variable = ${ "$" ~ identifier } constant = ${ "@" ~ identifier } -item = { macro_def | macro_call | repeat | stack | global_label_decl | local_label_decl | macro_label_decl | bytes_item | push_instruction | prover_input_instruction | nullary_instruction } +item = { macro_def | macro_call | repeat | stack | global_label_decl | local_label_decl | macro_label_decl | bytes_item | jumptable_item | push_instruction | prover_input_instruction | nullary_instruction } macro_def = { ^"%macro" ~ identifier ~ paramlist? ~ item* ~ ^"%endmacro" } macro_call = ${ "%" ~ !((^"macro" | ^"endmacro" | ^"rep" | ^"endrep" | ^"stack") ~ !identifier_char) ~ identifier ~ macro_arglist? } repeat = { ^"%rep" ~ literal ~ item* ~ ^"%endrep" } @@ -35,6 +35,7 @@ macro_label_decl = ${ "%%" ~ identifier ~ ":" } macro_label = ${ "%%" ~ identifier } bytes_item = { ^"BYTES " ~ literal ~ ("," ~ literal)* } +jumptable_item = { ^"JUMPTABLE " ~ identifier ~ ("," ~ identifier)* } push_instruction = { ^"PUSH " ~ push_target } push_target = { literal | identifier | macro_label | variable | constant } prover_input_instruction = { ^"PROVER_INPUT" ~ "(" ~ prover_input_fn ~ ")" } diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 82bd382b..6e3f9e5d 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -8,7 +8,6 @@ use keccak_hash::keccak; use plonky2::field::goldilocks_field::GoldilocksField; use crate::cpu::kernel::aggregator::KERNEL; -use crate::cpu::kernel::assembler::Kernel; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::constants::txn_fields::NormalizedTxnField; @@ -78,19 +77,18 @@ pub struct Interpreter<'a> { pub(crate) halt_offsets: Vec, pub(crate) debug_offsets: Vec, running: bool, + opcode_count: [usize; 0x100], } -pub fn run_with_kernel( - // TODO: Remove param and just use KERNEL. - kernel: &Kernel, +pub fn run_interpreter( initial_offset: usize, initial_stack: Vec, -) -> anyhow::Result { +) -> anyhow::Result> { run( - &kernel.code, + &KERNEL.code, initial_offset, initial_stack, - &kernel.prover_inputs, + &KERNEL.prover_inputs, ) } @@ -132,6 +130,7 @@ impl<'a> Interpreter<'a> { halt_offsets: vec![DEFAULT_HALT_OFFSET], debug_offsets: vec![], running: false, + opcode_count: [0; 0x100], } } @@ -140,6 +139,12 @@ impl<'a> Interpreter<'a> { while self.running { self.run_opcode()?; } + println!("Opcode count:"); + for i in 0..0x100 { + if self.opcode_count[i] > 0 { + println!("{}: {}", get_mnemonic(i as u8), self.opcode_count[i]) + } + } Ok(()) } @@ -223,6 +228,7 @@ impl<'a> Interpreter<'a> { fn run_opcode(&mut self) -> anyhow::Result<()> { let opcode = self.code().get(self.offset).byte(0); + self.opcode_count[opcode as usize] += 1; self.incr(1); match opcode { 0x00 => self.run_stop(), // "STOP", @@ -690,6 +696,170 @@ fn find_jumpdests(code: &[u8]) -> Vec { res } +fn get_mnemonic(opcode: u8) -> &'static str { + match opcode { + 0x00 => "STOP", + 0x01 => "ADD", + 0x02 => "MUL", + 0x03 => "SUB", + 0x04 => "DIV", + 0x05 => "SDIV", + 0x06 => "MOD", + 0x07 => "SMOD", + 0x08 => "ADDMOD", + 0x09 => "MULMOD", + 0x0a => "EXP", + 0x0b => "SIGNEXTEND", + 0x0c => "ADDFP254", + 0x0d => "MULFP254", + 0x0e => "SUBFP254", + 0x10 => "LT", + 0x11 => "GT", + 0x12 => "SLT", + 0x13 => "SGT", + 0x14 => "EQ", + 0x15 => "ISZERO", + 0x16 => "AND", + 0x17 => "OR", + 0x18 => "XOR", + 0x19 => "NOT", + 0x1a => "BYTE", + 0x1b => "SHL", + 0x1c => "SHR", + 0x1d => "SAR", + 0x20 => "KECCAK256", + 0x21 => "KECCAK_GENERAL", + 0x30 => "ADDRESS", + 0x31 => "BALANCE", + 0x32 => "ORIGIN", + 0x33 => "CALLER", + 0x34 => "CALLVALUE", + 0x35 => "CALLDATALOAD", + 0x36 => "CALLDATASIZE", + 0x37 => "CALLDATACOPY", + 0x38 => "CODESIZE", + 0x39 => "CODECOPY", + 0x3a => "GASPRICE", + 0x3b => "EXTCODESIZE", + 0x3c => "EXTCODECOPY", + 0x3d => "RETURNDATASIZE", + 0x3e => "RETURNDATACOPY", + 0x3f => "EXTCODEHASH", + 0x40 => "BLOCKHASH", + 0x41 => "COINBASE", + 0x42 => "TIMESTAMP", + 0x43 => "NUMBER", + 0x44 => "DIFFICULTY", + 0x45 => "GASLIMIT", + 0x46 => "CHAINID", + 0x48 => "BASEFEE", + 0x49 => "PROVER_INPUT", + 0x50 => "POP", + 0x51 => "MLOAD", + 0x52 => "MSTORE", + 0x53 => "MSTORE8", + 0x54 => "SLOAD", + 0x55 => "SSTORE", + 0x56 => "JUMP", + 0x57 => "JUMPI", + 0x58 => "GETPC", + 0x59 => "MSIZE", + 0x5a => "GAS", + 0x5b => "JUMPDEST", + 0x5c => "GET_STATE_ROOT", + 0x5d => "SET_STATE_ROOT", + 0x5e => "GET_RECEIPT_ROOT", + 0x5f => "SET_RECEIPT_ROOT", + 0x60 => "PUSH1", + 0x61 => "PUSH2", + 0x62 => "PUSH3", + 0x63 => "PUSH4", + 0x64 => "PUSH5", + 0x65 => "PUSH6", + 0x66 => "PUSH7", + 0x67 => "PUSH8", + 0x68 => "PUSH9", + 0x69 => "PUSH10", + 0x6a => "PUSH11", + 0x6b => "PUSH12", + 0x6c => "PUSH13", + 0x6d => "PUSH14", + 0x6e => "PUSH15", + 0x6f => "PUSH16", + 0x70 => "PUSH17", + 0x71 => "PUSH18", + 0x72 => "PUSH19", + 0x73 => "PUSH20", + 0x74 => "PUSH21", + 0x75 => "PUSH22", + 0x76 => "PUSH23", + 0x77 => "PUSH24", + 0x78 => "PUSH25", + 0x79 => "PUSH26", + 0x7a => "PUSH27", + 0x7b => "PUSH28", + 0x7c => "PUSH29", + 0x7d => "PUSH30", + 0x7e => "PUSH31", + 0x7f => "PUSH32", + 0x80 => "DUP1", + 0x81 => "DUP2", + 0x82 => "DUP3", + 0x83 => "DUP4", + 0x84 => "DUP5", + 0x85 => "DUP6", + 0x86 => "DUP7", + 0x87 => "DUP8", + 0x88 => "DUP9", + 0x89 => "DUP10", + 0x8a => "DUP11", + 0x8b => "DUP12", + 0x8c => "DUP13", + 0x8d => "DUP14", + 0x8e => "DUP15", + 0x8f => "DUP16", + 0x90 => "SWAP1", + 0x91 => "SWAP2", + 0x92 => "SWAP3", + 0x93 => "SWAP4", + 0x94 => "SWAP5", + 0x95 => "SWAP6", + 0x96 => "SWAP7", + 0x97 => "SWAP8", + 0x98 => "SWAP9", + 0x99 => "SWAP10", + 0x9a => "SWAP11", + 0x9b => "SWAP12", + 0x9c => "SWAP13", + 0x9d => "SWAP14", + 0x9e => "SWAP15", + 0x9f => "SWAP16", + 0xa0 => "LOG0", + 0xa1 => "LOG1", + 0xa2 => "LOG2", + 0xa3 => "LOG3", + 0xa4 => "LOG4", + 0xa5 => "PANIC", + 0xf0 => "CREATE", + 0xf1 => "CALL", + 0xf2 => "CALLCODE", + 0xf3 => "RETURN", + 0xf4 => "DELEGATECALL", + 0xf5 => "CREATE2", + 0xf6 => "GET_CONTEXT", + 0xf7 => "SET_CONTEXT", + 0xf8 => "CONSUME_GAS", + 0xf9 => "EXIT_KERNEL", + 0xfa => "STATICCALL", + 0xfb => "MLOAD_GENERAL", + 0xfc => "MSTORE_GENERAL", + 0xfd => "REVERT", + 0xfe => "INVALID", + 0xff => "SELFDESTRUCT", + _ => panic!("Unrecognized opcode {opcode}"), + } +} + #[cfg(test)] mod tests { use std::collections::HashMap; diff --git a/evm/src/cpu/kernel/parser.rs b/evm/src/cpu/kernel/parser.rs index b7a8124b..49181b71 100644 --- a/evm/src/cpu/kernel/parser.rs +++ b/evm/src/cpu/kernel/parser.rs @@ -39,6 +39,9 @@ fn parse_item(item: Pair) -> Item { Item::MacroLabelDeclaration(item.into_inner().next().unwrap().as_str().into()) } Rule::bytes_item => Item::Bytes(item.into_inner().map(parse_literal_u8).collect()), + Rule::jumptable_item => { + Item::Jumptable(item.into_inner().map(|i| i.as_str().into()).collect()) + } Rule::push_instruction => Item::Push(parse_push_target(item.into_inner().next().unwrap())), Rule::prover_input_instruction => Item::ProverInput( item.into_inner() diff --git a/evm/src/cpu/kernel/tests/curve_ops.rs b/evm/src/cpu/kernel/tests/curve_ops.rs index 9ba24185..3410cee8 100644 --- a/evm/src/cpu/kernel/tests/curve_ops.rs +++ b/evm/src/cpu/kernel/tests/curve_ops.rs @@ -3,17 +3,16 @@ mod bn { use anyhow::Result; use ethereum_types::U256; - use crate::cpu::kernel::aggregator::combined_kernel; - use crate::cpu::kernel::interpreter::run_with_kernel; + use crate::cpu::kernel::aggregator::KERNEL; + use crate::cpu::kernel::interpreter::run_interpreter; use crate::cpu::kernel::tests::u256ify; #[test] fn test_ec_ops() -> Result<()> { // Make sure we can parse and assemble the entire kernel. - let kernel = combined_kernel(); - let ec_add = kernel.global_labels["ec_add"]; - let ec_double = kernel.global_labels["ec_double"]; - let ec_mul = kernel.global_labels["ec_mul"]; + let ec_add = KERNEL.global_labels["ec_add"]; + let ec_double = KERNEL.global_labels["ec_double"]; + let ec_mul = KERNEL.global_labels["ec_mul"]; let identity = ("0x0", "0x0"); let invalid = ("0x0", "0x3"); // Not on curve let point0 = ( @@ -43,110 +42,76 @@ mod bn { // Standard addition #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point1.1, point1.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point2.1, point2.0])?); // Standard addition #2 let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point2.1, point2.0])?); // Standard doubling #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point3.1, point3.0])?); // Standard doubling #2 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_double, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_double, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point3.1, point3.0])?); // Standard doubling #3 let initial_stack = u256ify(["0xdeadbeef", "0x2", point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point3.1, point3.0])?); // Addition with identity #1 let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, point1.1, point1.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point1.1, point1.0])?); // Addition with identity #2 let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, identity.1, identity.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point1.1, point1.0])?); // Addition with identity #3 let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, identity.1, identity.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([identity.1, identity.0])?); // Addition with invalid point(s) #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, invalid.1, invalid.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Addition with invalid point(s) #2 let initial_stack = u256ify(["0xdeadbeef", invalid.1, invalid.0, point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Addition with invalid point(s) #3 let initial_stack = u256ify(["0xdeadbeef", invalid.1, invalid.0, identity.1, identity.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Addition with invalid point(s) #4 let initial_stack = u256ify(["0xdeadbeef", invalid.1, invalid.0, invalid.1, invalid.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Scalar multiplication #1 let initial_stack = u256ify(["0xdeadbeef", s, point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point4.1, point4.0])?); // Scalar multiplication #2 let initial_stack = u256ify(["0xdeadbeef", "0x0", point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([identity.1, identity.0])?); // Scalar multiplication #3 let initial_stack = u256ify(["0xdeadbeef", "0x1", point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point0.1, point0.0])?); // Scalar multiplication #4 let initial_stack = u256ify(["0xdeadbeef", s, identity.1, identity.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([identity.1, identity.0])?); // Scalar multiplication #5 let initial_stack = u256ify(["0xdeadbeef", s, invalid.1, invalid.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, vec![U256::MAX, U256::MAX]); // Multiple calls @@ -160,9 +125,7 @@ mod bn { point0.1, point0.0, ])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point4.1, point4.0])?); Ok(()) @@ -174,7 +137,7 @@ mod secp { use anyhow::Result; use crate::cpu::kernel::aggregator::combined_kernel; - use crate::cpu::kernel::interpreter::{run, run_with_kernel}; + use crate::cpu::kernel::interpreter::{run, run_interpreter}; use crate::cpu::kernel::tests::u256ify; #[test] @@ -212,9 +175,7 @@ mod secp { // Standard addition #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point1.1, point1.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point2.1, point2.0])?); // Standard addition #2 let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, point0.1, point0.0])?; @@ -225,66 +186,46 @@ mod secp { // Standard doubling #1 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point3.1, point3.0])?); // Standard doubling #2 let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_double, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_double, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point3.1, point3.0])?); // Standard doubling #3 let initial_stack = u256ify(["0xdeadbeef", "0x2", point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point3.1, point3.0])?); // Addition with identity #1 let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, point1.1, point1.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point1.1, point1.0])?); // Addition with identity #2 let initial_stack = u256ify(["0xdeadbeef", point1.1, point1.0, identity.1, identity.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point1.1, point1.0])?); // Addition with identity #3 let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, identity.1, identity.0])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([identity.1, identity.0])?); // Scalar multiplication #1 let initial_stack = u256ify(["0xdeadbeef", s, point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point4.1, point4.0])?); // Scalar multiplication #2 let initial_stack = u256ify(["0xdeadbeef", "0x0", point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([identity.1, identity.0])?); // Scalar multiplication #3 let initial_stack = u256ify(["0xdeadbeef", "0x1", point0.1, point0.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point0.1, point0.0])?); // Scalar multiplication #4 let initial_stack = u256ify(["0xdeadbeef", s, identity.1, identity.0])?; - let stack = run_with_kernel(&kernel, ec_mul, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([identity.1, identity.0])?); // Multiple calls @@ -298,9 +239,7 @@ mod secp { point0.1, point0.0, ])?; - let stack = run_with_kernel(&kernel, ec_add, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec(); assert_eq!(stack, u256ify([point4.1, point4.0])?); Ok(()) diff --git a/evm/src/cpu/kernel/tests/ecrecover.rs b/evm/src/cpu/kernel/tests/ecrecover.rs index c01adc53..944c1a71 100644 --- a/evm/src/cpu/kernel/tests/ecrecover.rs +++ b/evm/src/cpu/kernel/tests/ecrecover.rs @@ -3,35 +3,23 @@ use std::str::FromStr; use anyhow::Result; use ethereum_types::U256; -use crate::cpu::kernel::aggregator::combined_kernel; -use crate::cpu::kernel::assembler::Kernel; -use crate::cpu::kernel::interpreter::run_with_kernel; +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::interpreter::run_interpreter; use crate::cpu::kernel::tests::u256ify; -fn test_valid_ecrecover( - hash: &str, - v: &str, - r: &str, - s: &str, - expected: &str, - kernel: &Kernel, -) -> Result<()> { - let ecrecover = kernel.global_labels["ecrecover"]; +fn test_valid_ecrecover(hash: &str, v: &str, r: &str, s: &str, expected: &str) -> Result<()> { + let ecrecover = KERNEL.global_labels["ecrecover"]; let initial_stack = u256ify(["0xdeadbeef", s, r, v, hash])?; - let stack = run_with_kernel(kernel, ecrecover, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ecrecover, initial_stack)?.stack().to_vec(); assert_eq!(stack[0], U256::from_str(expected).unwrap()); Ok(()) } -fn test_invalid_ecrecover(hash: &str, v: &str, r: &str, s: &str, kernel: &Kernel) -> Result<()> { - let ecrecover = kernel.global_labels["ecrecover"]; +fn test_invalid_ecrecover(hash: &str, v: &str, r: &str, s: &str) -> Result<()> { + let ecrecover = KERNEL.global_labels["ecrecover"]; let initial_stack = u256ify(["0xdeadbeef", s, r, v, hash])?; - let stack = run_with_kernel(kernel, ecrecover, initial_stack)? - .stack() - .to_vec(); + let stack = run_interpreter(ecrecover, initial_stack)?.stack().to_vec(); assert_eq!(stack, vec![U256::MAX]); Ok(()) @@ -39,15 +27,12 @@ fn test_invalid_ecrecover(hash: &str, v: &str, r: &str, s: &str, kernel: &Kernel #[test] fn test_ecrecover() -> Result<()> { - let kernel = combined_kernel(); - test_valid_ecrecover( "0x55f77e8909b1f1c9531c4a309bb2d40388e9ed4b87830c8f90363c6b36255fb9", "0x1b", "0xd667c5a20fa899b253924099e10ae92998626718585b8171eb98de468bbebc", "0x58351f48ce34bf134ee611fb5bf255a5733f0029561d345a7d46bfa344b60ac0", "0x67f3c0Da351384838d7F7641AB0fCAcF853E1844", - &kernel, )?; test_valid_ecrecover( "0x55f77e8909b1f1c9531c4a309bb2d40388e9ed4b87830c8f90363c6b36255fb9", @@ -55,7 +40,6 @@ fn test_ecrecover() -> Result<()> { "0xd667c5a20fa899b253924099e10ae92998626718585b8171eb98de468bbebc", "0x58351f48ce34bf134ee611fb5bf255a5733f0029561d345a7d46bfa344b60ac0", "0xaA58436DeABb64982a386B2De1A8015AA28fCCc0", - &kernel, )?; test_valid_ecrecover( "0x0", @@ -63,7 +47,6 @@ fn test_ecrecover() -> Result<()> { "0x1", "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", "0x3344c6f6eeCA588be132142DB0a32C71ABFAAe7B", - &kernel, )?; test_invalid_ecrecover( @@ -71,28 +54,24 @@ fn test_ecrecover() -> Result<()> { "0x42", // v not in {27,28} "0x1", "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - &kernel, )?; test_invalid_ecrecover( "0x0", "0x42", "0xd667c5a20fa899b253924099e10ae92998626718585b8171eb98de468bbebc", "0x0", // s=0 - &kernel, )?; test_invalid_ecrecover( "0x0", "0x42", "0x0", // r=0 "0xd667c5a20fa899b253924099e10ae92998626718585b8171eb98de468bbebc", - &kernel, )?; test_invalid_ecrecover( "0x0", "0x1c", "0x3a18b21408d275dde53c0ea86f9c1982eca60193db0ce15008fa408d43024847", // r^3 + 7 isn't a square "0x5db9745f44089305b2f2c980276e7025a594828d878e6e36dd2abd34ca6b9e3d", - &kernel, )?; Ok(()) diff --git a/evm/src/cpu/kernel/tests/exp.rs b/evm/src/cpu/kernel/tests/exp.rs index 25bc5ad3..1655064e 100644 --- a/evm/src/cpu/kernel/tests/exp.rs +++ b/evm/src/cpu/kernel/tests/exp.rs @@ -2,50 +2,43 @@ use anyhow::Result; use ethereum_types::U256; use rand::{thread_rng, Rng}; -use crate::cpu::kernel::aggregator::combined_kernel; -use crate::cpu::kernel::interpreter::{run, run_with_kernel}; +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::interpreter::{run, run_interpreter}; #[test] fn test_exp() -> Result<()> { // Make sure we can parse and assemble the entire kernel. - let kernel = combined_kernel(); - let exp = kernel.global_labels["exp"]; + let exp = KERNEL.global_labels["exp"]; let mut rng = thread_rng(); let a = U256([0; 4].map(|_| rng.gen())); let b = U256([0; 4].map(|_| rng.gen())); // Random input let initial_stack = vec![0xDEADBEEFu32.into(), b, a]; - let stack_with_kernel = run_with_kernel(&kernel, exp, initial_stack)? - .stack() - .to_vec(); + let stack_with_kernel = run_interpreter(exp, initial_stack)?.stack().to_vec(); let initial_stack = vec![b, a]; let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP - let stack_with_opcode = run(&code, 0, initial_stack, &kernel.prover_inputs)? + let stack_with_opcode = run(&code, 0, initial_stack, &KERNEL.prover_inputs)? .stack() .to_vec(); assert_eq!(stack_with_kernel, stack_with_opcode); // 0 base let initial_stack = vec![0xDEADBEEFu32.into(), b, U256::zero()]; - let stack_with_kernel = run_with_kernel(&kernel, exp, initial_stack)? - .stack() - .to_vec(); + let stack_with_kernel = run_interpreter(exp, initial_stack)?.stack().to_vec(); let initial_stack = vec![b, U256::zero()]; let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP - let stack_with_opcode = run(&code, 0, initial_stack, &kernel.prover_inputs)? + let stack_with_opcode = run(&code, 0, initial_stack, &KERNEL.prover_inputs)? .stack() .to_vec(); assert_eq!(stack_with_kernel, stack_with_opcode); // 0 exponent let initial_stack = vec![0xDEADBEEFu32.into(), U256::zero(), a]; - let stack_with_kernel = run_with_kernel(&kernel, exp, initial_stack)? - .stack() - .to_vec(); + let stack_with_kernel = run_interpreter(exp, initial_stack)?.stack().to_vec(); let initial_stack = vec![U256::zero(), a]; let code = [0xa, 0x63, 0xde, 0xad, 0xbe, 0xef, 0x56]; // EXP, PUSH4 deadbeef, JUMP - let stack_with_opcode = run(&code, 0, initial_stack, &kernel.prover_inputs)? + let stack_with_opcode = run(&code, 0, initial_stack, &KERNEL.prover_inputs)? .stack() .to_vec(); assert_eq!(stack_with_kernel, stack_with_opcode); diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index b8a38887..289a8598 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -2,8 +2,8 @@ use anyhow::Result; use ethereum_types::U256; use rand::{thread_rng, Rng}; -use crate::cpu::kernel::aggregator::combined_kernel; -use crate::cpu::kernel::interpreter::run_with_kernel; +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::interpreter::run_interpreter; // TODO: 107 is hardcoded as a dummy prime for testing // should be changed to the proper implementation prime @@ -137,10 +137,9 @@ fn test_fp6() -> Result<()> { let mut input: Vec = [c, d].into_iter().flatten().flatten().collect(); input.push(0xdeadbeef); - let kernel = combined_kernel(); - let initial_offset = kernel.global_labels["mul_fp6"]; + let initial_offset = KERNEL.global_labels["mul_fp6"]; let initial_stack: Vec = as_stack(input); - let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? + let final_stack: Vec = run_interpreter(initial_offset, initial_stack)? .stack() .to_vec(); diff --git a/evm/src/cpu/kernel/tests/hash.rs b/evm/src/cpu/kernel/tests/hash.rs index d6c0f74f..b7b2e5c2 100644 --- a/evm/src/cpu/kernel/tests/hash.rs +++ b/evm/src/cpu/kernel/tests/hash.rs @@ -6,8 +6,8 @@ use rand::{thread_rng, Rng}; use ripemd::{Digest, Ripemd160}; use sha2::Sha256; -use crate::cpu::kernel::aggregator::combined_kernel; -use crate::cpu::kernel::interpreter::run_with_kernel; +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::interpreter::run_interpreter; /// Standard Sha2 implementation. fn sha2(input: Vec) -> U256 { @@ -62,12 +62,11 @@ fn test_hash(hash_fn_label: &str, standard_implementation: &dyn Fn(Vec) -> U let initial_stack_custom = make_input_stack(message_custom); // Make the kernel. - let kernel = combined_kernel(); - let kernel_function = kernel.global_labels[hash_fn_label]; + let kernel_function = KERNEL.global_labels[hash_fn_label]; // Run the kernel code. - let result_random = run_with_kernel(&kernel, kernel_function, initial_stack_random)?; - let result_custom = run_with_kernel(&kernel, kernel_function, initial_stack_custom)?; + let result_random = run_interpreter(kernel_function, initial_stack_random)?; + let result_custom = run_interpreter(kernel_function, initial_stack_custom)?; // Extract the final output. let actual_random = result_random.stack()[0]; diff --git a/evm/src/cpu/kernel/tests/ripemd.rs b/evm/src/cpu/kernel/tests/ripemd.rs index 305548ec..78b05cb8 100644 --- a/evm/src/cpu/kernel/tests/ripemd.rs +++ b/evm/src/cpu/kernel/tests/ripemd.rs @@ -2,8 +2,8 @@ use anyhow::Result; use ethereum_types::U256; use itertools::Itertools; -use crate::cpu::kernel::aggregator::combined_kernel; -use crate::cpu::kernel::interpreter::run_with_kernel; +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::interpreter::run_interpreter; fn make_input(word: &str) -> Vec { let mut input: Vec = vec![word.len().try_into().unwrap()]; @@ -44,10 +44,9 @@ fn test_ripemd_reference() -> Result<()> { let input: Vec = make_input(x); let expected = U256::from(y); - let kernel = combined_kernel(); - let initial_offset = kernel.global_labels["ripemd_stack"]; + let initial_offset = KERNEL.global_labels["ripemd_stack"]; let initial_stack: Vec = input.iter().map(|&x| U256::from(x)).rev().collect(); - let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? + let final_stack: Vec = run_interpreter(initial_offset, initial_stack)? .stack() .to_vec(); let actual = final_stack[0]; diff --git a/evm/src/cpu/mod.rs b/evm/src/cpu/mod.rs index fda5db80..ece07c1c 100644 --- a/evm/src/cpu/mod.rs +++ b/evm/src/cpu/mod.rs @@ -8,6 +8,7 @@ mod jumps; pub mod kernel; pub(crate) mod membus; mod modfp254; +mod shift; mod simple_logic; mod stack; mod stack_bounds; diff --git a/evm/src/cpu/shift.rs b/evm/src/cpu/shift.rs new file mode 100644 index 00000000..d383b6b2 --- /dev/null +++ b/evm/src/cpu/shift.rs @@ -0,0 +1,108 @@ +use plonky2::field::extension::Extendable; +use plonky2::field::packed::PackedField; +use plonky2::field::types::Field; +use plonky2::hash::hash_types::RichField; +use plonky2::iop::ext_target::ExtensionTarget; + +use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; +use crate::cpu::columns::CpuColumnsView; +use crate::cpu::membus::NUM_GP_CHANNELS; +use crate::memory::segments::Segment; + +pub(crate) fn eval_packed( + lv: &CpuColumnsView

, + yield_constr: &mut ConstraintConsumer

, +) { + let is_shift = lv.op.shl + lv.op.shr; + let displacement = lv.mem_channels[1]; // holds the shift displacement d + let two_exp = lv.mem_channels[2]; // holds 2^d + + // Not needed here; val is the input and we're verifying that output is + // val * 2^d (mod 2^256) + //let val = lv.mem_channels[0]; + //let output = lv.mem_channels[NUM_GP_CHANNELS - 1]; + + let shift_table_segment = P::Scalar::from_canonical_u64(Segment::ShiftTable as u64); + + // Only lookup the shifting factor when displacement is < 2^32. + // two_exp.used is true (1) if the high limbs of the displacement are + // zero and false (0) otherwise. + let high_limbs_are_zero = two_exp.used; + yield_constr.constraint(is_shift * (two_exp.is_read - P::ONES)); + + let high_limbs_sum: P = displacement.value[1..].iter().copied().sum(); + let high_limbs_sum_inv = lv.general.shift().high_limb_sum_inv; + // Verify that high_limbs_are_zero = 0 implies high_limbs_sum != 0 and + // high_limbs_are_zero = 1 implies high_limbs_sum = 0. + let t = high_limbs_sum * high_limbs_sum_inv - (P::ONES - high_limbs_are_zero); + yield_constr.constraint(is_shift * t); + yield_constr.constraint(is_shift * high_limbs_sum * high_limbs_are_zero); + + // When the shift displacement is < 2^32, constrain the two_exp + // mem_channel to be the entry corresponding to `displacement` in + // the shift table lookup (will be zero if displacement >= 256). + yield_constr.constraint(is_shift * two_exp.addr_context); // read from kernel memory + yield_constr.constraint(is_shift * (two_exp.addr_segment - shift_table_segment)); + yield_constr.constraint(is_shift * (two_exp.addr_virtual - displacement.value[0])); + + // Other channels must be unused + for chan in &lv.mem_channels[3..NUM_GP_CHANNELS - 1] { + yield_constr.constraint(is_shift * chan.used); // channel is not used + } + + // Cross-table lookup must connect the memory channels here to MUL + // (in the case of left shift) or DIV (in the case of right shift) + // in the arithmetic table. Specifically, the mapping is + // + // 0 -> 0 (value to be shifted is the same) + // 2 -> 1 (two_exp becomes the multiplicand (resp. divisor)) + // last -> last (output is the same) +} + +pub(crate) fn eval_ext_circuit, const D: usize>( + builder: &mut plonky2::plonk::circuit_builder::CircuitBuilder, + lv: &CpuColumnsView>, + yield_constr: &mut RecursiveConstraintConsumer, +) { + let is_shift = builder.add_extension(lv.op.shl, lv.op.shr); + let displacement = lv.mem_channels[1]; + let two_exp = lv.mem_channels[2]; + + let shift_table_segment = F::from_canonical_u64(Segment::ShiftTable as u64); + + let high_limbs_are_zero = two_exp.used; + let one = builder.one_extension(); + let t = builder.sub_extension(two_exp.is_read, one); + let t = builder.mul_extension(is_shift, t); + yield_constr.constraint(builder, t); + + let high_limbs_sum = builder.add_many_extension(&displacement.value[1..]); + let high_limbs_sum_inv = lv.general.shift().high_limb_sum_inv; + let t = builder.one_extension(); + let t = builder.sub_extension(t, high_limbs_are_zero); + let t = builder.mul_sub_extension(high_limbs_sum, high_limbs_sum_inv, t); + let t = builder.mul_extension(is_shift, t); + yield_constr.constraint(builder, t); + + let t = builder.mul_many_extension([is_shift, high_limbs_sum, high_limbs_are_zero]); + yield_constr.constraint(builder, t); + + let t = builder.mul_extension(is_shift, two_exp.addr_context); + yield_constr.constraint(builder, t); + let t = builder.arithmetic_extension( + F::ONE, + -shift_table_segment, + is_shift, + two_exp.addr_segment, + is_shift, + ); + yield_constr.constraint(builder, t); + let t = builder.sub_extension(two_exp.addr_virtual, displacement.value[0]); + let t = builder.mul_extension(is_shift, t); + yield_constr.constraint(builder, t); + + for chan in &lv.mem_channels[3..NUM_GP_CHANNELS - 1] { + let t = builder.mul_extension(is_shift, chan.used); + yield_constr.constraint(builder, t); + } +} diff --git a/evm/src/cpu/stack.rs b/evm/src/cpu/stack.rs index c72688ed..ea235578 100644 --- a/evm/src/cpu/stack.rs +++ b/evm/src/cpu/stack.rs @@ -40,73 +40,33 @@ const BASIC_TERNARY_OP: Option = Some(StackBehavior { // except the first `num_pops` and the last `pushes as usize` channels have their read flag and // address constrained automatically in this file. const STACK_BEHAVIORS: OpsColumnsView> = OpsColumnsView { - stop: None, // TODO add: BASIC_BINARY_OP, mul: BASIC_BINARY_OP, sub: BASIC_BINARY_OP, div: BASIC_BINARY_OP, - sdiv: BASIC_BINARY_OP, mod_: BASIC_BINARY_OP, - smod: BASIC_BINARY_OP, addmod: BASIC_TERNARY_OP, mulmod: BASIC_TERNARY_OP, - exp: None, // TODO - signextend: BASIC_BINARY_OP, addfp254: BASIC_BINARY_OP, mulfp254: BASIC_BINARY_OP, subfp254: BASIC_BINARY_OP, lt: BASIC_BINARY_OP, gt: BASIC_BINARY_OP, - slt: BASIC_BINARY_OP, - sgt: BASIC_BINARY_OP, eq: BASIC_BINARY_OP, iszero: BASIC_UNARY_OP, and: BASIC_BINARY_OP, or: BASIC_BINARY_OP, xor: BASIC_BINARY_OP, - not: BASIC_TERNARY_OP, + not: BASIC_UNARY_OP, byte: BASIC_BINARY_OP, shl: BASIC_BINARY_OP, shr: BASIC_BINARY_OP, - sar: BASIC_BINARY_OP, - keccak256: None, // TODO keccak_general: None, // TODO - address: None, // TODO - balance: None, // TODO - origin: None, // TODO - caller: None, // TODO - callvalue: None, // TODO - calldataload: None, // TODO - calldatasize: None, // TODO - calldatacopy: None, // TODO - codesize: None, // TODO - codecopy: None, // TODO - gasprice: None, // TODO - extcodesize: None, // TODO - extcodecopy: None, // TODO - returndatasize: None, // TODO - returndatacopy: None, // TODO - extcodehash: None, // TODO - blockhash: None, // TODO - coinbase: None, // TODO - timestamp: None, // TODO - number: None, // TODO - difficulty: None, // TODO - gaslimit: None, // TODO - chainid: None, // TODO - selfbalance: None, // TODO - basefee: None, // TODO prover_input: None, // TODO pop: None, // TODO - mload: None, // TODO - mstore: None, // TODO - mstore8: None, // TODO - sload: None, // TODO - sstore: None, // TODO jump: None, // TODO jumpi: None, // TODO pc: None, // TODO - msize: None, // TODO gas: None, // TODO jumpdest: None, // TODO get_state_root: None, // TODO @@ -116,27 +76,17 @@ const STACK_BEHAVIORS: OpsColumnsView> = OpsColumnsView { push: None, // TODO dup: None, swap: None, - log0: None, // TODO - log1: None, // TODO - log2: None, // TODO - log3: None, // TODO - log4: None, // TODO - create: None, // TODO - call: None, // TODO - callcode: None, // TODO - return_: None, // TODO - delegatecall: None, // TODO - create2: None, // TODO get_context: None, // TODO set_context: None, // TODO consume_gas: None, // TODO exit_kernel: None, // TODO - staticcall: None, // TODO mload_general: None, // TODO mstore_general: None, // TODO - revert: None, // TODO - selfdestruct: None, // TODO - invalid: None, // TODO + syscall: Some(StackBehavior { + num_pops: 0, + pushes: true, + disable_other_channels: false, + }), }; fn eval_packed_one( diff --git a/evm/src/cpu/syscalls.rs b/evm/src/cpu/syscalls.rs index 0ac31ef6..4033620e 100644 --- a/evm/src/cpu/syscalls.rs +++ b/evm/src/cpu/syscalls.rs @@ -2,62 +2,81 @@ //! //! These are usually the ones that are too complicated to implement in one CPU table row. -use once_cell::sync::Lazy; use plonky2::field::extension::Extendable; use plonky2::field::packed::PackedField; use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; +use static_assertions::const_assert; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use crate::cpu::columns::{CpuColumnsView, COL_MAP}; +use crate::cpu::columns::CpuColumnsView; use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::membus::NUM_GP_CHANNELS; +use crate::memory::segments::Segment; -const NUM_SYSCALLS: usize = 3; - -fn make_syscall_list() -> [(usize, usize); NUM_SYSCALLS] { - let kernel = Lazy::force(&KERNEL); - [ - (COL_MAP.op.stop, "sys_stop"), - (COL_MAP.op.exp, "sys_exp"), - (COL_MAP.op.invalid, "handle_invalid"), - ] - .map(|(col_index, handler_name)| (col_index, kernel.global_labels[handler_name])) -} - -static TRAP_LIST: Lazy<[(usize, usize); NUM_SYSCALLS]> = Lazy::new(make_syscall_list); +// Copy the constant but make it `usize`. +const BYTES_PER_OFFSET: usize = crate::cpu::kernel::assembler::BYTES_PER_OFFSET as usize; +const_assert!(BYTES_PER_OFFSET < NUM_GP_CHANNELS); // Reserve one channel for stack push pub fn eval_packed( lv: &CpuColumnsView

, nv: &CpuColumnsView

, yield_constr: &mut ConstraintConsumer

, ) { - let syscall_list = Lazy::force(&TRAP_LIST); - // 1 if _any_ syscall, else 0. - let should_syscall: P = syscall_list - .iter() - .map(|&(col_index, _)| lv[col_index]) - .sum(); - let filter = lv.is_cpu_cycle * should_syscall; + let filter = lv.is_cpu_cycle * lv.op.syscall; - // If syscall: set program counter to the handler address - // Note that at most one of the `lv[col_index]`s will be 1 and all others will be 0. - let syscall_dst: P = syscall_list - .iter() - .map(|&(col_index, handler_addr)| { - lv[col_index] * P::Scalar::from_canonical_usize(handler_addr) - }) + // Look up the handler in memory + let code_segment = P::Scalar::from_canonical_usize(Segment::Code as usize); + let syscall_jumptable_start = + P::Scalar::from_canonical_usize(KERNEL.global_labels["syscall_jumptable"]); + let opcode: P = lv + .opcode_bits + .into_iter() + .enumerate() + .map(|(i, bit)| bit * P::Scalar::from_canonical_u64(1 << i)) .sum(); - yield_constr.constraint_transition(filter * (nv.program_counter - syscall_dst)); - // If syscall: set kernel mode + let opcode_handler_addr_start = + syscall_jumptable_start + opcode * P::Scalar::from_canonical_usize(BYTES_PER_OFFSET); + for (i, channel) in lv.mem_channels[0..BYTES_PER_OFFSET].iter().enumerate() { + yield_constr.constraint(filter * (channel.used - P::ONES)); + yield_constr.constraint(filter * (channel.is_read - P::ONES)); + + // Set kernel context and code segment + yield_constr.constraint(filter * channel.addr_context); + yield_constr.constraint(filter * (channel.addr_segment - code_segment)); + + // Set address, using a separate channel for each of the `BYTES_PER_OFFSET` limbs. + let limb_address = opcode_handler_addr_start + P::Scalar::from_canonical_usize(i); + yield_constr.constraint(filter * (channel.addr_virtual - limb_address)); + } + + // Disable unused channels (the last channel is used to push to the stack) + for channel in &lv.mem_channels[BYTES_PER_OFFSET..NUM_GP_CHANNELS - 1] { + yield_constr.constraint(filter * channel.used); + } + + // Set program counter to the handler address + // The addresses are big-endian in memory + let target = lv.mem_channels[0..BYTES_PER_OFFSET] + .iter() + .map(|channel| channel.value[0]) + .fold(P::ZEROS, |cumul, limb| { + cumul * P::Scalar::from_canonical_u64(256) + limb + }); + yield_constr.constraint_transition(filter * (nv.program_counter - target)); + // Set kernel mode yield_constr.constraint_transition(filter * (nv.is_kernel_mode - P::ONES)); + // Maintain current context + yield_constr.constraint_transition(filter * (nv.context - lv.context)); - let output = lv.mem_channels[0].value; - // If syscall: push current PC to stack + // This memory channel is constrained in `stack.rs`. + let output = lv.mem_channels[NUM_GP_CHANNELS - 1].value; + // Push current PC to stack yield_constr.constraint(filter * (output[0] - lv.program_counter)); - // If syscall: push current kernel flag to stack (share register with PC) + // Push current kernel flag to stack (share register with PC) yield_constr.constraint(filter * (output[1] - lv.is_kernel_mode)); - // If syscall: zero the rest of that register + // Zero the rest of that register for &limb in &output[2..] { yield_constr.constraint(filter * limb); } @@ -69,46 +88,111 @@ pub fn eval_ext_circuit, const D: usize>( nv: &CpuColumnsView>, yield_constr: &mut RecursiveConstraintConsumer, ) { - let syscall_list = Lazy::force(&TRAP_LIST); - // 1 if _any_ syscall, else 0. - let should_syscall = - builder.add_many_extension(syscall_list.iter().map(|&(col_index, _)| lv[col_index])); - let filter = builder.mul_extension(lv.is_cpu_cycle, should_syscall); + let filter = builder.mul_extension(lv.is_cpu_cycle, lv.op.syscall); - // If syscall: set program counter to the handler address + // Look up the handler in memory + let code_segment = F::from_canonical_usize(Segment::Code as usize); + let syscall_jumptable_start = builder.constant_extension( + F::from_canonical_usize(KERNEL.global_labels["syscall_jumptable"]).into(), + ); + let opcode = lv + .opcode_bits + .into_iter() + .rev() + .fold(builder.zero_extension(), |cumul, bit| { + builder.mul_const_add_extension(F::TWO, cumul, bit) + }); + let opcode_handler_addr_start = builder.mul_const_add_extension( + F::from_canonical_usize(BYTES_PER_OFFSET), + opcode, + syscall_jumptable_start, + ); + for (i, channel) in lv.mem_channels[0..BYTES_PER_OFFSET].iter().enumerate() { + { + let constr = builder.mul_sub_extension(filter, channel.used, filter); + yield_constr.constraint(builder, constr); + } + { + let constr = builder.mul_sub_extension(filter, channel.is_read, filter); + yield_constr.constraint(builder, constr); + } + + // Set kernel context and code segment + { + let constr = builder.mul_extension(filter, channel.addr_context); + yield_constr.constraint(builder, constr); + } + { + let constr = builder.arithmetic_extension( + F::ONE, + -code_segment, + filter, + channel.addr_segment, + filter, + ); + yield_constr.constraint(builder, constr); + } + + // Set address, using a separate channel for each of the `BYTES_PER_OFFSET` limbs. + { + let diff = builder.sub_extension(channel.addr_virtual, opcode_handler_addr_start); + let constr = builder.arithmetic_extension( + F::ONE, + -F::from_canonical_usize(i), + filter, + diff, + filter, + ); + yield_constr.constraint(builder, constr); + } + } + + // Disable unused channels (the last channel is used to push to the stack) + for channel in &lv.mem_channels[BYTES_PER_OFFSET..NUM_GP_CHANNELS - 1] { + let constr = builder.mul_extension(filter, channel.used); + yield_constr.constraint(builder, constr); + } + + // Set program counter to the handler address + // The addresses are big-endian in memory { - // Note that at most one of the `lv[col_index]`s will be 1 and all others will be 0. - let syscall_dst = syscall_list.iter().fold( - builder.zero_extension(), - |cumul, &(col_index, handler_addr)| { - let handler_addr = F::from_canonical_usize(handler_addr); - builder.mul_const_add_extension(handler_addr, lv[col_index], cumul) - }, - ); - let constr = builder.sub_extension(nv.program_counter, syscall_dst); - let constr = builder.mul_extension(filter, constr); + let target = lv.mem_channels[0..BYTES_PER_OFFSET] + .iter() + .map(|channel| channel.value[0]) + .fold(builder.zero_extension(), |cumul, limb| { + builder.mul_const_add_extension(F::from_canonical_u64(256), cumul, limb) + }); + let diff = builder.sub_extension(nv.program_counter, target); + let constr = builder.mul_extension(filter, diff); yield_constr.constraint_transition(builder, constr); } - // If syscall: set kernel mode + // Set kernel mode { let constr = builder.mul_sub_extension(filter, nv.is_kernel_mode, filter); yield_constr.constraint_transition(builder, constr); } + // Maintain current context + { + let diff = builder.sub_extension(nv.context, lv.context); + let constr = builder.mul_extension(filter, diff); + yield_constr.constraint_transition(builder, constr); + } - let output = lv.mem_channels[0].value; - // If syscall: push current PC to stack + // This memory channel is constrained in `stack.rs`. + let output = lv.mem_channels[NUM_GP_CHANNELS - 1].value; + // Push current PC to stack { - let constr = builder.sub_extension(output[0], lv.program_counter); - let constr = builder.mul_extension(filter, constr); + let diff = builder.sub_extension(output[0], lv.program_counter); + let constr = builder.mul_extension(filter, diff); yield_constr.constraint(builder, constr); } - // If syscall: push current kernel flag to stack (share register with PC) + // Push current kernel flag to stack (share register with PC) { - let constr = builder.sub_extension(output[1], lv.is_kernel_mode); - let constr = builder.mul_extension(filter, constr); + let diff = builder.sub_extension(output[1], lv.is_kernel_mode); + let constr = builder.mul_extension(filter, diff); yield_constr.constraint(builder, constr); } - // If syscall: zero the rest of that register + // Zero the rest of that register for &limb in &output[2..] { let constr = builder.mul_extension(filter, limb); yield_constr.constraint(builder, constr); diff --git a/evm/src/memory/segments.rs b/evm/src/memory/segments.rs index f8d536e9..7a28cb96 100644 --- a/evm/src/memory/segments.rs +++ b/evm/src/memory/segments.rs @@ -35,10 +35,13 @@ pub(crate) enum Segment { TrieEncodedChild = 14, /// A buffer used to store the lengths of the encodings of a branch node's children. TrieEncodedChildLen = 15, + /// A table of values 2^i for i=0..255 for use with shift + /// instructions; initialised by `kernel/asm/shift.asm::init_shift_table()`. + ShiftTable = 16, } impl Segment { - pub(crate) const COUNT: usize = 16; + pub(crate) const COUNT: usize = 17; pub(crate) fn all() -> [Self; Self::COUNT] { [ @@ -58,6 +61,7 @@ impl Segment { Self::TrieData, Self::TrieEncodedChild, Self::TrieEncodedChildLen, + Self::ShiftTable, ] } @@ -80,6 +84,7 @@ impl Segment { Segment::TrieData => "SEGMENT_TRIE_DATA", Segment::TrieEncodedChild => "SEGMENT_TRIE_ENCODED_CHILD", Segment::TrieEncodedChildLen => "SEGMENT_TRIE_ENCODED_CHILD_LEN", + Segment::ShiftTable => "SEGMENT_SHIFT_TABLE", } } @@ -102,6 +107,7 @@ impl Segment { Segment::TrieData => 256, Segment::TrieEncodedChild => 256, Segment::TrieEncodedChildLen => 6, + Segment::ShiftTable => 256, } } } diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index b3fa5113..b63ef5a5 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -37,7 +37,7 @@ static_assertions = "1.1.0" [dev-dependencies] rand = "0.8.4" rand_chacha = "0.3.1" -criterion = "0.3.5" +criterion = "0.4.0" env_logger = "0.9.0" tynm = "0.1.6" structopt = "0.3.26" diff --git a/plonky2/src/gadgets/split_base.rs b/plonky2/src/gadgets/split_base.rs index c539d784..9c85863f 100644 --- a/plonky2/src/gadgets/split_base.rs +++ b/plonky2/src/gadgets/split_base.rs @@ -3,6 +3,7 @@ use std::borrow::Borrow; use itertools::Itertools; use plonky2_field::extension::Extendable; use plonky2_field::types::Field; +use plonky2_util::log_floor; use crate::gates::base_sum::BaseSumGate; use crate::hash::hash_types::RichField; @@ -33,6 +34,11 @@ impl, const D: usize> CircuitBuilder { pub(crate) fn le_sum(&mut self, bits: impl Iterator>) -> Target { let bits = bits.map(|b| *b.borrow()).collect_vec(); let num_bits = bits.len(); + assert!( + num_bits <= log_floor(F::ORDER, 2), + "{} bits may overflow the field", + num_bits + ); if num_bits == 0 { return self.zero(); } diff --git a/system_zero/Cargo.toml b/system_zero/Cargo.toml index f1cb5729..826d69d8 100644 --- a/system_zero/Cargo.toml +++ b/system_zero/Cargo.toml @@ -16,7 +16,7 @@ rand = "0.8.4" rand_chacha = "0.3.1" [dev-dependencies] -criterion = "0.3.5" +criterion = "0.4.0" [[bench]] name = "lookup_permuted_cols" diff --git a/util/Cargo.toml b/util/Cargo.toml index a1ab402a..4e0b4b15 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -5,3 +5,4 @@ version = "0.1.0" edition = "2021" [dependencies] +rand = { version = "0.8.5", default-features = false, features = ["getrandom"] } diff --git a/util/src/lib.rs b/util/src/lib.rs index b22a4236..eb297bd8 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -274,8 +274,50 @@ pub fn branch_hint() { #[cfg(test)] mod tests { + use rand::rngs::OsRng; + use rand::Rng; + use crate::{log2_ceil, log2_strict}; + #[test] + fn test_reverse_index_bits() { + let lengths = [32, 128, 1 << 16]; + let mut rng = OsRng; + for _ in 0..32 { + for length in lengths { + let mut rand_list: Vec = Vec::with_capacity(length); + rand_list.resize_with(length, || rng.gen()); + + let out = super::reverse_index_bits(&rand_list); + let expect = reverse_index_bits_naive(&rand_list); + + for (out, expect) in out.iter().zip(&expect) { + assert_eq!(out, expect); + } + } + } + } + + #[test] + fn test_reverse_index_bits_in_place() { + let lengths = [32, 128, 1 << 16]; + let mut rng = OsRng; + for _ in 0..32 { + for length in lengths { + let mut rand_list: Vec = Vec::with_capacity(length); + rand_list.resize_with(length, || rng.gen()); + + let expect = reverse_index_bits_naive(&rand_list); + + super::reverse_index_bits_in_place(&mut rand_list); + + for (got, expect) in rand_list.iter().zip(&expect) { + assert_eq!(got, expect); + } + } + } + } + #[test] fn test_log2_strict() { assert_eq!(log2_strict(1), 0); @@ -326,4 +368,17 @@ mod tests { assert_eq!(log2_ceil(usize::MAX - 1), usize::BITS as usize); assert_eq!(log2_ceil(usize::MAX), usize::BITS as usize); } + + fn reverse_index_bits_naive(arr: &[T]) -> Vec { + let n = arr.len(); + let n_power = log2_strict(n); + + let mut out = vec![None; n]; + for (i, v) in arr.iter().enumerate() { + let dst = i.reverse_bits() >> (64 - n_power); + out[dst] = Some(*v); + } + + out.into_iter().map(|x| x.unwrap()).collect() + } } From 289498e85422b5b9e56b585a27e47bd41af1dd12 Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 15 Nov 2022 01:52:27 -0500 Subject: [PATCH 22/49] fix: address review comments Signed-off-by: Brandon H. Gomes --- plonky2/Cargo.toml | 1 + plonky2/src/plonk/proof.rs | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index 88217d2d..b56de755 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -18,6 +18,7 @@ std = ["anyhow/std", "rand/std"] timing = ["std"] [dependencies] +ahash = { version = "0.8.2", default-features = false, features = ["compile-time-rng"] } anyhow = { version = "1.0.40", default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } hashbrown = { version = "0.12.3", default-features = false, features = ["ahash", "serde"] } diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index a5a66e26..e9b69b88 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -105,7 +105,9 @@ impl, C: GenericConfig, const D: usize> pub fn to_bytes(&self) -> Vec { let mut buffer = Vec::new(); - let _ = buffer.write_proof_with_public_inputs(self); + buffer + .write_proof_with_public_inputs(self) + .expect("Writing to a byte-vector cannot fail."); buffer } From 2520bd62c66937ec867470d37f570f69a626cf5b Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 15 Nov 2022 16:14:07 -0500 Subject: [PATCH 23/49] chore: match hashbrown ahash dependency Signed-off-by: Brandon H. Gomes --- plonky2/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index b56de755..541f2dcc 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -18,7 +18,7 @@ std = ["anyhow/std", "rand/std"] timing = ["std"] [dependencies] -ahash = { version = "0.8.2", default-features = false, features = ["compile-time-rng"] } +ahash = { version = "0.7.6", default-features = false, features = ["compile-time-rng"] } anyhow = { version = "1.0.40", default-features = false } derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } hashbrown = { version = "0.12.3", default-features = false, features = ["ahash", "serde"] } From 65d106bc31d42b429f083f232750055f87eec1dd Mon Sep 17 00:00:00 2001 From: "Brandon H. Gomes" Date: Tue, 15 Nov 2022 16:26:43 -0500 Subject: [PATCH 24/49] chore: remove derivative dependency as non-crucial Signed-off-by: Brandon H. Gomes --- plonky2/Cargo.toml | 5 ++--- plonky2/src/gates/poseidon.rs | 3 +-- plonky2/src/gates/poseidon_mds.rs | 3 +-- plonky2/src/iop/witness.rs | 3 +-- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/plonky2/Cargo.toml b/plonky2/Cargo.toml index 541f2dcc..ab131463 100644 --- a/plonky2/Cargo.toml +++ b/plonky2/Cargo.toml @@ -18,10 +18,9 @@ std = ["anyhow/std", "rand/std"] timing = ["std"] [dependencies] -ahash = { version = "0.7.6", default-features = false, features = ["compile-time-rng"] } +ahash = { version = "0.7.6", default-features = false, features = ["compile-time-rng"] } # NOTE: Be sure to keep this version the same as the dependency in `hashbrown`. anyhow = { version = "1.0.40", default-features = false } -derivative = { version = "2.2.0", default-features = false, features = ["use_core"] } -hashbrown = { version = "0.12.3", default-features = false, features = ["ahash", "serde"] } +hashbrown = { version = "0.12.3", default-features = false, features = ["ahash", "serde"] } # NOTE: When upgrading, see `ahash` dependency. itertools = { version = "0.10.0", default-features = false } keccak-hash = { version = "0.8.0", default-features = false } log = { version = "0.4.14", default-features = false } diff --git a/plonky2/src/gates/poseidon.rs b/plonky2/src/gates/poseidon.rs index c644ada5..c02eec84 100644 --- a/plonky2/src/gates/poseidon.rs +++ b/plonky2/src/gates/poseidon.rs @@ -26,8 +26,7 @@ use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// This also has some extra features to make it suitable for efficiently verifying Merkle proofs. /// It has a flag which can be used to swap the first four inputs with the next four, for ordering /// sibling digests. -#[derive(derivative::Derivative)] -#[derivative(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] +#[derive(Debug, Default)] pub struct PoseidonGate, const D: usize>(PhantomData); impl, const D: usize> PoseidonGate { diff --git a/plonky2/src/gates/poseidon_mds.rs b/plonky2/src/gates/poseidon_mds.rs index dd494328..94c1486c 100644 --- a/plonky2/src/gates/poseidon_mds.rs +++ b/plonky2/src/gates/poseidon_mds.rs @@ -21,8 +21,7 @@ use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBase}; /// Poseidon MDS Gate -#[derive(derivative::Derivative)] -#[derivative(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] +#[derive(Debug, Default)] pub struct PoseidonMdsGate + Poseidon, const D: usize>(PhantomData); impl + Poseidon, const D: usize> PoseidonMdsGate { diff --git a/plonky2/src/iop/witness.rs b/plonky2/src/iop/witness.rs index 218008ac..fe6b9473 100644 --- a/plonky2/src/iop/witness.rs +++ b/plonky2/src/iop/witness.rs @@ -250,8 +250,7 @@ impl MatrixWitness { } } -#[derive(derivative::Derivative)] -#[derivative(Clone, Debug, Default(bound = ""))] +#[derive(Clone, Debug, Default)] pub struct PartialWitness { pub(crate) target_values: HashMap, } From e22da77b342f5e5d9888ab95e391d88a8712e75c Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Mon, 14 Nov 2022 15:02:56 -0800 Subject: [PATCH 25/49] Include the FRI prover's PoW witness in the transcript We don't think this is required for soundness, but just to remove any doubt. Old protocol: ``` ... P sends final_poly V samples random r P sends pow_witness (not in transcript) V computes pow_response = H(r, pow_witness) V asserts pow_response has N leading 0s ... ``` New protocol: ``` ... P sends final_poly P sends pow_witness V samples random pow_response V asserts pow_response has N leading 0s ... ``` --- plonky2/src/fri/challenges.rs | 24 +++---------- plonky2/src/fri/prover.rs | 67 ++++++++++++++++++++++++----------- plonky2/src/iop/challenger.rs | 4 +-- 3 files changed, 53 insertions(+), 42 deletions(-) diff --git a/plonky2/src/fri/challenges.rs b/plonky2/src/fri/challenges.rs index 011a8897..d40423d5 100644 --- a/plonky2/src/fri/challenges.rs +++ b/plonky2/src/fri/challenges.rs @@ -49,16 +49,8 @@ impl> Challenger { self.observe_extension_elements(&final_poly.coeffs); - let fri_pow_response = C::InnerHasher::hash_no_pad( - &self - .get_hash() - .elements - .iter() - .copied() - .chain(Some(pow_witness)) - .collect::>(), - ) - .elements[0]; + self.observe_element(pow_witness); + let fri_pow_response = self.get_challenge(); let fri_query_indices = (0..num_fri_queries) .map(|_| self.get_challenge().to_canonical_u64() as usize % lde_size) @@ -105,16 +97,8 @@ impl, H: AlgebraicHasher, const D: usize> self.observe_extension_elements(&final_poly.0); - let pow_inputs = self - .get_hash(builder) - .elements - .iter() - .copied() - .chain(Some(pow_witness)) - .collect(); - let fri_pow_response = builder - .hash_n_to_hash_no_pad::(pow_inputs) - .elements[0]; + self.observe_element(pow_witness); + let fri_pow_response = self.get_challenge(builder); let fri_query_indices = (0..num_fri_queries) .map(|_| self.get_challenge(builder)) diff --git a/plonky2/src/fri/prover.rs b/plonky2/src/fri/prover.rs index 71efe98a..38311c27 100644 --- a/plonky2/src/fri/prover.rs +++ b/plonky2/src/fri/prover.rs @@ -1,4 +1,3 @@ -use itertools::Itertools; use maybe_rayon::*; use plonky2_field::extension::{flatten, unflatten, Extendable}; use plonky2_field::polynomial::{PolynomialCoeffs, PolynomialValues}; @@ -6,7 +5,8 @@ use plonky2_util::reverse_index_bits_in_place; use crate::fri::proof::{FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep}; use crate::fri::{FriConfig, FriParams}; -use crate::hash::hash_types::{HashOut, RichField}; +use crate::hash::hash_types::RichField; +use crate::hash::hashing::{PlonkyPermutation, SPONGE_RATE}; use crate::hash::merkle_tree::MerkleTree; use crate::iop::challenger::Challenger; use crate::plonk::config::{GenericConfig, Hasher}; @@ -44,11 +44,10 @@ where ); // PoW phase - let current_hash = challenger.get_hash(); let pow_witness = timed!( timing, "find proof-of-work witness", - fri_proof_of_work::(current_hash, &fri_params.config) + fri_proof_of_work::(challenger, &fri_params.config) ); // Query phase @@ -114,28 +113,56 @@ where (trees, coeffs) } +/// Performs the proof-of-work (a.k.a. grinding) step of the FRI protocol. Returns the PoW witness. fn fri_proof_of_work, C: GenericConfig, const D: usize>( - current_hash: HashOut, + challenger: &mut Challenger, config: &FriConfig, ) -> F { - (0..=F::NEG_ONE.to_canonical_u64()) + // let pow_seed = challenger.get_hash(); + let min_leading_zeros = config.proof_of_work_bits + (64 - F::order().bits()) as u32; + + // The easiest implementation would be repeatedly clone our Challenger. With each clone, we'd + // observe an incrementing PoW witness, then get the PoW response. If it contained sufficient + // leading zeros, we'd end the search, and store this clone as our new challenger. + // + // However, performance is critical here. We want to avoid cloning Challenger, particularly + // since it stores vectors, which means allocations. We'd like a more compact state to clone. + // + // We know that a duplex will be performed right after we send the PoW witness, so we can ignore + // any output_buffer, which will be invalidated. We also know input_buffer.len() < SPONGE_WIDTH, + // an invariant of Challenger. + // + // We separate the duplex operation into two steps, one which can be performed now, and the + // other which depends on the PoW witness candidate. The first step is the overwrite our sponge + // state with any inputs (excluding the PoW witness candidate). The second step is to overwrite + // one more element of our sponge state with the candidate, then apply the permutation, + // obtaining our duplex's post-state which contains the PoW response. + let mut duplex_intermediate_state = challenger.sponge_state; + let witness_input_pos = challenger.input_buffer.len(); + for (i, input) in challenger.input_buffer.iter().enumerate() { + duplex_intermediate_state[i] = *input; + } + + let pow_witness = (0..=F::NEG_ONE.to_canonical_u64()) .into_par_iter() - .find_any(|&i| { - C::InnerHasher::hash_no_pad( - ¤t_hash - .elements - .iter() - .copied() - .chain(Some(F::from_canonical_u64(i))) - .collect_vec(), - ) - .elements[0] - .to_canonical_u64() - .leading_zeros() - >= config.proof_of_work_bits + (64 - F::order().bits()) as u32 + .find_any(|&candidate| { + let mut duplex_state = duplex_intermediate_state; + duplex_state[witness_input_pos] = F::from_canonical_u64(candidate); + duplex_state = + <>::Hasher as Hasher>::Permutation::permute(duplex_state); + let pow_response = duplex_state[SPONGE_RATE - 1]; + let leading_zeros = pow_response.to_canonical_u64().leading_zeros(); + leading_zeros >= min_leading_zeros }) .map(F::from_canonical_u64) - .expect("Proof of work failed. This is highly unlikely!") + .expect("Proof of work failed. This is highly unlikely!"); + + // Recompute pow_response using our normal Challenger code, and make sure it matches. + challenger.observe_element(pow_witness); + let pow_response = challenger.get_challenge(); + let leading_zeros = pow_response.to_canonical_u64().leading_zeros(); + assert!(leading_zeros >= min_leading_zeros); + pow_witness } fn fri_prover_query_rounds< diff --git a/plonky2/src/iop/challenger.rs b/plonky2/src/iop/challenger.rs index c601ae0f..88c63d5e 100644 --- a/plonky2/src/iop/challenger.rs +++ b/plonky2/src/iop/challenger.rs @@ -15,8 +15,8 @@ use crate::plonk::config::{AlgebraicHasher, GenericHashOut, Hasher}; /// Observes prover messages, and generates challenges by hashing the transcript, a la Fiat-Shamir. #[derive(Clone)] pub struct Challenger> { - sponge_state: [F; SPONGE_WIDTH], - input_buffer: Vec, + pub(crate) sponge_state: [F; SPONGE_WIDTH], + pub(crate) input_buffer: Vec, output_buffer: Vec, _phantom: PhantomData, } From 1732399f05e9f743f708d21b12457dca0a2aab4e Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Thu, 17 Nov 2022 12:08:33 -0800 Subject: [PATCH 26/49] Remove comment --- plonky2/src/fri/prover.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/plonky2/src/fri/prover.rs b/plonky2/src/fri/prover.rs index 38311c27..0a09113e 100644 --- a/plonky2/src/fri/prover.rs +++ b/plonky2/src/fri/prover.rs @@ -118,7 +118,6 @@ fn fri_proof_of_work, C: GenericConfig, c challenger: &mut Challenger, config: &FriConfig, ) -> F { - // let pow_seed = challenger.get_hash(); let min_leading_zeros = config.proof_of_work_bits + (64 - F::order().bits()) as u32; // The easiest implementation would be repeatedly clone our Challenger. With each clone, we'd From 0271817730a53a931bbc3e0f773eff9a67e003ee Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Thu, 17 Nov 2022 12:27:43 -0800 Subject: [PATCH 27/49] workflow_dispatch --- .github/workflows/continuous-integration-workflow.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index 38231892..d929acd9 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -6,6 +6,9 @@ on: pull_request: branches: - "**" + workflow_dispatch: + branches: + - "**" jobs: test: From 0ed92ab878ff3aad5080dfb6bb81a997243a69cd Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Thu, 17 Nov 2022 12:27:43 -0800 Subject: [PATCH 28/49] workflow_dispatch --- .github/workflows/continuous-integration-workflow.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index 38231892..d929acd9 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -6,6 +6,9 @@ on: pull_request: branches: - "**" + workflow_dispatch: + branches: + - "**" jobs: test: From af2349e924dbe08e5a210bfa2ed1db8019a94276 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Thu, 17 Nov 2022 12:49:19 -0800 Subject: [PATCH 29/49] Imports --- util/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/src/lib.rs b/util/src/lib.rs index eb2d0430..d516a558 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -288,6 +288,9 @@ pub fn branch_hint() { #[cfg(test)] mod tests { + use alloc::vec; + use alloc::vec::Vec; + use rand::rngs::OsRng; use rand::Rng; From 25013860045751e76897dc08638af9b1228f0d46 Mon Sep 17 00:00:00 2001 From: Hamish Ivey-Law <426294+unzvfu@users.noreply.github.com> Date: Fri, 18 Nov 2022 15:00:58 +1100 Subject: [PATCH 30/49] Add missing feature to field crate. (#818) --- field/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/field/src/lib.rs b/field/src/lib.rs index dd4fc433..86b6aebe 100644 --- a/field/src/lib.rs +++ b/field/src/lib.rs @@ -6,6 +6,7 @@ #![allow(clippy::needless_range_loop)] #![allow(clippy::return_self_not_must_use)] #![feature(generic_const_exprs)] +#![feature(stdsimd)] #![feature(specialization)] #![cfg_attr(not(test), no_std)] From c31b0147f4b0154b376b151f83eaa371a1ea3007 Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Sat, 19 Nov 2022 18:58:55 +0100 Subject: [PATCH 31/49] Implement `CALLVALUE, CALLDATALOAD, CALLDATASIZE, CALLDATACOPY` in interpreter (#819) * Implement `CALLVALUE, CALLDATALOAD, CALLDATASIZE, CALLDATACOPY` in interpreter * PR feedback --- evm/src/cpu/kernel/interpreter.rs | 53 ++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 6e3f9e5d..9f7d3483 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -266,10 +266,10 @@ impl<'a> Interpreter<'a> { 0x31 => todo!(), // "BALANCE", 0x32 => todo!(), // "ORIGIN", 0x33 => todo!(), // "CALLER", - 0x34 => todo!(), // "CALLVALUE", - 0x35 => todo!(), // "CALLDATALOAD", - 0x36 => todo!(), // "CALLDATASIZE", - 0x37 => todo!(), // "CALLDATACOPY", + 0x34 => self.run_callvalue(), // "CALLVALUE", + 0x35 => self.run_calldataload(), // "CALLDATALOAD", + 0x36 => self.run_calldatasize(), // "CALLDATASIZE", + 0x37 => self.run_calldatacopy(), // "CALLDATACOPY", 0x38 => todo!(), // "CODESIZE", 0x39 => todo!(), // "CODECOPY", 0x3a => todo!(), // "GASPRICE", @@ -537,6 +537,51 @@ impl<'a> Interpreter<'a> { self.push(U256::from_big_endian(hash.as_bytes())); } + fn run_callvalue(&mut self) { + self.push( + self.memory.context_memory[self.context].segments[Segment::ContextMetadata as usize] + .get(ContextMetadata::CallValue as usize), + ) + } + + fn run_calldataload(&mut self) { + let offset = self.pop().as_usize(); + let value = U256::from_big_endian( + &(0..32) + .map(|i| { + self.memory + .mload_general(self.context, Segment::Calldata, offset + i) + .byte(0) + }) + .collect::>(), + ); + self.push(value); + } + + fn run_calldatasize(&mut self) { + self.push( + self.memory.context_memory[self.context].segments[Segment::ContextMetadata as usize] + .get(ContextMetadata::CalldataSize as usize), + ) + } + + fn run_calldatacopy(&mut self) { + let dest_offset = self.pop().as_usize(); + let offset = self.pop().as_usize(); + let size = self.pop().as_usize(); + for i in 0..size { + let calldata_byte = + self.memory + .mload_general(self.context, Segment::Calldata, offset + i); + self.memory.mstore_general( + self.context, + Segment::MainMemory, + dest_offset + i, + calldata_byte, + ); + } + } + fn run_prover_input(&mut self) -> anyhow::Result<()> { let prover_input_fn = self .prover_inputs_map From b0be6d7e8a169f8619efd0e90bfa1e8d4719d02b Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sun, 20 Nov 2022 09:21:58 -0800 Subject: [PATCH 32/49] Serialization refactor Followup to #806. A few goals here - Zero dependencies on std. (Previously deserialization depended on std for `Cursor`.) - Provide a single (memory buffering) impl of `Write` to make sure there's no confusion. (Previously `Buffer` and `Vec` both implemented it.) - Move closer to the `std::io` APIs. Hopefully they will be available without std at some point (there have been some discussions...). More specifically, this - Changes `Buffer` to not use std's `Cursor`. - Removes `impl Write` for `Buffer`, since it's implemented for `Vec`. - Adds a concrete I/O error type to mimic `std::io`'s. - Combines `Position` and `Size` into `Remaining`. --- plonky2/src/plonk/proof.rs | 12 +- plonky2/src/util/serialization.rs | 208 +++++++++++++----------------- 2 files changed, 98 insertions(+), 122 deletions(-) diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index e9b69b88..caf3a7f8 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -117,7 +117,9 @@ impl, C: GenericConfig, const D: usize> common_data: &CommonCircuitData, ) -> anyhow::Result { let mut buffer = Buffer::new(bytes); - let proof = buffer.read_proof_with_public_inputs(common_data)?; + let proof = buffer + .read_proof_with_public_inputs(common_data) + .map_err(anyhow::Error::msg)?; Ok(proof) } } @@ -233,7 +235,9 @@ impl, C: GenericConfig, const D: usize> pub fn to_bytes(&self) -> Vec { let mut buffer = Vec::new(); - let _ = buffer.write_compressed_proof_with_public_inputs(self); + buffer + .write_compressed_proof_with_public_inputs(self) + .expect("Writing to a byte-vector cannot fail."); buffer } @@ -243,7 +247,9 @@ impl, C: GenericConfig, const D: usize> common_data: &CommonCircuitData, ) -> anyhow::Result { let mut buffer = Buffer::new(bytes); - let proof = buffer.read_compressed_proof_with_public_inputs(common_data)?; + let proof = buffer + .read_compressed_proof_with_public_inputs(common_data) + .map_err(anyhow::Error::msg)?; Ok(proof) } } diff --git a/plonky2/src/util/serialization.rs b/plonky2/src/util/serialization.rs index ce56709d..712e936a 100644 --- a/plonky2/src/util/serialization.rs +++ b/plonky2/src/util/serialization.rs @@ -1,8 +1,8 @@ use alloc::vec; use alloc::vec::Vec; use core::convert::Infallible; -#[cfg(feature = "std")] -use std::io::{self, Cursor, Read as _, Write as _}; +use core::fmt::{Debug, Display, Formatter}; +use core::mem::size_of; use hashbrown::HashMap; @@ -23,69 +23,65 @@ use crate::plonk::proof::{ CompressedProof, CompressedProofWithPublicInputs, OpeningSet, Proof, ProofWithPublicInputs, }; -/// Buffer Position -pub trait Position { - /// Returns the position of the buffer. - fn position(&self) -> u64; +/// A no_std compatible variant of `std::io::Error` +#[derive(Debug)] +pub struct IoError; + +impl Display for IoError { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + Debug::fmt(self, f) + } } -/// Buffer Size -pub trait Size { - /// Returns the length of `self`. - fn len(&self) -> usize; +/// A no_std compatible variant of `std::io::Result` +pub type IoResult = Result; - /// Returns `true` if `self` has length zero. - #[inline] +/// A `Read` which is able to report how many bytes are remaining. +pub trait Remaining: Read { + /// Returns the number of bytes remaining in the buffer. + fn remaining(&self) -> usize; + + /// Returns whether zero bytes are remaining. fn is_empty(&self) -> bool { - self.len() == 0 + self.remaining() == 0 } } -impl Size for Vec { - #[inline] - fn len(&self) -> usize { - self.len() - } -} - -/// Reading +/// Similar to `std::io::Read`, but works with no_std. pub trait Read { - /// Error Type - type Error; - /// Reads exactly the length of `bytes` from `self` and writes it to `bytes`. - fn read_exact(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error>; + fn read_exact(&mut self, bytes: &mut [u8]) -> IoResult<()>; /// Reads a `u8` value from `self`. #[inline] - fn read_u8(&mut self) -> Result { - let mut buf = [0; core::mem::size_of::()]; + fn read_u8(&mut self) -> IoResult { + let mut buf = [0; size_of::()]; self.read_exact(&mut buf)?; Ok(buf[0]) } /// Reads a `u32` value from `self`. #[inline] - fn read_u32(&mut self) -> Result { - let mut buf = [0; core::mem::size_of::()]; + fn read_u32(&mut self) -> IoResult { + let mut buf = [0; size_of::()]; self.read_exact(&mut buf)?; Ok(u32::from_le_bytes(buf)) } /// Reads a element from the field `F` with size less than `2^64` from `self.` #[inline] - fn read_field(&mut self) -> Result + fn read_field(&mut self) -> IoResult where F: Field64, { - let mut buf = [0; core::mem::size_of::()]; + let mut buf = [0; size_of::()]; self.read_exact(&mut buf)?; Ok(F::from_canonical_u64(u64::from_le_bytes(buf))) } /// Reads a vector of elements from the field `F` from `self`. #[inline] - fn read_field_vec(&mut self, length: usize) -> Result, Self::Error> + fn read_field_vec(&mut self, length: usize) -> IoResult> where F: Field64, { @@ -96,7 +92,7 @@ pub trait Read { /// Reads an element from the field extension of `F` from `self.` #[inline] - fn read_field_ext(&mut self) -> Result + fn read_field_ext(&mut self) -> IoResult where F: Field64 + Extendable, { @@ -114,7 +110,7 @@ pub trait Read { fn read_field_ext_vec( &mut self, length: usize, - ) -> Result, Self::Error> + ) -> IoResult> where F: RichField + Extendable, { @@ -123,7 +119,7 @@ pub trait Read { /// Reads a hash value from `self`. #[inline] - fn read_hash(&mut self) -> Result + fn read_hash(&mut self) -> IoResult where F: RichField, H: Hasher, @@ -135,7 +131,7 @@ pub trait Read { /// Reads a value of type [`MerkleCap`] from `self` with the given `cap_height`. #[inline] - fn read_merkle_cap(&mut self, cap_height: usize) -> Result, Self::Error> + fn read_merkle_cap(&mut self, cap_height: usize) -> IoResult> where F: RichField, H: Hasher, @@ -153,7 +149,7 @@ pub trait Read { fn read_opening_set( &mut self, common_data: &CommonCircuitData, - ) -> Result, Self::Error> + ) -> IoResult> where F: RichField + Extendable, C: GenericConfig, @@ -182,7 +178,7 @@ pub trait Read { /// Reads a value of type [`MerkleProof`] from `self`. #[inline] - fn read_merkle_proof(&mut self) -> Result, Self::Error> + fn read_merkle_proof(&mut self) -> IoResult> where F: RichField, H: Hasher, @@ -200,7 +196,7 @@ pub trait Read { fn read_fri_initial_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result, Self::Error> + ) -> IoResult> where F: RichField + Extendable, C: GenericConfig, @@ -239,7 +235,7 @@ pub trait Read { &mut self, arity: usize, compressed: bool, - ) -> Result, Self::Error> + ) -> IoResult> where F: RichField + Extendable, C: GenericConfig, @@ -257,7 +253,7 @@ pub trait Read { fn read_fri_query_rounds( &mut self, common_data: &CommonCircuitData, - ) -> Result>, Self::Error> + ) -> IoResult>> where F: RichField + Extendable, C: GenericConfig, @@ -285,7 +281,7 @@ pub trait Read { fn read_fri_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result, Self::Error> + ) -> IoResult> where F: RichField + Extendable, C: GenericConfig, @@ -312,7 +308,7 @@ pub trait Read { fn read_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result, Self::Error> + ) -> IoResult> where F: RichField + Extendable, C: GenericConfig, @@ -337,16 +333,14 @@ pub trait Read { fn read_proof_with_public_inputs( &mut self, common_data: &CommonCircuitData, - ) -> Result, Self::Error> + ) -> IoResult> where - Self: Position + Size, + Self: Remaining, F: RichField + Extendable, C: GenericConfig, { let proof = self.read_proof(common_data)?; - let public_inputs = self.read_field_vec( - (self.len() - self.position() as usize) / core::mem::size_of::(), - )?; + let public_inputs = self.read_field_vec(self.remaining() / size_of::())?; Ok(ProofWithPublicInputs { proof, public_inputs, @@ -358,7 +352,7 @@ pub trait Read { fn read_compressed_fri_query_rounds( &mut self, common_data: &CommonCircuitData, - ) -> Result, Self::Error> + ) -> IoResult> where F: RichField + Extendable, C: GenericConfig, @@ -406,7 +400,7 @@ pub trait Read { fn read_compressed_fri_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result, Self::Error> + ) -> IoResult> where F: RichField + Extendable, C: GenericConfig, @@ -433,7 +427,7 @@ pub trait Read { fn read_compressed_proof( &mut self, common_data: &CommonCircuitData, - ) -> Result, Self::Error> + ) -> IoResult> where F: RichField + Extendable, C: GenericConfig, @@ -458,16 +452,14 @@ pub trait Read { fn read_compressed_proof_with_public_inputs( &mut self, common_data: &CommonCircuitData, - ) -> Result, Self::Error> + ) -> IoResult> where - Self: Position + Size, + Self: Remaining, F: RichField + Extendable, C: GenericConfig, { let proof = self.read_compressed_proof(common_data)?; - let public_inputs = self.read_field_vec( - (self.len() - self.position() as usize) / core::mem::size_of::(), - )?; + let public_inputs = self.read_field_vec((self.remaining() as usize) / size_of::())?; Ok(CompressedProofWithPublicInputs { proof, public_inputs, @@ -481,23 +473,23 @@ pub trait Write { type Error; /// Writes all `bytes` to `self`. - fn write_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error>; + fn write_all(&mut self, bytes: &[u8]) -> IoResult<()>; /// Writes a byte `x` to `self`. #[inline] - fn write_u8(&mut self, x: u8) -> Result<(), Self::Error> { + fn write_u8(&mut self, x: u8) -> IoResult<()> { self.write_all(&[x]) } /// Writes a word `x` to `self.` #[inline] - fn write_u32(&mut self, x: u32) -> Result<(), Self::Error> { + fn write_u32(&mut self, x: u32) -> IoResult<()> { self.write_all(&x.to_le_bytes()) } /// Writes an element `x` from the field `F` to `self`. #[inline] - fn write_field(&mut self, x: F) -> Result<(), Self::Error> + fn write_field(&mut self, x: F) -> IoResult<()> where F: PrimeField64, { @@ -506,7 +498,7 @@ pub trait Write { /// Writes a vector `v` of elements from the field `F` to `self`. #[inline] - fn write_field_vec(&mut self, v: &[F]) -> Result<(), Self::Error> + fn write_field_vec(&mut self, v: &[F]) -> IoResult<()> where F: PrimeField64, { @@ -518,7 +510,7 @@ pub trait Write { /// Writes an element `x` from the field extension of `F` to `self`. #[inline] - fn write_field_ext(&mut self, x: F::Extension) -> Result<(), Self::Error> + fn write_field_ext(&mut self, x: F::Extension) -> IoResult<()> where F: RichField + Extendable, { @@ -530,10 +522,7 @@ pub trait Write { /// Writes a vector `v` of elements from the field extension of `F` to `self`. #[inline] - fn write_field_ext_vec( - &mut self, - v: &[F::Extension], - ) -> Result<(), Self::Error> + fn write_field_ext_vec(&mut self, v: &[F::Extension]) -> IoResult<()> where F: RichField + Extendable, { @@ -545,7 +534,7 @@ pub trait Write { /// Writes a hash `h` to `self`. #[inline] - fn write_hash(&mut self, h: H::Hash) -> Result<(), Self::Error> + fn write_hash(&mut self, h: H::Hash) -> IoResult<()> where F: RichField, H: Hasher, @@ -555,7 +544,7 @@ pub trait Write { /// Writes `cap`, a value of type [`MerkleCap`], to `self`. #[inline] - fn write_merkle_cap(&mut self, cap: &MerkleCap) -> Result<(), Self::Error> + fn write_merkle_cap(&mut self, cap: &MerkleCap) -> IoResult<()> where F: RichField, H: Hasher, @@ -568,10 +557,7 @@ pub trait Write { /// Writes a value `os` of type [`OpeningSet`] to `self.` #[inline] - fn write_opening_set( - &mut self, - os: &OpeningSet, - ) -> Result<(), Self::Error> + fn write_opening_set(&mut self, os: &OpeningSet) -> IoResult<()> where F: RichField + Extendable, { @@ -586,7 +572,7 @@ pub trait Write { /// Writes a value `p` of type [`MerkleProof`] to `self.` #[inline] - fn write_merkle_proof(&mut self, p: &MerkleProof) -> Result<(), Self::Error> + fn write_merkle_proof(&mut self, p: &MerkleProof) -> IoResult<()> where F: RichField, H: Hasher, @@ -608,7 +594,7 @@ pub trait Write { fn write_fri_initial_proof( &mut self, fitp: &FriInitialTreeProof, - ) -> Result<(), Self::Error> + ) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -625,7 +611,7 @@ pub trait Write { fn write_fri_query_step( &mut self, fqs: &FriQueryStep, - ) -> Result<(), Self::Error> + ) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -639,7 +625,7 @@ pub trait Write { fn write_fri_query_rounds( &mut self, fqrs: &[FriQueryRound], - ) -> Result<(), Self::Error> + ) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -658,7 +644,7 @@ pub trait Write { fn write_fri_proof( &mut self, fp: &FriProof, - ) -> Result<(), Self::Error> + ) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -673,10 +659,7 @@ pub trait Write { /// Writes a value `proof` of type [`Proof`] to `self.` #[inline] - fn write_proof( - &mut self, - proof: &Proof, - ) -> Result<(), Self::Error> + fn write_proof(&mut self, proof: &Proof) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -693,7 +676,7 @@ pub trait Write { fn write_proof_with_public_inputs( &mut self, proof_with_pis: &ProofWithPublicInputs, - ) -> Result<(), Self::Error> + ) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -711,7 +694,7 @@ pub trait Write { fn write_compressed_fri_query_rounds( &mut self, cfqrs: &CompressedFriQueryRounds, - ) -> Result<(), Self::Error> + ) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -739,7 +722,7 @@ pub trait Write { fn write_compressed_fri_proof( &mut self, fp: &CompressedFriProof, - ) -> Result<(), Self::Error> + ) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -757,7 +740,7 @@ pub trait Write { fn write_compressed_proof( &mut self, proof: &CompressedProof, - ) -> Result<(), Self::Error> + ) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -774,7 +757,7 @@ pub trait Write { fn write_compressed_proof_with_public_inputs( &mut self, proof_with_pis: &CompressedProofWithPublicInputs, - ) -> Result<(), Self::Error> + ) -> IoResult<()> where F: RichField + Extendable, C: GenericConfig, @@ -792,7 +775,7 @@ impl Write for Vec { type Error = Infallible; #[inline] - fn write_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { + fn write_all(&mut self, bytes: &[u8]) -> IoResult<()> { self.extend_from_slice(bytes); Ok(()) } @@ -801,55 +784,42 @@ impl Write for Vec { /// Buffer #[cfg(feature = "std")] #[derive(Debug)] -pub struct Buffer(Cursor>); +pub struct Buffer { + bytes: Vec, + pos: usize, +} #[cfg(feature = "std")] impl Buffer { /// Builds a new [`Buffer`] over `buffer`. #[inline] - pub fn new(buffer: Vec) -> Self { - Self(Cursor::new(buffer)) + pub fn new(bytes: Vec) -> Self { + Self { bytes, pos: 0 } } /// Returns the inner buffer. #[inline] pub fn bytes(self) -> Vec { - self.0.into_inner() + self.bytes } } -#[cfg(feature = "std")] -impl Size for Buffer { - #[inline] - fn len(&self) -> usize { - self.0.get_ref().len() +impl Remaining for Buffer { + fn remaining(&self) -> usize { + self.bytes.len() - self.pos } } -#[cfg(feature = "std")] -impl Position for Buffer { - #[inline] - fn position(&self) -> u64 { - self.0.position() - } -} - -#[cfg(feature = "std")] impl Read for Buffer { - type Error = io::Error; - #[inline] - fn read_exact(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error> { - self.0.read_exact(bytes) - } -} - -#[cfg(feature = "std")] -impl Write for Buffer { - type Error = io::Error; - - #[inline] - fn write_all(&mut self, bytes: &[u8]) -> Result<(), Self::Error> { - self.0.write_all(bytes) + fn read_exact(&mut self, bytes: &mut [u8]) -> IoResult<()> { + let n = bytes.len(); + if self.remaining() < n { + Err(IoError) + } else { + bytes.copy_from_slice(&self.bytes[self.pos..][..n]); + self.pos += n; + Ok(()) + } } } From 05f4d2be4e216db222afbbd7db910c3e749053f2 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sun, 20 Nov 2022 09:43:16 -0800 Subject: [PATCH 33/49] Remove conversion --- plonky2/src/util/serialization.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonky2/src/util/serialization.rs b/plonky2/src/util/serialization.rs index 712e936a..c3ad0887 100644 --- a/plonky2/src/util/serialization.rs +++ b/plonky2/src/util/serialization.rs @@ -459,7 +459,7 @@ pub trait Read { C: GenericConfig, { let proof = self.read_compressed_proof(common_data)?; - let public_inputs = self.read_field_vec((self.remaining() as usize) / size_of::())?; + let public_inputs = self.read_field_vec(self.remaining() / size_of::())?; Ok(CompressedProofWithPublicInputs { proof, public_inputs, From d23cecfcd86927da1598d4ae432a9f85c8fb6bee Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sun, 20 Nov 2022 12:46:15 -0800 Subject: [PATCH 34/49] Kernel code to do jumpdest analysis --- evm/src/cpu/kernel/aggregator.rs | 1 + evm/src/cpu/kernel/asm/account_code.asm | 4 +- evm/src/cpu/kernel/asm/core/bootloader.asm | 10 ++- .../cpu/kernel/asm/core/jumpdest_analysis.asm | 64 +++++++++++++++++++ evm/src/cpu/kernel/interpreter.rs | 19 ++++++ .../kernel/tests/core/jumpdest_analysis.rs | 42 ++++++++++++ evm/src/cpu/kernel/tests/core/mod.rs | 1 + evm/src/memory/segments.rs | 6 +- 8 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm create mode 100644 evm/src/cpu/kernel/tests/core/jumpdest_analysis.rs diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 9ccfcd15..83aabf00 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -16,6 +16,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/core/create_addresses.asm"), include_str!("asm/core/intrinsic_gas.asm"), include_str!("asm/core/invalid.asm"), + include_str!("asm/core/jumpdest_analysis.asm"), include_str!("asm/core/nonce.asm"), include_str!("asm/core/process_txn.asm"), include_str!("asm/core/syscall.asm"), diff --git a/evm/src/cpu/kernel/asm/account_code.asm b/evm/src/cpu/kernel/asm/account_code.asm index 14ea4037..c1cfa450 100644 --- a/evm/src/cpu/kernel/asm/account_code.asm +++ b/evm/src/cpu/kernel/asm/account_code.asm @@ -96,8 +96,8 @@ extcodecopy_end: // Loads the code at `address` in the `SEGMENT_KERNEL_ACCOUNT_CODE` at the current context and starting at offset 0. // Checks that the hash of the loaded code corresponds to the `codehash` in the state trie. // Pre stack: address, retdest -// Post stack: extcodesize(address) -load_code: +// Post stack: code_len +global load_code: %stack (address, retdest) -> (extcodehash, address, load_code_ctd, retdest) JUMP load_code_ctd: diff --git a/evm/src/cpu/kernel/asm/core/bootloader.asm b/evm/src/cpu/kernel/asm/core/bootloader.asm index 7ebdf022..d1062bdc 100644 --- a/evm/src/cpu/kernel/asm/core/bootloader.asm +++ b/evm/src/cpu/kernel/asm/core/bootloader.asm @@ -1,10 +1,14 @@ // Loads some prover-provided contract code into the code segment of memory, // then hashes the code and returns the hash. - global bootload_contract: - // stack: retdest + // stack: address, retdest +// %stack (address, retdest) -> (address, after_load_code, retdest) +// %jump(load_code) + PANIC // TODO - // TODO +global bootload_code: + // stack: code_len, retdest + PANIC // TODO // stack: code_hash, retdest SWAP1 diff --git a/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm b/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm new file mode 100644 index 00000000..a9d8adf2 --- /dev/null +++ b/evm/src/cpu/kernel/asm/core/jumpdest_analysis.asm @@ -0,0 +1,64 @@ +// Populates @SEGMENT_JUMPDEST_BITS for the given context's code. +// Pre stack: ctx, code_len, retdest +// Post stack: (empty) +global jumpdest_analysis: + // stack: ctx, code_len, retdest + PUSH 0 // i = 0 + +loop: + // stack: i, ctx, code_len, retdest + // Ideally we would break if i >= code_len, but checking i > code_len is + // cheaper. It doesn't hurt to over-read by 1, since we'll read 0 which is + // a no-op. + DUP3 DUP2 GT // i > code_len + %jumpi(return) + + // stack: i, ctx, code_len, retdest + %stack (i, ctx) -> (ctx, @SEGMENT_CODE, i, i, ctx) + MLOAD_GENERAL + // stack: opcode, i, ctx, code_len, retdest + + DUP1 %eq_const(0x5b) + // stack: opcode == JUMPDEST, opcode, i, ctx, code_len, retdest + %jumpi(encountered_jumpdest) + + // stack: opcode, i, ctx, code_len, retdest + %code_bytes_to_skip + // stack: bytes_to_skip, i, ctx, code_len, retdest + ADD + %jump(continue) + +encountered_jumpdest: + // stack: opcode, i, ctx, code_len, retdest + POP + // stack: i, ctx, code_len, retdest + %stack (i, ctx) -> (ctx, @SEGMENT_JUMPDEST_BITS, i, 1, i, ctx) + MSTORE_GENERAL + +continue: + // stack: i, ctx, code_len, retdest + %increment + %jump(loop) + +return: + // stack: i, ctx, code_len, retdest + %pop3 + JUMP + +// Determines how many bytes to skip, if any, based on the opcode we read. +// If we read a PUSH opcode, we skip over n bytes, otherwise we skip 0. +// +// Note that the range of PUSH opcodes is [0x60, 0x80). I.e. PUSH1 is 0x60 +// and PUSH32 is 0x7f. +%macro code_bytes_to_skip + // stack: opcode + %sub_const(0x60) + // stack: opcode - 0x60 + DUP1 %lt_const(0x20) + // stack: is_push_opcode, opcode - 0x60 + SWAP1 + %increment // n = opcode - 0x60 + 1 + // stack: n, is_push_opcode + MUL + // stack: bytes_to_skip +%endmacro diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 9f7d3483..d9d70232 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -202,6 +202,25 @@ impl<'a> Interpreter<'a> { rlp.into_iter().map(U256::from).collect(); } + pub(crate) fn set_code(&mut self, context: usize, code: Vec) { + assert_ne!(context, 0, "Can't modify kernel code."); + while self.memory.context_memory.len() <= context { + self.memory + .context_memory + .push(MemoryContextState::default()); + } + self.memory.context_memory[context].segments[Segment::Code as usize].content = + code.into_iter().map(U256::from).collect(); + } + + pub(crate) fn get_jumpdest_bits(&self, context: usize) -> Vec { + self.memory.context_memory[context].segments[Segment::JumpdestBits as usize] + .content + .iter() + .map(|x| x.bit(0)) + .collect() + } + fn incr(&mut self, n: usize) { self.offset += n; } diff --git a/evm/src/cpu/kernel/tests/core/jumpdest_analysis.rs b/evm/src/cpu/kernel/tests/core/jumpdest_analysis.rs new file mode 100644 index 00000000..022a18d7 --- /dev/null +++ b/evm/src/cpu/kernel/tests/core/jumpdest_analysis.rs @@ -0,0 +1,42 @@ +use anyhow::Result; + +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::interpreter::Interpreter; +use crate::cpu::kernel::opcodes::{get_opcode, get_push_opcode}; + +#[test] +fn test_jumpdest_analysis() -> Result<()> { + let jumpdest_analysis = KERNEL.global_labels["jumpdest_analysis"]; + const CONTEXT: usize = 3; // arbitrary + + let add = get_opcode("ADD"); + let push2 = get_push_opcode(2); + let jumpdest = get_opcode("JUMPDEST"); + + #[rustfmt::skip] + let code: Vec = vec![ + add, + jumpdest, + push2, + jumpdest, // part of PUSH2 + jumpdest, // part of PUSH2 + jumpdest, + add, + jumpdest, + ]; + + let expected_jumpdest_bits = vec![false, true, false, false, false, true, false, true]; + + // Contract creation transaction. + let initial_stack = vec![0xDEADBEEFu32.into(), code.len().into(), CONTEXT.into()]; + let mut interpreter = Interpreter::new_with_kernel(jumpdest_analysis, initial_stack); + interpreter.set_code(CONTEXT, code); + interpreter.run()?; + assert_eq!(interpreter.stack(), vec![]); + assert_eq!( + interpreter.get_jumpdest_bits(CONTEXT), + expected_jumpdest_bits + ); + + Ok(()) +} diff --git a/evm/src/cpu/kernel/tests/core/mod.rs b/evm/src/cpu/kernel/tests/core/mod.rs index dc9b2f39..502c57f1 100644 --- a/evm/src/cpu/kernel/tests/core/mod.rs +++ b/evm/src/cpu/kernel/tests/core/mod.rs @@ -1,2 +1,3 @@ mod create_addresses; mod intrinsic_gas; +mod jumpdest_analysis; diff --git a/evm/src/memory/segments.rs b/evm/src/memory/segments.rs index 7a28cb96..1587d890 100644 --- a/evm/src/memory/segments.rs +++ b/evm/src/memory/segments.rs @@ -38,10 +38,11 @@ pub(crate) enum Segment { /// A table of values 2^i for i=0..255 for use with shift /// instructions; initialised by `kernel/asm/shift.asm::init_shift_table()`. ShiftTable = 16, + JumpdestBits = 17, } impl Segment { - pub(crate) const COUNT: usize = 17; + pub(crate) const COUNT: usize = 18; pub(crate) fn all() -> [Self; Self::COUNT] { [ @@ -62,6 +63,7 @@ impl Segment { Self::TrieEncodedChild, Self::TrieEncodedChildLen, Self::ShiftTable, + Self::JumpdestBits, ] } @@ -85,6 +87,7 @@ impl Segment { Segment::TrieEncodedChild => "SEGMENT_TRIE_ENCODED_CHILD", Segment::TrieEncodedChildLen => "SEGMENT_TRIE_ENCODED_CHILD_LEN", Segment::ShiftTable => "SEGMENT_SHIFT_TABLE", + Segment::JumpdestBits => "SEGMENT_JUMPDEST_BITS", } } @@ -108,6 +111,7 @@ impl Segment { Segment::TrieEncodedChild => 256, Segment::TrieEncodedChildLen => 6, Segment::ShiftTable => 256, + Segment::JumpdestBits => 1, } } } From 108cb836213818a1869714fc530a397d4c39cdd7 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Mon, 21 Nov 2022 13:24:46 -0800 Subject: [PATCH 35/49] Domain separator option --- plonky2/src/plonk/circuit_builder.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 1667205f..9c899643 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -53,6 +53,11 @@ use crate::util::{log2_ceil, log2_strict, transpose, transpose_poly_values}; pub struct CircuitBuilder, const D: usize> { pub config: CircuitConfig, + /// A domain separator, which is included in the initial Fiat-Shamir seed. This is generally not + /// needed, but can be used to ensure that proofs for one application are not valid for another. + /// Defaults to zero. + domain_separator: Option, + /// The types of gates used in this circuit. gates: HashSet>, @@ -102,6 +107,7 @@ impl, const D: usize> CircuitBuilder { pub fn new(config: CircuitConfig) -> Self { let builder = CircuitBuilder { config, + domain_separator: None, gates: HashSet::new(), gate_instances: Vec::new(), public_inputs: Vec::new(), @@ -145,6 +151,11 @@ impl, const D: usize> CircuitBuilder { ); } + pub fn set_domain_separator(&mut self, separator: F) { + assert!(self.domain_separator.is_none()); + self.domain_separator = Some(separator); + } + pub fn num_gates(&self) -> usize { self.gate_instances.len() } @@ -853,6 +864,7 @@ impl, const D: usize> CircuitBuilder { let circuit_digest_parts = [ constants_sigmas_cap.flatten(), vec![ + self.domain_separator.unwrap_or_default(), F::from_canonical_usize(degree_bits), /* Add other circuit data here */ ], From 1b4acf591705548353d27188e1356ad25907d2a2 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Mon, 21 Nov 2022 13:54:39 -0800 Subject: [PATCH 36/49] Make load_code a bit more general So that it can be used to load code we're going to execute into the code segment of a certain context. --- evm/src/cpu/kernel/asm/account_code.asm | 45 ++++++++++++++----------- evm/src/generation/prover_input.rs | 4 +-- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/evm/src/cpu/kernel/asm/account_code.asm b/evm/src/cpu/kernel/asm/account_code.asm index c1cfa450..78d877ec 100644 --- a/evm/src/cpu/kernel/asm/account_code.asm +++ b/evm/src/cpu/kernel/asm/account_code.asm @@ -21,7 +21,7 @@ global extcodehash: %endmacro %macro extcodesize - %stack (address) -> (address, %%after) + %stack (address) -> (address, 0, @SEGMENT_KERNEL_ACCOUNT_CODE, %%after) %jump(load_code) %%after: %endmacro @@ -44,7 +44,8 @@ global extcodesize: // Post stack: (empty) global extcodecopy: // stack: address, dest_offset, offset, size, retdest - %stack (address, dest_offset, offset, size, retdest) -> (address, extcodecopy_contd, size, offset, dest_offset, retdest) + %stack (address, dest_offset, offset, size, retdest) + -> (address, 0, @SEGMENT_KERNEL_ACCOUNT_CODE, extcodecopy_contd, size, offset, dest_offset, retdest) %jump(load_code) extcodecopy_contd: @@ -55,19 +56,22 @@ extcodecopy_contd: // Loop copying the `code[offset]` to `memory[dest_offset]` until `i==size`. // Each iteration increments `offset, dest_offset, i`. +// TODO: Consider implementing this with memcpy. extcodecopy_loop: // stack: i, size, code_length, offset, dest_offset, retdest DUP2 DUP2 EQ // stack: i == size, i, size, code_length, offset, dest_offset, retdest %jumpi(extcodecopy_end) - %stack (i, size, code_length, offset, dest_offset, retdest) -> (offset, code_length, offset, code_length, dest_offset, i, size, retdest) + %stack (i, size, code_length, offset, dest_offset, retdest) + -> (offset, code_length, offset, code_length, dest_offset, i, size, retdest) LT // stack: offset < code_length, offset, code_length, dest_offset, i, size, retdest DUP2 // stack: offset, offset < code_length, offset, code_length, dest_offset, i, size, retdest %mload_current(@SEGMENT_KERNEL_ACCOUNT_CODE) // stack: opcode, offset < code_length, offset, code_length, dest_offset, i, size, retdest - %stack (opcode, offset_lt_code_length, offset, code_length, dest_offset, i, size, retdest) -> (offset_lt_code_length, 0, opcode, offset, code_length, dest_offset, i, size, retdest) + %stack (opcode, offset_lt_code_length, offset, code_length, dest_offset, i, size, retdest) + -> (offset_lt_code_length, 0, opcode, offset, code_length, dest_offset, i, size, retdest) // If `offset >= code_length`, use `opcode=0`. Necessary since `SEGMENT_KERNEL_ACCOUNT_CODE` might be clobbered from previous calls. %select_bool // stack: opcode, offset, code_length, dest_offset, i, size, retdest @@ -93,41 +97,42 @@ extcodecopy_end: JUMP -// Loads the code at `address` in the `SEGMENT_KERNEL_ACCOUNT_CODE` at the current context and starting at offset 0. +// Loads the code at `address` into memory, at the given context and segment, starting at offset 0. // Checks that the hash of the loaded code corresponds to the `codehash` in the state trie. -// Pre stack: address, retdest +// Pre stack: address, ctx, segment, retdest // Post stack: code_len global load_code: - %stack (address, retdest) -> (extcodehash, address, load_code_ctd, retdest) + %stack (address, ctx, segment, retdest) -> (extcodehash, address, load_code_ctd, ctx, segment, retdest) JUMP load_code_ctd: - // stack: codehash, retdest + // stack: codehash, ctx, segment, retdest PROVER_INPUT(account_code::length) - // stack: code_length, codehash, retdest + // stack: code_length, codehash, ctx, segment, retdest PUSH 0 // Loop non-deterministically querying `code[i]` and storing it in `SEGMENT_KERNEL_ACCOUNT_CODE` at offset `i`, until `i==code_length`. load_code_loop: - // stack: i, code_length, codehash, retdest + // stack: i, code_length, codehash, ctx, segment, retdest DUP2 DUP2 EQ - // stack: i == code_length, i, code_length, codehash, retdest + // stack: i == code_length, i, code_length, codehash, ctx, segment, retdest %jumpi(load_code_check) PROVER_INPUT(account_code::get) - // stack: opcode, i, code_length, codehash, retdest + // stack: opcode, i, code_length, codehash, ctx, segment, retdest DUP2 - // stack: i, opcode, i, code_length, codehash, retdest - %mstore_current(@SEGMENT_KERNEL_ACCOUNT_CODE) - // stack: i, code_length, codehash, retdest + // stack: i, opcode, i, code_length, codehash, ctx, segment, retdest + DUP7 // segment + DUP7 // context + MSTORE_GENERAL + // stack: i, code_length, codehash, ctx, segment, retdest %increment - // stack: i+1, code_length, codehash, retdest + // stack: i+1, code_length, codehash, ctx, segment, retdest %jump(load_code_loop) // Check that the hash of the loaded code equals `codehash`. load_code_check: - // stack: i, code_length, codehash, retdest - POP - // stack: code_length, codehash, retdest - %stack (code_length, codehash, retdest) -> (0, @SEGMENT_KERNEL_ACCOUNT_CODE, 0, code_length, codehash, retdest, code_length) + // stack: i, code_length, codehash, ctx, segment, retdest + %stack (i, code_length, codehash, ctx, segment, retdest) + -> (ctx, segment, 0, code_length, codehash, retdest, code_length) KECCAK_GENERAL // stack: shouldbecodehash, codehash, retdest, code_length %assert_eq diff --git a/evm/src/generation/prover_input.rs b/evm/src/generation/prover_input.rs index ad1cfce0..4515bd95 100644 --- a/evm/src/generation/prover_input.rs +++ b/evm/src/generation/prover_input.rs @@ -70,7 +70,7 @@ impl GenerationState { match input_fn.0[1].as_str() { "length" => { // Return length of code. - // stack: codehash + // stack: codehash, ... let codehash = stack.last().expect("Empty stack"); self.inputs.contract_code[&H256::from_uint(codehash)] .len() @@ -78,7 +78,7 @@ impl GenerationState { } "get" => { // Return `code[i]`. - // stack: i, code_length, codehash + // stack: i, code_length, codehash, ... let stacklen = stack.len(); let i = stack[stacklen - 1].as_usize(); let codehash = stack[stacklen - 3]; From af1b6680e8a63c30a2f972fc8ef140e057af0e67 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 22 Nov 2022 08:02:22 -0800 Subject: [PATCH 37/49] Switch to Vec --- plonky2/src/plonk/circuit_builder.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 9c899643..c2c13b2c 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -40,7 +40,7 @@ use crate::plonk::circuit_data::{ CircuitConfig, CircuitData, CommonCircuitData, ProverCircuitData, ProverOnlyCircuitData, VerifierCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; -use crate::plonk::config::{GenericConfig, Hasher}; +use crate::plonk::config::{GenericConfig, GenericHashOut, Hasher}; use crate::plonk::copy_constraint::CopyConstraint; use crate::plonk::permutation_argument::Forest; use crate::plonk::plonk_common::PlonkOracle; @@ -56,7 +56,7 @@ pub struct CircuitBuilder, const D: usize> { /// A domain separator, which is included in the initial Fiat-Shamir seed. This is generally not /// needed, but can be used to ensure that proofs for one application are not valid for another. /// Defaults to zero. - domain_separator: Option, + domain_separator: Option>, /// The types of gates used in this circuit. gates: HashSet>, @@ -151,7 +151,7 @@ impl, const D: usize> CircuitBuilder { ); } - pub fn set_domain_separator(&mut self, separator: F) { + pub fn set_domain_separator(&mut self, separator: Vec) { assert!(self.domain_separator.is_none()); self.domain_separator = Some(separator); } @@ -860,11 +860,13 @@ impl, const D: usize> CircuitBuilder { num_partial_products(self.config.num_routed_wires, quotient_degree_factor); let constants_sigmas_cap = constants_sigmas_commitment.merkle_tree.cap.clone(); + let domain_separator = self.domain_separator.unwrap_or_default(); + let domain_separator_digest = C::Hasher::hash_pad(&domain_separator); // TODO: This should also include an encoding of gate constraints. let circuit_digest_parts = [ constants_sigmas_cap.flatten(), + domain_separator_digest.to_vec(), vec![ - self.domain_separator.unwrap_or_default(), F::from_canonical_usize(degree_bits), /* Add other circuit data here */ ], From 7ec14029c68e42b454181cf019e063e1f8669aff Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 22 Nov 2022 08:04:01 -0800 Subject: [PATCH 38/49] Fix comment --- plonky2/src/plonk/circuit_builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index c2c13b2c..8bd1d994 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -55,7 +55,7 @@ pub struct CircuitBuilder, const D: usize> { /// A domain separator, which is included in the initial Fiat-Shamir seed. This is generally not /// needed, but can be used to ensure that proofs for one application are not valid for another. - /// Defaults to zero. + /// Defaults to the empty vector. domain_separator: Option>, /// The types of gates used in this circuit. From 4048107892a4876922f38761877330b7683404a7 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 22 Nov 2022 20:09:10 -0800 Subject: [PATCH 39/49] Cyclic recursion tweaks --- plonky2/src/recursion/cyclic_recursion.rs | 35 ++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index efc336bc..04213f9e 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -35,7 +35,7 @@ pub struct CyclicRecursionTarget { pub verifier_data: VerifierCircuitTarget, pub dummy_proof: ProofWithPublicInputsTarget, pub dummy_verifier_data: VerifierCircuitTarget, - pub base_case: BoolTarget, + pub condition: BoolTarget, } impl, const D: usize> VerifierOnlyCircuitData { @@ -91,12 +91,22 @@ impl VerifierCircuitTarget { } impl, const D: usize> CircuitBuilder { - /// Cyclic recursion gadget. + /// If `condition` is true, recursively verify a proof for the same circuit as the one we're + /// currently building. + /// + /// For a typical IVC use case, `condition` will be false for the very first proof in a chain, + /// i.e. the base case. + /// + /// Note that this does not enforce that the inner circuit uses the correct verification key. + /// This is not possible to check in this recursive circuit, since we do not know the + /// verification key until after we build it. Verifiers must separately call + /// `check_cyclic_proof_verifier_data`, in addition to verifying a recursive proof, to check + /// that the verification key matches. + /// /// WARNING: Do not register any public input after calling this! TODO: relax this pub fn cyclic_recursion>( &mut self, - // Flag set to true for the base case of the cycle where we verify a dummy proof to bootstrap the cycle. Set to false otherwise. - base_case: BoolTarget, + condition: BoolTarget, previous_virtual_public_inputs: &[Target], common_data: &mut CommonCircuitData, ) -> Result> @@ -137,13 +147,13 @@ impl, const D: usize> CircuitBuilder { self.connect(*x, *y); } - // Verify the dummy proof if `base_case` is set to true, otherwise verify the "real" proof. + // Verify the real proof if `condition` is set to true, otherwise verify the dummy proof. self.conditionally_verify_proof::( - base_case, - &dummy_proof, - &dummy_verifier_data, + condition, &proof, &verifier_data, + &dummy_proof, + &dummy_verifier_data, common_data, ); @@ -161,7 +171,7 @@ impl, const D: usize> CircuitBuilder { verifier_data: verifier_data.clone(), dummy_proof, dummy_verifier_data, - base_case, + condition, }) } } @@ -182,7 +192,7 @@ where C::Hasher: AlgebraicHasher, { if let Some(proof) = cyclic_recursion_data.proof { - pw.set_bool_target(cyclic_recursion_data_target.base_case, false); + pw.set_bool_target(cyclic_recursion_data_target.condition, true); pw.set_proof_with_pis_target(&cyclic_recursion_data_target.proof, proof); pw.set_verifier_data_target( &cyclic_recursion_data_target.verifier_data, @@ -195,7 +205,7 @@ where ); } else { let (dummy_proof, dummy_data) = dummy_proof::(cyclic_recursion_data.common_data)?; - pw.set_bool_target(cyclic_recursion_data_target.base_case, true); + pw.set_bool_target(cyclic_recursion_data_target.condition, false); let mut proof = dummy_proof.clone(); proof.public_inputs[0..public_inputs.len()].copy_from_slice(public_inputs); let pis_len = proof.public_inputs.len(); @@ -231,8 +241,7 @@ where } /// Additional checks to be performed on a cyclic recursive proof in addition to verifying the proof. -/// Checks that the `base_case` flag is boolean and that the purported verifier data in the public inputs -/// match the real verifier data. +/// Checks that the purported verifier data in the public inputs match the real verifier data. pub fn check_cyclic_proof_verifier_data< F: RichField + Extendable, C: GenericConfig, From 964d2bc3736d75df4df6fe918caa23062a89d3a4 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 22 Nov 2022 22:33:41 -0800 Subject: [PATCH 40/49] Fix test --- plonky2/src/recursion/cyclic_recursion.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index 04213f9e..2e4f2613 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -337,7 +337,6 @@ mod tests { builder.register_public_inputs(&h.elements); // Previous counter. let old_counter = builder.add_virtual_target(); - let one = builder.one(); let new_counter = builder.add_virtual_public_input(); let old_pis = [ initial_hash.elements.as_slice(), @@ -348,16 +347,15 @@ mod tests { let mut common_data = common_data_for_recursion::(); - let base_case = builder.add_virtual_bool_target_safe(); + let condition = builder.add_virtual_bool_target_safe(); // Add cyclic recursion gadget. let cyclic_data_target = - builder.cyclic_recursion::(base_case, &old_pis, &mut common_data)?; + builder.cyclic_recursion::(condition, &old_pis, &mut common_data)?; let input_hash_bis = - builder.select_hash(cyclic_data_target.base_case, initial_hash, old_hash); + builder.select_hash(cyclic_data_target.condition, old_hash, initial_hash); builder.connect_hashes(input_hash, input_hash_bis); - let not_base_case = builder.sub(one, cyclic_data_target.base_case.target); // New counter is the previous counter +1 if the previous proof wasn't a base case. - let new_counter_bis = builder.add(old_counter, not_base_case); + let new_counter_bis = builder.add(old_counter, condition.target); builder.connect(new_counter, new_counter_bis); let cyclic_circuit_data = builder.build::(); From da23fb116b934925f8a5cf37c2f1f092452fdc4d Mon Sep 17 00:00:00 2001 From: BGluth Date: Mon, 28 Nov 2022 17:47:31 -0700 Subject: [PATCH 41/49] Set CI to use an older version of nightly - Needed until https://github.com/rust-lang/rust/issues/105037 is fixed. --- .github/workflows/continuous-integration-workflow.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index d929acd9..48848b73 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -24,7 +24,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly + toolchain: nightly-2022-11-23 override: true - name: rust-cache @@ -60,7 +60,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: nightly + toolchain: nightly-2022-11-23 override: true components: rustfmt, clippy From c528da4e66f2afff30a20acd6a613b9b4651f754 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Wed, 23 Nov 2022 14:24:09 -0800 Subject: [PATCH 42/49] Cyclic recursion tweaks - Have the caller to `cyclic_recursion` create and pass in the virtual proof - Split `dummy_proof` into preprocessing and proving, so that we don't need to redo the preprocessing work in each `set_cyclic_recursion_data_target` call - Have the caller update `num_public_inputs` instead of doing it in `cyclic_recursion`. This is a little less convenient but I think it's best not to modify the caller's config (principle of least surprise) - Have `set_cyclic_recursion_data_target` take a sparse set of public inputs. Taking some PIs with the lowest indices didn't seem very general. I still have some reservations about this part of the API - I think it would seem cleaner if PIs of a proof which wasn't selected for verification were simply ignored - but perhaps there are some optimization reasons to keep using them. --- plonky2/src/fri/proof.rs | 2 +- plonky2/src/gadgets/polynomial.rs | 2 +- plonky2/src/hash/hash_types.rs | 37 ++++ plonky2/src/plonk/circuit_builder.rs | 9 +- plonky2/src/plonk/proof.rs | 4 +- .../conditional_recursive_verifier.rs | 62 +----- plonky2/src/recursion/cyclic_recursion.rs | 187 ++++++++++-------- plonky2/src/recursion/dummy_circuit.rs | 69 +++++++ plonky2/src/recursion/mod.rs | 1 + 9 files changed, 229 insertions(+), 144 deletions(-) create mode 100644 plonky2/src/recursion/dummy_circuit.rs diff --git a/plonky2/src/fri/proof.rs b/plonky2/src/fri/proof.rs index 4c5f65d8..f841b274 100644 --- a/plonky2/src/fri/proof.rs +++ b/plonky2/src/fri/proof.rs @@ -112,7 +112,7 @@ pub struct FriProof, H: Hasher, const D: usize> pub pow_witness: F, } -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct FriProofTarget { pub commit_phase_merkle_caps: Vec, pub query_round_proofs: Vec>, diff --git a/plonky2/src/gadgets/polynomial.rs b/plonky2/src/gadgets/polynomial.rs index f7a59192..80beb62f 100644 --- a/plonky2/src/gadgets/polynomial.rs +++ b/plonky2/src/gadgets/polynomial.rs @@ -7,7 +7,7 @@ use crate::iop::target::Target; use crate::plonk::circuit_builder::CircuitBuilder; use crate::util::reducing::ReducingFactorTarget; -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct PolynomialCoeffsExtTarget(pub Vec>); impl PolynomialCoeffsExtTarget { diff --git a/plonky2/src/hash/hash_types.rs b/plonky2/src/hash/hash_types.rs index b95a2113..c725c45c 100644 --- a/plonky2/src/hash/hash_types.rs +++ b/plonky2/src/hash/hash_types.rs @@ -1,5 +1,6 @@ use alloc::vec::Vec; +use anyhow::ensure; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::field::goldilocks_field::GoldilocksField; @@ -25,6 +26,7 @@ impl HashOut { elements: [F::ZERO; 4], }; + // TODO: Switch to a TryFrom impl. pub fn from_vec(elements: Vec) -> Self { debug_assert!(elements.len() == 4); Self { @@ -39,6 +41,23 @@ impl HashOut { } } +impl From<[F; 4]> for HashOut { + fn from(elements: [F; 4]) -> Self { + Self { elements } + } +} + +impl TryFrom<&[F]> for HashOut { + type Error = anyhow::Error; + + fn try_from(elements: &[F]) -> Result { + ensure!(elements.len() == 4); + Ok(Self { + elements: elements.try_into().unwrap(), + }) + } +} + impl Sample for HashOut where F: Field, @@ -97,6 +116,7 @@ pub struct HashOutTarget { } impl HashOutTarget { + // TODO: Switch to a TryFrom impl. pub fn from_vec(elements: Vec) -> Self { debug_assert!(elements.len() == 4); Self { @@ -111,6 +131,23 @@ impl HashOutTarget { } } +impl From<[Target; 4]> for HashOutTarget { + fn from(elements: [Target; 4]) -> Self { + Self { elements } + } +} + +impl TryFrom<&[Target]> for HashOutTarget { + type Error = anyhow::Error; + + fn try_from(elements: &[Target]) -> Result { + ensure!(elements.len() == 4); + Ok(Self { + elements: elements.try_into().unwrap(), + }) + } +} + #[derive(Clone, Debug)] pub struct MerkleCapTarget(pub Vec); diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index 8bd1d994..c9f2edf0 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -244,9 +244,14 @@ impl, const D: usize> CircuitBuilder { self.register_public_input(t); t } + /// Add a virtual verifier data, register it as a public input and set it to `self.verifier_data_public_input`. /// WARNING: Do not register any public input after calling this! TODO: relax this - pub(crate) fn add_verifier_data_public_input(&mut self) { + pub fn add_verifier_data_public_inputs(&mut self) { + if self.verifier_data_public_input.is_some() { + return; + } + let verifier_data = VerifierCircuitTarget { constants_sigmas_cap: self.add_virtual_cap(self.config.fri_config.cap_height), circuit_digest: self.add_virtual_hash(), @@ -886,7 +891,7 @@ impl, const D: usize> CircuitBuilder { num_partial_products, }; if let Some(goal_data) = self.goal_common_data { - assert_eq!(goal_data, common); + assert_eq!(goal_data, common, "The expected circuit data passed to cyclic recursion method did not match the actual circuit"); } let prover_only = ProverOnlyCircuitData { diff --git a/plonky2/src/plonk/proof.rs b/plonky2/src/plonk/proof.rs index caf3a7f8..fb9e6cde 100644 --- a/plonky2/src/plonk/proof.rs +++ b/plonky2/src/plonk/proof.rs @@ -40,7 +40,7 @@ pub struct Proof, C: GenericConfig, const pub opening_proof: FriProof, } -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct ProofTarget { pub wires_cap: MerkleCapTarget, pub plonk_zs_partial_products_cap: MerkleCapTarget, @@ -283,7 +283,7 @@ pub(crate) struct FriInferredElements, const D: usi pub Vec, ); -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct ProofWithPublicInputsTarget { pub proof: ProofTarget, pub public_inputs: Vec, diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index 6cbce94a..e7b727b5 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -1,7 +1,5 @@ -use alloc::vec; use alloc::vec::Vec; -use anyhow::{ensure, Result}; use itertools::Itertools; use crate::field::extension::Extendable; @@ -9,66 +7,16 @@ use crate::fri::proof::{ FriInitialTreeProofTarget, FriProofTarget, FriQueryRoundTarget, FriQueryStepTarget, }; use crate::gadgets::polynomial::PolynomialCoeffsExtTarget; -use crate::gates::noop::NoopGate; use crate::hash::hash_types::{HashOutTarget, MerkleCapTarget, RichField}; use crate::hash::merkle_proofs::MerkleProofTarget; use crate::iop::ext_target::ExtensionTarget; use crate::iop::target::{BoolTarget, Target}; -use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; -use crate::plonk::circuit_data::{ - CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, -}; +use crate::plonk::circuit_data::{CommonCircuitData, VerifierCircuitTarget}; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; -use crate::plonk::proof::{ - OpeningSetTarget, ProofTarget, ProofWithPublicInputs, ProofWithPublicInputsTarget, -}; -use crate::util::ceil_div_usize; +use crate::plonk::proof::{OpeningSetTarget, ProofTarget, ProofWithPublicInputsTarget}; use crate::with_context; -/// Generate a proof having a given `CommonCircuitData`. -pub(crate) fn dummy_proof< - F: RichField + Extendable, - C: GenericConfig, - const D: usize, ->( - common_data: &CommonCircuitData, -) -> Result<( - ProofWithPublicInputs, - VerifierOnlyCircuitData, -)> { - let config = common_data.config.clone(); - - let mut pw = PartialWitness::new(); - let mut builder = CircuitBuilder::::new(config); - - ensure!( - !common_data.config.zero_knowledge, - "Degree calculation can be off if zero-knowledge is on." - ); - let degree = common_data.degree(); - // Number of `NoopGate`s to add to get a circuit of size `degree` in the end. - // Need to account for public input hashing, a `PublicInputGate` and a `ConstantGate`. - let num_noop_gate = degree - ceil_div_usize(common_data.num_public_inputs, 8) - 2; - - for _ in 0..num_noop_gate { - builder.add_gate(NoopGate, vec![]); - } - for gate in &common_data.gates { - builder.add_gate_to_gate_set(gate.clone()); - } - for _ in 0..common_data.num_public_inputs { - let t = builder.add_virtual_public_input(); - pw.set_target(t, F::ZERO); - } - - let data = builder.build::(); - assert_eq!(&data.common, common_data); - let proof = data.prove(pw)?; - - Ok((proof, data.verifier_only)) -} - impl, const D: usize> CircuitBuilder { /// Verify `proof0` if `condition` else verify `proof1`. /// `proof0` and `proof1` are assumed to use the same `CommonCircuitData`. @@ -376,6 +324,7 @@ mod tests { use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_data::CircuitConfig; use crate::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; + use crate::recursion::dummy_circuit::{dummy_circuit, dummy_proof}; #[test] fn test_conditional_recursive_verifier() -> Result<()> { @@ -400,7 +349,8 @@ mod tests { data.verify(proof.clone())?; // Generate dummy proof with the same `CommonCircuitData`. - let (dummy_proof, dummy_data) = dummy_proof(&data.common)?; + let dummy_data = dummy_circuit(&data.common); + let dummy_proof = dummy_proof(&dummy_data, &[])?; // Conditionally verify the two proofs. let mut builder = CircuitBuilder::::new(config); @@ -418,7 +368,7 @@ mod tests { constants_sigmas_cap: builder.add_virtual_cap(data.common.config.fri_config.cap_height), circuit_digest: builder.add_virtual_hash(), }; - pw.set_verifier_data_target(&dummy_inner_data, &dummy_data); + pw.set_verifier_data_target(&dummy_inner_data, &dummy_data.verifier_only); let b = builder.constant_bool(F::rand().0 % 2 == 0); builder.conditionally_verify_proof::( b, diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index 2e4f2613..b466c034 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -13,11 +13,11 @@ use crate::iop::target::{BoolTarget, Target}; use crate::iop::witness::{PartialWitness, Witness}; use crate::plonk::circuit_builder::CircuitBuilder; use crate::plonk::circuit_data::{ - CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, + CircuitData, CommonCircuitData, VerifierCircuitTarget, VerifierOnlyCircuitData, }; use crate::plonk::config::{AlgebraicHasher, GenericConfig}; use crate::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; -use crate::recursion::conditional_recursive_verifier::dummy_proof; +use crate::recursion::dummy_circuit::{dummy_circuit, dummy_proof}; pub struct CyclicRecursionData< 'a, @@ -30,12 +30,17 @@ pub struct CyclicRecursionData< common_data: &'a CommonCircuitData, } -pub struct CyclicRecursionTarget { - pub proof: ProofWithPublicInputsTarget, - pub verifier_data: VerifierCircuitTarget, - pub dummy_proof: ProofWithPublicInputsTarget, - pub dummy_verifier_data: VerifierCircuitTarget, - pub condition: BoolTarget, +pub struct CyclicRecursionTarget +where + F: RichField + Extendable, + C: GenericConfig, +{ + pub(crate) proof: ProofWithPublicInputsTarget, + pub(crate) verifier_data: VerifierCircuitTarget, + pub(crate) dummy_proof: ProofWithPublicInputsTarget, + pub(crate) dummy_verifier_data: VerifierCircuitTarget, + pub(crate) condition: BoolTarget, + pub(crate) dummy_circuit: CircuitData, } impl, const D: usize> VerifierOnlyCircuitData { @@ -107,17 +112,16 @@ impl, const D: usize> CircuitBuilder { pub fn cyclic_recursion>( &mut self, condition: BoolTarget, - previous_virtual_public_inputs: &[Target], - common_data: &mut CommonCircuitData, - ) -> Result> + proof_with_pis: &ProofWithPublicInputsTarget, + common_data: &CommonCircuitData, + ) -> Result> where C::Hasher: AlgebraicHasher, { - if self.verifier_data_public_input.is_none() { - self.add_verifier_data_public_input(); - } - let verifier_data = self.verifier_data_public_input.clone().unwrap(); - common_data.num_public_inputs = self.num_public_inputs(); + let verifier_data = self + .verifier_data_public_input + .clone() + .expect("Must call add_verifier_data_public_inputs before cyclic recursion"); self.goal_common_data = Some(common_data.clone()); let dummy_verifier_data = VerifierCircuitTarget { @@ -125,10 +129,12 @@ impl, const D: usize> CircuitBuilder { circuit_digest: self.add_virtual_hash(), }; - let proof = self.add_virtual_proof_with_pis::(common_data); let dummy_proof = self.add_virtual_proof_with_pis::(common_data); - let pis = VerifierCircuitTarget::from_slice::(&proof.public_inputs, common_data)?; + let pis = VerifierCircuitTarget::from_slice::( + &proof_with_pis.public_inputs, + common_data, + )?; // Connect previous verifier data to current one. This guarantees that every proof in the cycle uses the same verifier data. self.connect_hashes(pis.circuit_digest, verifier_data.circuit_digest); for (h0, h1) in pis @@ -140,17 +146,10 @@ impl, const D: usize> CircuitBuilder { self.connect_hashes(*h0, *h1); } - for (x, y) in previous_virtual_public_inputs - .iter() - .zip(&proof.public_inputs) - { - self.connect(*x, *y); - } - // Verify the real proof if `condition` is set to true, otherwise verify the dummy proof. self.conditionally_verify_proof::( condition, - &proof, + proof_with_pis, &verifier_data, &dummy_proof, &dummy_verifier_data, @@ -167,11 +166,12 @@ impl, const D: usize> CircuitBuilder { } Ok(CyclicRecursionTarget { - proof, - verifier_data: verifier_data.clone(), + proof: proof_with_pis.clone(), + verifier_data, dummy_proof, dummy_verifier_data, condition, + dummy_circuit: dummy_circuit(common_data), }) } } @@ -183,10 +183,10 @@ pub fn set_cyclic_recursion_data_target< const D: usize, >( pw: &mut PartialWitness, - cyclic_recursion_data_target: &CyclicRecursionTarget, + cyclic_recursion_data_target: &CyclicRecursionTarget, cyclic_recursion_data: &CyclicRecursionData, // Public inputs to set in the base case to seed some initial data. - public_inputs: &[F], + public_inputs: &[(usize, F)], ) -> Result<()> where C::Hasher: AlgebraicHasher, @@ -204,36 +204,42 @@ where cyclic_recursion_data.verifier_data, ); } else { - let (dummy_proof, dummy_data) = dummy_proof::(cyclic_recursion_data.common_data)?; pw.set_bool_target(cyclic_recursion_data_target.condition, false); - let mut proof = dummy_proof.clone(); - proof.public_inputs[0..public_inputs.len()].copy_from_slice(public_inputs); - let pis_len = proof.public_inputs.len(); - // The circuit checks that the verifier data is the same throughout the cycle, so - // we set the verifier data to the "real" verifier data even though it's unused in the base case. - let num_cap = cyclic_recursion_data + + let pis_len = cyclic_recursion_data_target + .dummy_circuit + .common + .num_public_inputs; + let cap_elements = cyclic_recursion_data .common_data .config .fri_config .num_cap_elements(); - let s = pis_len - 4 - 4 * num_cap; - proof.public_inputs[s..s + 4] - .copy_from_slice(&cyclic_recursion_data.verifier_data.circuit_digest.elements); - for i in 0..num_cap { - proof.public_inputs[s + 4 * (1 + i)..s + 4 * (2 + i)].copy_from_slice( - &cyclic_recursion_data.verifier_data.constants_sigmas_cap.0[i].elements, - ); + let start_vk_pis = pis_len - 4 - 4 * cap_elements; + + // The circuit checks that the verifier data is the same throughout the cycle, so + // we set the verifier data to the "real" verifier data even though it's unused in the base case. + let mut public_inputs = public_inputs.to_vec(); + let verifier_data = &cyclic_recursion_data.verifier_data; + public_inputs.extend((start_vk_pis..).zip(verifier_data.circuit_digest.elements)); + + for i in 0..cap_elements { + let start = start_vk_pis + 4 + 4 * i; + public_inputs.extend((start..).zip(verifier_data.constants_sigmas_cap.0[i].elements)); } + let proof = dummy_proof(&cyclic_recursion_data_target.dummy_circuit, &public_inputs)?; pw.set_proof_with_pis_target(&cyclic_recursion_data_target.proof, &proof); pw.set_verifier_data_target( &cyclic_recursion_data_target.verifier_data, cyclic_recursion_data.verifier_data, ); - pw.set_proof_with_pis_target(&cyclic_recursion_data_target.dummy_proof, &dummy_proof); + + let dummy_p = dummy_proof(&cyclic_recursion_data_target.dummy_circuit, &[])?; + pw.set_proof_with_pis_target(&cyclic_recursion_data_target.dummy_proof, &dummy_p); pw.set_verifier_data_target( &cyclic_recursion_data_target.dummy_verifier_data, - &dummy_data, + &cyclic_recursion_data_target.dummy_circuit.verifier_only, ); } @@ -264,11 +270,12 @@ where #[cfg(test)] mod tests { use anyhow::Result; + use itertools::Itertools; use crate::field::extension::Extendable; use crate::field::types::{Field, PrimeField64}; use crate::gates::noop::NoopGate; - use crate::hash::hash_types::RichField; + use crate::hash::hash_types::{HashOutTarget, RichField}; use crate::hash::hashing::hash_n_to_hash_no_pad; use crate::hash::poseidon::{PoseidonHash, PoseidonPermutation}; use crate::iop::witness::PartialWitness; @@ -315,6 +322,12 @@ mod tests { builder.build::().common } + /// Uses cyclic recursion to build a hash chain. + /// The circuit has the following public input structure: + /// - Initial hash (4) + /// - Output for the tip of the hash chain (4) + /// - Chain length, i.e. the number of times the hash has been applied (1) + /// - VK for cyclic recursion (?) #[test] fn test_cyclic_recursion() -> Result<()> { const D: usize = 2; @@ -322,55 +335,62 @@ mod tests { type F = >::F; let config = CircuitConfig::standard_recursion_config(); - let mut pw = PartialWitness::new(); let mut builder = CircuitBuilder::::new(config); + let one = builder.one(); // Circuit that computes a repeated hash. let initial_hash = builder.add_virtual_hash(); builder.register_public_inputs(&initial_hash.elements); - // Hash from the previous proof. - let old_hash = builder.add_virtual_hash(); - // The input hash is either the previous hash or the initial hash depending on whether - // the last proof was a base case. - let input_hash = builder.add_virtual_hash(); - let h = builder.hash_n_to_hash_no_pad::(input_hash.elements.to_vec()); - builder.register_public_inputs(&h.elements); - // Previous counter. - let old_counter = builder.add_virtual_target(); - let new_counter = builder.add_virtual_public_input(); - let old_pis = [ - initial_hash.elements.as_slice(), - old_hash.elements.as_slice(), - [old_counter].as_slice(), - ] - .concat(); + let current_hash_in = builder.add_virtual_hash(); + let current_hash_out = + builder.hash_n_to_hash_no_pad::(current_hash_in.elements.to_vec()); + builder.register_public_inputs(¤t_hash_out.elements); + let counter = builder.add_virtual_public_input(); let mut common_data = common_data_for_recursion::(); + builder.add_verifier_data_public_inputs(); + common_data.num_public_inputs = builder.num_public_inputs(); let condition = builder.add_virtual_bool_target_safe(); - // Add cyclic recursion gadget. + + // Unpack inner proof's public inputs. + let inner_proof_with_pis = builder.add_virtual_proof_with_pis::(&common_data); + let inner_pis = &inner_proof_with_pis.public_inputs; + let inner_initial_hash = HashOutTarget::try_from(&inner_pis[0..4]).unwrap(); + let inner_latest_hash = HashOutTarget::try_from(&inner_pis[4..8]).unwrap(); + let inner_counter = inner_pis[8]; + + // Connect our initial hash to that of our inner proof. (If there is no inner proof, the + // initial hash will be unconstrained, which is intentional.) + builder.connect_hashes(initial_hash, inner_initial_hash); + + // The input hash is the previous hash output if we have an inner proof, or the initial hash + // if this is the base case. + let actual_hash_in = builder.select_hash(condition, inner_latest_hash, initial_hash); + builder.connect_hashes(current_hash_in, actual_hash_in); + + // Our chain length will be inner_counter + 1 if we have an inner proof, or 1 if not. + let new_counter = builder.mul_add(condition.target, inner_counter, one); + builder.connect(counter, new_counter); + let cyclic_data_target = - builder.cyclic_recursion::(condition, &old_pis, &mut common_data)?; - let input_hash_bis = - builder.select_hash(cyclic_data_target.condition, old_hash, initial_hash); - builder.connect_hashes(input_hash, input_hash_bis); - // New counter is the previous counter +1 if the previous proof wasn't a base case. - let new_counter_bis = builder.add(old_counter, condition.target); - builder.connect(new_counter, new_counter_bis); + builder.cyclic_recursion::(condition, &inner_proof_with_pis, &common_data)?; let cyclic_circuit_data = builder.build::(); + let mut pw = PartialWitness::new(); let cyclic_recursion_data = CyclicRecursionData { proof: &None, // Base case: We don't have a proof to put here yet. verifier_data: &cyclic_circuit_data.verifier_only, common_data: &cyclic_circuit_data.common, }; let initial_hash = [F::ZERO, F::ONE, F::TWO, F::from_canonical_usize(3)]; + let initial_hash_pis = initial_hash.into_iter().enumerate().collect_vec(); set_cyclic_recursion_data_target( &mut pw, &cyclic_data_target, &cyclic_recursion_data, - &initial_hash, + &initial_hash_pis, )?; let proof = cyclic_circuit_data.prove(pw)?; check_cyclic_proof_verifier_data( @@ -425,17 +445,20 @@ mod tests { let initial_hash = &proof.public_inputs[..4]; let hash = &proof.public_inputs[4..8]; let counter = proof.public_inputs[8]; - let mut h: [F; 4] = initial_hash.try_into().unwrap(); - assert_eq!( - hash, - core::iter::repeat_with(|| { - h = hash_n_to_hash_no_pad::(&h).elements; - h - }) - .nth(counter.to_canonical_u64() as usize) - .unwrap() + let expected_hash: [F; 4] = iterate_poseidon( + initial_hash.try_into().unwrap(), + counter.to_canonical_u64() as usize, ); + assert_eq!(hash, expected_hash); cyclic_circuit_data.verify(proof) } + + fn iterate_poseidon(initial_state: [F; 4], n: usize) -> [F; 4] { + let mut current = initial_state; + for _ in 0..n { + current = hash_n_to_hash_no_pad::(¤t).elements; + } + current + } } diff --git a/plonky2/src/recursion/dummy_circuit.rs b/plonky2/src/recursion/dummy_circuit.rs new file mode 100644 index 00000000..049f5540 --- /dev/null +++ b/plonky2/src/recursion/dummy_circuit.rs @@ -0,0 +1,69 @@ +use alloc::vec; + +use plonky2_field::extension::Extendable; +use plonky2_util::ceil_div_usize; + +use crate::gates::noop::NoopGate; +use crate::hash::hash_types::RichField; +use crate::iop::witness::{PartialWitness, Witness}; +use crate::plonk::circuit_builder::CircuitBuilder; +use crate::plonk::circuit_data::{CircuitData, CommonCircuitData}; +use crate::plonk::config::GenericConfig; +use crate::plonk::proof::ProofWithPublicInputs; + +/// Generate a proof for a dummy circuit. The `public_inputs` parameter let the caller specify +/// certain public inputs (identified by their indices) which should be given specific values. +/// The rest will default to zero. +pub(crate) fn dummy_proof( + circuit: &CircuitData, + nonzero_public_inputs: &[(usize, F)], +) -> anyhow::Result> +where + F: RichField + Extendable, + C: GenericConfig, +{ + let mut pw = PartialWitness::new(); + for i in 0..circuit.common.num_public_inputs { + let pi = nonzero_public_inputs + .iter() + .find_map(|(j, pi)| (i == *j).then_some(*pi)) + .unwrap_or_default(); + pw.set_target(circuit.prover_only.public_inputs[i], pi); + } + circuit.prove(pw) +} + +/// Generate a circuit matching a given `CommonCircuitData`. +pub(crate) fn dummy_circuit< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, +>( + common_data: &CommonCircuitData, +) -> CircuitData { + let config = common_data.config.clone(); + assert!( + !common_data.config.zero_knowledge, + "Degree calculation can be off if zero-knowledge is on." + ); + + // Number of `NoopGate`s to add to get a circuit of size `degree` in the end. + // Need to account for public input hashing, a `PublicInputGate` and a `ConstantGate`. + let degree = common_data.degree(); + let num_noop_gate = degree - ceil_div_usize(common_data.num_public_inputs, 8) - 2; + + let mut builder = CircuitBuilder::::new(config); + for _ in 0..num_noop_gate { + builder.add_gate(NoopGate, vec![]); + } + for gate in &common_data.gates { + builder.add_gate_to_gate_set(gate.clone()); + } + for _ in 0..common_data.num_public_inputs { + builder.add_virtual_public_input(); + } + + let circuit = builder.build::(); + assert_eq!(&circuit.common, common_data); + circuit +} diff --git a/plonky2/src/recursion/mod.rs b/plonky2/src/recursion/mod.rs index 33e8212e..3aba4ffd 100644 --- a/plonky2/src/recursion/mod.rs +++ b/plonky2/src/recursion/mod.rs @@ -1,3 +1,4 @@ pub mod conditional_recursive_verifier; pub mod cyclic_recursion; +pub(crate) mod dummy_circuit; pub mod recursive_verifier; From 644a8a23360fa19f92297874ea9badaeae4446ee Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Mon, 28 Nov 2022 10:49:19 -0800 Subject: [PATCH 43/49] Make `proof_with_pis` a reference --- plonky2/examples/bench_recursion.rs | 9 +++++---- .../recursion/conditional_recursive_verifier.rs | 2 +- plonky2/src/recursion/cyclic_recursion.rs | 4 ++-- plonky2/src/recursion/recursive_verifier.rs | 14 +++++++------- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/plonky2/examples/bench_recursion.rs b/plonky2/examples/bench_recursion.rs index 27101d1a..059ca963 100644 --- a/plonky2/examples/bench_recursion.rs +++ b/plonky2/examples/bench_recursion.rs @@ -105,17 +105,14 @@ where { let (inner_proof, inner_vd, inner_cd) = inner; let mut builder = CircuitBuilder::::new(config.clone()); - let mut pw = PartialWitness::new(); let pt = builder.add_virtual_proof_with_pis::(inner_cd); - pw.set_proof_with_pis_target(&pt, inner_proof); let inner_data = VerifierCircuitTarget { constants_sigmas_cap: builder.add_virtual_cap(inner_cd.config.fri_config.cap_height), circuit_digest: builder.add_virtual_hash(), }; - pw.set_verifier_data_target(&inner_data, inner_vd); - builder.verify_proof::(pt, &inner_data, inner_cd); + builder.verify_proof::(&pt, &inner_data, inner_cd); builder.print_gate_counts(0); if let Some(min_degree_bits) = min_degree_bits { @@ -131,6 +128,10 @@ where let data = builder.build::(); + let mut pw = PartialWitness::new(); + pw.set_proof_with_pis_target(&pt, inner_proof); + pw.set_verifier_data_target(&inner_data, inner_vd); + let mut timing = TimingTree::new("prove", Level::Debug); let proof = prove(&data.prover_only, &data.common, pw, &mut timing)?; timing.print(); diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index 6cbce94a..f5c46f9e 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -143,7 +143,7 @@ impl, const D: usize> CircuitBuilder { ), }; - self.verify_proof::(selected_proof, &selected_verifier_data, inner_common_data); + self.verify_proof::(&selected_proof, &selected_verifier_data, inner_common_data); } /// Conditionally verify a proof with a new generated dummy proof. diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index 2e4f2613..706392b9 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -298,7 +298,7 @@ mod tests { constants_sigmas_cap: builder.add_virtual_cap(data.common.config.fri_config.cap_height), circuit_digest: builder.add_virtual_hash(), }; - builder.verify_proof::(proof, &verifier_data, &data.common); + builder.verify_proof::(&proof, &verifier_data, &data.common); let data = builder.build::(); let config = CircuitConfig::standard_recursion_config(); @@ -308,7 +308,7 @@ mod tests { constants_sigmas_cap: builder.add_virtual_cap(data.common.config.fri_config.cap_height), circuit_digest: builder.add_virtual_hash(), }; - builder.verify_proof::(proof, &verifier_data, &data.common); + builder.verify_proof::(&proof, &verifier_data, &data.common); while builder.num_gates() < 1 << 12 { builder.add_gate(NoopGate, vec![]); } diff --git a/plonky2/src/recursion/recursive_verifier.rs b/plonky2/src/recursion/recursive_verifier.rs index 0854dad8..d53095a4 100644 --- a/plonky2/src/recursion/recursive_verifier.rs +++ b/plonky2/src/recursion/recursive_verifier.rs @@ -16,7 +16,7 @@ impl, const D: usize> CircuitBuilder { /// Recursively verifies an inner proof. pub fn verify_proof>( &mut self, - proof_with_pis: ProofWithPublicInputsTarget, + proof_with_pis: &ProofWithPublicInputsTarget, inner_verifier_data: &VerifierCircuitTarget, inner_common_data: &CommonCircuitData, ) where @@ -36,7 +36,7 @@ impl, const D: usize> CircuitBuilder { ); self.verify_proof_with_challenges::( - proof_with_pis.proof, + &proof_with_pis.proof, public_inputs_hash, challenges, inner_verifier_data, @@ -47,7 +47,7 @@ impl, const D: usize> CircuitBuilder { /// Recursively verifies an inner proof. fn verify_proof_with_challenges>( &mut self, - proof: ProofTarget, + proof: &ProofTarget, public_inputs_hash: HashOutTarget, challenges: ProofChallengesTarget, inner_verifier_data: &VerifierCircuitTarget, @@ -106,9 +106,9 @@ impl, const D: usize> CircuitBuilder { let merkle_caps = &[ inner_verifier_data.constants_sigmas_cap.clone(), - proof.wires_cap, - proof.plonk_zs_partial_products_cap, - proof.quotient_polys_cap, + proof.wires_cap.clone(), + proof.plonk_zs_partial_products_cap.clone(), + proof.quotient_polys_cap.clone(), ]; let fri_instance = inner_common_data.get_fri_instance_target(self, challenges.plonk_zeta); @@ -376,7 +376,7 @@ mod tests { ); pw.set_hash_target(inner_data.circuit_digest, inner_vd.circuit_digest); - builder.verify_proof::(pt, &inner_data, &inner_cd); + builder.verify_proof::(&pt, &inner_data, &inner_cd); if print_gate_counts { builder.print_gate_counts(0); From 5a153278aafc15a8180cab0a4841610bdee59979 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Mon, 28 Nov 2022 22:34:29 -0800 Subject: [PATCH 44/49] fix --- evm/src/recursive_verifier.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/recursive_verifier.rs b/evm/src/recursive_verifier.rs index 999b5e13..bf307699 100644 --- a/evm/src/recursive_verifier.rs +++ b/evm/src/recursive_verifier.rs @@ -231,7 +231,7 @@ impl, C: GenericConfig, const D: usize> .enumerate() { builder.verify_proof::( - recursive_proof, + &recursive_proof, &verifier_data_target, &verifier_data[i].common, ); From 319d9b5a52cd51b2c09008b828e10bf1b5d44d97 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 29 Nov 2022 12:02:54 -0800 Subject: [PATCH 45/49] Feedback --- plonky2/src/plonk/circuit_builder.rs | 7 ++++--- plonky2/src/recursion/cyclic_recursion.rs | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plonky2/src/plonk/circuit_builder.rs b/plonky2/src/plonk/circuit_builder.rs index c9f2edf0..6bad9296 100644 --- a/plonky2/src/plonk/circuit_builder.rs +++ b/plonky2/src/plonk/circuit_builder.rs @@ -248,9 +248,10 @@ impl, const D: usize> CircuitBuilder { /// Add a virtual verifier data, register it as a public input and set it to `self.verifier_data_public_input`. /// WARNING: Do not register any public input after calling this! TODO: relax this pub fn add_verifier_data_public_inputs(&mut self) { - if self.verifier_data_public_input.is_some() { - return; - } + assert!( + self.verifier_data_public_input.is_none(), + "add_verifier_data_public_inputs only needs to be called once" + ); let verifier_data = VerifierCircuitTarget { constants_sigmas_cap: self.add_virtual_cap(self.config.fri_config.cap_height), diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index b466c034..807445d7 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -177,6 +177,8 @@ impl, const D: usize> CircuitBuilder { } /// Set the targets in a `CyclicRecursionTarget` to their corresponding values in a `CyclicRecursionData`. +/// The `public_inputs` parameter let the caller specify certain public inputs (identified by their +/// indices) which should be given specific values. The rest will default to zero. pub fn set_cyclic_recursion_data_target< F: RichField + Extendable, C: GenericConfig, From b23193ba8d16a6314088a8104b576cfbdac5540a Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 29 Nov 2022 12:17:33 -0800 Subject: [PATCH 46/49] use hashmap --- plonky2/src/recursion/cyclic_recursion.rs | 8 ++++---- plonky2/src/recursion/dummy_circuit.rs | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index 807445d7..d95df90a 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -3,6 +3,7 @@ use alloc::vec; use anyhow::{ensure, Result}; +use hashbrown::HashMap; use itertools::Itertools; use crate::field::extension::Extendable; @@ -188,7 +189,7 @@ pub fn set_cyclic_recursion_data_target< cyclic_recursion_data_target: &CyclicRecursionTarget, cyclic_recursion_data: &CyclicRecursionData, // Public inputs to set in the base case to seed some initial data. - public_inputs: &[(usize, F)], + mut public_inputs: HashMap, ) -> Result<()> where C::Hasher: AlgebraicHasher, @@ -221,7 +222,6 @@ where // The circuit checks that the verifier data is the same throughout the cycle, so // we set the verifier data to the "real" verifier data even though it's unused in the base case. - let mut public_inputs = public_inputs.to_vec(); let verifier_data = &cyclic_recursion_data.verifier_data; public_inputs.extend((start_vk_pis..).zip(verifier_data.circuit_digest.elements)); @@ -230,14 +230,14 @@ where public_inputs.extend((start..).zip(verifier_data.constants_sigmas_cap.0[i].elements)); } - let proof = dummy_proof(&cyclic_recursion_data_target.dummy_circuit, &public_inputs)?; + let proof = dummy_proof(&cyclic_recursion_data_target.dummy_circuit, public_inputs)?; pw.set_proof_with_pis_target(&cyclic_recursion_data_target.proof, &proof); pw.set_verifier_data_target( &cyclic_recursion_data_target.verifier_data, cyclic_recursion_data.verifier_data, ); - let dummy_p = dummy_proof(&cyclic_recursion_data_target.dummy_circuit, &[])?; + let dummy_p = dummy_proof(&cyclic_recursion_data_target.dummy_circuit, HashMap::new())?; pw.set_proof_with_pis_target(&cyclic_recursion_data_target.dummy_proof, &dummy_p); pw.set_verifier_data_target( &cyclic_recursion_data_target.dummy_verifier_data, diff --git a/plonky2/src/recursion/dummy_circuit.rs b/plonky2/src/recursion/dummy_circuit.rs index 049f5540..c596ac1a 100644 --- a/plonky2/src/recursion/dummy_circuit.rs +++ b/plonky2/src/recursion/dummy_circuit.rs @@ -1,5 +1,6 @@ use alloc::vec; +use hashbrown::HashMap; use plonky2_field::extension::Extendable; use plonky2_util::ceil_div_usize; @@ -16,7 +17,7 @@ use crate::plonk::proof::ProofWithPublicInputs; /// The rest will default to zero. pub(crate) fn dummy_proof( circuit: &CircuitData, - nonzero_public_inputs: &[(usize, F)], + nonzero_public_inputs: HashMap, ) -> anyhow::Result> where F: RichField + Extendable, From c3ae52f5b0b595d8c2a9a05ca2ad2425a50cfcea Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 29 Nov 2022 12:19:40 -0800 Subject: [PATCH 47/49] fix --- plonky2/src/recursion/dummy_circuit.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plonky2/src/recursion/dummy_circuit.rs b/plonky2/src/recursion/dummy_circuit.rs index c596ac1a..4012b5e6 100644 --- a/plonky2/src/recursion/dummy_circuit.rs +++ b/plonky2/src/recursion/dummy_circuit.rs @@ -25,10 +25,7 @@ where { let mut pw = PartialWitness::new(); for i in 0..circuit.common.num_public_inputs { - let pi = nonzero_public_inputs - .iter() - .find_map(|(j, pi)| (i == *j).then_some(*pi)) - .unwrap_or_default(); + let pi = nonzero_public_inputs.get(&i).copied().unwrap_or_default(); pw.set_target(circuit.prover_only.public_inputs[i], pi); } circuit.prove(pw) From ad58dcbc0ee11f13f0017cde128923848dc728c3 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 29 Nov 2022 12:39:17 -0800 Subject: [PATCH 48/49] fix --- plonky2/src/recursion/cyclic_recursion.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index d95df90a..d2c997b3 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -272,6 +272,7 @@ where #[cfg(test)] mod tests { use anyhow::Result; + use hashbrown::HashMap; use itertools::Itertools; use crate::field::extension::Extendable; @@ -387,12 +388,12 @@ mod tests { common_data: &cyclic_circuit_data.common, }; let initial_hash = [F::ZERO, F::ONE, F::TWO, F::from_canonical_usize(3)]; - let initial_hash_pis = initial_hash.into_iter().enumerate().collect_vec(); + let initial_hash_pis = initial_hash.into_iter().enumerate().collect(); set_cyclic_recursion_data_target( &mut pw, &cyclic_data_target, &cyclic_recursion_data, - &initial_hash_pis, + initial_hash_pis, )?; let proof = cyclic_circuit_data.prove(pw)?; check_cyclic_proof_verifier_data( @@ -413,7 +414,7 @@ mod tests { &mut pw, &cyclic_data_target, &cyclic_recursion_data, - &[], + HashMap::new(), )?; let proof = cyclic_circuit_data.prove(pw)?; check_cyclic_proof_verifier_data( @@ -434,7 +435,7 @@ mod tests { &mut pw, &cyclic_data_target, &cyclic_recursion_data, - &[], + HashMap::new(), )?; let proof = cyclic_circuit_data.prove(pw)?; check_cyclic_proof_verifier_data( From 3515fbddac772bc7bf63933a7c0f22774c19d219 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 29 Nov 2022 12:39:41 -0800 Subject: [PATCH 49/49] fix --- plonky2/src/recursion/conditional_recursive_verifier.rs | 3 ++- plonky2/src/recursion/cyclic_recursion.rs | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plonky2/src/recursion/conditional_recursive_verifier.rs b/plonky2/src/recursion/conditional_recursive_verifier.rs index e7b727b5..565ae94d 100644 --- a/plonky2/src/recursion/conditional_recursive_verifier.rs +++ b/plonky2/src/recursion/conditional_recursive_verifier.rs @@ -317,6 +317,7 @@ impl, const D: usize> CircuitBuilder { #[cfg(test)] mod tests { use anyhow::Result; + use hashbrown::HashMap; use super::*; use crate::field::types::Sample; @@ -350,7 +351,7 @@ mod tests { // Generate dummy proof with the same `CommonCircuitData`. let dummy_data = dummy_circuit(&data.common); - let dummy_proof = dummy_proof(&dummy_data, &[])?; + let dummy_proof = dummy_proof(&dummy_data, HashMap::new())?; // Conditionally verify the two proofs. let mut builder = CircuitBuilder::::new(config); diff --git a/plonky2/src/recursion/cyclic_recursion.rs b/plonky2/src/recursion/cyclic_recursion.rs index d2c997b3..cc5728b9 100644 --- a/plonky2/src/recursion/cyclic_recursion.rs +++ b/plonky2/src/recursion/cyclic_recursion.rs @@ -273,7 +273,6 @@ where mod tests { use anyhow::Result; use hashbrown::HashMap; - use itertools::Itertools; use crate::field::extension::Extendable; use crate::field::types::{Field, PrimeField64};