mirror of
https://github.com/arnaucube/sonobe.git
synced 2026-01-08 15:01:30 +01:00
add hash of public params for Nova & HyperNova (#118)
- implement hash of public params for Nova & HyperNova - abstract pp_hash computation for folding schemes - add pp_hash to solidity contract generator to verify the decider proof
This commit is contained in:
@@ -3,7 +3,7 @@ use crate::utils::encoding::{G1Repr, G2Repr};
|
||||
use crate::utils::HeaderInclusion;
|
||||
use crate::{ProtocolVerifierKey, GPL3_SDPX_IDENTIFIER};
|
||||
use ark_bn254::Bn254;
|
||||
use ark_groth16::VerifyingKey;
|
||||
use ark_groth16::VerifyingKey as ArkVerifyingKey;
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
use askama::Template;
|
||||
|
||||
@@ -48,10 +48,10 @@ impl From<Groth16VerifierKey> for Groth16Verifier {
|
||||
// Ideally this would be linked to the `Decider` trait in FoldingSchemes.
|
||||
// For now, this is the easiest as NovaCycleFold isn't clear target from where we can get all it's needed arguments.
|
||||
#[derive(CanonicalDeserialize, CanonicalSerialize, Clone, PartialEq, Debug)]
|
||||
pub struct Groth16VerifierKey(pub(crate) VerifyingKey<Bn254>);
|
||||
pub struct Groth16VerifierKey(pub(crate) ArkVerifyingKey<Bn254>);
|
||||
|
||||
impl From<VerifyingKey<Bn254>> for Groth16VerifierKey {
|
||||
fn from(value: VerifyingKey<Bn254>) -> Self {
|
||||
impl From<ArkVerifyingKey<Bn254>> for Groth16VerifierKey {
|
||||
fn from(value: ArkVerifyingKey<Bn254>) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn groth16_vk_serde_roundtrip() {
|
||||
let (_, _, _, vk, _) = setup(DEFAULT_SETUP_LEN);
|
||||
let (_, _, _, _, vk, _) = setup(DEFAULT_SETUP_LEN);
|
||||
|
||||
let g16_vk = Groth16VerifierKey::from(vk);
|
||||
let mut bytes = vec![];
|
||||
@@ -109,7 +109,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_groth16_verifier_accepts_and_rejects_proofs() {
|
||||
let mut rng = ark_std::rand::rngs::StdRng::seed_from_u64(test_rng().next_u64());
|
||||
let (_, _, g16_pk, g16_vk, circuit) = setup(DEFAULT_SETUP_LEN);
|
||||
let (_, _, _, g16_pk, g16_vk, circuit) = setup(DEFAULT_SETUP_LEN);
|
||||
let g16_vk = Groth16VerifierKey::from(g16_vk);
|
||||
|
||||
let proof = Groth16::<Bn254>::prove(&g16_pk, circuit, &mut rng).unwrap();
|
||||
|
||||
@@ -102,7 +102,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn kzg_vk_serde_roundtrip() {
|
||||
let (pk, vk, _, _, _) = setup(DEFAULT_SETUP_LEN);
|
||||
let (_, pk, vk, _, _, _) = setup(DEFAULT_SETUP_LEN);
|
||||
|
||||
let kzg_vk = KZG10VerifierKey::from((vk, pk.powers_of_g[0..3].to_vec()));
|
||||
let mut bytes = vec![];
|
||||
@@ -115,7 +115,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn kzg_verifier_compiles() {
|
||||
let (kzg_pk, kzg_vk, _, _, _) = setup(DEFAULT_SETUP_LEN);
|
||||
let (_, kzg_pk, kzg_vk, _, _, _) = setup(DEFAULT_SETUP_LEN);
|
||||
let kzg_vk = KZG10VerifierKey::from((kzg_vk.clone(), kzg_pk.powers_of_g[0..3].to_vec()));
|
||||
|
||||
let res = HeaderInclusion::<KZG10Verifier>::builder()
|
||||
@@ -136,7 +136,7 @@ mod tests {
|
||||
let transcript_p = &mut PoseidonTranscript::<G1>::new(&poseidon_config);
|
||||
let transcript_v = &mut PoseidonTranscript::<G1>::new(&poseidon_config);
|
||||
|
||||
let (kzg_pk, kzg_vk, _, _, _) = setup(DEFAULT_SETUP_LEN);
|
||||
let (_, kzg_pk, kzg_vk, _, _, _) = setup(DEFAULT_SETUP_LEN);
|
||||
let kzg_vk = KZG10VerifierKey::from((kzg_vk.clone(), kzg_pk.powers_of_g[0..3].to_vec()));
|
||||
|
||||
let v: Vec<Fr> = std::iter::repeat_with(|| Fr::rand(&mut rng))
|
||||
|
||||
@@ -97,6 +97,7 @@ pub mod tests {
|
||||
pub fn setup<'a>(
|
||||
n: usize,
|
||||
) -> (
|
||||
Fr, // public params hash
|
||||
KZGProverKey<'a, G1>,
|
||||
KZGVerifierKey<Bn254>,
|
||||
ark_groth16::ProvingKey<Bn254>,
|
||||
@@ -115,6 +116,7 @@ pub mod tests {
|
||||
|
||||
let (kzg_pk, kzg_vk): (KZGProverKey<G1>, KZGVerifierKey<Bn254>) =
|
||||
KZG::<Bn254>::setup(&mut rng, n).unwrap();
|
||||
(kzg_pk, kzg_vk, g16_pk, g16_vk, circuit)
|
||||
let pp_hash = Fr::from(42u32); // only for test
|
||||
(pp_hash, kzg_pk, kzg_vk, g16_pk, g16_vk, circuit)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(clippy::upper_case_acronyms)]
|
||||
|
||||
use ark_bn254::{Bn254, Fq, G1Affine};
|
||||
use ark_groth16::VerifyingKey;
|
||||
use ark_poly_commit::kzg10::VerifierKey;
|
||||
use ark_bn254::{Bn254, Fq, Fr, G1Affine};
|
||||
use ark_groth16::VerifyingKey as ArkG16VerifierKey;
|
||||
use ark_poly_commit::kzg10::VerifierKey as ArkKZG10VerifierKey;
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
use askama::Template;
|
||||
|
||||
@@ -27,6 +28,7 @@ pub fn get_decider_template_for_cyclefold_decider(
|
||||
#[derive(Template, Default)]
|
||||
#[template(path = "nova_cyclefold_decider.askama.sol", ext = "sol")]
|
||||
pub struct NovaCycleFoldDecider {
|
||||
pp_hash: Fr, // public params hash
|
||||
groth16_verifier: Groth16Verifier,
|
||||
kzg10_verifier: KZG10Verifier,
|
||||
// z_len denotes the FCircuit state (z_i) length
|
||||
@@ -42,6 +44,7 @@ impl From<NovaCycleFoldVerifierKey> for NovaCycleFoldDecider {
|
||||
let public_inputs_len = groth16_verifier.gamma_abc_len;
|
||||
let bits_per_limb = NonNativeUintVar::<Fq>::bits_per_limb();
|
||||
Self {
|
||||
pp_hash: value.pp_hash,
|
||||
groth16_verifier,
|
||||
kzg10_verifier: KZG10Verifier::from(value.kzg_vk),
|
||||
z_len: value.z_len,
|
||||
@@ -54,6 +57,7 @@ impl From<NovaCycleFoldVerifierKey> for NovaCycleFoldDecider {
|
||||
|
||||
#[derive(CanonicalDeserialize, CanonicalSerialize, PartialEq, Debug, Clone)]
|
||||
pub struct NovaCycleFoldVerifierKey {
|
||||
pp_hash: Fr,
|
||||
g16_vk: Groth16VerifierKey,
|
||||
kzg_vk: KZG10VerifierKey,
|
||||
z_len: usize,
|
||||
@@ -73,25 +77,37 @@ impl ProtocolVerifierKey for NovaCycleFoldVerifierKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Groth16VerifierKey, KZG10VerifierKey, usize)> for NovaCycleFoldVerifierKey {
|
||||
fn from(value: (Groth16VerifierKey, KZG10VerifierKey, usize)) -> Self {
|
||||
impl From<(Fr, Groth16VerifierKey, KZG10VerifierKey, usize)> for NovaCycleFoldVerifierKey {
|
||||
fn from(value: (Fr, Groth16VerifierKey, KZG10VerifierKey, usize)) -> Self {
|
||||
Self {
|
||||
g16_vk: value.0,
|
||||
kzg_vk: value.1,
|
||||
z_len: value.2,
|
||||
pp_hash: value.0,
|
||||
g16_vk: value.1,
|
||||
kzg_vk: value.2,
|
||||
z_len: value.3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// implements From assuming that the 'batchCheck' method from the KZG10 template will not be used
|
||||
// in the NovaCycleFoldDecider verifier contract
|
||||
impl From<((VerifyingKey<Bn254>, VerifierKey<Bn254>), usize)> for NovaCycleFoldVerifierKey {
|
||||
fn from(value: ((VerifyingKey<Bn254>, VerifierKey<Bn254>), usize)) -> Self {
|
||||
impl
|
||||
From<(
|
||||
(Fr, ArkG16VerifierKey<Bn254>, ArkKZG10VerifierKey<Bn254>),
|
||||
usize,
|
||||
)> for NovaCycleFoldVerifierKey
|
||||
{
|
||||
fn from(
|
||||
value: (
|
||||
(Fr, ArkG16VerifierKey<Bn254>, ArkKZG10VerifierKey<Bn254>),
|
||||
usize,
|
||||
),
|
||||
) -> Self {
|
||||
let decider_vp = value.0;
|
||||
let g16_vk = Groth16VerifierKey::from(decider_vp.0);
|
||||
let g16_vk = Groth16VerifierKey::from(decider_vp.1);
|
||||
// pass `Vec::new()` since batchCheck will not be used
|
||||
let kzg_vk = KZG10VerifierKey::from((decider_vp.1, Vec::new()));
|
||||
let kzg_vk = KZG10VerifierKey::from((decider_vp.2, Vec::new()));
|
||||
Self {
|
||||
pp_hash: decider_vp.0,
|
||||
g16_vk,
|
||||
kzg_vk,
|
||||
z_len: value.1,
|
||||
@@ -101,12 +117,14 @@ impl From<((VerifyingKey<Bn254>, VerifierKey<Bn254>), usize)> for NovaCycleFoldV
|
||||
|
||||
impl NovaCycleFoldVerifierKey {
|
||||
pub fn new(
|
||||
vkey_g16: VerifyingKey<Bn254>,
|
||||
vkey_kzg: VerifierKey<Bn254>,
|
||||
pp_hash: Fr,
|
||||
vkey_g16: ArkG16VerifierKey<Bn254>,
|
||||
vkey_kzg: ArkKZG10VerifierKey<Bn254>,
|
||||
crs_points: Vec<G1Affine>,
|
||||
z_len: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
pp_hash,
|
||||
g16_vk: Groth16VerifierKey::from(vkey_g16),
|
||||
kzg_vk: KZG10VerifierKey::from((vkey_kzg, crs_points)),
|
||||
z_len,
|
||||
@@ -117,12 +135,9 @@ impl NovaCycleFoldVerifierKey {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ark_bn254::{constraints::GVar, Bn254, Fr, G1Projective as G1};
|
||||
use ark_crypto_primitives::snark::SNARK;
|
||||
use ark_ff::PrimeField;
|
||||
use ark_groth16::VerifyingKey as G16VerifierKey;
|
||||
use ark_groth16::{Groth16, ProvingKey};
|
||||
use ark_groth16::Groth16;
|
||||
use ark_grumpkin::{constraints::GVar as GVar2, Projective as G2};
|
||||
use ark_poly_commit::kzg10::VerifierKey as KZGVerifierKey;
|
||||
use ark_r1cs_std::alloc::AllocVar;
|
||||
use ark_r1cs_std::fields::fp::FpVar;
|
||||
use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
|
||||
@@ -132,15 +147,10 @@ mod tests {
|
||||
use std::time::Instant;
|
||||
|
||||
use folding_schemes::{
|
||||
commitment::{
|
||||
kzg::{ProverKey as KZGProverKey, KZG},
|
||||
pedersen::Pedersen,
|
||||
CommitmentScheme,
|
||||
},
|
||||
commitment::{kzg::KZG, pedersen::Pedersen},
|
||||
folding::nova::{
|
||||
decider_eth::{prepare_calldata, Decider as DeciderEth},
|
||||
decider_eth_circuit::DeciderEthCircuit,
|
||||
get_cs_params_len, Nova, ProverParams,
|
||||
Nova, PreprocessorParam,
|
||||
},
|
||||
frontend::FCircuit,
|
||||
transcript::poseidon::poseidon_canonical_config,
|
||||
@@ -156,6 +166,24 @@ mod tests {
|
||||
NovaCycleFoldVerifierKey, ProtocolVerifierKey,
|
||||
};
|
||||
|
||||
type NOVA<FC> = Nova<G1, GVar, G2, GVar2, FC, KZG<'static, Bn254>, Pedersen<G2>>;
|
||||
type DECIDER<FC> = DeciderEth<
|
||||
G1,
|
||||
GVar,
|
||||
G2,
|
||||
GVar2,
|
||||
FC,
|
||||
KZG<'static, Bn254>,
|
||||
Pedersen<G2>,
|
||||
Groth16<Bn254>,
|
||||
NOVA<FC>,
|
||||
>;
|
||||
|
||||
type FS_PP<FC> = <NOVA<FC> as FoldingScheme<G1, G2, FC>>::ProverParam;
|
||||
type FS_VP<FC> = <NOVA<FC> as FoldingScheme<G1, G2, FC>>::VerifierParam;
|
||||
type DECIDER_PP<FC> = <DECIDER<FC> as Decider<G1, G2, FC, NOVA<FC>>>::ProverParam;
|
||||
type DECIDER_VP<FC> = <DECIDER<FC> as Decider<G1, G2, FC, NOVA<FC>>>::VerifierParam;
|
||||
|
||||
/// Test circuit to be folded
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct CubicFCircuit<F: PrimeField> {
|
||||
@@ -256,10 +284,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn nova_cyclefold_vk_serde_roundtrip() {
|
||||
let (_, kzg_vk, _, g16_vk, _) = setup(DEFAULT_SETUP_LEN);
|
||||
let (pp_hash, _, kzg_vk, _, g16_vk, _) = setup(DEFAULT_SETUP_LEN);
|
||||
|
||||
let mut bytes = vec![];
|
||||
let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from(((g16_vk, kzg_vk), 1));
|
||||
let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from(((pp_hash, g16_vk, kzg_vk), 1));
|
||||
|
||||
nova_cyclefold_vk
|
||||
.serialize_protocol_verifier_key(&mut bytes)
|
||||
@@ -272,8 +300,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn nova_cyclefold_decider_template_renders() {
|
||||
let (_, kzg_vk, _, g16_vk, _) = setup(DEFAULT_SETUP_LEN);
|
||||
let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from(((g16_vk, kzg_vk), 1));
|
||||
let (pp_hash, _, kzg_vk, _, g16_vk, _) = setup(DEFAULT_SETUP_LEN);
|
||||
let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from(((pp_hash, g16_vk, kzg_vk), 1));
|
||||
|
||||
let decider_solidity_code = HeaderInclusion::<NovaCycleFoldDecider>::builder()
|
||||
.template(nova_cyclefold_vk)
|
||||
@@ -282,59 +310,29 @@ mod tests {
|
||||
save_solidity("NovaDecider.sol", &decider_solidity_code.render().unwrap());
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn init_test_prover_params<FC: FCircuit<Fr, Params = ()>>() -> (
|
||||
ProverParams<G1, G2, KZG<'static, Bn254>, Pedersen<G2>>,
|
||||
KZGVerifierKey<Bn254>,
|
||||
) {
|
||||
let mut rng = ark_std::test_rng();
|
||||
let poseidon_config = poseidon_canonical_config::<Fr>();
|
||||
let f_circuit = FC::new(()).unwrap();
|
||||
let (cs_len, cf_cs_len) =
|
||||
get_cs_params_len::<G1, GVar, G2, GVar2, FC>(&poseidon_config, f_circuit).unwrap();
|
||||
let (kzg_pk, kzg_vk): (KZGProverKey<G1>, KZGVerifierKey<Bn254>) =
|
||||
KZG::<Bn254>::setup(&mut rng, cs_len).unwrap();
|
||||
let (cf_pedersen_params, _) = Pedersen::<G2>::setup(&mut rng, cf_cs_len).unwrap();
|
||||
let fs_prover_params = ProverParams::<G1, G2, KZG<Bn254>, Pedersen<G2>> {
|
||||
poseidon_config: poseidon_config.clone(),
|
||||
cs_pp: kzg_pk.clone(),
|
||||
cf_cs_pp: cf_pedersen_params,
|
||||
};
|
||||
(fs_prover_params, kzg_vk)
|
||||
}
|
||||
|
||||
/// Initializes Nova parameters and DeciderEth parameters. Only for test purposes.
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn init_params<FC: FCircuit<Fr, Params = ()>>() -> (
|
||||
ProverParams<G1, G2, KZG<'static, Bn254>, Pedersen<G2>>,
|
||||
KZGVerifierKey<Bn254>,
|
||||
ProvingKey<Bn254>,
|
||||
G16VerifierKey<Bn254>,
|
||||
) {
|
||||
fn init_params<FC: FCircuit<Fr, Params = ()>>(
|
||||
) -> ((FS_PP<FC>, FS_VP<FC>), (DECIDER_PP<FC>, DECIDER_VP<FC>)) {
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
let start = Instant::now();
|
||||
let (fs_prover_params, kzg_vk) = init_test_prover_params::<FC>();
|
||||
println!("generated Nova folding params: {:?}", start.elapsed());
|
||||
let poseidon_config = poseidon_canonical_config::<Fr>();
|
||||
|
||||
let f_circuit = FC::new(()).unwrap();
|
||||
|
||||
pub type NOVA_FCircuit<FC> =
|
||||
Nova<G1, GVar, G2, GVar2, FC, KZG<'static, Bn254>, Pedersen<G2>>;
|
||||
let z_0 = vec![Fr::zero(); f_circuit.state_len()];
|
||||
let nova = NOVA_FCircuit::init(&fs_prover_params, f_circuit, z_0.clone()).unwrap();
|
||||
|
||||
let decider_circuit =
|
||||
DeciderEthCircuit::<G1, GVar, G2, GVar2, KZG<Bn254>, Pedersen<G2>>::from_nova::<FC>(
|
||||
nova.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
let start = Instant::now();
|
||||
let (g16_pk, g16_vk) =
|
||||
Groth16::<Bn254>::circuit_specific_setup(decider_circuit.clone(), &mut rng).unwrap();
|
||||
println!(
|
||||
"generated G16 (Decider circuit) params: {:?}",
|
||||
start.elapsed()
|
||||
let prep_param = PreprocessorParam::<G1, G2, FC, KZG<'static, Bn254>, Pedersen<G2>>::new(
|
||||
poseidon_config,
|
||||
f_circuit.clone(),
|
||||
);
|
||||
(fs_prover_params, kzg_vk, g16_pk, g16_vk)
|
||||
let nova_params = NOVA::preprocess(&mut rng, &prep_param).unwrap();
|
||||
let nova = NOVA::init(
|
||||
nova_params.clone(),
|
||||
f_circuit.clone(),
|
||||
vec![Fr::zero(); f_circuit.state_len()].clone(),
|
||||
)
|
||||
.unwrap();
|
||||
let decider_params =
|
||||
DECIDER::preprocess(&mut rng, &nova_params.clone(), nova.clone()).unwrap();
|
||||
|
||||
(nova_params, decider_params)
|
||||
}
|
||||
|
||||
/// This function allows to define which FCircuit to use for the test, and how many prove_step
|
||||
@@ -346,52 +344,31 @@ mod tests {
|
||||
/// - modifies the z_0 and checks that it does not pass the EVM check
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn nova_cyclefold_solidity_verifier_opt<FC: FCircuit<Fr, Params = ()>>(
|
||||
params: (
|
||||
ProverParams<G1, G2, KZG<'static, Bn254>, Pedersen<G2>>,
|
||||
KZGVerifierKey<Bn254>,
|
||||
ProvingKey<Bn254>,
|
||||
G16VerifierKey<Bn254>,
|
||||
),
|
||||
fs_params: (FS_PP<FC>, FS_VP<FC>),
|
||||
decider_params: (DECIDER_PP<FC>, DECIDER_VP<FC>),
|
||||
z_0: Vec<Fr>,
|
||||
n_steps: usize,
|
||||
) {
|
||||
let (fs_prover_params, kzg_vk, g16_pk, g16_vk) = params.clone();
|
||||
let (decider_pp, decider_vp) = decider_params;
|
||||
|
||||
pub type NOVA_FCircuit<FC> =
|
||||
Nova<G1, GVar, G2, GVar2, FC, KZG<'static, Bn254>, Pedersen<G2>>;
|
||||
pub type DECIDERETH_FCircuit<FC> = DeciderEth<
|
||||
G1,
|
||||
GVar,
|
||||
G2,
|
||||
GVar2,
|
||||
FC,
|
||||
KZG<'static, Bn254>,
|
||||
Pedersen<G2>,
|
||||
Groth16<Bn254>,
|
||||
NOVA_FCircuit<FC>,
|
||||
>;
|
||||
let f_circuit = FC::new(()).unwrap();
|
||||
|
||||
let nova_cyclefold_vk = NovaCycleFoldVerifierKey::from((
|
||||
(g16_vk.clone(), kzg_vk.clone()),
|
||||
f_circuit.state_len(),
|
||||
));
|
||||
let nova_cyclefold_vk =
|
||||
NovaCycleFoldVerifierKey::from((decider_vp.clone(), f_circuit.state_len()));
|
||||
|
||||
let mut rng = rand::rngs::OsRng;
|
||||
|
||||
let mut nova = NOVA_FCircuit::init(&fs_prover_params, f_circuit, z_0).unwrap();
|
||||
let mut nova = NOVA::<FC>::init(fs_params, f_circuit, z_0).unwrap();
|
||||
for _ in 0..n_steps {
|
||||
nova.prove_step(&mut rng, vec![]).unwrap();
|
||||
}
|
||||
|
||||
let start = Instant::now();
|
||||
let proof =
|
||||
DECIDERETH_FCircuit::prove(rng, (g16_pk, fs_prover_params.cs_pp.clone()), nova.clone())
|
||||
.unwrap();
|
||||
let proof = DECIDER::<FC>::prove(rng, decider_pp, nova.clone()).unwrap();
|
||||
println!("generated Decider proof: {:?}", start.elapsed());
|
||||
|
||||
let verified = DECIDERETH_FCircuit::<FC>::verify(
|
||||
(g16_vk, kzg_vk),
|
||||
let verified = DECIDER::<FC>::verify(
|
||||
decider_vp,
|
||||
nova.i,
|
||||
nova.z_0.clone(),
|
||||
nova.z_i.clone(),
|
||||
@@ -448,12 +425,22 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn nova_cyclefold_solidity_verifier() {
|
||||
let params = init_params::<CubicFCircuit<Fr>>();
|
||||
let (nova_params, decider_params) = init_params::<CubicFCircuit<Fr>>();
|
||||
let z_0 = vec![Fr::from(3_u32)];
|
||||
nova_cyclefold_solidity_verifier_opt::<CubicFCircuit<Fr>>(params.clone(), z_0.clone(), 2);
|
||||
nova_cyclefold_solidity_verifier_opt::<CubicFCircuit<Fr>>(params.clone(), z_0.clone(), 3);
|
||||
nova_cyclefold_solidity_verifier_opt::<CubicFCircuit<Fr>>(
|
||||
nova_params.clone(),
|
||||
decider_params.clone(),
|
||||
z_0.clone(),
|
||||
2,
|
||||
);
|
||||
nova_cyclefold_solidity_verifier_opt::<CubicFCircuit<Fr>>(
|
||||
nova_params,
|
||||
decider_params,
|
||||
z_0,
|
||||
3,
|
||||
);
|
||||
|
||||
let params = init_params::<MultiInputsFCircuit<Fr>>();
|
||||
let (nova_params, decider_params) = init_params::<MultiInputsFCircuit<Fr>>();
|
||||
let z_0 = vec![
|
||||
Fr::from(1_u32),
|
||||
Fr::from(1_u32),
|
||||
@@ -462,12 +449,14 @@ mod tests {
|
||||
Fr::from(1_u32),
|
||||
];
|
||||
nova_cyclefold_solidity_verifier_opt::<MultiInputsFCircuit<Fr>>(
|
||||
params.clone(),
|
||||
nova_params.clone(),
|
||||
decider_params.clone(),
|
||||
z_0.clone(),
|
||||
2,
|
||||
);
|
||||
nova_cyclefold_solidity_verifier_opt::<MultiInputsFCircuit<Fr>>(
|
||||
params.clone(),
|
||||
nova_params,
|
||||
decider_params,
|
||||
z_0.clone(),
|
||||
3,
|
||||
);
|
||||
|
||||
@@ -78,10 +78,11 @@ contract NovaDecider is Groth16Verifier, KZG10Verifier {
|
||||
// from gamma_abc_len, we subtract 1.
|
||||
uint256[{{ public_inputs_len - 1 }}] memory public_inputs;
|
||||
|
||||
public_inputs[0] = i_z0_zi[0];
|
||||
public_inputs[0] = {{pp_hash}};
|
||||
public_inputs[1] = i_z0_zi[0];
|
||||
|
||||
for (uint i = 0; i < {{ z_len * 2 }}; i++) {
|
||||
public_inputs[1 + i] = i_z0_zi[1 + i];
|
||||
public_inputs[2 + i] = i_z0_zi[1 + i];
|
||||
}
|
||||
|
||||
{
|
||||
@@ -91,9 +92,9 @@ contract NovaDecider is Groth16Verifier, KZG10Verifier {
|
||||
uint256 x0 = rlc(U_i_x_u_i_cmW[0], U_i_u_u_i_u_r[2], u_i_x_cmT[0]);
|
||||
uint256 x1 = rlc(U_i_x_u_i_cmW[1], U_i_u_u_i_u_r[2], u_i_x_cmT[1]);
|
||||
|
||||
public_inputs[{{ z_len * 2 + 1 }}] = u;
|
||||
public_inputs[{{ z_len * 2 + 2 }}] = x0;
|
||||
public_inputs[{{ z_len * 2 + 3 }}] = x1;
|
||||
public_inputs[{{ z_len * 2 + 2 }}] = u;
|
||||
public_inputs[{{ z_len * 2 + 3 }}] = x0;
|
||||
public_inputs[{{ z_len * 2 + 4 }}] = x1;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -106,8 +107,8 @@ contract NovaDecider is Groth16Verifier, KZG10Verifier {
|
||||
uint256[{{num_limbs}}] memory cmE_y_limbs = LimbsDecomposition.decompose(cmE[1]);
|
||||
|
||||
for (uint8 k = 0; k < {{num_limbs}}; k++) {
|
||||
public_inputs[{{ z_len * 2 + 4 }} + k] = cmE_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 4 + num_limbs }} + k] = cmE_y_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 5 }} + k] = cmE_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs }} + k] = cmE_y_limbs[k];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,8 +125,8 @@ contract NovaDecider is Groth16Verifier, KZG10Verifier {
|
||||
uint256[{{num_limbs}}] memory cmW_y_limbs = LimbsDecomposition.decompose(cmW[1]);
|
||||
|
||||
for (uint8 k = 0; k < {{num_limbs}}; k++) {
|
||||
public_inputs[{{ z_len * 2 + 4 + num_limbs * 2 }} + k] = cmW_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 4 + num_limbs * 3 }} + k] = cmW_y_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 2 }} + k] = cmW_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 3 }} + k] = cmW_y_limbs[k];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,10 +135,10 @@ contract NovaDecider is Groth16Verifier, KZG10Verifier {
|
||||
|
||||
{
|
||||
// add challenges
|
||||
public_inputs[{{ z_len * 2 + 4 + num_limbs * 4 }}] = challenge_W_challenge_E_kzg_evals[0];
|
||||
public_inputs[{{ z_len * 2 + 4 + num_limbs * 4 + 1 }}] = challenge_W_challenge_E_kzg_evals[1];
|
||||
public_inputs[{{ z_len * 2 + 4 + num_limbs * 4 + 2 }}] = challenge_W_challenge_E_kzg_evals[2];
|
||||
public_inputs[{{ z_len * 2 + 4 + num_limbs * 4 + 3 }}] = challenge_W_challenge_E_kzg_evals[3];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 }}] = challenge_W_challenge_E_kzg_evals[0];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 + 1 }}] = challenge_W_challenge_E_kzg_evals[1];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 + 2 }}] = challenge_W_challenge_E_kzg_evals[2];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 + 3 }}] = challenge_W_challenge_E_kzg_evals[3];
|
||||
|
||||
uint256[{{num_limbs}}] memory cmT_x_limbs;
|
||||
uint256[{{num_limbs}}] memory cmT_y_limbs;
|
||||
@@ -146,8 +147,8 @@ contract NovaDecider is Groth16Verifier, KZG10Verifier {
|
||||
cmT_y_limbs = LimbsDecomposition.decompose(u_i_x_cmT[3]);
|
||||
|
||||
for (uint8 k = 0; k < {{num_limbs}}; k++) {
|
||||
public_inputs[{{ z_len * 2 + 4 + num_limbs * 4 }} + 4 + k] = cmT_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 4 + num_limbs * 5}} + 4 + k] = cmT_y_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 4 }} + 4 + k] = cmT_x_limbs[k];
|
||||
public_inputs[{{ z_len * 2 + 5 + num_limbs * 5}} + 4 + k] = cmT_y_limbs[k];
|
||||
}
|
||||
|
||||
// last element of the groth16 proof's public inputs is `r`
|
||||
|
||||
Reference in New Issue
Block a user