Fold

We plug our FCircuit into the library:

#![allow(unused)]
fn main() {
// The idea here is that we could replace the next line chunk that defines the
// `type NOVA = Nova<...>` by using another folding scheme that fulfills the `FoldingScheme`
// trait, and the rest of our code would be working without needing to be updated.
type FS = Nova<G1, G2, SHA256FCircuit<Fr>, Pedersen<G1>, Pedersen<G2>, false>;

let num_steps = 10;
let initial_state = vec![Fr::from(1_u32)];

let F_circuit = Sha256FCircuit::<Fr>::new(());

let poseidon_config = poseidon_canonical_config::<Fr>();
let mut rng = rand::rngs::OsRng;

println!("Prepare Nova ProverParams & VerifierParams");
let nova_preprocess_params = PreprocessorParam::new(poseidon_config, F_circuit);
let nova_params = FS::preprocess(&mut rng, &nova_preprocess_params)?;


println!("Initialize FoldingScheme");
let mut folding_scheme = FS::init(&nova_params, F_circuit, initial_state.clone())?;


// compute a step of the IVC
for i in 0..num_steps {
    let start = Instant::now();
    // - 2nd parameter: here we pass an empty vec since the FCircuit that we're
    // using does not use external_inputs
    // - 3rd parameter: is for schemes that support folding more than 2
    // instances at each fold, such as HyperNova. Since we're using Nova, we just
    // set it to 'None'
    folding_scheme.prove_step(rng, (), None)?;
    println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}

let ivc_proof: FS::IVCProof = folding_scheme.ivc_proof();

println!("Run the Nova's IVC verifier");
FS::verify(nova_params.1, ivc_proof)?;
}

Observe that we define the folding scheme to be used with the following line:

#![allow(unused)]
fn main() {
type FS = Nova<G1, G2, FC, Pedersen<G1>, Pedersen<G2>, false>;
}

(where FC is the FCircuit that we want to fold).

Now imagine that we want to switch the folding scheme being used. Is as simple as replacing FS by:

#![allow(unused)]
fn main() {
type FS = HyperNova< G1, G2, FC, Pedersen<G1>, Pedersen<G2>, 1, 1, false>;
}

and then adapting the folding_scheme.prove_step(...) call accordingly.

Similarly for using ProtoGalaxy folding schemes:

#![allow(unused)]
fn main() {
type FS = ProtoGalaxy<G1, G2, FC, Pedersen<G1>, Pedersen<G2>>;
}



As in the previous sections, you can find a full examples with all the code at sonobe/examples.