Skip to content

Commit

Permalink
feat(ivc): impl cyclefold zero step
Browse files Browse the repository at this point in the history
**Motivation**
Part of #373 and testing of #369

**Overview**
The first part of the implementation of the zero step cyclefold

__Temporarily commented out part of cyclefold step folding circuit concerning pairing check__
  • Loading branch information
cyphersnake committed Dec 16, 2024
1 parent 8681bd5 commit ae71038
Show file tree
Hide file tree
Showing 8 changed files with 824 additions and 227 deletions.
153 changes: 144 additions & 9 deletions src/ivc/cyclefold/incrementally_verifiable_computation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,158 @@
use std::marker::PhantomData;
use std::{marker::PhantomData, num::NonZeroUsize};

use public_params::PublicParams;
use tracing::info_span;

use super::{
ro,
support_circuit::{self, SupportCircuit},
};
use crate::{
halo2_proofs::halo2curves::{
ff::{FromUniformBytes, PrimeFieldBits},
group::prime::PrimeCurveAffine,
CurveAffine,
},
ivc::StepCircuit,
ivc::{
cyclefold::sfc::{self, StepFoldingCircuit},
StepCircuit,
},
nifs::{
self,
protogalaxy::{AccumulatorArgs, ProtoGalaxy},
sangria::VanillaFS as SangriaFS,
},
plonk::PlonkTrace,
table::CircuitRunner,
};

mod public_params;

pub struct IVC<const A1: usize, const A2: usize, C1, C2, SC>
pub struct IVC<const ARITY: usize, CMain, CSup, SC>
where
CMain: CurveAffine<Base = <CSup as PrimeCurveAffine>::Scalar>,
CSup: CurveAffine<Base = <CMain as PrimeCurveAffine>::Scalar>,
SC: StepCircuit<ARITY, CMain::Scalar>,
CMain::Scalar: PrimeFieldBits + FromUniformBytes<64>,
CSup::Scalar: PrimeFieldBits + FromUniformBytes<64>,
{
step: NonZeroUsize,
primary_trace: PlonkTrace<CMain>,
_p: PhantomData<(CMain, CSup, SC)>,
}

