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

feat(ivc): accumulation of step circuit instances #354

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions src/ivc/consistency_markers_computation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
gadgets::{ecc::AssignedPoint, nonnative::bn::big_uint::BigUint},
halo2curves::CurveAffine,
main_gate::{AssignedValue, MainGate, MainGateConfig, RegionCtx, WrapValue},
nifs::vanilla::{accumulator::RelaxedPlonkInstance, GetConsistencyMarkers},
nifs::vanilla::accumulator::RelaxedPlonkInstance,
poseidon::{AbsorbInRO, ROCircuitTrait, ROTrait},
util,
};
Expand Down Expand Up @@ -89,9 +89,10 @@ where
pub struct RelaxedPlonkInstanceBigUintView<'l, C: CurveAffine> {
pub(crate) W_commitments: &'l Vec<C>,
pub(crate) E_commitment: &'l C,
pub(crate) instance: Vec<BigUint<C::Base>>,
pub(crate) consistency_markers: Vec<BigUint<C::Base>>,
pub(crate) challenges: Vec<BigUint<C::Base>>,
pub(crate) u: &'l C::ScalarExt,
pub(crate) step_circuit_instances_hash_accumulator: &'l C::ScalarExt,
}

impl<'l, C: CurveAffine, RO: ROTrait<C::Base>> AbsorbInRO<C::Base, RO>
Expand All @@ -101,7 +102,7 @@ where
ro.absorb_point_iter(self.W_commitments.iter())
.absorb_point(self.E_commitment)
.absorb_field_iter(
self.instance
self.consistency_markers
.iter()
.flat_map(|bn| bn.limbs().iter())
.copied(),
Expand All @@ -112,17 +113,26 @@ where
.flat_map(|bn| bn.limbs().iter())
.copied(),
)
.absorb_field(util::fe_to_fe(self.u).unwrap());
.absorb_field(util::fe_to_fe(self.u).unwrap())
.absorb_field(
util::fe_to_fe(self.step_circuit_instances_hash_accumulator).unwrap(),
);
}
}

let RelaxedPlonkInstance {
W_commitments,
consistency_markers,
challenges,
E_commitment,
u,
step_circuit_instances_hash_accumulator,
} = &self.relaxed;

