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

Question about Off-chain Decider and the time of ”generated Decider proof” #182

Open
wanglu4042 opened this issue Dec 3, 2024 · 3 comments

Comments

@wanglu4042
Copy link

Hi!
Recently, I’ve been working with Nova to fold my circuit based on Sonobe. However, I couldn't find any example code for implementing the off-chain Decider implement.
All the code in the examples folder is focused on generating a DeciderEthCircuit final proof, I would like to generate a DeciderCircuit final proofinstead, and I don't want it to be based on EVM. Could you advise me on what I should do?

Another question I have is about the time it takes to generate the Decider proof.
I tried folding my own circuit as well as the example, circom_full_flow.rs.
I found that the time to generate the Decider proof is quite long—around 300 seconds. What could be the reason for this? Is it because my laptop's memory (16GB) is too small?
Below is the result from running the circom_full_flow.rs example:
image
Could you help me figure out what I should do?
Thanks!
Looking forward to your reply.

@arnaucube
Copy link
Collaborator

Hi, currently the only non-onchain decider (offchain decider, for usecases where verifying inside the EVM is not a requirement) available is for the Nova implementation and it's not ideal: since the only proving system that implements the arkworks SNARK trait is Groth16, even that we're not on the onchain case for the time being we're restricted to Groth16, and thus we depend on pairing friendly curves (on both sides of the cycle of curves used).
The offchain decider usage can be found here:
https://github.com/privacy-scaling-explorations/sonobe/tree/fa8f821fc2fd8d230342d67662206a8577ec1122/folding-schemes/src/folding/nova/decider.rs#L362

For Sonobe, any snark proving system could be used as long as it fits into the SNARK trait defined by arkworks. So any snark that implements that trait could be used in the sonobe's offchain decider. The current situation is that there are not many of such cases.

Since Groth16 is restricted to paring-friendly curves, and in the offchain decider case we use it on both curves of the cycle (ie. both curves need to be pairing friendly), it ends up meaning to use only the MNT curves available in arkworks, which translates into proving times of 7s for the MNT-298 curves, and 120s for the MNT-753 curves (numbers in a consumer laptop). And the MNT-298 are not considered secure enough anymore. So this is not ideal, and offchain proving times should be reduced to much less.

For example, ideally at some point there would be the Spartan port to arkworks adapted to fit in the SNARK trait defined by arkworks, and then this could be used in the Sonobe's offchain decider; removing the need to use pairing-friendly curves, and probably going faster than the current offchain decider that uses Groth16.

@wanglu4042
Copy link
Author

Hi!
Thanks for your reply!
I have read and test the test_decider in decider.rs, but the type of circuit in it was CubicFCircuit.
So I changed the N and D code in the circom_full_flow.rs, tried to use off-chain Decider on CircomFCircuit.
But it did not run successfully.

use folding_schemes::{
    commitment::{kzg::KZG, pedersen::Pedersen},
    folding::{
        nova::{
            decider_eth::{prepare_calldata, Decider as DeciderEth},
            decider::{Decider as Decideroffchain},
            Nova, PreprocessorParam,
        },
        traits::CommittedInstanceOps,
    },
    frontend::FCircuit,
    transcript::poseidon::poseidon_canonical_config,
    Decider, 
    FoldingScheme,
    // Error,
};
use ark_mnt4_298::{
    constraints::G1Var as GVar, Fr, G1Projective as Projective, MNT4_298 as MNT4,
};
use ark_mnt6_298::{
    constraints::G1Var as GVar2, G1Projective as Projective2, MNT6_298 as MNT6,
};
// initialize the Circom circuit
    let r1cs_path = PathBuf::from("D:/ZKP_file/Work/test/sonobe-main/frontends/src/circom/test_folder/with_external_inputs.r1cs");
    let wasm_path = PathBuf::from(
        "D:/ZKP_file/Work/test/sonobe-main/frontends/src/circom/test_folder/with_external_inputs_js/with_external_inputs.wasm",
    );

    let f_circuit_params = (r1cs_path.into(), wasm_path.into(), 1, 2);
    let f_circuit = CircomFCircuit::<Fr>::new(f_circuit_params).unwrap();

    type N = Nova<
        Projective,
        GVar,
        Projective2,
        GVar2,
        CircomFCircuit<Fr>,
        KZG<'static, MNT4>,
        KZG<'static, MNT6>,
        false,
    >;
    type D = Decideroffchain<
        Projective,
        GVar,
        Projective2,
        GVar2,
        CircomFCircuit<Fr>,
        KZG<'static, MNT4>,
        KZG<'static, MNT6>,
        Groth16<MNT4>,
        Groth16<MNT6>,
        N, // here we define the FoldingScheme to use
    >;

    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, f_circuit.clone());
    let nova_params = N::preprocess(&mut rng, &nova_preprocess_params).unwrap();

Above is part of the test code, and there was an error when running to this line of code let f_circuit = CircomFCircuit::<Fr>::new(f_circuit_params).unwrap();
image
Could you help me to fix this error?
Looking forward to your reply!
Thanks

@winderica
Copy link
Collaborator

Above is part of the test code, and there was an error when running to this line of code let f_circuit = CircomFCircuit::<Fr>::new(f_circuit_params).unwrap();

I believe the serialization error is due to the inconsistency of curves.
In your code, MNT4 and MNT6 are chosen as the cycle of curves for the folding scheme and the decider, but with_external_inputs.r1cs and with_external_inputs.wasm are generated by

circom ./experimental-frontends/src/circom/test_folder/with_external_inputs.circom --r1cs --sym --wasm --prime bn128 --output ./experimental-frontends/src/circom/test_folder/
, where bn128 (aka BN254) is used.

Unfortunately our off-chain decider currently relies on a curve cycle where both curves are pairing friendly (e.g., MNT4 and MNT6), but circom does not support these curves (their --prime flag only allows bn128, bls12381, goldilocks, grumpkin, secq256r1, pallas, vesta). One solution is to write your circuits in arkworks instead of circom, but once #185 is resolved, we can have an off-chain decider without two pairing friendly curves for all frontends.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants