Skip to content

Commit e1d7a80

Browse files
committed
Merge branch 'main' into sai/add_batch_circuits
2 parents 5e163cd + 9999dcf commit e1d7a80

File tree

13 files changed

+661
-450
lines changed

13 files changed

+661
-450
lines changed

circuit-prover/examples/mmcs_verify.rs

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -38,41 +38,45 @@ fn main() -> Result<(), ProverError> {
3838
let compress = config::baby_bear_compression();
3939
let mmcs_config = MmcsVerifyConfig::babybear_quartic_extension_default();
4040

41-
let mut builder = CircuitBuilder::new();
41+
let mut builder = CircuitBuilder::<F>::new();
4242
builder.enable_mmcs(&mmcs_config);
4343

4444
// Public inputs: leaf hash and expected root hash
45-
let leaf_hash = (0..mmcs_config.ext_field_digest_elems)
46-
.map(|_| builder.alloc_public_input("leaf_hash"))
47-
.collect::<Vec<ExprId>>();
48-
let index = builder.alloc_public_input("index");
45+
// The leaves will contain `mmcs_config.ext_field_digest_elems` wires,
46+
// when the leaf index is odd, and an empty vector otherwise. This means
47+
// we're proving the opening of an Mmcs to matrices of height 2^depth, 2^(depth -1), ...
48+
let leaves: Vec<Vec<ExprId>> = (0..depth)
49+
.map(|i| {
50+
(0..if i % 2 == 0 && i != depth - 1 {
51+
mmcs_config.ext_field_digest_elems
52+
} else {
53+
0
54+
})
55+
.map(|_| builder.alloc_public_input("leaf_hash"))
56+
.collect::<Vec<ExprId>>()
57+
})
58+
.collect();
59+
let directions: Vec<ExprId> = (0..depth)
60+
.map(|_| builder.alloc_public_input("directions"))
61+
.collect();
4962
let expected_root = (0..mmcs_config.ext_field_digest_elems)
5063
.map(|_| builder.alloc_public_input("expected_root"))
5164
.collect::<Vec<ExprId>>();
5265
// Add a Mmcs verification operation
5366
// This declares that leaf_hash and expected_root are connected to witness bus
5467
// The AIR constraints will verify the Mmcs path is valid
55-
let mmcs_op_id = builder.add_mmcs_verify(&leaf_hash, &index, &expected_root)?;
68+
let mmcs_op_id = builder.add_mmcs_verify(&leaves, &directions, &expected_root)?;
5669

5770
builder.dump_allocation_log();
5871

5972
let circuit = builder.build()?;
6073
let mut runner = circuit.runner();
6174

6275
// Set public inputs
63-
let leaf_value = [
64-
F::ZERO,
65-
F::ZERO,
66-
F::ZERO,
67-
F::ZERO,
68-
F::ZERO,
69-
F::ZERO,
70-
F::ZERO,
71-
F::from_u64(42),
72-
]; // Our leaf value
73-
let siblings: Vec<(Vec<F>, Option<Vec<F>>)> = (0..depth)
76+
//
77+
let leaves_value: Vec<Vec<F>> = (0..depth)
7478
.map(|i| {
75-
(
79+
if i % 2 == 0 && i != depth - 1 {
7680
vec![
7781
F::ZERO,
7882
F::ZERO,
@@ -81,47 +85,50 @@ fn main() -> Result<(), ProverError> {
8185
F::ZERO,
8286
F::ZERO,
8387
F::ZERO,
84-
F::from_u64((i + 1) * 10),
85-
],
86-
// Extra siblings on odd levels, but never on the last level
87-
if i % 2 == 0 || i == depth - 1 {
88-
None
89-
} else {
90-
Some(vec![
91-
F::ZERO,
92-
F::ZERO,
93-
F::ZERO,
94-
F::ZERO,
95-
F::ZERO,
96-
F::ZERO,
97-
F::ZERO,
98-
F::from_u64(i + 1),
99-
])
100-
},
101-
)
88+
F::from_u64(42),
89+
]
90+
} else {
91+
vec![]
92+
}
10293
})
103-
.collect(); // The siblings, containing extra siblings every other level (except the last)
104-
let directions: Vec<bool> = (0..depth).map(|i| i % 2 == 0).collect();
94+
.collect(); // Our leaf value
95+
let siblings: Vec<Vec<F>> = (0..depth)
96+
.map(|i| {
97+
vec![
98+
F::ZERO,
99+
F::ZERO,
100+
F::ZERO,
101+
F::ZERO,
102+
F::ZERO,
103+
F::ZERO,
104+
F::ZERO,
105+
F::from_u64((i + 1) * 10),
106+
]
107+
})
108+
.collect();
109+
105110
// the index is 0b1010...
106-
let index_value = F::from_u64(
107-
(0..32)
108-
.zip(directions.iter())
109-
.filter(|(_, dir)| **dir)
110-
.map(|(i, _)| 1 << i)
111-
.sum(),
112-
);
111+
let directions: Vec<bool> = (0..depth).map(|i| i % 2 == 0).collect();
112+
113113
let MmcsPrivateData {
114114
path_states: intermediate_states,
115115
..
116-
} = MmcsPrivateData::new(&compress, &mmcs_config, &leaf_value, &siblings, &directions)?;
116+
} = MmcsPrivateData::new(
117+
&compress,
118+
&mmcs_config,
119+
&leaves_value,
120+
&siblings,
121+
&directions,
122+
)?;
117123
let expected_root_value = intermediate_states
118124
.last()
119125
.expect("There is always at least the leaf hash")
126+
.0
120127
.clone();
121128

