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

Remove Groth16/SnarkPack+. #774

Merged
merged 3 commits into from
Oct 21, 2023
Merged
Changes from all commits
Commits
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
6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -18,7 +18,6 @@ base64 = { workspace = true }
base-x = "0.2.11"
Copy link
Contributor

Choose a reason for hiding this comment

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

The removal of memmap isn't there, but I think it doesn't matter as #777 is about to re-introduce it.

bellpepper = { workspace = true }
bellpepper-core = { workspace = true }
bellperson = { workspace = true }
bincode = { workspace = true }
blstrs = { workspace = true }
camino = { workspace = true }
@@ -87,8 +86,8 @@ rustyline = { version = "11.0", features = ["derive"], default-features = false

[features]
default = []
opencl = ["neptune/opencl", "bellperson/opencl", "nova/opencl"]
cuda = ["neptune/cuda", "bellperson/cuda", "nova/cuda"]
opencl = ["neptune/opencl", "nova/opencl"]
cuda = ["neptune/cuda", "nova/cuda"]
# compile without ISA extensions
portable = ["blstrs/portable", "pasta-msm/portable", "nova/portable"]
flamegraph = ["pprof/flamegraph", "pprof/criterion"]
@@ -124,7 +123,6 @@ anyhow = "1.0.72"
base64 = "0.13.1"
bellpepper = { git = "https://github.com/lurk-lab/bellpepper", branch = "dev" }
bellpepper-core = { git = "https://github.com/lurk-lab/bellpepper", branch = "dev" }
bellperson = { git = "https://github.com/lurk-lab/bellperson", branch = "dev" }
bincode = "1.3.3"
blstrs = { git = "https://github.com/lurk-lab/blstrs", branch = "dev" }
clap = "4.3.17"
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -11,8 +11,6 @@

Lurk is currently in Alpha. Code that runs in the Lurk Alpha release is expected to also run in Lurk Beta, and eventually Lurk 1.0. However, some low-level data representations are anticipated to change, and we will be refactoring the circuit implementation to increase auditability and further our confidence in Lurk's cryptographic security. Also note that since Lurk inherits some security properties from the underlying proving system, those who would rely on Lurk should investigate the security and status of Nova itself. We encourage early adopters to begin writing real applications taking advantage of Lurk so you can begin to familiarize yourself with the programming model. Likewise, we welcome your feedback -- which will help ensure ongoing development meets user need.

Note that Groth16 support is only partial, since no trusted setup has been run. If you wish to use Lurk with Groth16, a trusted setup will be required; and we would not recommend undertaking this until the 1.0 circuit has been released.

# Overview

Lurk is a statically scoped dialect of Lisp, influenced by Scheme and Common Lisp. A reference implementation focused on describing and developing the core language can be found in the [`lurk`](https://github.com/lurk-lab/lurk-lisp) repo.
@@ -26,8 +24,8 @@ Lurk's distinguishing feature relative to most zk-SNARK authoring languages is t
Integration with backend proving systems and tooling for proof generation are both still very early. Performance and user experience still have room for significant optimization and improvement, but simple examples can be found in the [fcomm example directory](fcomm/README.md).

# Backends
- Nova is Lurk's officially-supported backend. It uses the [Nova proving system](https://github.com/microsoft/Nova) and the Pasta Curves.
- There is also a Groth16 [SnarkPack](https://eprint.iacr.org/2021/529)[+](https://github.com/filecoin-project/bellperson/pull/257) backend using Bls12-381 (but see notes at *Status* above).
- Nova is Lurk's officially-supported IVC backend. It uses Lurk Lab's Arecibo fork of the [Nova proving system](https://github.com/lurk-lab/arecibo) and the Pasta Curves.
- SuperNova is Lurk's in-development NIVC backend. It uses Arecibo's [SuperNova extension ot the Nova proving system](https://github.com/lurk-lab/arecibo/tree/dev/src/supernova) and the Pasta Curves.
- Future work may target Halo2 or other proving systems.

It is an explicit design goal that statements about the evaluation of Lurk programs have identical semantic meaning across backends, with the qualification that Lurk language instances are themselves parameterized on scalar field and hash function. When backends use the same scalar field and hash function, they can be used to generate equivalent proofs. This is because the concrete representation of content-addressed data is fixed.
2 changes: 1 addition & 1 deletion benches/end2end.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use blstrs::Scalar as Fr;
use camino::Utf8Path;
use criterion::{
black_box, criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion, SamplingMode,
};
use pasta_curves::pallas::Scalar as Fr;

use lurk::{
circuit::circuit_frame::MultiFrame,
2 changes: 1 addition & 1 deletion benches/end2end_lem.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use blstrs::Scalar as Fr;
use criterion::{
black_box, criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion, SamplingMode,
};
use pasta_curves::pallas::Scalar as Fr;
use pasta_curves::pallas::Scalar as Fq;
use std::{cell::RefCell, rc::Rc, sync::Arc, time::Duration};

20 changes: 0 additions & 20 deletions benches/public_params.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use blstrs::Scalar as Fr;
use criterion::{black_box, criterion_group, criterion_main, Criterion, SamplingMode};
use lurk::{
circuit::circuit_frame::MultiFrame,
eval::lang::{Coproc, Lang},
proof::groth16::Groth16Prover,
proof::nova,
};
use std::sync::Arc;
@@ -17,8 +15,6 @@ const DEFAULT_REDUCTION_COUNT: usize = 10;
fn public_params_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("public_params_benchmark");
group.sampling_mode(SamplingMode::Flat);
let lang_bls = Lang::<Fr, Coproc<Fr>>::new();
let lang_bls_rc = Arc::new(lang_bls);
let lang_pallas =
Lang::<pasta_curves::pallas::Scalar, Coproc<pasta_curves::pallas::Scalar>>::new();
let lang_pallas_rc = Arc::new(lang_pallas);
@@ -34,22 +30,6 @@ fn public_params_benchmark(c: &mut Criterion) {
black_box(result)
})
});

group.bench_function("public_params_groth", |b| {
b.iter(|| {
let result = Groth16Prover::<
_,
Coproc<Fr>,
Fr,
MultiFrame<'_, Fr, Coproc<Fr>>,
>::create_groth_params(
DEFAULT_REDUCTION_COUNT,
lang_bls_rc.clone(),
)
.unwrap();
black_box(result)
})
});
}

cfg_if::cfg_if! {
1 change: 0 additions & 1 deletion clutch/Cargo.toml
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@ repository = "https://github.com/lurk-lab/lurk-rs"

[dependencies]
anyhow = { workspace = true }
blstrs = { workspace = true }
camino = { workspace = true }
clap = { workspace = true }
fcomm = { path = "../fcomm" }
5 changes: 0 additions & 5 deletions clutch/src/main.rs
Original file line number Diff line number Diff line change
@@ -30,11 +30,6 @@ fn main() -> Result<()> {
Coproc<pallas::Scalar>,
>(Lang::<pallas::Scalar, Coproc<pallas::Scalar>>::new()),
// TODO: Support all LanguageFields.
// LanguageField::BLS12_381 => repl_cli::<
// blstrs::Scalar,
// ClutchState<blstrs::Scalar, Coproc<blstrs::Scalar>>,
// Coproc<blstrs::Scalar>,
// >(Lang::<blstrs::Scalar, Coproc<blstrs::Scalar>>::new()),
// LanguageField::Vesta => repl_cli::<
// vesta::Scalar,
// ClutchState<vesta::Scalar, Coproc<vesta::Scalar>>,
1 change: 0 additions & 1 deletion fcomm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@ anyhow = { workspace = true }
base64 = { workspace = true }
bellpepper-core = { workspace = true }
bincode = { workspace = true }
blstrs = { workspace = true }
camino = { workspace = true }
clap = { workspace = true, features = ["derive"] }
clap-verbosity-flag = "2.0"
1 change: 0 additions & 1 deletion fcomm/README.md
Original file line number Diff line number Diff line change
@@ -60,7 +60,6 @@ To verify the generated proof:

Please note the following limitations:
- Proof as serialized here are not optimized for size.
- The Groth16 and SnarkPack+ parameters used here were not the result of a trusted setup so are insecure.
- To simplify reproducibility in development and for example purposes, these parameters are deterministically generated on-demand.
- The parameters are currently uncached.
- This adds time to both proof and verification.
2 changes: 1 addition & 1 deletion notes/reduction-notes.md
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ calculate an evaluation. `lurk-rs` implements a concrete instance of the Lurk la
evaluation can be generated. `lurk-rs` generates zk-SNARK proofs for multiple backends, and verification of these
proofs requires reference to a verification key whose identity is derived from the computation encoded in the
corresponding arithmetic circuit. The initial Lurk circuit implementation is specified as a Rank-1 Constraint System
(R1CS), from which Groth16 or Nova proofs are created.
(R1CS), from which Nova or SuperNova proofs are created.

Because the circuit must check the computation to be proved, many aspects of the implementation itself must be fully
specified. The reference implementation of Lurk expression evaluation in
79 changes: 33 additions & 46 deletions src/circuit/circuit_frame.rs
Original file line number Diff line number Diff line change
@@ -5756,16 +5756,14 @@
lang::{Coproc, Lang},
Evaluable, IO,
};
use crate::proof::groth16::Groth16Prover;
use crate::proof::nova::{public_params, NovaProver};
use crate::proof::{Provable, Prover};
use crate::store::Store;
use bellpepper::util_cs::metric_cs::MetricCS;
use bellpepper_core::test_cs::TestConstraintSystem;
use bellpepper_core::{Comparable, Delta};
use bellperson::groth16;
use blstrs::{Bls12, Scalar as Fr};
use ff::{Field, PrimeField};
use pairing::Engine;
use pasta_curves::pallas::Scalar as Fr;

const DEFAULT_REDUCTION_COUNT: usize = 1;

@@ -5784,20 +5782,11 @@
let lang = Arc::new(raw_lang.clone());
let (_, witness, meta) = input.reduce(&store, &lang).unwrap();

let public_params = Groth16Prover::<Bls12, Coproc<Fr>, Fr, MultiFrame<'_, Fr, Coproc<Fr>>>::create_groth_params(
let public_params = public_params(DEFAULT_REDUCTION_COUNT, lang.clone());
let nova_prover = NovaProver::<Fr, Coproc<Fr>, MultiFrame<'_, Fr, Coproc<Fr>>>::new(

Check warning on line 5786 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L5785-L5786

Added lines #L5785 - L5786 were not covered by tests
DEFAULT_REDUCTION_COUNT,
lang.clone(),
)
.unwrap();
let groth_prover =
Groth16Prover::<Bls12, Coproc<Fr>, Fr, MultiFrame<'_, Fr, Coproc<Fr>>>::new(
DEFAULT_REDUCTION_COUNT,
raw_lang,
);
let groth_params = &public_params.0;

let vk = &groth_params.vk;
let pvk = groth16::prepare_verifying_key(vk);
raw_lang,
);

