Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial experimental HyperNova multifolding support #175

Draft
wants to merge 102 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
789354a
Add utils for hadamard and matrix vector product
oskarth May 24, 2023
5a025c6
utils: Add more utils, sparse matrix vector product etc
oskarth May 25, 2023
a3e2182
feat: First cut of CCS (#14)
oskarth May 26, 2023
5d4b110
refactor: Remove digest
oskarth May 26, 2023
60bbec2
feat(CCS): Add from_r1cs and get rid of hardcoded constants
oskarth May 26, 2023
4f5e784
fix(CCS): Add commitment key and CCS is_sat test
oskarth May 26, 2023
f72c49b
style(ccs): Remove old comments and unused code, clarify todos
oskarth Jun 2, 2023
4470d92
refactor(ccs): Add experimental hypernova feature flag (on by default)
oskarth Jun 2, 2023
9182cc3
chore(ccs): Turn off hypernova feature flag by default
oskarth Jun 2, 2023
db6add0
chore: update dep
oskarth Jun 2, 2023
2a59d80
chore: Cargo.toml
oskarth Jun 5, 2023
85f4e22
add doc and tests for spartan/polynomial.rs
wangtsiao May 27, 2023
5223fea
use pasta instead of defining new fp
wangtsiao May 31, 2023
6a45489
wrap link with <> in comment
wangtsiao Jun 1, 2023
9598d1d
fmt(spartan): cargo fmt
oskarth Jun 5, 2023
64b7bd7
Remove: Clippy unused fn lint
CPerezz Jun 5, 2023
8db47a5
change: Impl SparseMatrix type
CPerezz Jun 5, 2023
ac57cb6
change: Adopt SparseMatrix type and make `pad` recieve &mut
CPerezz Jun 5, 2023
d373753
Fix: Update tests to match new trait bounds
CPerezz Jun 5, 2023
ed36b4a
feat(ccs): Sketch out basic CCCS/LCCCS associated data structures
oskarth Jun 7, 2023
0262dc6
feat(utils): Add SparseMatrix n_rows/n_cols utils
oskarth Jun 7, 2023
f1a8834
fix(ccs): Calculcate m n_rows correctly for a set of sparse matrices
oskarth Jun 7, 2023
d1e63a0
feat(ccs): Add m, n, s and s_prime to CCS struct
oskarth Jun 7, 2023
0192d63
WIP CCCS
oskarth Jun 12, 2023
49455f8
WIP: CCS MLE stuff
oskarth Jun 13, 2023
1a9244e
fix(utils): fix sparse_matrix_to_mlp test
oskarth Jun 14, 2023
93fc061
refactor(ccs): change c to be Scalar
oskarth Jun 14, 2023
dbc0c22
feat(polynomial): Add convenience functions for MLP
oskarth Jun 14, 2023
48c1ac9
wip(ccs): compute_g function
oskarth Jun 14, 2023
0a473b0
refactor: use shorthand syntax for add and mul operations
oskarth Jun 15, 2023
e404742
feat: Add BooleanHypercube to evaluate multilinear polynomial at give…
oskarth Jun 15, 2023
987359b
refactor: Move Boolean hypercube to separate module
oskarth Jun 15, 2023
5ec547a
feat(ccs): compute_sum_Mz
oskarth Jun 15, 2023
ab70853
fix: Correct SparseMatrix aux methods
CPerezz Jun 21, 2023
d0a5160
fix: Update CCS-related structs & constructor
CPerezz Jun 21, 2023
fa0376e
change: Remove Result from Matrix/vec ops
CPerezz Jun 21, 2023
0559644
change: Update CCS.is_sat() to use iterators
CPerezz Jun 21, 2023
10f1b9f
change: Move matrix padding to SparseMatrix
CPerezz Jun 21, 2023
659ef74
change: Update `from_r1cs` & `pad` CCSShape fns
CPerezz Jun 21, 2023
ff4b44b
change: Standarize `new` methods & remove CAPS
CPerezz Jun 21, 2023
af1e3d5
remove: Unused CCShape::matrix_mul fn
CPerezz Jun 21, 2023
9b2f3c5
fix: Move test-only fns to test mod & fix sparse tests
CPerezz Jun 21, 2023
2a79b9e
change: Remove num_cons & unneeded Results
CPerezz Jun 21, 2023
1b8bba8
fix: Add test feature flag to HyperCube tests mod
CPerezz Jun 21, 2023
8075c15
add: Migrate VirtualPolynomial from espresso/Hyperplonk
CPerezz Jun 22, 2023
b81e432
fix: Include err variant to handle VirtualPolynomial
CPerezz Jun 22, 2023
0f26a23
change: Move CCS stuff to it's own module
CPerezz Jun 22, 2023
68afd5e
add: Migrate VirtualPolynomial from espresso/HyperPlonk
CPerezz Jun 22, 2023
f48dda8
fix: Correct q_computation & update to VirtualPoly usage
CPerezz Jun 22, 2023
71668c7
add: Add CCS -> CCCS conversions
CPerezz Jun 22, 2023
b2e8a6b
change: Update/Improve a bit the HyperCube API
CPerezz Jun 22, 2023
578431c
fix: Include n_cos & n_rows info in SparseMatrix
CPerezz Jun 23, 2023
bc94cb7
change: Update `pad` and `from_r1cs` CCS methods.
CPerezz Jun 23, 2023
dec29ae
remove: coefficients field from HyperCube & refactor
CPerezz Jun 25, 2023
a11cf9c
change: Change HyperCube `evaluate_at` endianness
CPerezz Jun 25, 2023
055751e
add: Port MLE support & tests passing
CPerezz Jun 25, 2023
1450875
fix: Vec * Sparse
CPerezz Jun 25, 2023
a057978
fix: Split Matrix_Vec prod into dense+sparse
CPerezz Jun 25, 2023
1b60494
this code is cursed
CPerezz Jun 26, 2023
827a1ff
lift the curse:
arnaucube Jun 26, 2023
fe14cdd
fix SparseMatrix.to_mle() method, fix test_matrix_to_mle
arnaucube Jun 27, 2023
ce646e6
fix cccs.compute_sum_Mz method, small fix in compute_q, so by consequ…
arnaucube Jun 27, 2023
af45a4c
change: Get M_j_mle from precomputed CCCS M's
CPerezz Jun 27, 2023
c800b39
remove: CCS struct which is unused
CPerezz Jun 27, 2023
b714a20
change: Plce impl blocks under their structs
CPerezz Jun 27, 2023
d436f87
change: Create utils folder under ccs
CPerezz Jun 27, 2023
8e2d99c
change: Move Compute_sum_Mz into util mode
CPerezz Jun 28, 2023
99679fb
change: Move `fix_variables` & util tests to util mod
CPerezz Jun 28, 2023
8b73f47
change: Move CCS test fns as associated fns
CPerezz Jun 28, 2023
eaadaf2
Add: Compute_all_sum_Mz_evals fn to utils module
CPerezz Jun 28, 2023
e3303cd
add: Ck computation & instance satisfaction fns for LCCCS
CPerezz Jun 28, 2023
f5a13a4
remove: Rng param in gen_test_ccs instance fn
CPerezz Jun 28, 2023
bf589be
Add: CCS to LCCCS transformation & v_j s comp
CPerezz Jun 28, 2023
45e8391
add: LCCCS tests with test_lcccs_v_j FAILING
CPerezz Jun 28, 2023
a14d27d
fix: compute_all_sum_Mz_evals with test
CPerezz Jun 29, 2023
3c1017c
fix: test_lcccs_v_j working
CPerezz Jun 29, 2023
2a1fa7a
add: Basic multifolding functions & tests
CPerezz Jun 30, 2023
a2d4408
add: Failing test for sigmas_and_thetas comp
CPerezz Jun 30, 2023
78a4059
fix: test_compute_sigmas_and_thetas
CPerezz Jul 7, 2023
d37afdb
add: Folding functions pending for tests to pass
CPerezz Jul 7, 2023
09cef38
tmp: Check CCCS instance correctness failing
CPerezz Jul 10, 2023
a33e7c3
test(multifolding): Fix CCCS assert
oskarth Jul 11, 2023
216e0e6
refactor(ccs): Remove special CCCSWitness
oskarth Jul 11, 2023
f3bcf68
tests(ccs): Fix test_lcccs_fold test
oskarth Jul 11, 2023
af959fb
chore: fix errors after rebase
oskarth Jul 11, 2023
f07e71b
Merge upstream/main
oskarth Jul 12, 2023
4828a20
chore: fix merge artifact
oskarth Jul 12, 2023
6f1ed22
chore: Restore global warnings and unused
oskarth Jul 12, 2023
20ba46c
refactor: Enable requirement of even public IO by default
oskarth Jul 12, 2023
ca55e73
Hypernova first cut (#15)
CPerezz Jul 12, 2023
cde23f3
refactor(utils): SparseMatrix taking F instead of G (#33)
oskarth Jul 14, 2023
3fdaeab
test(utils): Make generic over Field
oskarth Jul 13, 2023
4ae0cf7
test(utils): Make generic over PrimeField for SparseMatrix
oskarth Jul 14, 2023
3437fae
fix: Address all Clippy suggestions/lints
CPerezz Jul 14, 2023
6fa448f
Update bit_decompose def:
arnaucube Jul 16, 2023
a23c6ab
refactor(virtual_poly): Remove unnecessary default from PhantomData (…
oskarth Jul 20, 2023
9a508b2
refactor: Make tests generic w.r.t. curve/group (#40)
oskarth Jul 20, 2023
1119702
NIMFS-centric API refactor for multifolding impl (#41)
CPerezz Jul 31, 2023
bb7a651
Use polynomial.rs instead of virtual_poly for equality polynomial (#42)
oskarth Aug 2, 2023
0c8915b
Transcript usage inclusion into the codebase (#43)
CPerezz Aug 2, 2023
5f24446
Remove witness from CCCS & LCCCS instances (#48)
CPerezz Aug 4, 2023
a18afe0
Chore/sync upstream (#51)
oskarth Aug 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nova-snark"
version = "0.22.0"
version = "0.23.0"
authors = ["Srinath Setty <srinath@microsoft.com>"]
edition = "2021"
description = "Recursive zkSNARKs without trusted setup"
Expand Down Expand Up @@ -28,11 +28,11 @@ num-traits = "0.2"
num-integer = "0.1"
serde = { version = "1.0", features = ["derive"] }
bincode = "1.3"
flate2 = "1.0"
bitvec = "1.0"
byteorder = "1.4.3"
thiserror = "1.0"
halo2curves = { version = "0.1.0", features = ["derive_serde"] }
thiserror = "1.0"
rand = "0.8.4"
halo2curves = { version="0.1.0", features = [ "derive_serde" ] }

[target.'cfg(any(target_arch = "x86_64", target_arch = "aarch64"))'.dependencies]
pasta-msm = { version = "0.1.4" }
Expand All @@ -44,10 +44,12 @@ getrandom = { version = "0.2.0", default-features = false, features = ["js"] }
[dev-dependencies]
criterion = { version = "0.4", features = ["html_reports"] }
rand = "0.8.4"
flate2 = "1.0"
hex = "0.4.3"
pprof = { version = "0.11" }
cfg-if = "1.0.0"
sha2 = "0.10.7"
proptest = "1.2.0"

[[bench]]
name = "recursive-snark"
Expand All @@ -66,9 +68,11 @@ name = "sha256"
harness = false

[features]
default = []
default = ["hypernova"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can turn this off before merging, we use this in our fork

# Compiles in portable mode, w/o ISA extensions => binary can be executed on all systems.
portable = ["pasta-msm/portable"]
cuda = ["neptune/cuda", "neptune/pasta", "neptune/arity24"]
opencl = ["neptune/opencl", "neptune/pasta", "neptune/arity24"]
hypernova = []

flamegraph = ["pprof/flamegraph", "pprof/criterion"]
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.


### Experimental features
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This is currently a subsection under "Contributing". Could we please move this above the "References section"? And use "##" so it is not a subsection?


To run early experimental work on CCS and HyperNova, use the `hypernova` feature flag:

```text
cargo test --features hypernova ccs
```

## Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
Expand Down
97 changes: 94 additions & 3 deletions benches/compressed-snark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
type EE1 = nova_snark::provider::ipa_pc::EvaluationEngine<G1>;
type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine<G2>;
// SNARKs without computational commitments
type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK<G1, EE1>;
type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK<G2, EE2>;
// SNARKs with computational commitments
type SS1 = nova_snark::spartan::ppsnark::RelaxedR1CSSNARK<G1, EE1>;
type SS2 = nova_snark::spartan::ppsnark::RelaxedR1CSSNARK<G2, EE2>;
type C1 = NonTrivialTestCircuit<<G1 as Group>::Scalar>;
type C2 = TrivialTestCircuit<<G2 as Group>::Scalar>;

Expand All @@ -31,13 +35,13 @@ cfg_if::cfg_if! {
criterion_group! {
name = compressed_snark;
config = Criterion::default().warm_up_time(Duration::from_millis(3000)).with_profiler(pprof::criterion::PProfProfiler::new(100, pprof::criterion::Output::Flamegraph(None)));
targets = bench_compressed_snark
targets = bench_compressed_snark, bench_compressed_snark_with_computational_commitments
}
} else {
criterion_group! {
name = compressed_snark;
config = Criterion::default().warm_up_time(Duration::from_millis(3000));
targets = bench_compressed_snark
targets = bench_compressed_snark, bench_compressed_snark_with_computational_commitments
}
}
}
Expand All @@ -61,7 +65,7 @@ fn bench_compressed_snark(c: &mut Criterion) {
let c_secondary = TrivialTestCircuit::default();

// Produce public parameters
let pp = PublicParams::<G1, G2, C1, C2>::setup(c_primary.clone(), c_secondary.clone());
let pp = PublicParams::<G1, G2, C1, C2>::setup(&c_primary, &c_secondary);

// Produce prover and verifier keys for CompressedSNARK
let (pk, vk) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap();
Expand Down Expand Up @@ -129,6 +133,93 @@ fn bench_compressed_snark(c: &mut Criterion) {
}
}

fn bench_compressed_snark_with_computational_commitments(c: &mut Criterion) {
let num_samples = 10;
let num_cons_verifier_circuit_primary = 9819;
// we vary the number of constraints in the step circuit
for &num_cons_in_augmented_circuit in [9819, 16384, 32768, 65536, 131072, 262144].iter() {
// number of constraints in the step circuit
let num_cons = num_cons_in_augmented_circuit - num_cons_verifier_circuit_primary;

let mut group = c.benchmark_group(format!(
"CompressedSNARK-Commitments-StepCircuitSize-{num_cons}"
));
group
.sampling_mode(SamplingMode::Flat)
.sample_size(num_samples);

let c_primary = NonTrivialTestCircuit::new(num_cons);
let c_secondary = TrivialTestCircuit::default();

// Produce public parameters
let pp = PublicParams::<G1, G2, C1, C2>::setup(&c_primary, &c_secondary);

// Produce prover and verifier keys for CompressedSNARK
let (pk, vk) = CompressedSNARK::<_, _, _, _, SS1, SS2>::setup(&pp).unwrap();

// produce a recursive SNARK
let num_steps = 3;
let mut recursive_snark: RecursiveSNARK<G1, G2, C1, C2> = RecursiveSNARK::new(
&pp,
&c_primary,
&c_secondary,
vec![<G1 as Group>::Scalar::from(2u64)],
vec![<G2 as Group>::Scalar::from(2u64)],
);

for i in 0..num_steps {
let res = recursive_snark.prove_step(
&pp,
&c_primary,
&c_secondary,
vec![<G1 as Group>::Scalar::from(2u64)],
vec![<G2 as Group>::Scalar::from(2u64)],
);
assert!(res.is_ok());

// verify the recursive snark at each step of recursion
let res = recursive_snark.verify(
&pp,
i + 1,
&[<G1 as Group>::Scalar::from(2u64)],
&[<G2 as Group>::Scalar::from(2u64)],
);
assert!(res.is_ok());
}

// Bench time to produce a compressed SNARK
group.bench_function("Prove", |b| {
b.iter(|| {
assert!(CompressedSNARK::<_, _, _, _, SS1, SS2>::prove(
black_box(&pp),
black_box(&pk),
black_box(&recursive_snark)
)
.is_ok());
})
});
let res = CompressedSNARK::<_, _, _, _, SS1, SS2>::prove(&pp, &pk, &recursive_snark);
assert!(res.is_ok());
let compressed_snark = res.unwrap();

// Benchmark the verification time
group.bench_function("Verify", |b| {
b.iter(|| {
assert!(black_box(&compressed_snark)
.verify(
black_box(&vk),
black_box(num_steps),
black_box(vec![<G1 as Group>::Scalar::from(2u64)]),
black_box(vec![<G2 as Group>::Scalar::from(2u64)]),
)
.is_ok());
})
});

group.finish();
}
}

#[derive(Clone, Debug, Default)]
struct NonTrivialTestCircuit<F: PrimeField> {
num_cons: usize,
Expand Down
2 changes: 1 addition & 1 deletion benches/compute-digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ criterion_main!(compute_digest);
fn bench_compute_digest(c: &mut Criterion) {
c.bench_function("compute_digest", |b| {
b.iter(|| {
PublicParams::<G1, G2, C1, C2>::setup(black_box(C1::new(10)), black_box(C2::default()))
PublicParams::<G1, G2, C1, C2>::setup(black_box(&C1::new(10)), black_box(&C2::default()))
})
});
}
Expand Down
2 changes: 1 addition & 1 deletion benches/recursive-snark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn bench_recursive_snark(c: &mut Criterion) {
let c_secondary = TrivialTestCircuit::default();

// Produce public parameters
let pp = PublicParams::<G1, G2, C1, C2>::setup(c_primary.clone(), c_secondary.clone());
let pp = PublicParams::<G1, G2, C1, C2>::setup(&c_primary, &c_secondary);

// Bench time to produce a recursive SNARK;
// we execute a certain number of warm-up steps since executing
Expand Down
4 changes: 2 additions & 2 deletions benches/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ fn bench_recursive_snark(c: &mut Criterion) {
group.sample_size(10);

// Produce public parameters
let pp =
PublicParams::<G1, G2, C1, C2>::setup(circuit_primary.clone(), TrivialTestCircuit::default());
let ttc = TrivialTestCircuit::default();
let pp = PublicParams::<G1, G2, C1, C2>::setup(&circuit_primary, &ttc);

let circuit_secondary = TrivialTestCircuit::default();
let z0_primary = vec![<G1 as Group>::Scalar::from(2u64)];
Expand Down
2 changes: 1 addition & 1 deletion examples/minroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ fn main() {
G2,
MinRootCircuit<<G1 as Group>::Scalar>,
TrivialTestCircuit<<G2 as Group>::Scalar>,
>::setup(circuit_primary.clone(), circuit_secondary.clone());
>::setup(&circuit_primary, &circuit_secondary);
println!("PublicParams::setup, took {:?} ", start.elapsed());

println!(
Expand Down
10 changes: 2 additions & 8 deletions src/bellperson/r1cs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ pub trait NovaShape<G: Group> {
fn r1cs_shape(&self) -> (R1CSShape<G>, CommitmentKey<G>);
}

impl<G: Group> NovaWitness<G> for SatisfyingAssignment<G>
where
G::Scalar: PrimeField,
{
impl<G: Group> NovaWitness<G> for SatisfyingAssignment<G> {
fn r1cs_instance_and_witness(
&self,
shape: &R1CSShape<G>,
Expand All @@ -48,10 +45,7 @@ where
}
}

impl<G: Group> NovaShape<G> for ShapeCS<G>
where
G::Scalar: PrimeField,
{
impl<G: Group> NovaShape<G> for ShapeCS<G> {
fn r1cs_shape(&self) -> (R1CSShape<G>, CommitmentKey<G>) {
let mut A: Vec<(usize, usize, G::Scalar)> = Vec::new();
let mut B: Vec<(usize, usize, G::Scalar)> = Vec::new();
Expand Down
20 changes: 4 additions & 16 deletions src/bellperson/shape_cs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ impl Ord for OrderedVariable {

#[allow(clippy::upper_case_acronyms)]
/// `ShapeCS` is a `ConstraintSystem` for creating `R1CSShape`s for a circuit.
pub struct ShapeCS<G: Group>
where
G::Scalar: PrimeField + Field,
{
pub struct ShapeCS<G: Group> {
named_objects: HashMap<String, NamedObject>,
current_namespace: Vec<String>,
#[allow(clippy::type_complexity)]
Expand Down Expand Up @@ -92,10 +89,7 @@ fn proc_lc<Scalar: PrimeField>(
map
}

impl<G: Group> ShapeCS<G>
where
G::Scalar: PrimeField,
{
impl<G: Group> ShapeCS<G> {
/// Create a new, default `ShapeCS`,
pub fn new() -> Self {
ShapeCS::default()
Expand Down Expand Up @@ -216,10 +210,7 @@ where
}
}

impl<G: Group> Default for ShapeCS<G>
where
G::Scalar: PrimeField,
{
impl<G: Group> Default for ShapeCS<G> {
fn default() -> Self {
let mut map = HashMap::new();
map.insert("ONE".into(), NamedObject::Var(ShapeCS::<G>::one()));
Expand All @@ -233,10 +224,7 @@ where
}
}

impl<G: Group> ConstraintSystem<G::Scalar> for ShapeCS<G>
where
G::Scalar: PrimeField,
{
impl<G: Group> ConstraintSystem<G::Scalar> for ShapeCS<G> {
type Root = Self;

fn alloc<F, A, AR>(&mut self, annotation: A, _f: F) -> Result<Variable, SynthesisError>
Expand Down
17 changes: 4 additions & 13 deletions src/bellperson/solver.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
//! Support for generating R1CS witness using bellperson.

use crate::traits::Group;
use ff::{Field, PrimeField};
use ff::Field;

use bellperson::{
multiexp::DensityTracker, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable,
};

/// A `ConstraintSystem` which calculates witness values for a concrete instance of an R1CS circuit.
#[derive(PartialEq)]
pub struct SatisfyingAssignment<G: Group>
where
G::Scalar: PrimeField,
{
pub struct SatisfyingAssignment<G: Group> {
// Density of queries
a_aux_density: DensityTracker,
b_input_density: DensityTracker,
Expand All @@ -29,10 +26,7 @@ where
}
use std::fmt;

impl<G: Group> fmt::Debug for SatisfyingAssignment<G>
where
G::Scalar: PrimeField,
{
impl<G: Group> fmt::Debug for SatisfyingAssignment<G> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt
.debug_struct("SatisfyingAssignment")
Expand Down Expand Up @@ -69,10 +63,7 @@ where
}
}

impl<G: Group> ConstraintSystem<G::Scalar> for SatisfyingAssignment<G>
where
G::Scalar: PrimeField,
{
impl<G: Group> ConstraintSystem<G::Scalar> for SatisfyingAssignment<G> {
type Root = Self;

fn new() -> Self {
Expand Down
Loading