122129
let mut public_inputs = vec![];
123-
public_inputs.extend(leaf_value);
124-
public_inputs.push(index_value);
130+
public_inputs.extend(leaves_value.iter().flatten());
131+
public_inputs.extend(directions.iter().map(|dir| F::from_bool(*dir)));
125132
public_inputs.extend(&expected_root_value);
126133

127134
runner.set_public_inputs(&public_inputs)?;
@@ -131,12 +138,11 @@ fn main() -> Result<(), ProverError> {
131138
NonPrimitiveOpPrivateData::MmcsVerify(MmcsPrivateData::new(
132139
&compress,
133140
&mmcs_config,
134-
&leaf_value,
141+
&leaves_value,
135142
&siblings,
136143
&directions,
137144
)?),
138145
)?;
139-
140146
let traces = runner.run()?;
141147
let multi_prover = MultiTableProver::new(config).with_mmcs_table(mmcs_config.into());
142148
let proof = multi_prover.prove_all_tables(&traces)?;

circuit/src/alloc_entry.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub struct AllocationEntry {
3434
/// User-provided label (if any)
3535
pub label: &'static str,
3636
/// Dependencies for this entry, i.e. the expressions that this entry depends on.
37-
pub dependencies: Vec<ExprId>,
37+
pub dependencies: Vec<Vec<ExprId>>,
3838
/// Scope/sub-circuit this allocation belongs to (if any)
3939
pub scope: Option<&'static str>,
4040
}
@@ -149,8 +149,8 @@ fn dump_internal_log(allocation_log: &[AllocationEntry]) {
149149
tracing::debug!(
150150
" expr_{} = expr_{} + expr_{}{}",
151151
entry.expr_id.0,
152-
entry.dependencies[0].0,
153-
entry.dependencies[1].0,
152+
entry.dependencies[0][0].0,
153+
entry.dependencies[1][0].0,
154154
display_label(entry.label)
155155
);
156156
} else {
@@ -171,8 +171,8 @@ fn dump_internal_log(allocation_log: &[AllocationEntry]) {
171171
tracing::debug!(
172172
" expr_{} = expr_{} - expr_{}{}",
173173
entry.expr_id.0,
174-
entry.dependencies[0].0,
175-
entry.dependencies[1].0,
174+
entry.dependencies[0][0].0,
175+
entry.dependencies[1][0].0,
176176
display_label(entry.label)
177177
);
178178
} else {
@@ -193,8 +193,8 @@ fn dump_internal_log(allocation_log: &[AllocationEntry]) {
193193
tracing::debug!(
194194
" expr_{} = expr_{} * expr_{}{}",
195195
entry.expr_id.0,
196-
entry.dependencies[0].0,
197-
entry.dependencies[1].0,
196+
entry.dependencies[0][0].0,
197+
entry.dependencies[1][0].0,
198198
display_label(entry.label)
199199
);
200200
} else {
@@ -215,8 +215,8 @@ fn dump_internal_log(allocation_log: &[AllocationEntry]) {
215215
tracing::debug!(
216216
" expr_{} = expr_{} / expr_{}{}",
217217
entry.expr_id.0,
218-
entry.dependencies[0].0,
219-
entry.dependencies[1].0,
218+
entry.dependencies[0][0].0,
219+
entry.dependencies[1][0].0,
220220
display_label(entry.label)
221221
);
222222
} else {
@@ -244,6 +244,7 @@ fn dump_internal_log(allocation_log: &[AllocationEntry]) {
244244
let deps: Vec<_> = entry
245245
.dependencies
246246
.iter()
247+
.flatten()
247248
.map(|e| format!("expr_{}", e.0).to_string())
248249
.collect();
249250
tracing::debug!(

circuit/src/builder/circuit_builder.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@ pub struct CircuitBuilder<F> {
2424
witness_alloc: WitnessAllocator,
2525

2626
/// Non-primitive operations (complex constraints that don't produce `ExprId`s)
27-
non_primitive_ops: Vec<(NonPrimitiveOpId, NonPrimitiveOpType, Vec<ExprId>)>,
27+
non_primitive_ops: Vec<NonPrimitiveOperationData>,
2828

2929
/// Builder configuration
3030
config: BuilderConfig,
3131
}
3232

33+
/// The non-primitive operation id, type, and the vectors of the expressions representing its inputs
34+
pub type NonPrimitiveOperationData = (NonPrimitiveOpId, NonPrimitiveOpType, Vec<Vec<ExprId>>);
35+
3336
impl<F> Default for CircuitBuilder<F>
3437
where
3538
F: Clone + PrimeCharacteristicRing + Eq + core::hash::Hash,
@@ -251,7 +254,7 @@ where
251254
pub(crate) fn push_non_primitive_op(
252255
&mut self,
253256
op_type: NonPrimitiveOpType,
254-
witness_exprs: Vec<ExprId>,
257+
witness_exprs: Vec<Vec<ExprId>>,
255258
label: &'static str,
256259
) -> NonPrimitiveOpId {
257260
let op_id = NonPrimitiveOpId(self.non_primitive_ops.len() as u32);

0 commit comments

Comments
 (0)