Skip to content

Commit

Permalink
make Minroot example generic over the supported curve cycles (argumen…
Browse files Browse the repository at this point in the history
…tcomputer#272)

* make Minroot example generic over the supported curve cycles

* upgrade version
  • Loading branch information
srinathsetty authored Nov 28, 2023
1 parent 2209a4f commit d52eb82
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 39 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nova-snark"
version = "0.31.0"
version = "0.32.0"
authors = ["Srinath Setty <[email protected]>"]
edition = "2021"
description = "High-speed recursive arguments from folding schemes"
Expand Down
79 changes: 41 additions & 38 deletions examples/minroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,54 @@
//! iterations of the `MinRoot` function, thereby realizing a Nova-based verifiable delay function (VDF).
//! We execute a configurable number of iterations of the `MinRoot` function per step of Nova's recursion.
use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError};
use ff::PrimeField;
use ff::Field;
use flate2::{write::ZlibEncoder, Compression};
use nova_snark::{
provider::{PallasEngine, VestaEngine},
provider::{mlkzg::Bn256EngineKZG, GrumpkinEngine},
traits::{
circuit::{StepCircuit, TrivialCircuit},
snark::default_ck_hint,
Engine,
snark::RelaxedR1CSSNARKTrait,
Engine, Group,
},
CompressedSNARK, PublicParams, RecursiveSNARK,
};
use num_bigint::BigUint;
use std::time::Instant;

type E1 = PallasEngine;
type E2 = VestaEngine;
type E1 = Bn256EngineKZG;
type E2 = GrumpkinEngine;
type EE1 = nova_snark::provider::mlkzg::EvaluationEngine<E1>;
type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine<E2>;
type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK<E1, EE1>; // non-preprocessing SNARK
type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK<E2, EE2>; // non-preprocessing SNARK

#[derive(Clone, Debug)]
struct MinRootIteration<F: PrimeField> {
x_i: F,
y_i: F,
x_i_plus_1: F,
y_i_plus_1: F,
struct MinRootIteration<G: Group> {
x_i: G::Scalar,
y_i: G::Scalar,
x_i_plus_1: G::Scalar,
y_i_plus_1: G::Scalar,
}

impl<F: PrimeField> MinRootIteration<F> {
impl<G: Group> MinRootIteration<G> {
// produces a sample non-deterministic advice, executing one invocation of MinRoot per step
fn new(num_iters: usize, x_0: &F, y_0: &F) -> (Vec<F>, Vec<Self>) {
// although this code is written generically, it is tailored to Pallas' scalar field
// (p - 3 / 5)
let exp = BigUint::parse_bytes(
b"23158417847463239084714197001737581570690445185553317903743794198714690358477",
10,
)
.unwrap();
fn new(num_iters: usize, x_0: &G::Scalar, y_0: &G::Scalar) -> (Vec<G::Scalar>, Vec<Self>) {
// exp = (p - 3 / 5), where p is the order of the group
// x^{exp} mod p provides the fifth root of x
let exp = {
let p = G::group_params().2.to_biguint().unwrap();
let two = BigUint::parse_bytes(b"2", 10).unwrap();
let three = BigUint::parse_bytes(b"3", 10).unwrap();
let five = BigUint::parse_bytes(b"5", 10).unwrap();
let five_inv = five.modpow(&(&p - &two), &p);
(&five_inv * (&p - &three)) % &p
};

let mut res = Vec::new();
let mut x_i = *x_0;
let mut y_i = *y_0;
for _i in 0..num_iters {
let x_i_plus_1 = (x_i + y_i).pow_vartime(exp.to_u64_digits()); // computes the fifth root of x_i + y_i
let x_i_plus_1 = (x_i + y_i).pow_vartime(&exp.to_u64_digits()); // computes the fifth root of x_i + y_i

// sanity check
if cfg!(debug_assertions) {
Expand Down Expand Up @@ -72,21 +79,21 @@ impl<F: PrimeField> MinRootIteration<F> {
}

#[derive(Clone, Debug)]
struct MinRootCircuit<F: PrimeField> {
seq: Vec<MinRootIteration<F>>,
struct MinRootCircuit<G: Group> {
seq: Vec<MinRootIteration<G>>,
}

impl<F: PrimeField> StepCircuit<F> for MinRootCircuit<F> {
impl<G: Group> StepCircuit<G::Scalar> for MinRootCircuit<G> {
fn arity(&self) -> usize {
2
}

fn synthesize<CS: ConstraintSystem<F>>(
fn synthesize<CS: ConstraintSystem<G::Scalar>>(
&self,
cs: &mut CS,
z: &[AllocatedNum<F>],
) -> Result<Vec<AllocatedNum<F>>, SynthesisError> {
let mut z_out: Result<Vec<AllocatedNum<F>>, SynthesisError> =
z: &[AllocatedNum<G::Scalar>],
) -> Result<Vec<AllocatedNum<G::Scalar>>, SynthesisError> {
let mut z_out: Result<Vec<AllocatedNum<G::Scalar>>, SynthesisError> =
Err(SynthesisError::AssignmentMissing);

// use the provided inputs
Expand Down Expand Up @@ -161,13 +168,13 @@ fn main() {
let pp = PublicParams::<
E1,
E2,
MinRootCircuit<<E1 as Engine>::Scalar>,
MinRootCircuit<<E1 as Engine>::GE>,
TrivialCircuit<<E2 as Engine>::Scalar>,
>::setup(
&circuit_primary,
&circuit_secondary,
&*default_ck_hint(),
&*default_ck_hint(),
&*S1::ck_floor(),
&*S2::ck_floor(),
);
println!("PublicParams::setup, took {:?} ", start.elapsed());

Expand All @@ -190,7 +197,7 @@ fn main() {
);

// produce non-deterministic advice
let (z0_primary, minroot_iterations) = MinRootIteration::new(
let (z0_primary, minroot_iterations) = MinRootIteration::<<E1 as Engine>::GE>::new(
num_iters_per_step * num_steps,
&<E1 as Engine>::Scalar::zero(),
&<E1 as Engine>::Scalar::one(),
Expand All @@ -210,7 +217,7 @@ fn main() {

let z0_secondary = vec![<E2 as Engine>::Scalar::zero()];

type C1 = MinRootCircuit<<E1 as Engine>::Scalar>;
type C1 = MinRootCircuit<<E1 as Engine>::GE>;
type C2 = TrivialCircuit<<E2 as Engine>::Scalar>;
// produce a recursive SNARK
println!("Generating a RecursiveSNARK...");
Expand Down Expand Up @@ -248,14 +255,10 @@ fn main() {
assert!(res.is_ok());

// produce a compressed SNARK
println!("Generating a CompressedSNARK using Spartan with IPA-PC...");
println!("Generating a CompressedSNARK using Spartan with multilinear KZG...");
let (pk, vk) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap();

let start = Instant::now();
type EE1 = nova_snark::provider::ipa_pc::EvaluationEngine<E1>;
type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine<E2>;
type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK<E1, EE1>;
type S2 = nova_snark::spartan::snark::RelaxedR1CSSNARK<E2, EE2>;

let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &pk, &recursive_snark);
println!(
Expand Down

0 comments on commit d52eb82

Please sign in to comment.