Skip to content
Draft
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
4 changes: 2 additions & 2 deletions circuits/src/hash/poseidon/poseidon_chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ impl<F: PoseidonField> ComposableChip<F> for PoseidonChip<F> {
let constant_cols = shared_res.1;

let q_full_round = meta.selector();
let q_partial_round = meta.complex_selector();
let q_partial_round = meta.selector();

register_cols[..WIDTH].iter().for_each(|col| meta.enable_equality(*col));

Expand Down Expand Up @@ -253,7 +253,7 @@ impl<F: PoseidonField> ComposableChip<F> for PoseidonChip<F> {
.chain(input_pow_constraints)
.chain(once(output_pow_constraint))
.collect::<Vec<_>>();
Constraints::with_additive_selector(q_partial_round, constraints)
Constraints::with_selector(q_partial_round, constraints)
});

PoseidonConfig {
Expand Down
21 changes: 21 additions & 0 deletions circuits/src/verifier/accumulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ impl<S: SelfEmulation> Accumulator<S> {
self.rhs.collapse();
}

/// Evaluates the variable and fixed parts of the Accumulator collapsing
/// each side to a single point.
pub fn fully_collapse(&self, fixed_bases: &BTreeMap<String, S::C>) -> (S::C, S::C) {
(self.lhs.eval(fixed_bases), self.rhs.eval(fixed_bases))
}

/// Accumulates several accumulators together. The resulting acc will
/// satisfy the invariant iff all the accumulators individually do.
pub fn accumulate(accs: &[Self]) -> Self {
Expand Down Expand Up @@ -293,6 +299,21 @@ impl<S: SelfEmulation> AssignedAccumulator<S> {
self.rhs.collapse(layouter, curve_chip, scalar_chip)
}

/// Evaluates the variable and fixed parts of the AssignedAccumulator
/// collapsing each side to a single point.
///
/// This will likely be an expensive in-circuit operation.
pub fn fully_collapse(
&self,
layouter: &mut impl Layouter<S::F>,
curve_chip: &S::CurveChip,
fixed_bases: &BTreeMap<String, S::C>,
) -> Result<(S::AssignedPoint, S::AssignedPoint), Error> {
let lhs_pt = self.lhs.eval(layouter, curve_chip, fixed_bases)?;
let rhs_pt = self.rhs.eval(layouter, curve_chip, fixed_bases)?;
Ok((lhs_pt, rhs_pt))
}

/// Accumulates several accumulators together. The resulting acc will
/// satisfy the invariant iff all the accumulators individually do.
pub fn accumulate(
Expand Down
28 changes: 28 additions & 0 deletions circuits/src/verifier/msm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,34 @@ impl<S: SelfEmulation> AssignedMsm<S> {
Ok(())
}

/// Evaluates the variable and fixed base parts of the AssignedMsm
/// collapsing it to a single point.
///
/// The fixed bases are constrained in-circuit to be fixed.
pub fn eval(
&self,
layouter: &mut impl Layouter<S::F>,
curve_chip: &S::CurveChip,
fixed_bases: &BTreeMap<String, S::C>,
) -> Result<S::AssignedPoint, Error> {
let mut bases = self.bases.clone();
let mut scalars = self.scalars.clone();

for (key, scalar) in self.fixed_base_scalars.iter() {
let base = fixed_bases.get(key).expect("Base not provided: {key}");
let fixed_base = curve_chip.assign_fixed(layouter, *base)?;
bases.push(fixed_base);
scalars.push(scalar.clone());
}

let scalar_tuples = scalars
.iter()
.map(|s| (s.scalar.clone(), s.bound.bits() as usize))
.collect::<Vec<_>>();

S::msm(layouter, curve_chip, &scalar_tuples, &bases)
}

/// Scales all the scalars of the AssignedMsm by the given factor r.
///
/// This function mutates self.
Expand Down
25 changes: 25 additions & 0 deletions circuits/src/verifier/verifier_gadget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,31 @@ impl<S: SelfEmulation> VerifierGadget<S> {

Ok(assigned_vk)
}

/// Assigns a verifying key to a fixed/constant `transcript_repr` value.
pub fn assign_vk_to_fixed(
&self,
layouter: &mut impl Layouter<S::F>,
vk_name: &str,
domain: &EvaluationDomain<S::F>,
cs: &ConstraintSystem<S::F>,
transcript_repr_constant: S::F,
) -> Result<AssignedVk<S>, Error> {
let transcript_repr = self.scalar_chip.assign_fixed(layouter, transcript_repr_constant)?;
// We expect a finalized cs with no selectors, i.e. whose selectors have been
// converted into fixed columns.
let selectors = vec![vec![false]; cs.num_selectors()];
let (processed_cs, _) = cs.clone().directly_convert_selectors_to_fixed(selectors);

let assigned_vk = AssignedVk {
vk_name: vk_name.to_string(),
domain: domain.clone(),
cs: processed_cs,
transcript_repr,
};

Ok(assigned_vk)
}
}

impl<S: SelfEmulation> VerifierGadget<S> {
Expand Down