Check warning on line 5789 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L5788-L5789

Added lines #L5788 - L5789 were not covered by tests

store.hydrate_scalar_cache();
let test_with_output = |output: IO<Fr>, expect_success: bool, store: &Store<Fr>| {
@@ -5808,28 +5797,23 @@
lang.clone(),
DEFAULT_REDUCTION_COUNT,
));
let blank_multiframe = MultiFrame::<<Bls12 as Engine>::Fr, Coproc<Fr>>::blank(
folding_config.clone(),
Meta::Lurk,
);
let blank_multiframe =
MultiFrame::<Fr, Coproc<Fr>>::blank(folding_config.clone(), Meta::Lurk);

Check warning on line 5801 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L5800-L5801

Added lines #L5800 - L5801 were not covered by tests

blank_multiframe
.synthesize(&mut cs_blank)
.expect("failed to synthesize");

let multiframes = MultiFrame::from_frames(
DEFAULT_REDUCTION_COUNT,
&[Frame {
input,
output,
i: 0,
witness,
meta,
_p: Default::default(),
}],
store,
folding_config,
);
let frames = [Frame {
input,
output,
i: 0,
witness,
meta,
_p: Default::default(),
}];
let multiframes =
MultiFrame::from_frames(DEFAULT_REDUCTION_COUNT, &frames, store, folding_config);

