Skip to content

Commit f97e23b

Browse files
updated mod-builder to support generalized setup and better finalization
1 parent 8fc6d8c commit f97e23b

File tree

8 files changed

+134
-477
lines changed

8 files changed

+134
-477
lines changed

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ k256 = { version = "0.13.3", default-features = false }
250250
elliptic-curve = { version = "0.13.8", default-features = false }
251251
ecdsa = { version = "0.16.9", default-features = false }
252252
num-bigint = { version = "0.4.6", default-features = false }
253+
num-bigint-dig = { version = "0.8.4", default-features = false }
253254
num-integer = { version = "0.1.46", default-features = false }
254255
num-traits = { version = "0.2.19", default-features = false }
255256
ff = { version = "0.13.0", default-features = false }

crates/circuits/mod-builder/src/builder.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use std::{cell::RefCell, ops::Deref, rc::Rc};
1+
use std::{cell::RefCell, iter, ops::Deref, rc::Rc};
22

3+
use itertools::{zip_eq, Itertools};
34
use num_bigint::{BigInt, BigUint, Sign};
45
use num_traits::Zero;
56
use openvm_circuit_primitives::{
@@ -310,18 +311,32 @@ impl<AB: InteractionBuilder> SubAir<AB> for FieldExpr {
310311
// however this has the challenge that when the same chip is used
311312
// across continuation segments,
312313
// only the first segment will have setup called
313-
for i in 0..inputs[0].len().max(self.builder.prime_limbs.len()) {
314-
let lhs = if i < inputs[0].len() {
315-
inputs[0][i].into()
316-
} else {
317-
AB::Expr::ZERO
318-
};
319-
let rhs = if i < self.builder.prime_limbs.len() {
320-
AB::Expr::from_canonical_usize(self.builder.prime_limbs[i])
321-
} else {
322-
AB::Expr::ZERO
323-
};
324-
builder.when(is_setup.clone()).assert_eq(lhs, rhs);
314+
315+
let expected = iter::empty()
316+
.chain(self.builder.prime_limbs.clone())
317+
.chain(self.setup_values.iter().flat_map(|x| {
318+
big_uint_to_num_limbs(x, self.builder.limb_bits, self.builder.num_limbs)
319+
.into_iter()
320+
}))
321+
.collect_vec();
322+
323+
let reads: Vec<AB::Expr> = inputs
324+
.clone()
325+
.into_iter()
326+
.flatten()
327+
.map(Into::into)
328+
.take(expected.len())
329+
.collect();
330+
331+
if format!("{:?}", flags[0].into()) == "0" {
332+
println!("lhs: {:?}", reads);
333+
println!("rhs: {:?}", expected);
334+
}
335+
336+
for (lhs, rhs) in zip_eq(&reads, expected) {
337+
builder
338+
.when(is_setup.clone())
339+
.assert_eq(lhs.clone(), AB::F::from_canonical_usize(rhs));
325340
}
326341
}
327342

crates/circuits/mod-builder/src/core_chip.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use itertools::Itertools;
22
use num_bigint::BigUint;
3+
use num_traits::Zero;
34
use openvm_circuit::arch::{
45
AdapterAirContext, AdapterRuntimeContext, DynAdapterInterface, DynArray, MinimalInstruction,
56
Result, VmAdapterInterface, VmCoreAir, VmCoreChip,
@@ -314,14 +315,36 @@ where
314315
// We will copy over the core part of first row to padded rows (all rows after num_records).
315316
let core_width = <Self::Air as BaseAir<F>>::width(&self.air);
316317
let adapter_width = trace.width() - core_width;
317-
let first_row = trace.rows().nth(0).unwrap().collect::<Vec<_>>();
318-
let first_row_core = first_row.split_at(adapter_width).1;
318+
let dummy_row = self.generate_dummy_trace_row(adapter_width, core_width);
319319
for row in trace.rows_mut().skip(num_records) {
320-
let core_row = row.split_at_mut(adapter_width).1;
321-
// The same as first row, except "is_valid" (the first element of core part) is zero.
322-
core_row.copy_from_slice(first_row_core);
323-
core_row[0] = F::ZERO;
320+
row.copy_from_slice(&dummy_row);
324321
}
325322
}
326323
}
327324
}
325+
326+
impl FieldExpressionCoreChip {
327+
// We will be setting is_valid = 0. That forces all flags be 0 (otherwise setup will be -1).
328+
// We generate a dummy row with all flags set to 0, then we set is_valid = 0.
329+
fn generate_dummy_trace_row<F: PrimeField32>(
330+
&self,
331+
adapter_width: usize,
332+
core_width: usize,
333+
) -> Vec<F> {
334+
let record = FieldExpressionRecord {
335+
inputs: vec![BigUint::zero(); self.air.num_inputs()],
336+
flags: vec![false; self.air.num_flags()],
337+
};
338+
let mut row = vec![F::ZERO; adapter_width + core_width];
339+
let core_row = &mut row[adapter_width..];
340+
// We **do not** want this trace row to update the range checker
341+
// so we must create a temporary range checker
342+
let tmp_range_checker = SharedVariableRangeCheckerChip::new(self.range_checker.bus());
343+
self.air.expr.generate_subrow(
344+
(tmp_range_checker.as_ref(), record.inputs, record.flags),
345+
core_row,
346+
);
347+
core_row[0] = F::ZERO; // is_valid = 0
348+
row
349+
}
350+
}

extensions/ecc/circuit/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ openvm-rv32-adapters = { workspace = true }
2121
openvm-ecc-transpiler = { workspace = true }
2222

2323
num-bigint = { workspace = true }
24+
num-bigint-dig = { workspace = true }
2425
num-traits = { workspace = true }
2526
strum = { workspace = true }
2627
derive_more = { workspace = true }

0 commit comments

Comments
 (0)