let relaxed = RelaxedPlonkInstanceBigUintView {
W_commitments: &self.relaxed.W_commitments,
E_commitment: &self.relaxed.E_commitment,
instance: self
.relaxed
.get_consistency_markers()
.unwrap()
W_commitments,
E_commitment,
consistency_markers: consistency_markers
.iter()
.map(|v| {
BigUint::from_f(
Expand All @@ -133,9 +143,7 @@ where
.unwrap()
})
.collect(),
challenges: self
.relaxed
.challenges
challenges: challenges
.iter()
.map(|v| {
BigUint::from_f(
Expand All @@ -146,7 +154,8 @@ where
.unwrap()
})
.collect(),
u: &self.relaxed.u,
step_circuit_instances_hash_accumulator,
u,
};

util::fe_to_fe(
Expand Down Expand Up @@ -217,6 +226,7 @@ mod tests {
challenges: vec![Scalar::from_u128(0x123456); 10],
E_commitment: CommitmentKey::<C1>::default_value(),
u: Scalar::from_u128(u128::MAX),
step_circuit_instances_hash_accumulator: Scalar::from_u128(0xaaaaaaaaaaaaa),
};

let off_circuit_hash: Base = ConsistencyMarkerComputation::<
Expand Down
104 changes: 92 additions & 12 deletions src/ivc/fold_relaxed_plonk_instance_chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ use itertools::Itertools;
use num_traits::Num;
use tracing::*;

use super::instances_accumulator_computation;
use crate::{
constants::NUM_CHALLENGE_BITS,
ff::{Field, FromUniformBytes, PrimeField, PrimeFieldBits},
Expand All @@ -65,7 +66,9 @@ use crate::{
AdviceCyclicAssignor, AssignedBit, AssignedValue, MainGate, MainGateConfig, RegionCtx,
WrapValue,
},
nifs::vanilla::{accumulator::RelaxedPlonkInstance, GetConsistencyMarkers},
nifs::vanilla::{
accumulator::RelaxedPlonkInstance, GetConsistencyMarkers, GetStepCircuitInstances,
},
plonk::PlonkInstance,
poseidon::ROCircuitTrait,
util::{self, CellsValuesView},
Expand Down Expand Up @@ -105,6 +108,9 @@ pub(crate) struct AssignedRelaxedPlonkInstance<C: CurveAffine> {
/// Vector of assigned values for each limb of the folded big number X0 & X1.
/// Derived from [`FoldRelaxedPlonkInstanceChip::X0`]
pub folded_consistency_markers: [Vec<AssignedValue<C::Base>>; 2],

/// TODO #316
pub folded_step_circuit_instances_hash_accumulator: AssignedValue<C::Base>,
}

impl<C: CurveAffine> AssignedRelaxedPlonkInstance<C> {
Expand All @@ -127,6 +133,8 @@ impl<C: CurveAffine> AssignedRelaxedPlonkInstance<C> {
folded_u: lhs_folded_u,
folded_challenges: lhs_folded_challenges,
folded_consistency_markers: [lhs_folded_X0, lhs_folded_X1],
folded_step_circuit_instances_hash_accumulator:
lhs_step_circuit_instances_hash_accumulator,
} = lhs;

let Self {
Expand All @@ -135,6 +143,8 @@ impl<C: CurveAffine> AssignedRelaxedPlonkInstance<C> {
folded_u: rhs_folded_u,
folded_challenges: rhs_folded_challenges,
folded_consistency_markers: [rhs_folded_X0, rhs_folded_X1],
folded_step_circuit_instances_hash_accumulator:
rhs_step_circuit_instances_hash_accumulator,
} = rhs;

let folded_W = lhs_folded_W
Expand Down Expand Up @@ -171,12 +181,20 @@ impl<C: CurveAffine> AssignedRelaxedPlonkInstance<C> {
.map(|(lhs, rhs)| gate.conditional_select(region, lhs, rhs, &condition))
.collect::<Result<Vec<_>, _>>()?;

let folded_step_circuit_instances_hash_accumulator = gate.conditional_select(
region,
lhs_step_circuit_instances_hash_accumulator,
rhs_step_circuit_instances_hash_accumulator,
&condition,
)?;

Ok(Self {
folded_W,
folded_E,
folded_u,
folded_challenges,
folded_consistency_markers: [folded_X0, folded_X1],
folded_step_circuit_instances_hash_accumulator,
})
}

Expand All @@ -190,6 +208,7 @@ impl<C: CurveAffine> AssignedRelaxedPlonkInstance<C> {
folded_u,
folded_challenges,
folded_consistency_markers: [folded_X0, folded_X1],
folded_step_circuit_instances_hash_accumulator,
} = self;

folded_W
Expand All @@ -200,6 +219,9 @@ impl<C: CurveAffine> AssignedRelaxedPlonkInstance<C> {
.chain(folded_X1.iter().map(Into::into))
.chain(folded_challenges.iter().flatten().map(Into::into))
.chain(iter::once(WrapValue::from(folded_u)))
.chain(iter::once(
folded_step_circuit_instances_hash_accumulator.into(),
))
}
}
impl<C: CurveAffine> AssignedRelaxedPlonkInstance<C> {
Expand All @@ -215,6 +237,7 @@ impl<C: CurveAffine> AssignedRelaxedPlonkInstance<C> {
folded_u,
folded_challenges,
folded_consistency_markers: [folded_X0, folded_X1],
folded_step_circuit_instances_hash_accumulator,
} = self;

macro_rules! unwrap_result_option {
Expand Down Expand Up @@ -278,6 +301,13 @@ impl<C: CurveAffine> AssignedRelaxedPlonkInstance<C> {
E_commitment: unwrap_result_option!(folded_E.to_curve()),
u: util::fe_to_fe_safe(&unwrap_result_option!(folded_u.value().unwrap().copied()))
.expect("fields same bytes len"),
step_circuit_instances_hash_accumulator: util::fe_to_fe_safe(&unwrap_result_option!(
folded_step_circuit_instances_hash_accumulator
.value()
.unwrap()
.copied()
))
.expect("fields same bytes len"),
}))
}
}
Expand Down Expand Up @@ -316,6 +346,9 @@ pub(crate) struct AssignedWitness<C: CurveAffine> {
/// Vector of assigned points representing the commitments to the cross terms.
/// Sourced directly from the `cross_term_commits` argument of [`FoldRelaxedPlonkInstanceChip::fold`].
cross_terms_commits: Vec<AssignedPoint<C>>,

/// TODO #319
pub input_step_circuit_instances: Vec<AssignedValue<C::Base>>,
}

impl<C: CurveAffine> ops::Deref for AssignedWitness<C> {
Expand Down Expand Up @@ -562,7 +595,7 @@ where
/// fn call.
///
/// ```markdown
/// new_folded_instances[i] = fold_via_biguin(folded_instances[i], input_istances[i], m, r)
/// new_folded_consistency_marker[i] = fold_via_biguin(folded_consistency_marker[i], input_consistency_marker[i], m, r)
/// ```
///
/// Please check [`FoldRelaxedPlonkInstanceChip::fold_via_biguint`] for more details
Expand Down Expand Up @@ -601,6 +634,22 @@ where
Ok([new_folded_X0, new_folded_X1])
}

fn fold_step_circuit_instances(
ctx: &mut RegionCtx<C::Base>,
config: MainGateConfig<T>,
input_instances: &[AssignedValue<C::Base>],
folded_instances: &AssignedValue<C::Base>,
) -> Result<AssignedValue<C::Base>, Error> {
Ok(
instances_accumulator_computation::fold_assign_step_circuit_instances_hash_accumulator(
ctx,
config.into_smaller_size().unwrap(),
folded_instances,
input_instances,
)?,
)
}

/// Fold [`RelaxedPlonkInstance::challenges`] & [`PlonkInstance::challenges`]
///
/// # Description
Expand Down Expand Up @@ -685,17 +734,14 @@ where
region,
&self.bn_chip,
w.input_consistency_markers
.iter()
.map(|instance| instance.as_bn_limbs.clone())
.collect::<Vec<_>>()
.try_into()
.unwrap(),
.clone()
.map(|instance| instance.as_bn_limbs),
w.folded_consistency_markers.clone(),
&r.as_bn_limbs,
&m_bn,
self.limb_width,
)
.inspect_err(|err| error!("while fold instances: {err:?}"))?;
.inspect_err(|err| error!("while fold consistency markers: {err:?}"))?;

let new_folded_challenges = Self::fold_challenges(
region,
Expand All @@ -709,12 +755,22 @@ where
.inspect_err(|err| error!("while fold challenges: {err:?}"))?;
debug!("fold: challenges folded: {new_folded_challenges:?}");

let new_folded_instances = Self::fold_step_circuit_instances(
region,
self.config.clone(),
&w.input_step_circuit_instances,
&w.assigned_relaxed
.folded_step_circuit_instances_hash_accumulator,
)
.inspect_err(|err| error!("while fold instances: {err:?}"))?;

let assigned_result_of_fold = AssignedRelaxedPlonkInstance {
folded_W: new_folded_W.clone(),
folded_E: new_folded_E.clone(),
folded_consistency_markers: [new_folded_X0.clone(), new_folded_X1.clone()],
folded_challenges: new_folded_challenges.clone(),
folded_u: new_folded_u.clone(),
folded_step_circuit_instances_hash_accumulator: new_folded_instances.clone(),
};

Ok(FoldResult {
Expand Down Expand Up @@ -784,12 +840,18 @@ where

let assigned_u = assign_diff_field!(&self.relaxed.u, || "relaxed u")?;

let assigned_step_circuit_instances = assign_diff_field!(
&self.relaxed.step_circuit_instances_hash_accumulator,
|| "relaxed u"
)?;

Ok(AssignedRelaxedPlonkInstance {
folded_W: assigned_W,
folded_E: assigned_E,
folded_u: assigned_u,
folded_challenges: assigned_challenges,
folded_consistency_markers: [assigned_X0, assigned_X1],
folded_step_circuit_instances_hash_accumulator: assigned_step_circuit_instances,
})
}

Expand Down Expand Up @@ -879,12 +941,18 @@ where

let assigned_u = assign_and_absorb_diff_field!(&self.relaxed.u, || "relaxed u")?;

let assigned_step_circuit_instances = assign_and_absorb_diff_field!(
&self.relaxed.step_circuit_instances_hash_accumulator,
|| { "step_circuit_instances" }
)?;

let assigned_relaxed = AssignedRelaxedPlonkInstance {
folded_W: assigned_W,
folded_E: assigned_E,
folded_u: assigned_u,
folded_challenges: assigned_challenges,
folded_consistency_markers: [assigned_X0, assigned_X1],
folded_step_circuit_instances_hash_accumulator: assigned_step_circuit_instances,
};

let assigned_instance_W_commitment_coordinates = input_plonk
Expand All @@ -911,6 +979,17 @@ where
.try_into()
.expect("from array to array");

let assigned_step_circuit_instances = input_plonk
.get_step_circuit_instances()
.iter()
.flat_map(|instance| instance.iter().enumerate())
.enumerate()
.map(|(column_index, (row_index, instance))| {
let annot = format!("instance[{column_index}][{row_index}] value");
assign_and_absorb_diff_field!(instance, || annot.clone())
})
.collect::<Result<Vec<_>, _>>()?;

let assigned_challanges_instance = input_plonk
.challenges
.iter()
Expand Down Expand Up @@ -939,6 +1018,7 @@ where
input_W_commitments: assigned_instance_W_commitment_coordinates,
input_consistency_markers: assigned_consistency_markers,
cross_terms_commits: assigned_cross_term_commits,
input_step_circuit_instances: assigned_step_circuit_instances,
},
r,
))
Expand Down Expand Up @@ -1261,7 +1341,7 @@ mod tests {
plonk = plonk.fold(
&PlonkInstance {
W_commitments: input_W.clone(),
instances: vec![vec![ScalarExt::ONE, ScalarExt::ONE]],
instances: vec![vec![ScalarExt::ZERO, ScalarExt::ZERO]],
challenges: vec![],
},
&[],
Expand Down Expand Up @@ -1378,7 +1458,7 @@ mod tests {

#[traced_test]
#[test]
fn fold_instances_test() {
fn fold_consistency_markers_test() {
let Fixture {
mut ws,
config,
Expand Down Expand Up @@ -1438,7 +1518,7 @@ mod tests {
.assign_next_advice(&mut ctx, || "r", util::fe_to_fe(&r).unwrap())
.unwrap();

let assigned_fold_instances = relaxed_plonk
let assigned_consistency_markers = relaxed_plonk
.get_consistency_markers()
.unwrap()
.iter()
Expand Down Expand Up @@ -1472,7 +1552,7 @@ mod tests {
&mut ctx,
&bn_chip,
assigned_input_instance,
assigned_fold_instances,
assigned_consistency_markers,
&r_as_bn,
&m_bn,
LIMB_WIDTH,
Expand Down
2 changes: 2 additions & 0 deletions src/ivc/incrementally_verifiable_computation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ where
C2: CurveAffine<Base = <C1 as PrimeCurveAffine>::Scalar>,
SC1: StepCircuit<A1, C1::Scalar>,
SC2: StepCircuit<A2, C2::Scalar>,
C1::Scalar: PrimeFieldBits + FromUniformBytes<64>,
C2::Scalar: PrimeFieldBits + FromUniformBytes<64>,
{
primary: StepCircuitContext<A1, C1, SC1>,
secondary: StepCircuitContext<A2, C2, SC2>,
Expand Down
Loading
Loading