Check warning on line 5816 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L5807-L5816

Added lines #L5807 - L5816 were not covered by tests

let multiframe = &multiframes[0];

@@ -5843,20 +5827,23 @@
assert!(delta == Delta::Equal);

// println!("{}", print_cs(&cs));
assert_eq!(11823, cs.num_constraints());
assert_eq!(11463, cs.num_constraints());

Check warning on line 5830 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L5830

Added line #L5830 was not covered by tests
assert_eq!(13, cs.num_inputs());
assert_eq!(11479, cs.aux().len());
assert_eq!(11119, cs.aux().len());

Check warning on line 5832 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L5832

Added line #L5832 was not covered by tests

let public_inputs = multiframe.public_inputs();
let mut rng = rand::thread_rng();

let proof = groth_prover
.prove(multiframe.clone(), groth_params, &mut rng)
let (proof, ..) = nova_prover
.prove(&public_params, &frames, store, &lang)

Check warning on line 5837 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L5836-L5837

Added lines #L5836 - L5837 were not covered by tests
.unwrap();
let cs_verified = cs.is_satisfied() && cs.verify(&public_inputs);
let verified = multiframe
.clone()
.verify_groth16_proof(&pvk, &proof)
let verified = proof
.verify(
&public_params,
1,
&input.to_inputs(store),
&output.to_inputs(store),
)

Check warning on line 5846 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L5840-L5846

Added lines #L5840 - L5846 were not covered by tests
.unwrap();

