Implement HyperNova's IVC into the FoldingScheme trait (#116)

- implement the IVC `FoldingScheme` trait for HyperNova
- refactor Nova's preprocess logic to make it simplier to use
- add to Decider trait (& Nova's DeciderEth) a preprocess method
- get rid of the `init_nova_ivc_params` and `init_ivc_and_decider_params` methods in `examples` since this is achieved with the `FS::preprocess` & `Decider::preprocess` methods
  - (update the examples code to the simplified interface using
    FS::preprocess & Decider::preprocess)
This commit is contained in:
2024-07-04 11:14:31 +02:00
committed by GitHub
parent 456dc9f7a1
commit b5667968f4
25 changed files with 1144 additions and 465 deletions

View File

@@ -19,16 +19,14 @@ use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
use std::marker::PhantomData;
use std::time::Instant;
mod utils;
use utils::init_ivc_and_decider_params;
use folding_schemes::{
commitment::{kzg::KZG, pedersen::Pedersen},
folding::nova::{
decider_eth::{prepare_calldata, Decider as DeciderEth},
Nova,
Nova, PreprocessorParam,
},
frontend::FCircuit,
transcript::poseidon::poseidon_canonical_config,
Decider, Error, FoldingScheme,
};
use solidity_verifiers::{
@@ -82,11 +80,9 @@ fn main() {
let z_0 = vec![Fr::from(3_u32)];
let f_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
let (fs_prover_params, kzg_vk, g16_pk, g16_vk) =
init_ivc_and_decider_params::<CubicFCircuit<Fr>>(f_circuit);
pub type NOVA = Nova<G1, GVar, G2, GVar2, CubicFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>>;
pub type DECIDERETH_FCircuit = DeciderEth<
pub type N = Nova<G1, GVar, G2, GVar2, CubicFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>>;
pub type D = DeciderEth<
G1,
GVar,
G2,
@@ -95,30 +91,35 @@ fn main() {
KZG<'static, Bn254>,
Pedersen<G2>,
Groth16<Bn254>,
NOVA,
N,
>;
let poseidon_config = poseidon_canonical_config::<Fr>();
let mut rng = rand::rngs::OsRng;
// prepare the Nova prover & verifier params
let nova_preprocess_params = PreprocessorParam::new(poseidon_config.clone(), f_circuit);
let (fs_pp, fs_vp) = N::preprocess(&mut rng, &nova_preprocess_params).unwrap();
// initialize the folding scheme engine, in our case we use Nova
let mut nova = NOVA::init(&fs_prover_params, f_circuit, z_0).unwrap();
let mut nova = N::init(&fs_pp, f_circuit, z_0).unwrap();
// prepare the Decider prover & verifier params
let (decider_pp, decider_vp) = D::preprocess(&mut rng, &(fs_pp, fs_vp), nova.clone()).unwrap();
// run n steps of the folding iteration
for i in 0..n_steps {
let start = Instant::now();
nova.prove_step(vec![]).unwrap();
nova.prove_step(rng, vec![]).unwrap();
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}
let rng = rand::rngs::OsRng;
let start = Instant::now();
let proof = DECIDERETH_FCircuit::prove(
(g16_pk, fs_prover_params.cs_params.clone()),
rng,
nova.clone(),
)
.unwrap();
let proof = D::prove(rng, decider_pp, nova.clone()).unwrap();
println!("generated Decider proof: {:?}", start.elapsed());
let verified = DECIDERETH_FCircuit::verify(
(g16_vk.clone(), kzg_vk.clone()),
let verified = D::verify(
decider_vp.clone(),
nova.i,
nova.z_0.clone(),
nova.z_i.clone(),
@@ -146,7 +147,7 @@ fn main() {
.unwrap();
// prepare the setup params for the solidity verifier
let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from((g16_vk, kzg_vk, f_circuit.state_len()));
let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from((decider_vp, f_circuit.state_len()));
// generate the solidity code
let decider_solidity_code = get_decider_template_for_cyclefold_decider(nova_cyclefold_vk);