impl<const ARITY: usize, CMain, CSup, SC> IVC<ARITY, CMain, CSup, SC>
where
C1: CurveAffine<Base = <C2 as PrimeCurveAffine>::Scalar>,
C2: CurveAffine<Base = <C1 as PrimeCurveAffine>::Scalar>,
SC: StepCircuit<A1, C1::Scalar>,
C1::Scalar: PrimeFieldBits + FromUniformBytes<64>,
C2::Scalar: PrimeFieldBits + FromUniformBytes<64>,
CMain: CurveAffine<Base = <CSup as PrimeCurveAffine>::Scalar>,
CSup: CurveAffine<Base = <CMain as PrimeCurveAffine>::Scalar>,
SC: StepCircuit<ARITY, CMain::Scalar>,
CMain::Scalar: PrimeFieldBits + FromUniformBytes<64>,
CSup::Scalar: PrimeFieldBits + FromUniformBytes<64>,
{
_p: PhantomData<(C1, C2, SC)>,
pub fn new(
pp: &PublicParams<ARITY, ARITY, CMain, CSup, SC>,
sc: &SC,
z_0: [CMain::ScalarExt; ARITY],
) -> Self {
let _primary_span = info_span!("primary").entered();

let initial_self_acc = ProtoGalaxy::<CMain, 1>::new_accumulator(
AccumulatorArgs::from(&pp.primary_S),
&nifs::protogalaxy::ProverParam {
S: pp.primary_S.clone(),
pp_digest: pp.cmain_pp_digest(),
},
&mut ro(),
);

// At zero step cyclefold ivc - output protogalaxy-accumulator is input
// protogalaxy-accumulator. Bug proof still should be valid.
let (_new_acc, self_proof) = ProtoGalaxy::prove(
&pp.primary_ck,
&nifs::protogalaxy::ProverParam {
S: pp.primary_S.clone(),
pp_digest: pp.cmain_pp_digest(),
},
&mut ro(),
initial_self_acc.clone(),
&[pp.primary_initial_trace.clone()],
)
.unwrap();

// At zero step cyclefold ivc - output sangria-accumulator is input
// sangria-accumulator. Bug proofs still should be valid.
//
// At this block we fold three same support-circuit initial traces (from pp) but result of
// this folding will be not used in next step, because of zero step
let paired_incoming = {
let mut proofs = Vec::with_capacity(initial_self_acc.W_commitment_len());

let mut paired_acc_ptr = nifs::sangria::accumulator::RelaxedPlonkTrace::from_regular(
pp.support_initial_trace.clone(),
SupportCircuit::<CMain>::MIN_K_TABLE_SIZE as usize,
);

for _ in 0..initial_self_acc.W_commitment_len() {
let (new_acc, paired_proof) =
SangriaFS::<CSup, { support_circuit::INSTANCES_LEN }>::prove(
&pp.support_ck,
&nifs::sangria::ProverParam {
S: pp.support_S.clone(),
pp_digest: pp.csup_pp_digest(),
},
&mut ro(),
paired_acc_ptr,
&[pp.support_initial_trace.clone()],
)
.unwrap();

proofs.push((pp.support_initial_trace.u.clone(), paired_proof));

paired_acc_ptr = new_acc;
}

proofs
};

let primary_sfc = StepFoldingCircuit::<'_, ARITY, CMain, CSup, SC> {
sc,
input: sfc::InputBuilder {
step: 0,
pp_digest: pp.csup_pp_digest(),
self_incoming: &pp.primary_initial_trace.u,
self_proof,
paired_acc: &pp.support_initial_trace.u.clone().into(),
paired_incoming: paired_incoming.as_slice(),
self_acc: &initial_self_acc.into(),
z_i: z_0,
z_0,
}
.build(),
_p: PhantomData,
};

let primary_initial_instances = primary_sfc.initial_instances();
let primary_witness = CircuitRunner::new(
pp.primary_k_table_size,
primary_sfc,
primary_initial_instances.clone(),
)
.try_collect_witness()
.unwrap();

let primary_post_initial_trace = ProtoGalaxy::<CMain, 1>::generate_plonk_trace(
&pp.primary_ck,
&primary_initial_instances,
&primary_witness,
&pp.protogalaxy_prover_params(),
&mut ro(),
)
.unwrap();

Self {
step: NonZeroUsize::new(1).unwrap(),
primary_trace: primary_post_initial_trace,
_p: PhantomData,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,22 @@ use crate::{
table::CircuitRunner,
};

pub struct PublicParams<const A1: usize, const A2: usize, C1, C2, SC>
pub struct PublicParams<const A1: usize, const A2: usize, CMain, CSup, SC>
where
C1: CurveAffine<Base = <C2 as PrimeCurveAffine>::Scalar>,
C2: CurveAffine<Base = <C1 as PrimeCurveAffine>::Scalar>,
SC: StepCircuit<A1, C1::Scalar>,
C1::Scalar: PrimeFieldBits + FromUniformBytes<64>,
C2::Scalar: PrimeFieldBits + FromUniformBytes<64>,
CMain: CurveAffine<Base = <CSup as PrimeCurveAffine>::Scalar>,
CSup: CurveAffine<Base = <CMain as PrimeCurveAffine>::Scalar>,
SC: StepCircuit<A1, CMain::Scalar>,
CMain::Scalar: PrimeFieldBits + FromUniformBytes<64>,
CSup::Scalar: PrimeFieldBits + FromUniformBytes<64>,
{
ck1: CommitmentKey<C1>,
primary_S: PlonkStructure<C1::ScalarExt>,
primary_k_table_size: u32,
initial_primary_trace: PlonkTrace<C1>,
pub primary_ck: CommitmentKey<CMain>,
pub primary_S: PlonkStructure<CMain::ScalarExt>,
pub primary_k_table_size: u32,
pub primary_initial_trace: PlonkTrace<CMain>,

ck2: CommitmentKey<C2>,
secondary_S: PlonkStructure<C2::ScalarExt>,
initial_secondary_trace: FoldablePlonkTrace<C2>,
pub support_ck: CommitmentKey<CSup>,
pub support_S: PlonkStructure<CSup::ScalarExt>,
pub support_initial_trace: FoldablePlonkTrace<CSup>,

_p: PhantomData<SC>,
}
Expand All @@ -61,18 +61,14 @@ where
CMain::Scalar: PrimeFieldBits + FromUniformBytes<64>,
CSup::Scalar: PrimeFieldBits + FromUniformBytes<64>,
{
/// StepFoldingCircuit {
/// step == 0 => init(acc, incoming) => output_trace,
/// step != 0 => fold(acc, incoming) => output_trace,
/// }
pub fn new(
primary_sfc: &SC,
primary_sc: &SC,
ck1: CommitmentKey<CMain>,
ck2: CommitmentKey<CSup>,
k_table_size: u32,
) -> Self {
// Trace in C1::Base or C2::Scalar
let (support_plonk_structure, initial_support_trace): (
let (support_S, support_initial_trace): (
PlonkStructure<CMain::Base>,
FoldablePlonkTrace<CSup>,
) = {
Expand Down Expand Up @@ -111,16 +107,16 @@ where
)
};

let (primary_plonk_structure, initial_primary_trace) = {
let (primary_S, primary_initial_trace) = {
let mut mock_sfc = StepFoldingCircuit::<A1, CMain, CSup, SC> {
sc: primary_sfc,
sc: primary_sc,
input: sfc::Input::<A1, CMain::ScalarExt>::new_initial::<CMain, CSup>(
&PlonkStructure {
k: k_table_size as usize,
..Default::default()
},
&support_plonk_structure,
&initial_support_trace.u,
&support_S,
&support_initial_trace.u,
),
_p: PhantomData,
};
Expand All @@ -134,25 +130,24 @@ where
num_io: mock_instances.iter().map(|col| col.len()).collect(),
..Default::default()
},
&support_plonk_structure,
&initial_support_trace.u,
&support_S,
&support_initial_trace.u,
);

let mock_S = CircuitRunner::new(k_table_size, mock_sfc, mock_instances)
.try_collect_plonk_structure()
.unwrap();

let sfc = StepFoldingCircuit::<A1, CMain, CSup, SC> {
sc: primary_sfc,
sc: primary_sc,
input: sfc::Input::<A1, CMain::ScalarExt>::new_initial::<CMain, CSup>(
&mock_S,
&support_plonk_structure,
&initial_support_trace.u,
&support_S,
&support_initial_trace.u,
),
_p: PhantomData,
};

// TODO #369 Use expected out marker, instead of zero
let primary_instances = sfc.initial_instances();
let primary_cr = CircuitRunner::new(k_table_size, sfc, primary_instances.clone());

Expand All @@ -173,17 +168,40 @@ where
};

Self {
ck1,
ck2,
primary_ck: ck1,
support_ck: ck2,
primary_k_table_size: k_table_size,

initial_primary_trace,
initial_secondary_trace: initial_support_trace,
primary_initial_trace,
support_initial_trace,

primary_S: primary_plonk_structure,
secondary_S: support_plonk_structure,
primary_S,
support_S,

_p: PhantomData,
}
}

pub fn cmain_pp_digest(&self) -> CMain {
todo!()
}

pub fn csup_pp_digest(&self) -> CSup {
todo!()
}

pub fn cmain_pp_digest_coordinates(&self) -> (CMain::Scalar, CMain::Scalar) {
todo!()
}

pub fn csup_pp_digest_coordinates(&self) -> (CMain::Base, CMain::Base) {
todo!()
}

pub fn protogalaxy_prover_params(&self) -> nifs::protogalaxy::ProverParam<CMain> {
nifs::protogalaxy::ProverParam {
S: self.primary_S.clone(),
pp_digest: self.cmain_pp_digest(),
}
}
}
6 changes: 3 additions & 3 deletions src/ivc/cyclefold/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ pub const RATE: usize = T - 1;
pub const R_F: usize = 10;
pub const R_P: usize = 10;

/// Safety: because 32 != 0
pub const DEFAULT_LIMB_WIDTH: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(32) };
/// Safety: because 64 != 0
pub const DEFAULT_LIMB_WIDTH: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(64) };

/// Safety: because 10 != 0
pub const DEFAULT_LIMBS_COUNT_LIMIT: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(10) };
pub const DEFAULT_LIMBS_COUNT_LIMIT: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(20) };

pub fn ro_const<F: PrimeFieldBits + FromUniformBytes<64>>() -> Spec<F, T, RATE> {
Spec::<F, T, RATE>::new(R_F, R_P)
Expand Down
Loading

0 comments on commit ae71038

Please sign in to comment.