Skip to content

Commit a056b28

Browse files
chore: make Archon witness population more flexible (#127)
Accept pushes of arbitrary numbers of uints to entries of witness modules instead of always requiring 128 bits of data. The data is accumulated on buffers and gets concretized into underliers in chunks of 128 bits (the size of an `OptimalUnderlier`). This API is propagated to Lean via unsafe bindings.
1 parent 67a1eac commit a056b28

File tree

8 files changed

+233
-78
lines changed

8 files changed

+233
-78
lines changed

Ix/Archon/Witness.lean

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,24 @@ opaque addEntryWithCapacity : WitnessModule → (logBits : UInt8) → EntryId ×
3333
opaque bindOracleTo : WitnessModule → OracleIdx → EntryId → TowerField → WitnessModule
3434

3535
/-- **Invalidates** the input `WitnessModule` -/
36-
@[never_extract, extern "c_rs_witness_module_push_u128_to"]
37-
opaque pushUInt128To : WitnessModule → @& UInt128 → EntryId → WitnessModule
36+
@[never_extract, extern "c_rs_witness_module_push_u8s_to"]
37+
opaque pushUInt8sTo : WitnessModule → @& Array UInt8 → EntryId → WitnessModule
38+
39+
/-- **Invalidates** the input `WitnessModule` -/
40+
@[never_extract, extern "c_rs_witness_module_push_u16s_to"]
41+
opaque pushUInt16sTo : WitnessModule → @& Array UInt16 → EntryId → WitnessModule
42+
43+
/-- **Invalidates** the input `WitnessModule` -/
44+
@[never_extract, extern "c_rs_witness_module_push_u32s_to"]
45+
opaque pushUInt32sTo : WitnessModule → @& Array UInt32 → EntryId → WitnessModule
46+
47+
/-- **Invalidates** the input `WitnessModule` -/
48+
@[never_extract, extern "c_rs_witness_module_push_u64s_to"]
49+
opaque pushUInt64sTo : WitnessModule → @& Array UInt64 → EntryId → WitnessModule
50+
51+
/-- **Invalidates** the input `WitnessModule` -/
52+
@[never_extract, extern "c_rs_witness_module_push_u128s_to"]
53+
opaque pushUInt128sTo : WitnessModule → @& Array UInt128 → EntryId → WitnessModule
3854

3955
/-- **Invalidates** the input `WitnessModule` -/
4056
@[never_extract, extern "c_rs_witness_module_populate"]

Tests/Archon.lean

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def linearCombination : TestSeq := Id.run do
4545
witnessModule := newWitnessModule
4646
for j in [0 : 1 <<< i ] do
4747
let u128 := UInt128.ofNatWrap (j * j + 17)
48-
witnessModule := witnessModule.pushUInt128To u128 entryId
48+
witnessModule := witnessModule.pushUInt128sTo #[u128] entryId
4949
match i with
5050
| 0 => witnessModule := witnessModule.bindOracleTo oracleId entryId .b1
5151
| 1 => witnessModule := witnessModule.bindOracleTo oracleId entryId .b2
@@ -66,7 +66,7 @@ def packed : TestSeq :=
6666
let circuitModule := circuitModule.freezeOracles
6767
let witnessModule := circuitModule.initWitnessModule
6868
let (entryId, witnessModule) := witnessModule.addEntryWithCapacity 7
69-
let witnessModule := witnessModule.pushUInt128To 2347928368726 entryId
69+
let witnessModule := witnessModule.pushUInt128sTo #[2347928368726] entryId
7070
let witnessModule := witnessModule.bindOracleTo x entryId .b1
7171
populateAndValidate circuitModule witnessModule 128 "Archon packed works"
7272

@@ -77,10 +77,40 @@ def shifted : TestSeq :=
7777
let circuitModule := circuitModule.freezeOracles
7878
let witnessModule := circuitModule.initWitnessModule
7979
let (entryId, witnessModule) := witnessModule.addEntryWithCapacity 7
80-
let witnessModule := witnessModule.pushUInt128To 2347928368726 entryId
80+
let witnessModule := witnessModule.pushUInt128sTo #[2347928368726] entryId
8181
let witnessModule := witnessModule.bindOracleTo x entryId .b1
8282
populateAndValidate circuitModule witnessModule 128 "Archon shifted works"
8383

84+
def pushData : TestSeq :=
85+
let circuitModule := CircuitModule.new 0
86+
let (u8s, circuitModule) := circuitModule.addCommitted "u8s" .b1
87+
let (u16s, circuitModule) := circuitModule.addCommitted "u16s" .b1
88+
let (u32s, circuitModule) := circuitModule.addCommitted "u32s" .b1
89+
let (u64s, circuitModule) := circuitModule.addCommitted "u64s" .b1
90+
let (u128s, circuitModule) := circuitModule.addCommitted "u128s" .b1
91+
let circuitModule := circuitModule.assertZero "u8s xor u16s" #[] $ .add (.oracle u8s) (.oracle u16s)
92+
let circuitModule := circuitModule.assertZero "u16s xor u32s" #[] $ .add (.oracle u16s) (.oracle u32s)
93+
let circuitModule := circuitModule.assertZero "u32s xor u64s" #[] $ .add (.oracle u32s) (.oracle u64s)
94+
let circuitModule := circuitModule.assertZero "u64s xor u128s" #[] $ .add (.oracle u64s) (.oracle u128s)
95+
let circuitModule := circuitModule.freezeOracles
96+
let witnessModule := circuitModule.initWitnessModule
97+
let (u8sEntry, witnessModule) := witnessModule.addEntryWithCapacity 7
98+
let (u16sEntry, witnessModule) := witnessModule.addEntryWithCapacity 7
99+
let (u32sEntry, witnessModule) := witnessModule.addEntryWithCapacity 7
100+
let (u64sEntry, witnessModule) := witnessModule.addEntryWithCapacity 7
101+
let (u128sEntry, witnessModule) := witnessModule.addEntryWithCapacity 7
102+
let witnessModule := witnessModule.pushUInt8sTo ⟨(List.replicate 16 0)⟩ u8sEntry
103+
let witnessModule := witnessModule.pushUInt16sTo ⟨(List.replicate 8 0)⟩ u16sEntry
104+
let witnessModule := witnessModule.pushUInt32sTo #[0, 0, 0, 0] u32sEntry
105+
let witnessModule := witnessModule.pushUInt64sTo #[0, 0] u64sEntry
106+
let witnessModule := witnessModule.pushUInt128sTo #[0] u128sEntry
107+
let witnessModule := witnessModule.bindOracleTo u8s u8sEntry .b1
108+
let witnessModule := witnessModule.bindOracleTo u16s u16sEntry .b1
109+
let witnessModule := witnessModule.bindOracleTo u32s u32sEntry .b1
110+
let witnessModule := witnessModule.bindOracleTo u64s u64sEntry .b1
111+
let witnessModule := witnessModule.bindOracleTo u128s u128sEntry .b1
112+
populateAndValidate circuitModule witnessModule 128 "Archon witness data pushes work"
113+
84114
def proveAndVerify : TestSeq :=
85115
let circuitModule := CircuitModule.new 0
86116
let (x, circuitModule) := circuitModule.addCommitted "x" .b1
@@ -89,7 +119,7 @@ def proveAndVerify : TestSeq :=
89119
let circuitModule := circuitModule.freezeOracles
90120
let witnessModule := circuitModule.initWitnessModule
91121
let (entryId, witnessModule) := witnessModule.addEntryWithCapacity 7
92-
let witnessModule := witnessModule.pushUInt128To (.ofNatCore $ UInt128.size - 1) entryId
122+
let witnessModule := witnessModule.pushUInt128sTo #[(.ofNatCore $ UInt128.size - 1)] entryId
93123
let witnessModule := witnessModule.bindOracleTo x entryId .b1
94124
let witnessModule := witnessModule.bindOracleTo y entryId .b1
95125
let height := 128
@@ -115,6 +145,7 @@ def Tests.Archon.suite := [
115145
linearCombination,
116146
packed,
117147
shifted,
148+
pushData,
118149
proveAndVerify,
119150
versionCircuitModules,
120151
]

c/archon.c

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,83 @@ extern lean_obj_res c_rs_witness_module_bind_oracle_to(
4747
return alloc_lean_linear_object(new_linear);
4848
}
4949

50-
extern lean_obj_res c_rs_witness_module_push_u128_to(
50+
static inline lean_obj_res c_rs_witness_module_push_data_to(
5151
lean_obj_arg l_witness,
52-
b_lean_obj_arg u128,
53-
size_t entry_id
52+
b_lean_obj_arg data,
53+
size_t entry_id,
54+
void (*rs_fn)(void*, b_lean_obj_arg, size_t)
5455
) {
5556
linear_object *linear = validated_linear(l_witness);
56-
rs_witness_module_push_u128_to(
57-
get_object_ref(linear),
58-
lean_get_external_data(u128),
59-
entry_id
60-
);
57+
rs_fn(get_object_ref(linear), data, entry_id);
6158
linear_object *new_linear = linear_bump(linear);
6259
return alloc_lean_linear_object(new_linear);
6360
}
6461

62+
extern lean_obj_res c_rs_witness_module_push_u8s_to(
63+
lean_obj_arg l_witness,
64+
b_lean_obj_arg u8s,
65+
size_t entry_id
66+
) {
67+
return c_rs_witness_module_push_data_to(
68+
l_witness,
69+
u8s,
70+
entry_id,
71+
rs_witness_module_push_u8s_to
72+
);
73+
}
74+
75+
extern lean_obj_res c_rs_witness_module_push_u16s_to(
76+
lean_obj_arg l_witness,
77+
b_lean_obj_arg u16s,
78+
size_t entry_id
79+
) {
80+
return c_rs_witness_module_push_data_to(
81+
l_witness,
82+
u16s,
83+
entry_id,
84+
rs_witness_module_push_u16s_to
85+
);
86+
}
87+
88+
extern lean_obj_res c_rs_witness_module_push_u32s_to(
89+
lean_obj_arg l_witness,
90+
b_lean_obj_arg u32s,
91+
size_t entry_id
92+
) {
93+
return c_rs_witness_module_push_data_to(
94+
l_witness,
95+
u32s,
96+
entry_id,
97+
rs_witness_module_push_u32s_to
98+
);
99+
}
100+
101+
extern lean_obj_res c_rs_witness_module_push_u64s_to(
102+
lean_obj_arg l_witness,
103+
b_lean_obj_arg u64s,
104+
size_t entry_id
105+
) {
106+
return c_rs_witness_module_push_data_to(
107+
l_witness,
108+
u64s,
109+
entry_id,
110+
rs_witness_module_push_u64s_to
111+
);
112+
}
113+
114+
extern lean_obj_res c_rs_witness_module_push_u128s_to(
115+
lean_obj_arg l_witness,
116+
b_lean_obj_arg u128s,
117+
size_t entry_id
118+
) {
119+
return c_rs_witness_module_push_data_to(
120+
l_witness,
121+
u128s,
122+
entry_id,
123+
rs_witness_module_push_u128s_to
124+
);
125+
}
126+
65127
extern lean_obj_res c_rs_witness_module_populate(lean_obj_arg l_witness, uint64_t height) {
66128
linear_object *linear = validated_linear(l_witness);
67129
rs_witness_module_populate(get_object_ref(linear), height);

c/rust.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ void rs_witness_module_free(void*);
1313
size_t rs_witness_module_add_entry(void*);
1414
size_t rs_witness_module_add_entry_with_capacity(void*, uint8_t);
1515
void rs_witness_module_bind_oracle_to(void*, size_t, size_t, uint8_t);
16-
void rs_witness_module_push_u128_to(void*, void*, size_t);
16+
void rs_witness_module_push_u8s_to(void*, b_lean_obj_arg, size_t);
17+
void rs_witness_module_push_u16s_to(void*, b_lean_obj_arg, size_t);
18+
void rs_witness_module_push_u32s_to(void*, b_lean_obj_arg, size_t);
19+
void rs_witness_module_push_u64s_to(void*, b_lean_obj_arg, size_t);
20+
void rs_witness_module_push_u128s_to(void*, b_lean_obj_arg, size_t);
1721
void rs_witness_module_populate(void*, uint64_t);
1822
void *rs_compile_witness_modules(void**, b_lean_obj_arg);
1923

src/archon/precompiles/blake3.rs

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,7 @@ fn state_transition_module(
137137

138138
for (xy, trace) in traces.clone().state_trace.into_iter().enumerate() {
139139
let entry_id_xy = witness_module.new_entry();
140-
141-
for chunk in trace.chunks(4) {
142-
witness_module.push_u32s_to(chunk.try_into()?, entry_id_xy);
143-
}
140+
witness_module.push_u32s_to(trace, entry_id_xy);
144141
witness_module.bind_oracle_to::<B32>(state_transitions[xy], entry_id_xy);
145142
}
146143

@@ -299,18 +296,10 @@ fn additions_xor_rotates_module(
299296
let yin_entry = witness_module.new_entry();
300297
let zout_entry = witness_module.new_entry();
301298

302-
for chunk in xin_traces[xy].chunks(4) {
303-
witness_module.push_u32s_to(chunk.try_into()?, xin_entry)
304-
}
305-
for chunk in yin_traces[xy].chunks(4) {
306-
witness_module.push_u32s_to(chunk.try_into()?, yin_entry)
307-
}
308-
for chunk in traces.cout_trace[xy].chunks(4) {
309-
witness_module.push_u32s_to(chunk.try_into()?, cout_entry)
310-
}
311-
for chunk in zout_traces[xy].chunks(4) {
312-
witness_module.push_u32s_to(chunk.try_into()?, zout_entry)
313-
}
299+
witness_module.push_u32s_to(xin_traces[xy].clone(), xin_entry);
300+
witness_module.push_u32s_to(yin_traces[xy].clone(), yin_entry);
301+
witness_module.push_u32s_to(traces.cout_trace[xy].clone(), cout_entry);
302+
witness_module.push_u32s_to(zout_traces[xy].clone(), zout_entry);
314303

315304
witness_module.bind_oracle_to::<B1>(xins[xy], xin_entry);
316305
witness_module.bind_oracle_to::<B1>(yins[xy], yin_entry);
@@ -320,9 +309,7 @@ fn additions_xor_rotates_module(
320309

321310
// not to forget about d_in
322311
let d_in_entry = witness_module.new_entry();
323-
for chunk in traces.d_in_trace.chunks(4) {
324-
witness_module.push_u32s_to(chunk.try_into()?, d_in_entry)
325-
}
312+
witness_module.push_u32s_to(traces.d_in_trace.clone(), d_in_entry);
326313
witness_module.bind_oracle_to::<B1>(d_in, d_in_entry);
327314

328315
witness_module.populate(height)?;
@@ -364,17 +351,9 @@ fn cv_output_module(
364351
let state_i_entry = witness_module.new_entry();
365352
let state_i_8_entry = witness_module.new_entry();
366353

367-
for cv_vals in traces.cv_trace.chunks(4) {
368-
witness_module.push_u32s_to(cv_vals.try_into().unwrap(), cv_entry);
369-
}
370-
371-
for state_i_vals in traces.state_i_trace.chunks(4) {
372-
witness_module.push_u32s_to(state_i_vals.try_into().unwrap(), state_i_entry);
373-
}
374-
375-
for state_i_8_vals in traces.state_i_8_trace.chunks(4) {
376-
witness_module.push_u32s_to(state_i_8_vals.try_into().unwrap(), state_i_8_entry);
377-
}
354+
witness_module.push_u32s_to(traces.cv_trace.clone(), cv_entry);
355+
witness_module.push_u32s_to(traces.state_i_trace.clone(), state_i_entry);
356+
witness_module.push_u32s_to(traces.state_i_8_trace.clone(), state_i_8_entry);
378357

379358
witness_module.bind_oracle_to::<B32>(cv, cv_entry);
380359
witness_module.bind_oracle_to::<B32>(state_i, state_i_entry);
@@ -951,13 +930,13 @@ pub mod tests {
951930
let a_0_entry = witness_modules[witness_module_id].new_entry();
952931
let d_in_entry = witness_modules[witness_module_id].new_entry();
953932

954-
for chunk in traces.a_0_trace.chunks(4) {
955-
witness_modules[witness_module_id].push_u32s_to(chunk.try_into().unwrap(), a_0_entry)
956-
}
957-
958-
for chunk in traces.d_in_trace.chunks(4) {
959-
witness_modules[witness_module_id].push_u32s_to(chunk.try_into().unwrap(), d_in_entry)
960-
}
933+
let Trace {
934+
a_0_trace,
935+
d_in_trace,
936+
..
937+
} = traces;
938+
witness_modules[witness_module_id].push_u32s_to(a_0_trace, a_0_entry);
939+
witness_modules[witness_module_id].push_u32s_to(d_in_trace, d_in_entry);
961940

962941
witness_modules[witness_module_id].bind_oracle_to::<B1>(a_0, a_0_entry);
963942
witness_modules[witness_module_id].bind_oracle_to::<B1>(d_in, d_in_entry);

src/archon/protocol.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ mod tests {
192192

193193
fn populate_a_xor_b_witness_with_ones(witness_module: &mut WitnessModule, oracles: &Oracles) {
194194
let ones = witness_module.new_entry_with_capacity(7);
195-
witness_module.push_u128_to(u128::MAX, ones);
195+
witness_module.push_u128s_to([u128::MAX], ones);
196196
witness_module.bind_oracle_to::<B1>(oracles.s, ones);
197197
witness_module.bind_oracle_to::<B1>(oracles.a, ones);
198198
witness_module.bind_oracle_to::<B1>(oracles.b, ones);
@@ -204,8 +204,8 @@ mod tests {
204204
let mut witness_module = circuit_module.init_witness_module().unwrap();
205205
let zeros = witness_module.new_entry_with_capacity(7);
206206
let ones = witness_module.new_entry_with_capacity(7);
207-
witness_module.push_u128_to(0, zeros);
208-
witness_module.push_u128_to(u128::MAX, ones);
207+
witness_module.push_u128s_to([0], zeros);
208+
witness_module.push_u128s_to([u128::MAX], ones);
209209
witness_module.bind_oracle_to::<B1>(oracles.s, ones);
210210
witness_module.bind_oracle_to::<B1>(oracles.a, ones);
211211
witness_module.bind_oracle_to::<B1>(oracles.b, zeros);

0 commit comments

Comments
 (0)