From d9cab4ee7a490a2567abf35afd05ebded396640f Mon Sep 17 00:00:00 2001 From: Srinath Setty Date: Thu, 19 Dec 2024 10:43:09 -0800 Subject: [PATCH 1/6] checkpoint --- Cargo.toml | 4 ++- src/circuit.rs | 1 + src/digest.rs | 3 +-- src/errors.rs | 3 +-- src/frontend/constraint_system.rs | 7 +++--- src/frontend/gadgets/boolean.rs | 6 +++-- src/frontend/gadgets/mod.rs | 1 - src/frontend/gadgets/multieq.rs | 6 +++-- src/frontend/gadgets/num.rs | 11 ++++++--- src/frontend/gadgets/sha256.rs | 8 +++--- src/frontend/gadgets/uint32.rs | 9 ++++--- src/frontend/lc.rs | 4 +-- src/frontend/shape_cs.rs | 1 + src/frontend/solver.rs | 4 +-- src/frontend/test_shape_cs.rs | 11 ++++----- src/frontend/util_cs/test_cs.rs | 10 ++++---- src/frontend/util_cs/witness_cs.rs | 6 +++-- src/gadgets/ecc.rs | 1 + src/gadgets/nonnative/bignat.rs | 13 ++++++---- src/gadgets/nonnative/mod.rs | 2 +- src/gadgets/nonnative/util.rs | 11 +++++---- src/gadgets/r1cs.rs | 1 + src/gadgets/utils.rs | 1 + src/lib.rs | 30 ++++++++++++++++++++--- src/provider/hyperkzg.rs | 1 + src/provider/ipa_pc.rs | 1 + src/provider/keccak.rs | 1 + src/provider/pasta.rs | 1 + src/provider/pedersen.rs | 1 + src/provider/poseidon/circuit2.rs | 4 ++- src/provider/poseidon/circuit2_witness.rs | 3 +-- src/provider/poseidon/hash_type.rs | 2 +- src/provider/poseidon/matrix.rs | 1 + src/provider/poseidon/mds.rs | 1 + src/provider/poseidon/poseidon_inner.rs | 4 +-- src/provider/poseidon/preprocessing.rs | 1 + src/provider/poseidon/round_constants.rs | 1 + src/provider/poseidon/serde_impl.rs | 4 +-- src/provider/poseidon/sponge/api.rs | 2 +- src/provider/poseidon/sponge/circuit.rs | 4 +-- src/provider/poseidon/sponge/vanilla.rs | 5 +++- src/provider/secp_secq.rs | 1 + src/provider/traits.rs | 4 ++- src/r1cs/mod.rs | 1 + src/r1cs/sparse.rs | 1 + src/spartan/direct.rs | 1 + src/spartan/polys/eq.rs | 1 + src/spartan/polys/masked_eq.rs | 2 +- src/spartan/polys/multilinear.rs | 9 ++++--- src/spartan/polys/power.rs | 4 +-- src/spartan/polys/univariate.rs | 6 +++-- src/spartan/ppsnark.rs | 1 + src/spartan/snark.rs | 1 + src/spartan/sumcheck.rs | 13 ++++++---- src/traits/circuit.rs | 5 +++- src/traits/commitment.rs | 4 ++- src/traits/mod.rs | 1 + src/traits/snark.rs | 2 +- 58 files changed, 161 insertions(+), 87 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 92062aeff..e40efe7cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ thiserror = "2.0" group = "0.13.0" once_cell = "1.18.0" itertools = "0.13.0" +hashbrown = { version = "0.15.2", features = ["alloc"], optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] getrandom = { version = "0.2", default-features = false, features = ["js"] } @@ -69,5 +70,6 @@ name = "ppsnark" harness = false [features] -default = ["halo2curves/asm"] +default = ["halo2curves/asm", "std"] +std = [] flamegraph = ["pprof2/flamegraph", "pprof2/criterion"] diff --git a/src/circuit.rs b/src/circuit.rs index d9b2e36e4..6562d944b 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -16,6 +16,7 @@ use crate::{ alloc_num_equals, alloc_scalar_as_base, alloc_zero, conditionally_select_vec, le_bits_to_num, }, }, + prelude::*, r1cs::{R1CSInstance, RelaxedR1CSInstance}, traits::{ circuit::StepCircuit, commitment::CommitmentTrait, Engine, ROCircuitTrait, ROConstantsCircuit, diff --git a/src/digest.rs b/src/digest.rs index b5969fdde..aaa3bbece 100644 --- a/src/digest.rs +++ b/src/digest.rs @@ -1,11 +1,10 @@ +use crate::{constants::NUM_HASH_BITS}; use bincode::Options; use ff::PrimeField; use serde::Serialize; use sha3::{Digest, Sha3_256}; use std::{io, marker::PhantomData}; -use crate::constants::NUM_HASH_BITS; - /// Trait for components with potentially discrete digests to be included in their container's digest. pub trait Digestible { /// Write the byte representation of Self in a byte buffer diff --git a/src/errors.rs b/src/errors.rs index f2730e72a..6eef053f2 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,9 +1,8 @@ //! This module defines errors returned by the library. +use crate::{frontend::SynthesisError, prelude::*}; use core::fmt::Debug; use thiserror::Error; -use crate::frontend::SynthesisError; - /// Errors returned by Nova #[derive(Clone, Debug, Eq, PartialEq, Error)] #[non_exhaustive] diff --git a/src/frontend/constraint_system.rs b/src/frontend/constraint_system.rs index 51306f714..8e6c67c59 100644 --- a/src/frontend/constraint_system.rs +++ b/src/frontend/constraint_system.rs @@ -1,8 +1,7 @@ -use std::{io, marker::PhantomData}; - -use ff::PrimeField; - use super::lc::{Index, LinearCombination, Variable}; +use crate::prelude::*; +use core::{io, marker::PhantomData}; +use ff::PrimeField; /// Computations are expressed in terms of arithmetic circuits, in particular /// rank-1 quadratic constraint systems. The `Circuit` trait represents a diff --git a/src/frontend/gadgets/boolean.rs b/src/frontend/gadgets/boolean.rs index f5f0c656e..64371841a 100644 --- a/src/frontend/gadgets/boolean.rs +++ b/src/frontend/gadgets/boolean.rs @@ -1,9 +1,11 @@ //! Gadgets for allocating bits in the circuit and performing boolean logic. +use crate::{ + frontend::{ConstraintSystem, LinearCombination, SynthesisError, Variable}, + prelude::*, +}; use ff::{PrimeField, PrimeFieldBits}; -use crate::frontend::{ConstraintSystem, LinearCombination, SynthesisError, Variable}; - /// Represents a variable in the constraint system which is guaranteed /// to be either zero or one. #[derive(Debug, Clone)] diff --git a/src/frontend/gadgets/mod.rs b/src/frontend/gadgets/mod.rs index bb7512319..2bcbb5e4a 100644 --- a/src/frontend/gadgets/mod.rs +++ b/src/frontend/gadgets/mod.rs @@ -1,5 +1,4 @@ //! Self-contained sub-circuit implementations for various primitives. - use super::SynthesisError; pub mod boolean; mod multieq; diff --git a/src/frontend/gadgets/multieq.rs b/src/frontend/gadgets/multieq.rs index 35a388003..68881d905 100644 --- a/src/frontend/gadgets/multieq.rs +++ b/src/frontend/gadgets/multieq.rs @@ -1,7 +1,9 @@ +use crate::{ + frontend::{ConstraintSystem, LinearCombination, SynthesisError, Variable}, + prelude::*, +}; use ff::PrimeField; -use crate::frontend::{ConstraintSystem, LinearCombination, SynthesisError, Variable}; - #[derive(Debug)] pub struct MultiEq> { cs: CS, diff --git a/src/frontend/gadgets/num.rs b/src/frontend/gadgets/num.rs index af324a563..a0617a772 100644 --- a/src/frontend/gadgets/num.rs +++ b/src/frontend/gadgets/num.rs @@ -1,12 +1,15 @@ //! Gadgets representing numbers in the scalar field of the underlying curve. +use crate::{ + frontend::{ + gadgets::boolean::{self, AllocatedBit, Boolean}, + {ConstraintSystem, LinearCombination, SynthesisError, Variable}, + }, + prelude::*, +}; use ff::{PrimeField, PrimeFieldBits}; use serde::{Deserialize, Serialize}; -use crate::frontend::{ConstraintSystem, LinearCombination, SynthesisError, Variable}; - -use crate::frontend::gadgets::boolean::{self, AllocatedBit, Boolean}; - /// Represents an allocated number in the circuit. #[derive(Debug, Serialize, Deserialize)] pub struct AllocatedNum { diff --git a/src/frontend/gadgets/sha256.rs b/src/frontend/gadgets/sha256.rs index a0408ad7c..b636c62f7 100644 --- a/src/frontend/gadgets/sha256.rs +++ b/src/frontend/gadgets/sha256.rs @@ -5,10 +5,12 @@ #![allow(clippy::many_single_char_names)] -use ff::PrimeField; - use super::{boolean::Boolean, multieq::MultiEq, uint32::UInt32}; -use crate::frontend::{ConstraintSystem, SynthesisError}; +use crate::{ + frontend::{ConstraintSystem, SynthesisError}, + prelude::*, +}; +use ff::PrimeField; #[allow(clippy::unreadable_literal)] const ROUND_CONSTANTS: [u32; 64] = [ diff --git a/src/frontend/gadgets/uint32.rs b/src/frontend/gadgets/uint32.rs index ef0467e88..2657e0ceb 100644 --- a/src/frontend/gadgets/uint32.rs +++ b/src/frontend/gadgets/uint32.rs @@ -1,14 +1,15 @@ //! Circuit representation of a [`u32`], with helpers for the [`sha256`] //! gadgets. -use ff::PrimeField; - -use crate::frontend::{ConstraintSystem, LinearCombination, SynthesisError}; - use super::{ boolean::{AllocatedBit, Boolean}, multieq::MultiEq, }; +use crate::{ + frontend::{ConstraintSystem, LinearCombination, SynthesisError}, + prelude::*, +}; +use ff::PrimeField; /// Represents an interpretation of 32 `Boolean` objects as an /// unsigned integer. diff --git a/src/frontend/lc.rs b/src/frontend/lc.rs index cf6d89ea2..2d7e83842 100644 --- a/src/frontend/lc.rs +++ b/src/frontend/lc.rs @@ -1,5 +1,5 @@ -use std::ops::{Add, Sub}; - +use crate::prelude::*; +use core::ops::{Add, Sub}; use ff::PrimeField; use serde::{Deserialize, Serialize}; diff --git a/src/frontend/shape_cs.rs b/src/frontend/shape_cs.rs index 05a4e996f..b33d347bd 100644 --- a/src/frontend/shape_cs.rs +++ b/src/frontend/shape_cs.rs @@ -2,6 +2,7 @@ use crate::{ frontend::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}, + prelude::*, traits::Engine, }; use ff::PrimeField; diff --git a/src/frontend/solver.rs b/src/frontend/solver.rs index 5f9abaf9f..172f2f1a4 100644 --- a/src/frontend/solver.rs +++ b/src/frontend/solver.rs @@ -1,8 +1,6 @@ //! Support for generating R1CS witness using bellpepper. -use crate::traits::Engine; - -use crate::frontend::util_cs::witness_cs::WitnessCS; +use crate::{frontend::util_cs::witness_cs::WitnessCS, traits::Engine}; /// A `ConstraintSystem` which calculates witness values for a concrete instance of an R1CS circuit. pub type SatisfyingAssignment = WitnessCS<::Scalar>; diff --git a/src/frontend/test_shape_cs.rs b/src/frontend/test_shape_cs.rs index dfa2e419e..194bb05b9 100644 --- a/src/frontend/test_shape_cs.rs +++ b/src/frontend/test_shape_cs.rs @@ -1,16 +1,15 @@ //! Support for generating R1CS shape using bellpepper. //! `TestShapeCS` implements a superset of `ShapeCS`, adding non-trivial namespace support for use in testing. -use std::{ - cmp::Ordering, - collections::{BTreeMap, HashMap}, -}; - use crate::{ frontend::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}, + prelude::*, traits::Engine, }; -use core::fmt::Write; +use core::{ + cmp::Ordering, + fmt::Write, +}; use ff::{Field, PrimeField}; #[derive(Clone, Copy)] diff --git a/src/frontend/util_cs/test_cs.rs b/src/frontend/util_cs/test_cs.rs index a75f33d6b..ff6f01d31 100644 --- a/src/frontend/util_cs/test_cs.rs +++ b/src/frontend/util_cs/test_cs.rs @@ -1,9 +1,9 @@ //! Test constraint system for use in tests. - -use std::collections::HashMap; - -use crate::frontend::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; - +use crate::{ + frontend::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}, + prelude::*, +}; +use core::collections::HashMap; use ff::PrimeField; #[derive(Debug)] diff --git a/src/frontend/util_cs/witness_cs.rs b/src/frontend/util_cs/witness_cs.rs index 40df6a741..f12f3fd35 100644 --- a/src/frontend/util_cs/witness_cs.rs +++ b/src/frontend/util_cs/witness_cs.rs @@ -1,9 +1,11 @@ //! Support for efficiently generating R1CS witness using bellperson. +use crate::{ + frontend::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}, + prelude::*, +}; use ff::PrimeField; -use crate::frontend::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; - /// A [`ConstraintSystem`] trait pub trait SizedWitness { /// Returns the number of constraints in the constraint system diff --git a/src/gadgets/ecc.rs b/src/gadgets/ecc.rs index 937fb0094..8c7d690d5 100644 --- a/src/gadgets/ecc.rs +++ b/src/gadgets/ecc.rs @@ -9,6 +9,7 @@ use crate::{ select_num_or_one, select_num_or_zero, select_num_or_zero2, select_one_or_diff2, select_one_or_num2, select_zero_or_num2, }, + prelude::*, traits::{Engine, Group}, }; use ff::{Field, PrimeField}; diff --git a/src/gadgets/nonnative/bignat.rs b/src/gadgets/nonnative/bignat.rs index 61ff1a4c7..137821068 100644 --- a/src/gadgets/nonnative/bignat.rs +++ b/src/gadgets/nonnative/bignat.rs @@ -2,15 +2,18 @@ use super::{ util::{f_to_nat, nat_to_f, Bitvector, Num}, OptionExt, }; -use crate::frontend::{ConstraintSystem, LinearCombination, SynthesisError}; -use ff::PrimeField; -use num_bigint::BigInt; -use num_traits::cast::ToPrimitive; -use std::{ +use crate::{ + frontend::{ConstraintSystem, LinearCombination, SynthesisError}, + prelude::*, +}; +use core::{ borrow::Borrow, cmp::{max, min}, convert::From, }; +use ff::PrimeField; +use num_bigint::BigInt; +use num_traits::cast::ToPrimitive; /// Compute the natural number represented by an array of limbs. /// The limbs are assumed to be based the `limb_width` power of 2. diff --git a/src/gadgets/nonnative/mod.rs b/src/gadgets/nonnative/mod.rs index 80c8e12ae..8337ff513 100644 --- a/src/gadgets/nonnative/mod.rs +++ b/src/gadgets/nonnative/mod.rs @@ -1,7 +1,7 @@ //! This module implements various gadgets necessary for doing non-native arithmetic //! Code in this module is adapted from [bellman-bignat](https://github.com/alex-ozdemir/bellman-bignat), which is licenced under MIT -use crate::frontend::SynthesisError; +use crate::{frontend::SynthesisError, prelude::*}; use ff::PrimeField; trait OptionExt { diff --git a/src/gadgets/nonnative/util.rs b/src/gadgets/nonnative/util.rs index e02435665..e1cd158a7 100644 --- a/src/gadgets/nonnative/util.rs +++ b/src/gadgets/nonnative/util.rs @@ -1,14 +1,15 @@ use super::{BitAccess, OptionExt}; -use crate::frontend::{ - num::AllocatedNum, ConstraintSystem, LinearCombination, SynthesisError, Variable, +use crate::{ + frontend::{num::AllocatedNum, ConstraintSystem, LinearCombination, SynthesisError, Variable}, + prelude::*, }; use byteorder::WriteBytesExt; -use ff::PrimeField; -use num_bigint::{BigInt, Sign}; -use std::{ +use core::{ convert::From, io::{self, Write}, }; +use ff::PrimeField; +use num_bigint::{BigInt, Sign}; #[derive(Clone)] /// A representation of a bit diff --git a/src/gadgets/r1cs.rs b/src/gadgets/r1cs.rs index 25167508c..15228ac18 100644 --- a/src/gadgets/r1cs.rs +++ b/src/gadgets/r1cs.rs @@ -13,6 +13,7 @@ use crate::{ conditionally_select_bignat, le_bits_to_num, }, }, + prelude::*, r1cs::{R1CSInstance, RelaxedR1CSInstance}, traits::{commitment::CommitmentTrait, Engine, Group, ROCircuitTrait, ROConstantsCircuit}, }; diff --git a/src/gadgets/utils.rs b/src/gadgets/utils.rs index 867790767..4a05b1190 100644 --- a/src/gadgets/utils.rs +++ b/src/gadgets/utils.rs @@ -5,6 +5,7 @@ use crate::{ num::AllocatedNum, AllocatedBit, Assignment, Boolean, ConstraintSystem, LinearCombination, SynthesisError, }, + prelude::*, traits::Engine, }; use ff::{Field, PrimeField, PrimeFieldBits}; diff --git a/src/lib.rs b/src/lib.rs index a56845a3c..a7ebfb579 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ //! This library implements Nova, a high-speed recursive SNARK. +#![cfg_attr(not(feature = "std"), no_std)] #![deny( warnings, unused, @@ -10,6 +11,30 @@ #![allow(non_snake_case)] #![forbid(unsafe_code)] +#[cfg(not(feature = "std"))] +extern crate alloc; + +pub(crate) mod prelude { + #[cfg(not(feature = "std"))] + pub use alloc::boxed::Box; + #[cfg(not(feature = "std"))] + pub use alloc::string::String; + #[cfg(not(feature = "std"))] + pub use alloc::vec::Vec; + #[cfg(not(feature = "std"))] + pub use alloc::vec; + #[cfg(not(feature = "std"))] + pub use alloc::format; + + // use std::collections::{BTreeMap, HashMap} when std is enabled + #[cfg(not(feature = "std"))] + pub use alloc::collections::{BTreeMap}; + #[cfg(not(feature = "std"))] + pub use hashbrown::HashMap; + #[cfg(feature = "std")] + pub use std::collections::{BTreeMap, HashMap}; +} + // private modules mod circuit; mod constants; @@ -21,12 +46,10 @@ mod r1cs; pub mod errors; pub mod frontend; pub mod gadgets; -pub mod provider; +//pub mod provider; pub mod spartan; pub mod traits; -use once_cell::sync::OnceCell; - use crate::digest::{DigestComputer, SimpleDigestible}; use circuit::{NovaAugmentedCircuit, NovaAugmentedCircuitInputs, NovaAugmentedCircuitParams}; use constants::{BN_LIMB_WIDTH, BN_N_LIMBS, NUM_FE_WITHOUT_IO_FOR_CRHF, NUM_HASH_BITS}; @@ -41,6 +64,7 @@ use frontend::{ }; use gadgets::utils::scalar_as_base; use nifs::{NIFSRelaxed, NIFS}; +use once_cell::sync::OnceCell; use r1cs::{ CommitmentKeyHint, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness, }; diff --git a/src/provider/hyperkzg.rs b/src/provider/hyperkzg.rs index 4ee1f9567..196dc0a50 100644 --- a/src/provider/hyperkzg.rs +++ b/src/provider/hyperkzg.rs @@ -8,6 +8,7 @@ #![allow(non_snake_case)] use crate::{ errors::NovaError, + prelude::*, provider::traits::{DlogGroup, PairingGroup}, traits::{ commitment::{CommitmentEngineTrait, CommitmentTrait, Len}, diff --git a/src/provider/ipa_pc.rs b/src/provider/ipa_pc.rs index 63680dca9..ca4680bf5 100644 --- a/src/provider/ipa_pc.rs +++ b/src/provider/ipa_pc.rs @@ -1,6 +1,7 @@ //! This module implements `EvaluationEngine` using an IPA-based polynomial commitment scheme use crate::{ errors::NovaError, + prelude::*, provider::{pedersen::CommitmentKeyExtTrait, traits::DlogGroup}, spartan::polys::eq::EqPolynomial, traits::{ diff --git a/src/provider/keccak.rs b/src/provider/keccak.rs index 82bf37d6f..f53d4e964 100644 --- a/src/provider/keccak.rs +++ b/src/provider/keccak.rs @@ -1,6 +1,7 @@ //! This module provides an implementation of `TranscriptEngineTrait` using keccak256 use crate::{ errors::NovaError, + prelude::*, traits::{Engine, PrimeFieldExt, TranscriptEngineTrait, TranscriptReprTrait}, }; use core::marker::PhantomData; diff --git a/src/provider/pasta.rs b/src/provider/pasta.rs index e09edfa35..a58f37f26 100644 --- a/src/provider/pasta.rs +++ b/src/provider/pasta.rs @@ -1,5 +1,6 @@ //! This module implements the Nova traits for `pallas::Point`, `pallas::Scalar`, `vesta::Point`, `vesta::Scalar`. use crate::{ + prelude::*, provider::traits::DlogGroup, traits::{Group, PrimeFieldExt, TranscriptReprTrait}, }; diff --git a/src/provider/pedersen.rs b/src/provider/pedersen.rs index 92e8cd9a6..07fb7b713 100644 --- a/src/provider/pedersen.rs +++ b/src/provider/pedersen.rs @@ -1,6 +1,7 @@ //! This module provides an implementation of a commitment engine use crate::{ errors::NovaError, + prelude::*, provider::traits::DlogGroup, traits::{ commitment::{CommitmentEngineTrait, CommitmentTrait, Len}, diff --git a/src/provider/poseidon/circuit2.rs b/src/provider/poseidon/circuit2.rs index e0085d781..9aba7bd95 100644 --- a/src/provider/poseidon/circuit2.rs +++ b/src/provider/poseidon/circuit2.rs @@ -6,9 +6,11 @@ use super::{ mds::SparseMatrix, poseidon_inner::{Arity, PoseidonConstants}, }; -use crate::frontend::{ +use crate::{prelude::*, + frontend::{ num::{self, AllocatedNum}, Boolean, ConstraintSystem, LinearCombination, SynthesisError, +} }; use ff::PrimeField; use std::marker::PhantomData; diff --git a/src/provider/poseidon/circuit2_witness.rs b/src/provider/poseidon/circuit2_witness.rs index af9bb21d4..a519da793 100644 --- a/src/provider/poseidon/circuit2_witness.rs +++ b/src/provider/poseidon/circuit2_witness.rs @@ -1,7 +1,6 @@ /// The `circuit2_witness` module implements witness-generation for the optimal Poseidon hash circuit. use super::poseidon_inner::{Arity, Poseidon}; -use crate::frontend::util_cs::witness_cs::SizedWitness; - +use crate::{prelude::*, frontend::util_cs::witness_cs::SizedWitness}; use ff::PrimeField; use generic_array::{sequence::GenericSequence, typenum::Unsigned, GenericArray}; diff --git a/src/provider/poseidon/hash_type.rs b/src/provider/poseidon/hash_type.rs index ff2cd664a..516397a38 100644 --- a/src/provider/poseidon/hash_type.rs +++ b/src/provider/poseidon/hash_type.rs @@ -10,9 +10,9 @@ /// Because `neptune` also supports a first-class notion of `Strength`, we include a mechanism for composing /// `Strength` with `HashType` so that hashes with `Strength` other than `Standard` (currently only `Strengthened`) /// may still express the full range of hash function types. +use crate::prelude::*; use ff::PrimeField; use serde::{Deserialize, Serialize}; - use super::poseidon_inner::Arity; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] diff --git a/src/provider/poseidon/matrix.rs b/src/provider/poseidon/matrix.rs index b260ba061..cb4aed25d 100644 --- a/src/provider/poseidon/matrix.rs +++ b/src/provider/poseidon/matrix.rs @@ -2,6 +2,7 @@ #![allow(clippy::ptr_arg)] use ff::PrimeField; +use crate::prelude::*; /// Matrix functions here are, at least for now, quick and dirty — intended only to support precomputation of poseidon optimization. /// diff --git a/src/provider/poseidon/mds.rs b/src/provider/poseidon/mds.rs index 9929c55ca..3245349e8 100644 --- a/src/provider/poseidon/mds.rs +++ b/src/provider/poseidon/mds.rs @@ -3,6 +3,7 @@ use ff::PrimeField; use serde::{Deserialize, Serialize}; +use crate::prelude::*; use super::{ matrix, diff --git a/src/provider/poseidon/poseidon_inner.rs b/src/provider/poseidon/poseidon_inner.rs index ab98efe45..9ff22d463 100644 --- a/src/provider/poseidon/poseidon_inner.rs +++ b/src/provider/poseidon/poseidon_inner.rs @@ -1,8 +1,8 @@ -use std::marker::PhantomData; - +use core::marker::PhantomData; use ff::PrimeField; use generic_array::{sequence::GenericSequence, typenum, ArrayLength, GenericArray}; use typenum::*; +use crate::prelude::*; use super::{ matrix::transpose, diff --git a/src/provider/poseidon/preprocessing.rs b/src/provider/poseidon/preprocessing.rs index 750ffa9bc..6e9455672 100644 --- a/src/provider/poseidon/preprocessing.rs +++ b/src/provider/poseidon/preprocessing.rs @@ -4,6 +4,7 @@ use super::{ quintic_s_box, }; use ff::PrimeField; +use crate::prelude::*; // - Compress constants by pushing them back through linear layers and through the identity components of partial layers. // - As a result, constants need only be added after each S-box. diff --git a/src/provider/poseidon/round_constants.rs b/src/provider/poseidon/round_constants.rs index c5182432e..b78d1ce50 100644 --- a/src/provider/poseidon/round_constants.rs +++ b/src/provider/poseidon/round_constants.rs @@ -1,4 +1,5 @@ use ff::PrimeField; +use crate::prelude::*; /// From the paper (): /// The round constants are generated using the Grain LFSR [23] in a self-shrinking diff --git a/src/provider/poseidon/serde_impl.rs b/src/provider/poseidon/serde_impl.rs index 0439243d9..a1b781ac9 100644 --- a/src/provider/poseidon/serde_impl.rs +++ b/src/provider/poseidon/serde_impl.rs @@ -4,12 +4,12 @@ use serde::{ ser::{SerializeStruct, Serializer}, Deserialize, Serialize, }; -use std::{fmt, marker::PhantomData}; - +use core::{fmt, marker::PhantomData}; use super::{ hash_type::HashType, poseidon_inner::{Arity, PoseidonConstants}, }; +use crate::prelude::*; impl Serialize for PoseidonConstants where diff --git a/src/provider/poseidon/sponge/api.rs b/src/provider/poseidon/sponge/api.rs index 86ce867de..0cbe514f5 100644 --- a/src/provider/poseidon/sponge/api.rs +++ b/src/provider/poseidon/sponge/api.rs @@ -2,7 +2,7 @@ /// /// The API is defined by the `SpongeAPI` trait, which is implemented in terms of the `InnerSpongeAPI` trait. /// `Neptune` provides implementations of `InnerSpongeAPI` for both `sponge::Sponge` and `sponge_circuit::SpongeCircuit`. -use crate::provider::poseidon::poseidon_inner::Arity; +use crate::{prelude::*, provider::poseidon::poseidon_inner::Arity}; use ff::PrimeField; #[derive(Debug)] diff --git a/src/provider/poseidon/sponge/circuit.rs b/src/provider/poseidon/sponge/circuit.rs index d1b0ec0f6..e591cd9aa 100644 --- a/src/provider/poseidon/sponge/circuit.rs +++ b/src/provider/poseidon/sponge/circuit.rs @@ -1,4 +1,5 @@ use crate::{ + prelude::*, frontend::{util_cs::witness_cs::SizedWitness, ConstraintSystem, Namespace, SynthesisError}, provider::poseidon::{ circuit2::{Elt, PoseidonCircuit2}, @@ -9,9 +10,8 @@ use crate::{ }, }, }; - use ff::PrimeField; -use std::{collections::VecDeque, marker::PhantomData}; +use core::{collections::VecDeque, marker::PhantomData}; /// The Poseidon sponge circuit pub struct SpongeCircuit<'a, F, A, C> diff --git a/src/provider/poseidon/sponge/vanilla.rs b/src/provider/poseidon/sponge/vanilla.rs index e6bdaeefd..29c04ed26 100644 --- a/src/provider/poseidon/sponge/vanilla.rs +++ b/src/provider/poseidon/sponge/vanilla.rs @@ -1,8 +1,11 @@ -use crate::provider::poseidon::{ +use crate::{ + prelude::*, + provider::poseidon::{ hash_type::HashType, poseidon_inner::{Arity, Poseidon, PoseidonConstants}, sponge::api::{IOPattern, InnerSpongeAPI}, PoseidonError, Strength, +} }; use ff::PrimeField; use std::collections::VecDeque; diff --git a/src/provider/secp_secq.rs b/src/provider/secp_secq.rs index d47271584..9b39fd7f8 100644 --- a/src/provider/secp_secq.rs +++ b/src/provider/secp_secq.rs @@ -1,6 +1,7 @@ //! This module implements the Nova traits for `secp::Point`, `secp::Scalar`, `secq::Point`, `secq::Scalar`. use crate::{ impl_traits, + prelude::*, provider::traits::DlogGroup, traits::{Group, PrimeFieldExt, TranscriptReprTrait}, }; diff --git a/src/provider/traits.rs b/src/provider/traits.rs index 3e6886c20..1bd3b7e06 100644 --- a/src/provider/traits.rs +++ b/src/provider/traits.rs @@ -1,4 +1,6 @@ -use crate::traits::{commitment::ScalarMul, Group, TranscriptReprTrait}; +use crate::{ + traits::{commitment::ScalarMul, Group, TranscriptReprTrait}, +}; use core::{ fmt::Debug, ops::{Add, AddAssign, Sub, SubAssign}, diff --git a/src/r1cs/mod.rs b/src/r1cs/mod.rs index 12a3678be..263ef4fa3 100644 --- a/src/r1cs/mod.rs +++ b/src/r1cs/mod.rs @@ -7,6 +7,7 @@ use crate::{ nonnative::{bignat::nat_to_limbs, util::f_to_nat}, utils::scalar_as_base, }, + prelude::*, traits::{ commitment::CommitmentEngineTrait, AbsorbInROTrait, Engine, ROTrait, TranscriptReprTrait, }, diff --git a/src/r1cs/sparse.rs b/src/r1cs/sparse.rs index 5ec86b0cf..f3d0f09eb 100644 --- a/src/r1cs/sparse.rs +++ b/src/r1cs/sparse.rs @@ -3,6 +3,7 @@ //! This module defines a custom implementation of CSR/CSC sparse matrices. //! Specifically, we implement sparse matrix / dense vector multiplication //! to compute the `A z`, `B z`, and `C z` in Nova. +use crate::prelude::*; use ff::PrimeField; use rayon::prelude::*; use serde::{Deserialize, Serialize}; diff --git a/src/spartan/direct.rs b/src/spartan/direct.rs index 885495ad9..93f58f356 100644 --- a/src/spartan/direct.rs +++ b/src/spartan/direct.rs @@ -10,6 +10,7 @@ use crate::{ solver::SatisfyingAssignment, Circuit, ConstraintSystem, SynthesisError, }, + prelude::*, r1cs::{R1CSShape, RelaxedR1CSInstance, RelaxedR1CSWitness}, traits::{ circuit::StepCircuit, diff --git a/src/spartan/polys/eq.rs b/src/spartan/polys/eq.rs index aacab8f24..cbb73c3cb 100644 --- a/src/spartan/polys/eq.rs +++ b/src/spartan/polys/eq.rs @@ -1,5 +1,6 @@ //! `EqPolynomial`: Represents multilinear extension of equality polynomials, evaluated based on binary input values. +use crate::prelude::*; use ff::PrimeField; use rayon::prelude::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator}; diff --git a/src/spartan/polys/masked_eq.rs b/src/spartan/polys/masked_eq.rs index c725f69f3..09c20b04f 100644 --- a/src/spartan/polys/masked_eq.rs +++ b/src/spartan/polys/masked_eq.rs @@ -1,6 +1,6 @@ //! `MaskedEqPolynomial`: Represents the `eq` polynomial over n variables, where the first 2^m entries are 0. -use crate::spartan::polys::eq::EqPolynomial; +use crate::{prelude::*, spartan::polys::eq::EqPolynomial}; use ff::PrimeField; use itertools::zip_eq; diff --git a/src/spartan/polys/multilinear.rs b/src/spartan/polys/multilinear.rs index 7d342bb99..80ddbb196 100644 --- a/src/spartan/polys/multilinear.rs +++ b/src/spartan/polys/multilinear.rs @@ -2,8 +2,11 @@ //! - `MultilinearPolynomial`: Dense representation of multilinear polynomials, represented by evaluations over all possible binary inputs. //! - `SparsePolynomial`: Efficient representation of sparse multilinear polynomials, storing only non-zero evaluations. -use std::ops::{Add, Index}; - +use crate::{ + prelude::*, + spartan::{math::Math, polys::eq::EqPolynomial}, +}; +use core::ops::{Add, Index}; use ff::PrimeField; use itertools::Itertools as _; use rayon::prelude::{ @@ -12,8 +15,6 @@ use rayon::prelude::{ }; use serde::{Deserialize, Serialize}; -use crate::spartan::{math::Math, polys::eq::EqPolynomial}; - /// A multilinear extension of a polynomial $Z(\cdot)$, denote it as $\tilde{Z}(x_1, ..., x_m)$ /// where the degree of each variable is at most one. /// diff --git a/src/spartan/polys/power.rs b/src/spartan/polys/power.rs index 13d52ba0a..5a9c579af 100644 --- a/src/spartan/polys/power.rs +++ b/src/spartan/polys/power.rs @@ -1,8 +1,8 @@ //! `PowPolynomial`: Represents multilinear extension of power polynomials -use crate::spartan::polys::eq::EqPolynomial; +use crate::{prelude::*, spartan::polys::eq::EqPolynomial}; +use core::iter::successors; use ff::PrimeField; -use std::iter::successors; /// Represents the multilinear extension polynomial (MLE) of the equality polynomial $pow(x,t)$, denoted as $\tilde{pow}(x, t)$. /// diff --git a/src/spartan/polys/univariate.rs b/src/spartan/polys/univariate.rs index 4bb96c5a7..228c7deff 100644 --- a/src/spartan/polys/univariate.rs +++ b/src/spartan/polys/univariate.rs @@ -1,12 +1,14 @@ //! Main components: //! - `UniPoly`: an univariate dense polynomial in coefficient form (big endian), //! - `CompressedUniPoly`: a univariate dense polynomial, compressed (omitted linear term), in coefficient form (little endian), +use crate::{ + prelude::*, + traits::{Group, TranscriptReprTrait}, +}; use ff::PrimeField; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use serde::{Deserialize, Serialize}; -use crate::traits::{Group, TranscriptReprTrait}; - // ax^2 + bx + c stored as vec![c, b, a] // ax^3 + bx^2 + cx + d stored as vec![d, c, b, a] #[derive(Debug, PartialEq, Eq)] diff --git a/src/spartan/ppsnark.rs b/src/spartan/ppsnark.rs index 42b85d1e4..7198faacf 100644 --- a/src/spartan/ppsnark.rs +++ b/src/spartan/ppsnark.rs @@ -7,6 +7,7 @@ use crate::{ digest::{DigestComputer, SimpleDigestible}, errors::NovaError, + prelude::*, r1cs::{R1CSShape, RelaxedR1CSInstance, RelaxedR1CSWitness}, spartan::{ math::Math, diff --git a/src/spartan/snark.rs b/src/spartan/snark.rs index b59b6bf54..3aa7f96c1 100644 --- a/src/spartan/snark.rs +++ b/src/spartan/snark.rs @@ -7,6 +7,7 @@ use crate::{ digest::{DigestComputer, SimpleDigestible}, errors::NovaError, + prelude::*, r1cs::{R1CSShape, RelaxedR1CSInstance, RelaxedR1CSWitness, SparseMatrix}, spartan::{ compute_eval_table_sparse, diff --git a/src/spartan/sumcheck.rs b/src/spartan/sumcheck.rs index 93c75a7f7..ab318d93c 100644 --- a/src/spartan/sumcheck.rs +++ b/src/spartan/sumcheck.rs @@ -1,9 +1,12 @@ -use crate::errors::NovaError; -use crate::spartan::polys::{ - multilinear::MultilinearPolynomial, - univariate::{CompressedUniPoly, UniPoly}, +use crate::{ + errors::NovaError, + prelude::*, + spartan::polys::{ + multilinear::MultilinearPolynomial, + univariate::{CompressedUniPoly, UniPoly}, + }, + traits::{Engine, TranscriptEngineTrait}, }; -use crate::traits::{Engine, TranscriptEngineTrait}; use ff::Field; use itertools::Itertools as _; use rayon::prelude::*; diff --git a/src/traits/circuit.rs b/src/traits/circuit.rs index 4f8a2da06..3e3e7fb8d 100644 --- a/src/traits/circuit.rs +++ b/src/traits/circuit.rs @@ -1,5 +1,8 @@ //! This module defines traits that a step function must implement -use crate::frontend::{num::AllocatedNum, ConstraintSystem, SynthesisError}; +use crate::{ + frontend::{num::AllocatedNum, ConstraintSystem, SynthesisError}, + prelude::*, +}; use core::marker::PhantomData; use ff::PrimeField; diff --git a/src/traits/commitment.rs b/src/traits/commitment.rs index 2a61ca799..92e681cfc 100644 --- a/src/traits/commitment.rs +++ b/src/traits/commitment.rs @@ -1,6 +1,8 @@ //! This module defines a collection of traits that define the behavior of a commitment engine //! We require the commitment engine to provide a commitment to vectors with a single group element -use crate::traits::{AbsorbInROTrait, Engine, TranscriptReprTrait}; +use crate::{ + traits::{AbsorbInROTrait, Engine, TranscriptReprTrait}, +}; use core::{ fmt::Debug, ops::{Add, Mul, MulAssign}, diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 8f128fb5f..d3da8b03f 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -2,6 +2,7 @@ use crate::{ errors::NovaError, frontend::{num::AllocatedNum, AllocatedBit, ConstraintSystem, SynthesisError}, + prelude::*, }; use core::fmt::Debug; use ff::{PrimeField, PrimeFieldBits}; diff --git a/src/traits/snark.rs b/src/traits/snark.rs index b162185e9..799a2843c 100644 --- a/src/traits/snark.rs +++ b/src/traits/snark.rs @@ -1,11 +1,11 @@ //! This module defines a collection of traits that define the behavior of a `zkSNARK` for `RelaxedR1CS` use crate::{ errors::NovaError, + prelude::*, r1cs::{R1CSShape, RelaxedR1CSInstance, RelaxedR1CSWitness}, traits::Engine, CommitmentKey, }; - use serde::{Deserialize, Serialize}; /// Public parameter creation takes a size hint. This size hint carries the particular requirements of From 151a3a84e4cd588857548bb8483f312888bfd767 Mon Sep 17 00:00:00 2001 From: Srinath Setty Date: Thu, 19 Dec 2024 11:09:37 -0800 Subject: [PATCH 2/6] checkpoint --- Cargo.toml | 2 +- src/digest.rs | 12 ++++----- src/frontend/constraint_system.rs | 5 +--- src/frontend/test_shape_cs.rs | 5 +--- src/gadgets/nonnative/bignat.rs | 31 +++++++++++++++-------- src/gadgets/nonnative/mod.rs | 2 +- src/gadgets/nonnative/util.rs | 8 ++---- src/lib.rs | 15 +++++++---- src/provider/bn256_grumpkin.rs | 2 +- src/provider/ipa_pc.rs | 2 +- src/provider/keccak.rs | 1 - src/provider/pasta.rs | 1 - src/provider/poseidon/circuit2.rs | 13 +++++----- src/provider/poseidon/circuit2_witness.rs | 2 +- src/provider/poseidon/hash_type.rs | 3 +-- src/provider/poseidon/matrix.rs | 2 +- src/provider/poseidon/mds.rs | 2 +- src/provider/poseidon/mod.rs | 23 ++++++++--------- src/provider/poseidon/poseidon_inner.rs | 8 +++--- src/provider/poseidon/preprocessing.rs | 2 +- src/provider/poseidon/round_constants.rs | 2 +- src/provider/poseidon/serde_impl.rs | 11 ++++---- src/provider/poseidon/sponge/circuit.rs | 4 +-- src/provider/poseidon/sponge/vanilla.rs | 11 ++++---- src/provider/secp_secq.rs | 1 - src/provider/traits.rs | 1 + src/spartan/mod.rs | 1 + src/traits/commitment.rs | 4 +-- 28 files changed, 87 insertions(+), 89 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e40efe7cd..500cb7977 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ thiserror = "2.0" group = "0.13.0" once_cell = "1.18.0" itertools = "0.13.0" -hashbrown = { version = "0.15.2", features = ["alloc"], optional = true } +hashbrown = { version = "0.15.2", features = ["alloc"] } [target.'cfg(target_arch = "wasm32")'.dependencies] getrandom = { version = "0.2", default-features = false, features = ["js"] } diff --git a/src/digest.rs b/src/digest.rs index aaa3bbece..bb593e72c 100644 --- a/src/digest.rs +++ b/src/digest.rs @@ -1,14 +1,14 @@ -use crate::{constants::NUM_HASH_BITS}; +use crate::{constants::NUM_HASH_BITS, errors::NovaError}; use bincode::Options; +use core::marker::PhantomData; use ff::PrimeField; use serde::Serialize; use sha3::{Digest, Sha3_256}; -use std::{io, marker::PhantomData}; /// Trait for components with potentially discrete digests to be included in their container's digest. pub trait Digestible { /// Write the byte representation of Self in a byte buffer - fn write_bytes(&self, byte_sink: &mut W) -> Result<(), io::Error>; + fn write_bytes(&self, byte_sink: &mut W) -> Result<(), NovaError>; } /// Marker trait to be implemented for types that implement `Digestible` and `Serialize`. @@ -16,14 +16,14 @@ pub trait Digestible { pub trait SimpleDigestible: Serialize {} impl Digestible for T { - fn write_bytes(&self, byte_sink: &mut W) -> Result<(), io::Error> { + fn write_bytes(&self, byte_sink: &mut W) -> Result<(), NovaError> { let config = bincode::DefaultOptions::new() .with_little_endian() .with_fixint_encoding(); // Note: bincode recursively length-prefixes every field! config .serialize_into(byte_sink, self) - .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) + .map_err(|e| NovaError::SerializationError(e.to_string())) } } @@ -65,7 +65,7 @@ impl<'a, F: PrimeField, T: Digestible> DigestComputer<'a, F, T> { } /// Compute the digest of a `Digestible` instance. - pub fn digest(&self) -> Result { + pub fn digest(&self) -> Result { let mut hasher = Self::hasher(); self .inner diff --git a/src/frontend/constraint_system.rs b/src/frontend/constraint_system.rs index 8e6c67c59..dbc920f07 100644 --- a/src/frontend/constraint_system.rs +++ b/src/frontend/constraint_system.rs @@ -1,6 +1,6 @@ use super::lc::{Index, LinearCombination, Variable}; use crate::prelude::*; -use core::{io, marker::PhantomData}; +use core::marker::PhantomData; use ff::PrimeField; /// Computations are expressed in terms of arithmetic circuits, in particular @@ -32,9 +32,6 @@ pub enum SynthesisError { /// During proof generation, we encountered an identity in the CRS #[error("encountered an identity element in the CRS")] UnexpectedIdentity, - /// During proof generation, we encountered an I/O error with the CRS - #[error("encountered an I/O error: {0}")] - IoError(#[from] io::Error), /// During verification, our verifying key was malformed. #[error("malformed verifying key")] MalformedVerifyingKey, diff --git a/src/frontend/test_shape_cs.rs b/src/frontend/test_shape_cs.rs index 194bb05b9..c236d9fbd 100644 --- a/src/frontend/test_shape_cs.rs +++ b/src/frontend/test_shape_cs.rs @@ -6,10 +6,7 @@ use crate::{ prelude::*, traits::Engine, }; -use core::{ - cmp::Ordering, - fmt::Write, -}; +use core::{cmp::Ordering, fmt::Write}; use ff::{Field, PrimeField}; #[derive(Clone, Copy)] diff --git a/src/gadgets/nonnative/bignat.rs b/src/gadgets/nonnative/bignat.rs index 137821068..3768c0e3c 100644 --- a/src/gadgets/nonnative/bignat.rs +++ b/src/gadgets/nonnative/bignat.rs @@ -55,7 +55,11 @@ pub fn nat_to_limbs( .collect(), ) } else { - eprintln!("nat {nat} does not fit in {n_limbs} limbs of width {limb_width}"); + // print only in std feature + #[cfg(feature = "std")] + { + eprintln!("nat {nat} does not fit in {n_limbs} limbs of width {limb_width}"); + } Err(SynthesisError::Unsatisfiable) } } @@ -135,6 +139,8 @@ impl BigNat { || match values_cell { Ok(ref vs) => { if vs.len() != n_limbs { + // print in std feature + #[cfg(feature = "std")] eprintln!("Values do not match stated limb count"); return Err(SynthesisError::Unsatisfiable); } @@ -147,10 +153,12 @@ impl BigNat { Ok(vs[limb_i]) } // Hack b/c SynthesisError and io::Error don't implement Clone - Err(ref e) => Err(SynthesisError::from(std::io::Error::new( - std::io::ErrorKind::Other, - format!("{e}"), - ))), + Err(ref e) => { + // print in std feature + #[cfg(feature = "std")] + eprintln!("{e}"); + Err(SynthesisError::InvalidAssignment) + } }, ) .map(|v| LinearCombination::zero() + v) @@ -199,8 +207,8 @@ impl BigNat { Ok(vs[limb_i]) } // Hack b/c SynthesisError and io::Error don't implement Clone - Err(ref e) => Err(SynthesisError::from(std::io::Error::new( - std::io::ErrorKind::Other, + Err(ref e) => Err(SynthesisError::from(bincode::Error::new( + bincode::ErrorKind::Other, format!("{e}"), ))), }, @@ -321,14 +329,15 @@ impl BigNat { pub fn enforce_limb_width_agreement( &self, other: &Self, - location: &str, + _location: &str, ) -> Result { if self.params.limb_width == other.params.limb_width { Ok(self.params.limb_width) } else { + #[cfg(feature = "std")] eprintln!( "Limb widths {}, {}, do not agree at {}", - self.params.limb_width, other.params.limb_width, location + self.params.limb_width, other.params.limb_width, _location ); Err(SynthesisError::Unsatisfiable) } @@ -645,7 +654,7 @@ impl BigNat { shift = Scalar::ONE; } limbs[i / limbs_per_group] = - std::mem::replace(&mut limbs[i / limbs_per_group], LinearCombination::zero()) + core::mem::replace(&mut limbs[i / limbs_per_group], LinearCombination::zero()) + (shift, limb); shift.mul_assign(&limb_block); } @@ -688,7 +697,7 @@ impl Polynomial { let n_product_coeffs = self.coefficients.len() + other.coefficients.len() - 1; let values = self.values.as_ref().and_then(|self_vs| { other.values.as_ref().map(|other_vs| { - let mut values: Vec = std::iter::repeat_with(|| Scalar::ZERO) + let mut values: Vec = core::iter::repeat_with(|| Scalar::ZERO) .take(n_product_coeffs) .collect(); for (self_i, self_v) in self_vs.iter().enumerate() { diff --git a/src/gadgets/nonnative/mod.rs b/src/gadgets/nonnative/mod.rs index 8337ff513..80c8e12ae 100644 --- a/src/gadgets/nonnative/mod.rs +++ b/src/gadgets/nonnative/mod.rs @@ -1,7 +1,7 @@ //! This module implements various gadgets necessary for doing non-native arithmetic //! Code in this module is adapted from [bellman-bignat](https://github.com/alex-ozdemir/bellman-bignat), which is licenced under MIT -use crate::{frontend::SynthesisError, prelude::*}; +use crate::frontend::SynthesisError; use ff::PrimeField; trait OptionExt { diff --git a/src/gadgets/nonnative/util.rs b/src/gadgets/nonnative/util.rs index e1cd158a7..f1a6bb452 100644 --- a/src/gadgets/nonnative/util.rs +++ b/src/gadgets/nonnative/util.rs @@ -3,11 +3,7 @@ use crate::{ frontend::{num::AllocatedNum, ConstraintSystem, LinearCombination, SynthesisError, Variable}, prelude::*, }; -use byteorder::WriteBytesExt; -use core::{ - convert::From, - io::{self, Write}, -}; +use core::{convert::From, fmt::Write}; use ff::PrimeField; use num_bigint::{BigInt, Sign}; @@ -233,7 +229,7 @@ impl From> for Num { } } -fn write_be(f: &F, mut writer: W) -> io::Result<()> { +fn write_be(f: &F, mut writer: W) -> core::result::Result<(), _> { for digit in f.to_repr().as_ref().iter().rev() { writer.write_u8(*digit)?; } diff --git a/src/lib.rs b/src/lib.rs index a7ebfb579..78ab0ff21 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,21 +18,25 @@ pub(crate) mod prelude { #[cfg(not(feature = "std"))] pub use alloc::boxed::Box; #[cfg(not(feature = "std"))] + pub use alloc::format; + #[cfg(not(feature = "std"))] pub use alloc::string::String; #[cfg(not(feature = "std"))] - pub use alloc::vec::Vec; + pub use alloc::string::ToString; #[cfg(not(feature = "std"))] pub use alloc::vec; #[cfg(not(feature = "std"))] - pub use alloc::format; + pub use alloc::vec::Vec; // use std::collections::{BTreeMap, HashMap} when std is enabled #[cfg(not(feature = "std"))] - pub use alloc::collections::{BTreeMap}; + pub use alloc::collections::BTreeMap; + #[cfg(not(feature = "std"))] + pub use alloc::collections::VecDeque; #[cfg(not(feature = "std"))] pub use hashbrown::HashMap; #[cfg(feature = "std")] - pub use std::collections::{BTreeMap, HashMap}; + pub use std::collections::{BTreeMap, HashMap, VecDeque}; } // private modules @@ -46,7 +50,7 @@ mod r1cs; pub mod errors; pub mod frontend; pub mod gadgets; -//pub mod provider; +pub mod provider; pub mod spartan; pub mod traits; @@ -65,6 +69,7 @@ use frontend::{ use gadgets::utils::scalar_as_base; use nifs::{NIFSRelaxed, NIFS}; use once_cell::sync::OnceCell; +use prelude::*; use r1cs::{ CommitmentKeyHint, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness, }; diff --git a/src/provider/bn256_grumpkin.rs b/src/provider/bn256_grumpkin.rs index 7ad8f3ea7..ba3b96e39 100644 --- a/src/provider/bn256_grumpkin.rs +++ b/src/provider/bn256_grumpkin.rs @@ -1,6 +1,7 @@ //! This module implements the Nova traits for `bn256::Point`, `bn256::Scalar`, `grumpkin::Point`, `grumpkin::Scalar`. use crate::{ impl_traits, + prelude::*, provider::traits::{DlogGroup, PairingGroup}, traits::{Group, PrimeFieldExt, TranscriptReprTrait}, }; @@ -18,7 +19,6 @@ use halo2curves::{ use pasta_curves::arithmetic::{CurveAffine, CurveExt}; use rayon::prelude::*; use sha3::Shake256; -use std::io::Read; /// Re-exports that give access to the standard aliases used in the code base, for bn256 pub mod bn256 { diff --git a/src/provider/ipa_pc.rs b/src/provider/ipa_pc.rs index ca4680bf5..0a7db706a 100644 --- a/src/provider/ipa_pc.rs +++ b/src/provider/ipa_pc.rs @@ -11,10 +11,10 @@ use crate::{ Commitment, CommitmentKey, CE, }; use core::iter; +use core::marker::PhantomData; use ff::Field; use rayon::prelude::*; use serde::{Deserialize, Serialize}; -use std::marker::PhantomData; /// Provides an implementation of the prover key #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/src/provider/keccak.rs b/src/provider/keccak.rs index f53d4e964..82bf37d6f 100644 --- a/src/provider/keccak.rs +++ b/src/provider/keccak.rs @@ -1,7 +1,6 @@ //! This module provides an implementation of `TranscriptEngineTrait` using keccak256 use crate::{ errors::NovaError, - prelude::*, traits::{Engine, PrimeFieldExt, TranscriptEngineTrait, TranscriptReprTrait}, }; use core::marker::PhantomData; diff --git a/src/provider/pasta.rs b/src/provider/pasta.rs index a58f37f26..7fd87c786 100644 --- a/src/provider/pasta.rs +++ b/src/provider/pasta.rs @@ -17,7 +17,6 @@ use pasta_curves::{ }; use rayon::prelude::*; use sha3::Shake256; -use std::io::Read; macro_rules! impl_traits { ( diff --git a/src/provider/poseidon/circuit2.rs b/src/provider/poseidon/circuit2.rs index 9aba7bd95..6b8506af5 100644 --- a/src/provider/poseidon/circuit2.rs +++ b/src/provider/poseidon/circuit2.rs @@ -6,14 +6,15 @@ use super::{ mds::SparseMatrix, poseidon_inner::{Arity, PoseidonConstants}, }; -use crate::{prelude::*, +use crate::{ frontend::{ - num::{self, AllocatedNum}, - Boolean, ConstraintSystem, LinearCombination, SynthesisError, -} + num::{self, AllocatedNum}, + Boolean, ConstraintSystem, LinearCombination, SynthesisError, + }, + prelude::*, }; +use core::marker::PhantomData; use ff::PrimeField; -use std::marker::PhantomData; /// Similar to `num::Num`, we use `Elt` to accumulate both values and linear combinations, then eventually /// extract into a `num::AllocatedNum`, enforcing that the linear combination corresponds to the result. @@ -400,7 +401,7 @@ where } fn initial_elements>() -> Vec> { - std::iter::repeat(Elt::num_from_fr::(Scalar::ZERO)) + core::iter::repeat(Elt::num_from_fr::(Scalar::ZERO)) .take(A::to_usize() + 1) .collect() } diff --git a/src/provider/poseidon/circuit2_witness.rs b/src/provider/poseidon/circuit2_witness.rs index a519da793..4e43371d5 100644 --- a/src/provider/poseidon/circuit2_witness.rs +++ b/src/provider/poseidon/circuit2_witness.rs @@ -1,6 +1,6 @@ /// The `circuit2_witness` module implements witness-generation for the optimal Poseidon hash circuit. use super::poseidon_inner::{Arity, Poseidon}; -use crate::{prelude::*, frontend::util_cs::witness_cs::SizedWitness}; +use crate::frontend::util_cs::witness_cs::SizedWitness; use ff::PrimeField; use generic_array::{sequence::GenericSequence, typenum::Unsigned, GenericArray}; diff --git a/src/provider/poseidon/hash_type.rs b/src/provider/poseidon/hash_type.rs index 516397a38..287f71bc5 100644 --- a/src/provider/poseidon/hash_type.rs +++ b/src/provider/poseidon/hash_type.rs @@ -1,3 +1,4 @@ +use super::poseidon_inner::Arity; /// `HashType` provides support for domain separation tags. /// For 128-bit security, we need to reserve one (~256-bit) field element per Poseidon permutation. /// This element cannot be used for hash preimage data — but can be assigned a constant value designating @@ -10,10 +11,8 @@ /// Because `neptune` also supports a first-class notion of `Strength`, we include a mechanism for composing /// `Strength` with `HashType` so that hashes with `Strength` other than `Standard` (currently only `Strengthened`) /// may still express the full range of hash function types. -use crate::prelude::*; use ff::PrimeField; use serde::{Deserialize, Serialize}; -use super::poseidon_inner::Arity; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(bound(serialize = "F: Serialize", deserialize = "F: Deserialize<'de>"))] diff --git a/src/provider/poseidon/matrix.rs b/src/provider/poseidon/matrix.rs index cb4aed25d..a0321ef43 100644 --- a/src/provider/poseidon/matrix.rs +++ b/src/provider/poseidon/matrix.rs @@ -1,8 +1,8 @@ // Allow `&Matrix` in function signatures. #![allow(clippy::ptr_arg)] -use ff::PrimeField; use crate::prelude::*; +use ff::PrimeField; /// Matrix functions here are, at least for now, quick and dirty — intended only to support precomputation of poseidon optimization. /// diff --git a/src/provider/poseidon/mds.rs b/src/provider/poseidon/mds.rs index 3245349e8..131286bbb 100644 --- a/src/provider/poseidon/mds.rs +++ b/src/provider/poseidon/mds.rs @@ -1,9 +1,9 @@ // Allow `&Matrix` in function signatures. #![allow(clippy::ptr_arg)] +use crate::prelude::*; use ff::PrimeField; use serde::{Deserialize, Serialize}; -use crate::prelude::*; use super::{ matrix, diff --git a/src/provider/poseidon/mod.rs b/src/provider/poseidon/mod.rs index f80bb0c9e..df7d33aef 100644 --- a/src/provider/poseidon/mod.rs +++ b/src/provider/poseidon/mod.rs @@ -2,10 +2,6 @@ //! //! The underlying Poseidon sponge code is ported from https://github.com/argumentcomputer/neptune. -use ff::PrimeField; -use round_constants::generate_constants; -use round_numbers::{round_numbers_base, round_numbers_strengthened}; -use serde::{Deserialize, Serialize}; mod circuit2; mod circuit2_witness; mod hash_type; @@ -18,22 +14,25 @@ mod round_numbers; mod serde_impl; mod sponge; -pub use circuit2::Elt; - -pub use sponge::{ - api::{IOPattern, SpongeAPI, SpongeOp}, - circuit::SpongeCircuit, - vanilla::{Mode::Simplex, Sponge, SpongeTrait}, -}; - use crate::{ frontend::{num::AllocatedNum, AllocatedBit, Boolean, ConstraintSystem, SynthesisError}, + prelude::*, provider::poseidon::poseidon_inner::PoseidonConstants, traits::{ROCircuitTrait, ROTrait}, }; +use circuit2::Elt; use core::marker::PhantomData; +use ff::PrimeField; use ff::PrimeFieldBits; use generic_array::typenum::U24; +use round_constants::generate_constants; +use round_numbers::{round_numbers_base, round_numbers_strengthened}; +use serde::{Deserialize, Serialize}; +use sponge::{ + api::{IOPattern, SpongeAPI, SpongeOp}, + circuit::SpongeCircuit, + vanilla::{Mode::Simplex, Sponge, SpongeTrait}, +}; /// The strength of the Poseidon hash function #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] diff --git a/src/provider/poseidon/poseidon_inner.rs b/src/provider/poseidon/poseidon_inner.rs index 9ff22d463..0b1079be3 100644 --- a/src/provider/poseidon/poseidon_inner.rs +++ b/src/provider/poseidon/poseidon_inner.rs @@ -1,8 +1,8 @@ +use crate::prelude::*; use core::marker::PhantomData; use ff::PrimeField; use generic_array::{sequence::GenericSequence, typenum, ArrayLength, GenericArray}; use typenum::*; -use crate::prelude::*; use super::{ matrix::transpose, @@ -453,12 +453,12 @@ where } } - let _ = std::mem::replace(&mut self.elements, result); + let _ = core::mem::replace(&mut self.elements, result); } pub(crate) fn product_mds_with_matrix_left(&mut self, matrix: &Matrix) { let result = left_apply_matrix(matrix, &self.elements); - let _ = std::mem::replace( + let _ = core::mem::replace( &mut self.elements, GenericArray::::generate(|i| result[i]), ); @@ -485,6 +485,6 @@ where val.add_assign(&tmp); } - let _ = std::mem::replace(&mut self.elements, result); + let _ = core::mem::replace(&mut self.elements, result); } } diff --git a/src/provider/poseidon/preprocessing.rs b/src/provider/poseidon/preprocessing.rs index 6e9455672..78a4475f5 100644 --- a/src/provider/poseidon/preprocessing.rs +++ b/src/provider/poseidon/preprocessing.rs @@ -3,8 +3,8 @@ use super::{ mds::MdsMatrices, quintic_s_box, }; -use ff::PrimeField; use crate::prelude::*; +use ff::PrimeField; // - Compress constants by pushing them back through linear layers and through the identity components of partial layers. // - As a result, constants need only be added after each S-box. diff --git a/src/provider/poseidon/round_constants.rs b/src/provider/poseidon/round_constants.rs index b78d1ce50..0e8ec3893 100644 --- a/src/provider/poseidon/round_constants.rs +++ b/src/provider/poseidon/round_constants.rs @@ -1,5 +1,5 @@ -use ff::PrimeField; use crate::prelude::*; +use ff::PrimeField; /// From the paper (): /// The round constants are generated using the Grain LFSR [23] in a self-shrinking diff --git a/src/provider/poseidon/serde_impl.rs b/src/provider/poseidon/serde_impl.rs index a1b781ac9..1a0e3c03f 100644 --- a/src/provider/poseidon/serde_impl.rs +++ b/src/provider/poseidon/serde_impl.rs @@ -1,15 +1,14 @@ +use super::{ + hash_type::HashType, + poseidon_inner::{Arity, PoseidonConstants}, +}; +use core::{fmt, marker::PhantomData}; use ff::PrimeField; use serde::{ de::{self, Deserializer, MapAccess, SeqAccess, Visitor}, ser::{SerializeStruct, Serializer}, Deserialize, Serialize, }; -use core::{fmt, marker::PhantomData}; -use super::{ - hash_type::HashType, - poseidon_inner::{Arity, PoseidonConstants}, -}; -use crate::prelude::*; impl Serialize for PoseidonConstants where diff --git a/src/provider/poseidon/sponge/circuit.rs b/src/provider/poseidon/sponge/circuit.rs index e591cd9aa..485bf81da 100644 --- a/src/provider/poseidon/sponge/circuit.rs +++ b/src/provider/poseidon/sponge/circuit.rs @@ -1,6 +1,6 @@ use crate::{ - prelude::*, frontend::{util_cs::witness_cs::SizedWitness, ConstraintSystem, Namespace, SynthesisError}, + prelude::*, provider::poseidon::{ circuit2::{Elt, PoseidonCircuit2}, poseidon_inner::{Arity, Poseidon, PoseidonConstants}, @@ -10,8 +10,8 @@ use crate::{ }, }, }; +use core::marker::PhantomData; use ff::PrimeField; -use core::{collections::VecDeque, marker::PhantomData}; /// The Poseidon sponge circuit pub struct SpongeCircuit<'a, F, A, C> diff --git a/src/provider/poseidon/sponge/vanilla.rs b/src/provider/poseidon/sponge/vanilla.rs index 29c04ed26..bc15ba403 100644 --- a/src/provider/poseidon/sponge/vanilla.rs +++ b/src/provider/poseidon/sponge/vanilla.rs @@ -1,14 +1,13 @@ use crate::{ prelude::*, provider::poseidon::{ - hash_type::HashType, - poseidon_inner::{Arity, Poseidon, PoseidonConstants}, - sponge::api::{IOPattern, InnerSpongeAPI}, - PoseidonError, Strength, -} + hash_type::HashType, + poseidon_inner::{Arity, Poseidon, PoseidonConstants}, + sponge::api::{IOPattern, InnerSpongeAPI}, + PoseidonError, Strength, + }, }; use ff::PrimeField; -use std::collections::VecDeque; // General information on sponge construction: https://keccak.team/files/CSF-0.1.pdf diff --git a/src/provider/secp_secq.rs b/src/provider/secp_secq.rs index 9b39fd7f8..1033d5a75 100644 --- a/src/provider/secp_secq.rs +++ b/src/provider/secp_secq.rs @@ -18,7 +18,6 @@ use num_traits::Num; use pasta_curves::arithmetic::{CurveAffine, CurveExt}; use rayon::prelude::*; use sha3::Shake256; -use std::io::Read; /// Re-exports that give access to the standard aliases used in the code base, for secp pub mod secp256k1 { diff --git a/src/provider/traits.rs b/src/provider/traits.rs index 1bd3b7e06..e23c5bd9e 100644 --- a/src/provider/traits.rs +++ b/src/provider/traits.rs @@ -1,4 +1,5 @@ use crate::{ + prelude::*, traits::{commitment::ScalarMul, Group, TranscriptReprTrait}, }; use core::{ diff --git a/src/spartan/mod.rs b/src/spartan/mod.rs index 64edd6434..9e3bd5feb 100644 --- a/src/spartan/mod.rs +++ b/src/spartan/mod.rs @@ -15,6 +15,7 @@ pub mod snark; mod sumcheck; use crate::{ + prelude::*, r1cs::{R1CSShape, SparseMatrix}, traits::Engine, Commitment, diff --git a/src/traits/commitment.rs b/src/traits/commitment.rs index 92e681cfc..2a61ca799 100644 --- a/src/traits/commitment.rs +++ b/src/traits/commitment.rs @@ -1,8 +1,6 @@ //! This module defines a collection of traits that define the behavior of a commitment engine //! We require the commitment engine to provide a commitment to vectors with a single group element -use crate::{ - traits::{AbsorbInROTrait, Engine, TranscriptReprTrait}, -}; +use crate::traits::{AbsorbInROTrait, Engine, TranscriptReprTrait}; use core::{ fmt::Debug, ops::{Add, Mul, MulAssign}, From c6d479113f55ad84bd9b362643760f2508974e44 Mon Sep 17 00:00:00 2001 From: Srinath Setty Date: Thu, 19 Dec 2024 14:03:55 -0800 Subject: [PATCH 3/6] fix remaining issues --- src/digest.rs | 87 ++++++++++++-------------------- src/errors.rs | 7 ++- src/frontend/util_cs/test_cs.rs | 7 +-- src/gadgets/ecc.rs | 3 -- src/gadgets/nonnative/bignat.rs | 19 ++++--- src/gadgets/nonnative/util.rs | 17 ++++--- src/lib.rs | 2 + src/nifs.rs | 3 +- src/provider/bn256_grumpkin.rs | 2 +- src/provider/keccak.rs | 3 +- src/provider/mod.rs | 10 ++-- src/provider/pasta.rs | 4 +- src/provider/poseidon/mod.rs | 9 ++-- src/provider/secp_secq.rs | 2 +- src/provider/traits.rs | 2 +- src/spartan/polys/masked_eq.rs | 4 +- src/spartan/polys/multilinear.rs | 4 +- 17 files changed, 89 insertions(+), 96 deletions(-) diff --git a/src/digest.rs b/src/digest.rs index bb593e72c..cc3a15b2a 100644 --- a/src/digest.rs +++ b/src/digest.rs @@ -1,5 +1,5 @@ -use crate::{constants::NUM_HASH_BITS, errors::NovaError}; -use bincode::Options; +use crate::{prelude::*, NovaError, NUM_HASH_BITS}; +use bincode::{DefaultOptions, Options}; use core::marker::PhantomData; use ff::PrimeField; use serde::Serialize; @@ -8,7 +8,7 @@ use sha3::{Digest, Sha3_256}; /// Trait for components with potentially discrete digests to be included in their container's digest. pub trait Digestible { /// Write the byte representation of Self in a byte buffer - fn write_bytes(&self, byte_sink: &mut W) -> Result<(), NovaError>; + fn write_bytes(&self) -> Result, NovaError>; } /// Marker trait to be implemented for types that implement `Digestible` and `Serialize`. @@ -16,17 +16,18 @@ pub trait Digestible { pub trait SimpleDigestible: Serialize {} impl Digestible for T { - fn write_bytes(&self, byte_sink: &mut W) -> Result<(), NovaError> { - let config = bincode::DefaultOptions::new() + fn write_bytes(&self) -> Result, NovaError> { + let config = DefaultOptions::new() .with_little_endian() .with_fixint_encoding(); - // Note: bincode recursively length-prefixes every field! - config - .serialize_into(byte_sink, self) - .map_err(|e| NovaError::SerializationError(e.to_string())) + // Serialize into a Vec and return it + config.serialize(self).map_err(|e| NovaError::DigestError { + reason: e.to_string(), + }) } } +/// Compute the digest of a `Digestible` instance. pub struct DigestComputer<'a, F: PrimeField, T> { inner: &'a T, _phantom: PhantomData, @@ -45,15 +46,15 @@ impl<'a, F: PrimeField, T: Digestible> DigestComputer<'a, F, T> { }); // turn the bit vector into a scalar - let mut digest = F::ZERO; + let mut result = F::ZERO; let mut coeff = F::ONE; for bit in bv { if bit { - digest += coeff; + result += coeff; } coeff += coeff; } - digest + result } /// Create a new `DigestComputer` @@ -66,12 +67,15 @@ impl<'a, F: PrimeField, T: Digestible> DigestComputer<'a, F, T> { /// Compute the digest of a `Digestible` instance. pub fn digest(&self) -> Result { + // Get the serialized bytes + let bytes = self.inner.write_bytes().expect("Serialization error"); + let mut hasher = Self::hasher(); - self - .inner - .write_bytes(&mut hasher) - .expect("Serialization error"); - let bytes: [u8; 32] = hasher.finalize().into(); + hasher.update(&bytes); + let final_bytes = hasher.finalize(); + let bytes: Vec = final_bytes.to_vec(); + + // Now map to the field or handle it as necessary Ok(Self::map_to_field(&bytes)) } } @@ -81,7 +85,6 @@ mod tests { use super::{DigestComputer, SimpleDigestible}; use crate::{provider::PallasEngine, traits::Engine}; use ff::Field; - use once_cell::sync::OnceCell; use serde::{Deserialize, Serialize}; type E = PallasEngine; @@ -89,38 +92,28 @@ mod tests { #[derive(Serialize, Deserialize)] struct S { i: usize, - #[serde(skip, default = "OnceCell::new")] - digest: OnceCell, + #[serde(skip)] + digest: Option, // Use Option instead of OnceCell } impl SimpleDigestible for S {} impl S { fn new(i: usize) -> Self { - S { - i, - digest: OnceCell::new(), - } + S { i, digest: None } } - fn digest(&self) -> E::Scalar { - self - .digest - .get_or_try_init(|| DigestComputer::new(self).digest()) - .cloned() - .unwrap() + fn digest(&mut self) -> E::Scalar { + let digest: E::Scalar = DigestComputer::new(self).digest().unwrap(); + self.digest.get_or_insert_with(|| digest).clone() } } #[test] fn test_digest_field_not_ingested_in_computation() { let s1 = S::::new(42); - - // let's set up a struct with a weird digest field to make sure the digest computation does not depend of it - let oc = OnceCell::new(); - oc.set(::Scalar::ONE).unwrap(); - - let s2: S = S { i: 42, digest: oc }; + let mut s2 = S::::new(42); + s2.digest = Some(::Scalar::ONE); // Set manually for test assert_eq!( DigestComputer::<::Scalar, _>::new(&s1) @@ -130,32 +123,18 @@ mod tests { .digest() .unwrap() ); - - // note: because of the semantics of `OnceCell::get_or_try_init`, the above - // equality will not result in `s1.digest() == s2.digest` - assert_ne!( - s2.digest(), - DigestComputer::<::Scalar, _>::new(&s2) - .digest() - .unwrap() - ); } #[test] fn test_digest_impervious_to_serialization() { - let good_s = S::::new(42); - - // let's set up a struct with a weird digest field to confuse deserializers - let oc = OnceCell::new(); - oc.set(::Scalar::ONE).unwrap(); + let mut good_s = S::::new(42); + let mut bad_s = S::::new(42); + bad_s.digest = Some(::Scalar::ONE); // Set manually for test - let bad_s: S = S { i: 42, digest: oc }; - // this justifies the adjective "bad" assert_ne!(good_s.digest(), bad_s.digest()); let naughty_bytes = bincode::serialize(&bad_s).unwrap(); - - let retrieved_s: S = bincode::deserialize(&naughty_bytes).unwrap(); + let mut retrieved_s: S = bincode::deserialize(&naughty_bytes).unwrap(); assert_eq!(good_s.digest(), retrieved_s.digest()) } } diff --git a/src/errors.rs b/src/errors.rs index 6eef053f2..dcd6d9f1c 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -63,8 +63,11 @@ pub enum NovaError { reason: String, }, /// returned when there is an error creating a digest - #[error("DigestError")] - DigestError, + #[error("DigestError: {reason}")] + DigestError { + /// The reason for digest creation failure + reason: String, + }, /// returned when the prover cannot prove the provided statement due to completeness error #[error("InternalError")] InternalError, diff --git a/src/frontend/util_cs/test_cs.rs b/src/frontend/util_cs/test_cs.rs index ff6f01d31..e273ddb10 100644 --- a/src/frontend/util_cs/test_cs.rs +++ b/src/frontend/util_cs/test_cs.rs @@ -3,7 +3,6 @@ use crate::{ frontend::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}, prelude::*, }; -use core::collections::HashMap; use ff::PrimeField; #[derive(Debug)] @@ -110,8 +109,10 @@ impl TestConstraintSystem { /// Check if the constraint system is satisfied. pub fn is_satisfied(&self) -> bool { match self.which_is_unsatisfied() { - Some(b) => { - println!("fail: {:?}", b); + Some(_b) => { + // print only in std feature + #[cfg(feature = "std")] + println!("fail: {:?}", _b); false } None => true, diff --git a/src/gadgets/ecc.rs b/src/gadgets/ecc.rs index 8c7d690d5..7220c0b84 100644 --- a/src/gadgets/ecc.rs +++ b/src/gadgets/ecc.rs @@ -1030,7 +1030,6 @@ mod tests { // First create the shape let mut cs: TestShapeCS = TestShapeCS::new(); let _ = synthesize_smul::(cs.namespace(|| "synthesize")); - println!("Number of constraints: {}", cs.num_constraints()); let (shape, ck) = cs.r1cs_shape(&*default_ck_hint()); // Then the satisfying assignment @@ -1086,7 +1085,6 @@ mod tests { // First create the shape let mut cs: TestShapeCS = TestShapeCS::new(); let _ = synthesize_add_equal::(cs.namespace(|| "synthesize add equal")); - println!("Number of constraints: {}", cs.num_constraints()); let (shape, ck) = cs.r1cs_shape(&*default_ck_hint()); // Then the satisfying assignment @@ -1146,7 +1144,6 @@ mod tests { // First create the shape let mut cs: TestShapeCS = TestShapeCS::new(); let _ = synthesize_add_negation::(cs.namespace(|| "synthesize add equal")); - println!("Number of constraints: {}", cs.num_constraints()); let (shape, ck) = cs.r1cs_shape(&*default_ck_hint()); // Then the satisfying assignment diff --git a/src/gadgets/nonnative/bignat.rs b/src/gadgets/nonnative/bignat.rs index 3768c0e3c..bc02f4b9d 100644 --- a/src/gadgets/nonnative/bignat.rs +++ b/src/gadgets/nonnative/bignat.rs @@ -153,11 +153,11 @@ impl BigNat { Ok(vs[limb_i]) } // Hack b/c SynthesisError and io::Error don't implement Clone - Err(ref e) => { + Err(ref _e) => { // print in std feature #[cfg(feature = "std")] eprintln!("{e}"); - Err(SynthesisError::InvalidAssignment) + Err(SynthesisError::AssignmentMissing) } }, ) @@ -207,10 +207,12 @@ impl BigNat { Ok(vs[limb_i]) } // Hack b/c SynthesisError and io::Error don't implement Clone - Err(ref e) => Err(SynthesisError::from(bincode::Error::new( - bincode::ErrorKind::Other, - format!("{e}"), - ))), + Err(ref _e) => { + // print in std feature + #[cfg(feature = "std")] + eprintln!("{_e}"); + Err(SynthesisError::AssignmentMissing) + } }, ) .map(|v| LinearCombination::zero() + v) @@ -843,8 +845,9 @@ mod tests { circuit.synthesize(&mut cs).expect("synthesis failed"); - if let Some(token) = cs.which_is_unsatisfied() { - eprintln!("Error: {} is unsatisfied", token); + if let Some(_token) = cs.which_is_unsatisfied() { + #[cfg(feature = "std")] + eprintln!("Error: {} is unsatisfied", _token); } } diff --git a/src/gadgets/nonnative/util.rs b/src/gadgets/nonnative/util.rs index f1a6bb452..abd003270 100644 --- a/src/gadgets/nonnative/util.rs +++ b/src/gadgets/nonnative/util.rs @@ -3,7 +3,7 @@ use crate::{ frontend::{num::AllocatedNum, ConstraintSystem, LinearCombination, SynthesisError, Variable}, prelude::*, }; -use core::{convert::From, fmt::Write}; +use core::{convert::From, result::Result}; use ff::PrimeField; use num_bigint::{BigInt, Sign}; @@ -229,18 +229,23 @@ impl From> for Num { } } -fn write_be(f: &F, mut writer: W) -> core::result::Result<(), _> { +// Assuming PrimeField is a trait from some elliptic curve or cryptographic library +pub fn write_be(f: &F, buffer: &mut [u8]) -> Result<(), ()> { + let mut offset = 0; for digit in f.to_repr().as_ref().iter().rev() { - writer.write_u8(*digit)?; + if offset >= buffer.len() { + return Err(()); // Overflow: not enough space in buffer + } + buffer[offset] = *digit; + offset += 1; } - Ok(()) } /// Convert a field element to a natural number pub fn f_to_nat(f: &Scalar) -> BigInt { - let mut s = Vec::new(); - write_be(f, &mut s).unwrap(); // f.to_repr().write_be(&mut s).unwrap(); + let mut buffer = [0u8; 256]; // Fixed-size buffer for the serialized representation of the field element + write_be(f, &mut buffer).unwrap(); BigInt::from_bytes_le(Sign::Plus, f.to_repr().as_ref()) } diff --git a/src/lib.rs b/src/lib.rs index 78ab0ff21..24e114eb2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,8 @@ extern crate alloc; pub(crate) mod prelude { + #[cfg(not(feature = "std"))] + pub use alloc::borrow::ToOwned; #[cfg(not(feature = "std"))] pub use alloc::boxed::Box; #[cfg(not(feature = "std"))] diff --git a/src/nifs.rs b/src/nifs.rs index ca0e3e839..6d07fc1aa 100644 --- a/src/nifs.rs +++ b/src/nifs.rs @@ -217,6 +217,7 @@ mod tests { test_shape_cs::TestShapeCS, ConstraintSystem, SynthesisError, }, + prelude::*, provider::{Bn256EngineKZG, PallasEngine, Secp256k1Engine}, r1cs::{SparseMatrix, R1CS}, traits::{commitment::CommitmentEngineTrait, snark::default_ck_hint, Engine}, @@ -549,8 +550,6 @@ mod tests { let (_O, U1, W1) = rand_inst_witness_generator(&ck, &I); let (U2, W2) = S.sample_random_instance_witness(&ck).unwrap(); // random fold - println!("INSTANCE {:#?}", U1.clone()); - // execute a sequence of folds let (final_U, final_W) = execute_sequence_relaxed( &ck, diff --git a/src/provider/bn256_grumpkin.rs b/src/provider/bn256_grumpkin.rs index ba3b96e39..e209ccb83 100644 --- a/src/provider/bn256_grumpkin.rs +++ b/src/provider/bn256_grumpkin.rs @@ -5,7 +5,7 @@ use crate::{ provider::traits::{DlogGroup, PairingGroup}, traits::{Group, PrimeFieldExt, TranscriptReprTrait}, }; -use digest::{ExtendableOutput, Update}; +use digest::{ExtendableOutput, Update, XofReader}; use ff::{FromUniformBytes, PrimeField}; use group::{cofactor::CofactorCurveAffine, Curve, Group as AnotherGroup}; use num_bigint::BigInt; diff --git a/src/provider/keccak.rs b/src/provider/keccak.rs index 82bf37d6f..3880e25b3 100644 --- a/src/provider/keccak.rs +++ b/src/provider/keccak.rs @@ -98,6 +98,7 @@ impl TranscriptEngineTrait for Keccak256Transcript { #[cfg(test)] mod tests { use crate::{ + prelude::*, provider::{ keccak::Keccak256Transcript, Bn256EngineKZG, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine, @@ -213,7 +214,7 @@ mod tests { let mut rng = rand::thread_rng(); // ten scalars - let scalars = std::iter::from_fn(|| Some(::Scalar::from(rng.gen::()))) + let scalars = core::iter::from_fn(|| Some(::Scalar::from(rng.gen::()))) .take(10) .collect::>(); diff --git a/src/provider/mod.rs b/src/provider/mod.rs index fea6dd394..2131616aa 100644 --- a/src/provider/mod.rs +++ b/src/provider/mod.rs @@ -129,13 +129,15 @@ impl Engine for VestaEngine { #[cfg(test)] mod tests { - use crate::provider::{bn256_grumpkin::bn256, secp_secq::secp256k1, traits::DlogGroup}; - use digest::{ExtendableOutput, Update}; + use crate::{ + prelude::*, + provider::{bn256_grumpkin::bn256, secp_secq::secp256k1, traits::DlogGroup}, + }; + use digest::{ExtendableOutput, Update, XofReader}; use group::Curve; use halo2curves::CurveExt; use pasta_curves::pallas; use sha3::Shake256; - use std::io::Read; macro_rules! impl_cycle_pair_test { ($curve:ident) => { @@ -146,7 +148,7 @@ mod tests { (0..n) .map(|_| { let mut uniform_bytes = [0u8; 32]; - reader.read_exact(&mut uniform_bytes).unwrap(); + reader.read(&mut uniform_bytes); let hash = $curve::Point::hash_to_curve("from_uniform_bytes"); hash(&uniform_bytes).to_affine() }) diff --git a/src/provider/pasta.rs b/src/provider/pasta.rs index 7fd87c786..3710b855f 100644 --- a/src/provider/pasta.rs +++ b/src/provider/pasta.rs @@ -4,7 +4,7 @@ use crate::{ provider::traits::DlogGroup, traits::{Group, PrimeFieldExt, TranscriptReprTrait}, }; -use digest::{ExtendableOutput, Update}; +use digest::{ExtendableOutput, Update, XofReader}; use ff::{FromUniformBytes, PrimeField}; use halo2curves::msm::best_multiexp; use num_bigint::BigInt; @@ -65,7 +65,7 @@ macro_rules! impl_traits { let mut uniform_bytes_vec = Vec::new(); for _ in 0..n { let mut uniform_bytes = [0u8; 32]; - reader.read_exact(&mut uniform_bytes).unwrap(); + reader.read(&mut uniform_bytes); uniform_bytes_vec.push(uniform_bytes); } let ck_proj: Vec<$name_curve> = (0..n) diff --git a/src/provider/poseidon/mod.rs b/src/provider/poseidon/mod.rs index df7d33aef..33815cbf0 100644 --- a/src/provider/poseidon/mod.rs +++ b/src/provider/poseidon/mod.rs @@ -20,7 +20,6 @@ use crate::{ provider::poseidon::poseidon_inner::PoseidonConstants, traits::{ROCircuitTrait, ROTrait}, }; -use circuit2::Elt; use core::marker::PhantomData; use ff::PrimeField; use ff::PrimeFieldBits; @@ -28,7 +27,9 @@ use generic_array::typenum::U24; use round_constants::generate_constants; use round_numbers::{round_numbers_base, round_numbers_strengthened}; use serde::{Deserialize, Serialize}; -use sponge::{ + +pub use circuit2::Elt; +pub use sponge::{ api::{IOPattern, SpongeAPI, SpongeOp}, circuit::SpongeCircuit, vanilla::{Mode::Simplex, Sponge, SpongeTrait}, @@ -278,8 +279,8 @@ mod tests { where // we can print the field elements we get from E's Base & Scalar fields, // and compare their byte representations - <::Base as PrimeField>::Repr: std::fmt::Debug, - <::Scalar as PrimeField>::Repr: std::fmt::Debug, + <::Base as PrimeField>::Repr: core::fmt::Debug, + <::Scalar as PrimeField>::Repr: core::fmt::Debug, <::Base as PrimeField>::Repr: PartialEq<<::Scalar as PrimeField>::Repr>, { diff --git a/src/provider/secp_secq.rs b/src/provider/secp_secq.rs index 1033d5a75..e4d6a530f 100644 --- a/src/provider/secp_secq.rs +++ b/src/provider/secp_secq.rs @@ -5,7 +5,7 @@ use crate::{ provider::traits::DlogGroup, traits::{Group, PrimeFieldExt, TranscriptReprTrait}, }; -use digest::{ExtendableOutput, Update}; +use digest::{ExtendableOutput, Update, XofReader}; use ff::{FromUniformBytes, PrimeField}; use group::{cofactor::CofactorCurveAffine, Curve, Group as AnotherGroup}; use halo2curves::{ diff --git a/src/provider/traits.rs b/src/provider/traits.rs index e23c5bd9e..471dacc8d 100644 --- a/src/provider/traits.rs +++ b/src/provider/traits.rs @@ -135,7 +135,7 @@ macro_rules! impl_traits { let mut uniform_bytes_vec = Vec::new(); for _ in 0..n { let mut uniform_bytes = [0u8; 32]; - reader.read_exact(&mut uniform_bytes).unwrap(); + reader.read(&mut uniform_bytes); uniform_bytes_vec.push(uniform_bytes); } let gens_proj: Vec<$name_curve> = (0..n) diff --git a/src/spartan/polys/masked_eq.rs b/src/spartan/polys/masked_eq.rs index 09c20b04f..e9ff18411 100644 --- a/src/spartan/polys/masked_eq.rs +++ b/src/spartan/polys/masked_eq.rs @@ -94,11 +94,11 @@ mod tests { let num_masked_evals = 1 << num_masked_vars; // random point - let r = std::iter::from_fn(|| Some(F::random(&mut rng))) + let r = core::iter::from_fn(|| Some(F::random(&mut rng))) .take(num_vars) .collect::>(); // evaluation point - let rx = std::iter::from_fn(|| Some(F::random(&mut rng))) + let rx = core::iter::from_fn(|| Some(F::random(&mut rng))) .take(num_vars) .collect::>(); diff --git a/src/spartan/polys/multilinear.rs b/src/spartan/polys/multilinear.rs index 80ddbb196..7367b3bcb 100644 --- a/src/spartan/polys/multilinear.rs +++ b/src/spartan/polys/multilinear.rs @@ -285,7 +285,7 @@ mod tests { mut rng: &mut R, ) -> MultilinearPolynomial { MultilinearPolynomial::new( - std::iter::from_fn(|| Some(Scalar::random(&mut rng))) + core::iter::from_fn(|| Some(Scalar::random(&mut rng))) .take(1 << num_vars) .collect(), ) @@ -321,7 +321,7 @@ mod tests { let poly = random(n, &mut rng); // draw a random point - let pt: Vec<_> = std::iter::from_fn(|| Some(F::random(&mut rng))) + let pt: Vec<_> = core::iter::from_fn(|| Some(F::random(&mut rng))) .take(n) .collect(); // this shows the order in which coordinates are evaluated From 9ee86de56cc6719a1d217ec606e88261f46c032e Mon Sep 17 00:00:00 2001 From: Srinath Setty Date: Thu, 19 Dec 2024 14:15:08 -0800 Subject: [PATCH 4/6] temp workarounds --- .github/workflows/rust.yml | 16 +++++++++++++--- src/digest.rs | 2 +- src/gadgets/nonnative/bignat.rs | 2 +- src/gadgets/nonnative/util.rs | 4 +--- src/lib.rs | 5 +++-- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 0cea2dce1..efc341ab6 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Build + - name: Build (std) uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -38,7 +38,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Run tests + - name: Run tests (std) uses: actions-rs/toolchain@v1 with: toolchain: stable @@ -47,6 +47,15 @@ jobs: command: test args: --release --verbose + - name: Run tests (no_std) + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - uses: actions-rs/cargo@v1 + with: + command: test + args: --release --no-default-features --features no_std --verbose + fmt: runs-on: ubuntu-latest steps: @@ -73,4 +82,5 @@ jobs: - uses: actions-rs/cargo@v1 with: command: clippy - args: --all-targets -- -D warnings + #args: --all-targets -- -D warnings // TODO: bring back + args: --all-targets \ No newline at end of file diff --git a/src/digest.rs b/src/digest.rs index cc3a15b2a..9687e1659 100644 --- a/src/digest.rs +++ b/src/digest.rs @@ -105,7 +105,7 @@ mod tests { fn digest(&mut self) -> E::Scalar { let digest: E::Scalar = DigestComputer::new(self).digest().unwrap(); - self.digest.get_or_insert_with(|| digest).clone() + *self.digest.get_or_insert(digest) } } diff --git a/src/gadgets/nonnative/bignat.rs b/src/gadgets/nonnative/bignat.rs index bc02f4b9d..7f7f4ace9 100644 --- a/src/gadgets/nonnative/bignat.rs +++ b/src/gadgets/nonnative/bignat.rs @@ -156,7 +156,7 @@ impl BigNat { Err(ref _e) => { // print in std feature #[cfg(feature = "std")] - eprintln!("{e}"); + eprintln!("{_e}"); Err(SynthesisError::AssignmentMissing) } }, diff --git a/src/gadgets/nonnative/util.rs b/src/gadgets/nonnative/util.rs index abd003270..9063fea66 100644 --- a/src/gadgets/nonnative/util.rs +++ b/src/gadgets/nonnative/util.rs @@ -231,13 +231,11 @@ impl From> for Num { // Assuming PrimeField is a trait from some elliptic curve or cryptographic library pub fn write_be(f: &F, buffer: &mut [u8]) -> Result<(), ()> { - let mut offset = 0; - for digit in f.to_repr().as_ref().iter().rev() { + for (offset, digit) in f.to_repr().as_ref().iter().rev().enumerate() { if offset >= buffer.len() { return Err(()); // Overflow: not enough space in buffer } buffer[offset] = *digit; - offset += 1; } Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 24e114eb2..87942d489 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,15 @@ //! This library implements Nova, a high-speed recursive SNARK. #![cfg_attr(not(feature = "std"), no_std)] #![deny( - warnings, - unused, + //warnings, + //unused, TODO: bring this back future_incompatible, nonstandard_style, rust_2018_idioms, missing_docs )] #![allow(non_snake_case)] + #![forbid(unsafe_code)] #[cfg(not(feature = "std"))] From ad1bb380ccdee0bb5e6d78453d258b5e300adca0 Mon Sep 17 00:00:00 2001 From: Srinath Setty Date: Thu, 19 Dec 2024 14:16:28 -0800 Subject: [PATCH 5/6] fix --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index efc341ab6..c4a4cc8b7 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -54,7 +54,7 @@ jobs: - uses: actions-rs/cargo@v1 with: command: test - args: --release --no-default-features --features no_std --verbose + args: --release --no-default-features --verbose fmt: runs-on: ubuntu-latest From a88e1d3d29ffef2059cc854d96c2ea865dca711f Mon Sep 17 00:00:00 2001 From: Srinath Setty Date: Thu, 19 Dec 2024 14:18:02 -0800 Subject: [PATCH 6/6] Fix fmt --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 87942d489..f5a397a65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,6 @@ missing_docs )] #![allow(non_snake_case)] - #![forbid(unsafe_code)] #[cfg(not(feature = "std"))]