if expect_success {
@@ -5945,7 +5932,7 @@
lang.clone(),
DEFAULT_REDUCTION_COUNT,
));
MultiFrame::<<Bls12 as Engine>::Fr, Coproc<Fr>>::from_frames(
MultiFrame::<Fr, Coproc<Fr>>::from_frames(

Check warning on line 5935 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L5935

Added line #L5935 was not covered by tests
DEFAULT_REDUCTION_COUNT,
&[frame],
store,
@@ -6030,7 +6017,7 @@
lang.clone(),
DEFAULT_REDUCTION_COUNT,
));
MultiFrame::<<Bls12 as Engine>::Fr, Coproc<Fr>>::from_frames(
MultiFrame::<Fr, Coproc<Fr>>::from_frames(

Check warning on line 6020 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L6020

Added line #L6020 was not covered by tests
DEFAULT_REDUCTION_COUNT,
&[frame],
store,
@@ -6118,7 +6105,7 @@
DEFAULT_REDUCTION_COUNT,
));

MultiFrame::<<Bls12 as Engine>::Fr, Coproc<Fr>>::from_frames(
MultiFrame::<Fr, Coproc<Fr>>::from_frames(

Check warning on line 6108 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L6108

Added line #L6108 was not covered by tests
DEFAULT_REDUCTION_COUNT,
&[frame],
store,
@@ -6205,7 +6192,7 @@
DEFAULT_REDUCTION_COUNT,
));

MultiFrame::<<Bls12 as Engine>::Fr, Coproc<Fr>>::from_frames(
MultiFrame::<Fr, Coproc<Fr>>::from_frames(

Check warning on line 6195 in src/circuit/circuit_frame.rs

Codecov / codecov/patch

src/circuit/circuit_frame.rs#L6195

Added line #L6195 was not covered by tests
DEFAULT_REDUCTION_COUNT,
&[frame],
store,
4 changes: 2 additions & 2 deletions src/circuit/gadgets/case.rs
Original file line number Diff line number Diff line change
@@ -357,7 +357,7 @@

#[allow(unused_imports)]
mod tests {
use blstrs::Scalar as Fr;
use pasta_curves::pallas::Scalar as Fr;

use super::*;
use crate::store::Store;
@@ -692,7 +692,7 @@
}

#[test]
fn groth_case() {
fn circuit_consistency_case() {

Check warning on line 695 in src/circuit/gadgets/case.rs

Codecov / codecov/patch

src/circuit/gadgets/case.rs#L695

Added line #L695 was not covered by tests
let mut cs = TestConstraintSystem::<Fr>::new();
let mut cs_blank = MetricCS::<Fr>::new();
let s = &mut Store::<Fr>::default();
4 changes: 2 additions & 2 deletions src/circuit/gadgets/constraints.rs
Original file line number Diff line number Diff line change
@@ -696,7 +696,7 @@ pub(crate) fn and_v<CS: ConstraintSystem<F>, F: PrimeField>(
Ok(and)
}

/// This is a replication of Bellperson's original `and`, but receives a mutable
/// This is a replication of Bellpepper's original `and`, but receives a mutable
/// reference for the constraint system instead of a copy
#[allow(dead_code)]
pub(crate) fn and<CS: ConstraintSystem<F>, F: PrimeField>(
@@ -948,8 +948,8 @@ mod tests {
use super::*;

use bellpepper_core::test_cs::TestConstraintSystem;
use blstrs::Scalar as Fr;
use ff::Field;
use pasta_curves::pallas::Scalar as Fr;
use proptest::prelude::*;
use std::ops::{AddAssign, SubAssign};

6 changes: 1 addition & 5 deletions src/cli/backend.rs
Original file line number Diff line number Diff line change
@@ -4,14 +4,12 @@

pub enum Backend {
Nova,
SnarkPackPlus,
}

impl std::fmt::Display for Backend {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Nova => write!(f, "Nova"),
Self::SnarkPackPlus => write!(f, "SnarkPack+"),
}
}
}
@@ -20,15 +18,13 @@
pub(crate) fn default_field(&self) -> LanguageField {
match self {
Self::Nova => LanguageField::Pallas,
Self::SnarkPackPlus => LanguageField::BLS12_381,
}
}

fn compatible_fields(&self) -> Vec<LanguageField> {
use LanguageField::{Pallas, Vesta, BLS12_381};
use LanguageField::{Pallas, Vesta};

Check warning on line 25 in src/cli/backend.rs

Codecov / codecov/patch

src/cli/backend.rs#L25

Added line #L25 was not covered by tests
match self {
Self::Nova => vec![Pallas, Vesta],
Self::SnarkPackPlus => vec![BLS12_381],
}
}

Loading