From 3332b80ff09007ad5db8d7b1ecbd3281831d1672 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 15 Jul 2024 18:53:24 +0000 Subject: [PATCH] Move `bellman::groth16` into a separate crate --- .github/workflows/ci.yml | 10 +++--- CHANGELOG.md | 2 ++ Cargo.lock | 17 ++++++++++ Cargo.toml | 22 ++++++------- groth16/CHANGELOG.md | 9 ++++++ groth16/Cargo.toml | 32 +++++++++++++++++++ groth16/README.md | 21 ++++++++++++ {benches => groth16/benches}/batch.rs | 2 +- {src/groth16 => groth16/src}/generator.rs | 25 +++++++++------ src/groth16/mod.rs => groth16/src/lib.rs | 5 ++- {src/groth16 => groth16/src}/prover.rs | 31 +++++++++++------- .../src}/tests/dummy_engine.rs | 0 {src/groth16 => groth16/src}/tests/mod.rs | 2 +- {src/groth16 => groth16/src}/verifier.rs | 2 +- .../groth16 => groth16/src}/verifier/batch.rs | 6 ++-- {tests => groth16/tests}/common/mod.rs | 0 {tests => groth16/tests}/mimc.rs | 2 +- src/lib.rs | 5 +-- 18 files changed, 141 insertions(+), 52 deletions(-) create mode 100644 groth16/CHANGELOG.md create mode 100644 groth16/Cargo.toml create mode 100644 groth16/README.md rename {benches => groth16/benches}/batch.rs (99%) rename {src/groth16 => groth16/src}/generator.rs (95%) rename src/groth16/mod.rs => groth16/src/lib.rs (99%) rename {src/groth16 => groth16/src}/prover.rs (92%) rename {src/groth16 => groth16/src}/tests/dummy_engine.rs (100%) rename {src/groth16 => groth16/src}/tests/mod.rs (99%) rename {src/groth16 => groth16/src}/verifier.rs (98%) rename {src/groth16 => groth16/src}/verifier/batch.rs (99%) rename {tests => groth16/tests}/common/mod.rs (100%) rename {tests => groth16/tests}/mimc.rs (99%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89f0526e5..1234ab983 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Run tests - run: cargo test --verbose --release + run: cargo test --verbose --release --workspace build: name: Build target ${{ matrix.target }} @@ -31,7 +31,7 @@ jobs: - name: Add target run: rustup target add ${{ matrix.target }} - name: Build for target - run: cargo build --verbose --target ${{ matrix.target }} ${{ matrix.build_flags }} + run: cargo build --verbose --workspace --target ${{ matrix.target }} ${{ matrix.build_flags }} bitrot: name: Bitrot check @@ -41,7 +41,7 @@ jobs: - uses: actions/checkout@v3 # Build benchmarks to prevent bitrot - name: Build benchmarks - run: cargo build --benches --all-features + run: cargo build --benches --workspace --all-features doc-links: name: Intra-doc links @@ -50,7 +50,7 @@ jobs: - uses: actions/checkout@v3 # Requires #![deny(rustdoc::broken_intra_doc_links)] in crates. - name: Check intra-doc links - run: cargo doc --document-private-items + run: cargo doc --workspace --document-private-items fmt: name: Rustfmt @@ -59,4 +59,4 @@ jobs: steps: - uses: actions/checkout@v3 - name: Check formatting - run: cargo fmt -- --check + run: cargo fmt --all -- --check diff --git a/CHANGELOG.md b/CHANGELOG.md index f1713d898..5be45039c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to Rust's notion of [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Removed +- `bellman::groth16` (moved to the `groth16` crate). ## [0.14.0] - 2023-03-20 ### Changed diff --git a/Cargo.lock b/Cargo.lock index 21b179a8b..cc09cbbd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,6 +48,7 @@ dependencies = [ "criterion", "crossbeam-channel", "ff", + "groth16", "group", "hex-literal", "lazy_static", @@ -343,6 +344,22 @@ dependencies = [ "wasi", ] +[[package]] +name = "groth16" +version = "0.0.0" +dependencies = [ + "bellman", + "bls12_381", + "byteorder", + "criterion", + "ff", + "group", + "pairing", + "rand", + "rand_core", + "subtle", +] + [[package]] name = "group" version = "0.13.0" diff --git a/Cargo.toml b/Cargo.toml index 770f5ab64..754b26499 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,9 @@ +[workspace] +members = [ + ".", + "groth16", +] + [package] authors = [ "Sean Bowe ", @@ -34,23 +40,17 @@ rayon = { version = "1.5.1", optional = true } bls12_381 = "0.8" criterion = "0.4" hex-literal = "0.3" +pairing = "0.23" rand = "0.8" rand_xorshift = "0.3" sha2 = "0.10" +# Only for doctests. +groth16 = { path = "groth16" } + [features] -groth16 = ["pairing"] multicore = ["crossbeam-channel", "lazy_static", "log", "num_cpus", "rayon", "rand_core/getrandom"] -default = ["groth16", "multicore"] - -[[test]] -name = "mimc" -path = "tests/mimc.rs" -required-features = ["groth16"] - -[[bench]] -name = "batch" -harness = false +default = ["multicore"] [[bench]] name = "slow" diff --git a/groth16/CHANGELOG.md b/groth16/CHANGELOG.md new file mode 100644 index 000000000..121701a84 --- /dev/null +++ b/groth16/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to Rust's notion of +[Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] +Initial release (moved from `bellman::groth16`) diff --git a/groth16/Cargo.toml b/groth16/Cargo.toml new file mode 100644 index 000000000..bacae5f41 --- /dev/null +++ b/groth16/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "groth16" +version = "0.0.0" +authors = [ + "Sean Bowe ", + "Jack Grigg ", +] +edition = "2021" +rust-version = "1.60" +description = "Groth16 prover and verifier for Bellman" +readme = "README.md" +homepage = "https://github.com/zkcrypto/bellman" +repository = "https://github.com/zkcrypto/bellman" +license = "MIT OR Apache-2.0" + +[dependencies] +bellman = { version = "0.14", path = "../" } +byteorder = "1" +ff = "0.13" +group = "0.13" +pairing = "0.23" +rand_core = "0.6" + +[dev-dependencies] +bls12_381 = "0.8" +criterion = "0.4" +rand = "0.8" +subtle = "2.2.1" + +[[bench]] +name = "batch" +harness = false diff --git a/groth16/README.md b/groth16/README.md new file mode 100644 index 000000000..5552e3398 --- /dev/null +++ b/groth16/README.md @@ -0,0 +1,21 @@ +# groth16 [![Crates.io](https://img.shields.io/crates/v/groth16.svg)](https://crates.io/crates/groth16) # + +`groth16` is an implementation of the Groth16 proving system, backed by the +`bellman` circuit-building library. + +## License + +Licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](../LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally +submitted for inclusion in the work by you, as defined in the Apache-2.0 +license, shall be dual licensed as above, without any additional terms or +conditions. diff --git a/benches/batch.rs b/groth16/benches/batch.rs similarity index 99% rename from benches/batch.rs rename to groth16/benches/batch.rs index 693c68576..717489670 100644 --- a/benches/batch.rs +++ b/groth16/benches/batch.rs @@ -4,7 +4,7 @@ use bls12_381::Bls12; use ff::Field; use rand::thread_rng; -use bellman::groth16::{ +use groth16::{ batch, create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, }; diff --git a/src/groth16/generator.rs b/groth16/src/generator.rs similarity index 95% rename from src/groth16/generator.rs rename to groth16/src/generator.rs index dc9ab42d1..01f419904 100644 --- a/src/groth16/generator.rs +++ b/groth16/src/generator.rs @@ -8,11 +8,11 @@ use pairing::Engine; use super::{Parameters, VerifyingKey}; -use crate::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; +use bellman::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; -use crate::domain::{EvaluationDomain, Scalar}; +use bellman::domain::{EvaluationDomain, Scalar}; -use crate::multicore::Worker; +use bellman::multicore::Worker; /// Generates a random common reference string for /// a circuit. @@ -71,7 +71,7 @@ impl ConstraintSystem for KeypairAssembly { self.bt_aux.push(vec![]); self.ct_aux.push(vec![]); - Ok(Variable(Index::Aux(index))) + Ok(Variable::new_unchecked(Index::Aux(index))) } fn alloc_input(&mut self, _: A, _: F) -> Result @@ -90,7 +90,7 @@ impl ConstraintSystem for KeypairAssembly { self.bt_inputs.push(vec![]); self.ct_inputs.push(vec![]); - Ok(Variable(Index::Input(index))) + Ok(Variable::new_unchecked(Index::Input(index))) } fn enforce(&mut self, _: A, a: LA, b: LB, c: LC) @@ -107,10 +107,10 @@ impl ConstraintSystem for KeypairAssembly { aux: &mut [Vec<(Scalar, usize)>], this_constraint: usize, ) { - for (index, coeff) in l.0 { - match index { - Variable(Index::Input(id)) => inputs[id].push((coeff, this_constraint)), - Variable(Index::Aux(id)) => aux[id].push((coeff, this_constraint)), + for (index, coeff) in l.as_ref() { + match index.get_unchecked() { + Index::Input(id) => inputs[id].push((*coeff, this_constraint)), + Index::Aux(id) => aux[id].push((*coeff, this_constraint)), } } } @@ -193,7 +193,12 @@ where // Input constraints to ensure full density of IC query // x * 0 = 0 for i in 0..assembly.num_inputs { - assembly.enforce(|| "", |lc| lc + Variable(Index::Input(i)), |lc| lc, |lc| lc); + assembly.enforce( + || "", + |lc| lc + Variable::new_unchecked(Index::Input(i)), + |lc| lc, + |lc| lc, + ); } // Create bases for blind evaluation of polynomials at tau diff --git a/src/groth16/mod.rs b/groth16/src/lib.rs similarity index 99% rename from src/groth16/mod.rs rename to groth16/src/lib.rs index b0e20887e..5114bf228 100644 --- a/src/groth16/mod.rs +++ b/groth16/src/lib.rs @@ -5,9 +5,8 @@ use group::{prime::PrimeCurveAffine, GroupEncoding, UncompressedEncoding}; use pairing::{Engine, MultiMillerLoop}; -use crate::SynthesisError; +use bellman::{multiexp::SourceBuilder, SynthesisError}; -use crate::multiexp::SourceBuilder; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use std::io::{self, Read, Write}; use std::sync::Arc; @@ -477,8 +476,8 @@ impl<'a, E: Engine> ParameterSource for &'a Parameters { #[cfg(test)] mod test_with_bls12_381 { use super::*; - use crate::{Circuit, ConstraintSystem, SynthesisError}; + use bellman::{Circuit, ConstraintSystem, SynthesisError}; use bls12_381::{Bls12, Scalar}; use ff::{Field, PrimeField}; use rand::thread_rng; diff --git a/src/groth16/prover.rs b/groth16/src/prover.rs similarity index 92% rename from src/groth16/prover.rs rename to groth16/src/prover.rs index 78061387c..c61c2a034 100644 --- a/src/groth16/prover.rs +++ b/groth16/src/prover.rs @@ -8,13 +8,13 @@ use pairing::Engine; use super::{ParameterSource, Proof}; -use crate::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; +use bellman::{Circuit, ConstraintSystem, Index, LinearCombination, SynthesisError, Variable}; -use crate::domain::{EvaluationDomain, Scalar}; +use bellman::domain::{EvaluationDomain, Scalar}; -use crate::multiexp::{multiexp, DensityTracker, FullDensity}; +use bellman::multiexp::{multiexp, DensityTracker, FullDensity}; -use crate::multicore::Worker; +use bellman::multicore::Worker; fn eval( lc: &LinearCombination, @@ -25,18 +25,18 @@ fn eval( ) -> S { let mut acc = S::ZERO; - for &(index, coeff) in lc.0.iter() { + for &(index, coeff) in lc.as_ref() { let mut tmp; if !coeff.is_zero_vartime() { - match index { - Variable(Index::Input(i)) => { + match index.get_unchecked() { + Index::Input(i) => { tmp = input_assignment[i]; if let Some(ref mut v) = input_density { v.inc(i); } } - Variable(Index::Aux(i)) => { + Index::Aux(i) => { tmp = aux_assignment[i]; if let Some(ref mut v) = aux_density { v.inc(i); @@ -83,7 +83,9 @@ impl ConstraintSystem for ProvingAssignment { self.a_aux_density.add_element(); self.b_aux_density.add_element(); - Ok(Variable(Index::Aux(self.aux_assignment.len() - 1))) + Ok(Variable::new_unchecked(Index::Aux( + self.aux_assignment.len() - 1, + ))) } fn alloc_input(&mut self, _: A, f: F) -> Result @@ -95,7 +97,9 @@ impl ConstraintSystem for ProvingAssignment { self.input_assignment.push(f()?); self.b_input_density.add_element(); - Ok(Variable(Index::Input(self.input_assignment.len() - 1))) + Ok(Variable::new_unchecked(Index::Input( + self.input_assignment.len() - 1, + ))) } fn enforce(&mut self, _: A, a: LA, b: LB, c: LC) @@ -202,7 +206,12 @@ where circuit.synthesize(&mut prover)?; for i in 0..prover.input_assignment.len() { - prover.enforce(|| "", |lc| lc + Variable(Index::Input(i)), |lc| lc, |lc| lc); + prover.enforce( + || "", + |lc| lc + Variable::new_unchecked(Index::Input(i)), + |lc| lc, + |lc| lc, + ); } let worker = Worker::new(); diff --git a/src/groth16/tests/dummy_engine.rs b/groth16/src/tests/dummy_engine.rs similarity index 100% rename from src/groth16/tests/dummy_engine.rs rename to groth16/src/tests/dummy_engine.rs diff --git a/src/groth16/tests/mod.rs b/groth16/src/tests/mod.rs similarity index 99% rename from src/groth16/tests/mod.rs rename to groth16/src/tests/mod.rs index d43e6bf23..28ea6fedd 100644 --- a/src/groth16/tests/mod.rs +++ b/groth16/src/tests/mod.rs @@ -6,7 +6,7 @@ use self::dummy_engine::*; use std::marker::PhantomData; use std::ops::{AddAssign, MulAssign, SubAssign}; -use crate::{Circuit, ConstraintSystem, SynthesisError}; +use bellman::{Circuit, ConstraintSystem, SynthesisError}; use super::{create_proof, generate_parameters, prepare_verifying_key, verify_proof}; diff --git a/src/groth16/verifier.rs b/groth16/src/verifier.rs similarity index 98% rename from src/groth16/verifier.rs rename to groth16/src/verifier.rs index 607eb70f1..83d35e3be 100644 --- a/src/groth16/verifier.rs +++ b/groth16/src/verifier.rs @@ -4,7 +4,7 @@ use std::ops::{AddAssign, Neg}; use super::{PreparedVerifyingKey, Proof, VerifyingKey}; -use crate::VerificationError; +use bellman::VerificationError; pub mod batch; diff --git a/src/groth16/verifier/batch.rs b/groth16/src/verifier/batch.rs similarity index 99% rename from src/groth16/verifier/batch.rs rename to groth16/src/verifier/batch.rs index 274cd0a6c..eddbb41b7 100644 --- a/src/groth16/verifier/batch.rs +++ b/groth16/src/verifier/batch.rs @@ -17,6 +17,7 @@ use std::ops::AddAssign; +use bellman::VerificationError; use ff::Field; use group::{Curve, Group}; use pairing::{MillerLoopResult, MultiMillerLoop}; @@ -28,10 +29,7 @@ use rand_core::OsRng; #[cfg(feature = "multicore")] use rayon::{iter::ParallelIterator, prelude::ParallelSlice}; -use crate::{ - groth16::{PreparedVerifyingKey, Proof, VerifyingKey}, - VerificationError, -}; +use crate::{PreparedVerifyingKey, Proof, VerifyingKey}; /// A batch verification item. /// diff --git a/tests/common/mod.rs b/groth16/tests/common/mod.rs similarity index 100% rename from tests/common/mod.rs rename to groth16/tests/common/mod.rs diff --git a/tests/mimc.rs b/groth16/tests/mimc.rs similarity index 99% rename from tests/mimc.rs rename to groth16/tests/mimc.rs index ce0a28054..bf6df815e 100644 --- a/tests/mimc.rs +++ b/groth16/tests/mimc.rs @@ -11,7 +11,7 @@ use ff::Field; use bls12_381::{Bls12, Scalar}; // We're going to use the Groth16 proving system. -use bellman::groth16::{ +use groth16::{ batch, create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, Proof, }; diff --git a/src/lib.rs b/src/lib.rs index 6277ff3c6..dc851c8cf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,11 +20,10 @@ //! multipack, //! sha256::sha256, //! }, -//! groth16, Circuit, ConstraintSystem, SynthesisError, +//! Circuit, ConstraintSystem, SynthesisError, //! }; //! use bls12_381::Bls12; //! use ff::PrimeField; -//! use pairing::Engine; //! use rand::rngs::OsRng; //! use sha2::{Digest, Sha256}; //! @@ -139,8 +138,6 @@ pub mod domain; pub mod gadgets; -#[cfg(feature = "groth16")] -pub mod groth16; pub mod multicore; pub mod multiexp;