Skip to content

Commit 8fcd809

Browse files
committed
refactor & clean-up
1 parent 34956c9 commit 8fcd809

File tree

10 files changed

+175
-140
lines changed

10 files changed

+175
-140
lines changed

ceno_emul/src/syscalls.rs

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub trait SyscallSpec {
2222
const CODE: u32;
2323

2424
const HAS_LOOKUPS: bool = false;
25+
26+
const GKR_OUTPUTS: usize = 0;
2527
}
2628

2729
/// Trace the inputs and effects of a syscall.

ceno_zkvm/src/e2e.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ fn generate_fixed_traces<E: ExtensionField>(
295295
}
296296

297297
pub fn generate_witness<E: ExtensionField>(
298-
system_config: &mut ConstraintSystemConfig<E>,
298+
system_config: &ConstraintSystemConfig<E>,
299299
emul_result: EmulationResult,
300300
program: &Program,
301301
is_mock_proving: bool,
@@ -312,7 +312,7 @@ pub fn generate_witness<E: ExtensionField>(
312312
.unwrap();
313313
system_config
314314
.dummy_config
315-
.assign_opcode_circuit(&mut system_config.zkvm_cs, &mut zkvm_witness, dummy_records)
315+
.assign_opcode_circuit(&system_config.zkvm_cs, &mut zkvm_witness, dummy_records)
316316
.unwrap();
317317
zkvm_witness.finalize_lk_multiplicities(is_mock_proving);
318318

@@ -394,7 +394,7 @@ pub fn run_e2e_with_checkpoint<
394394
};
395395

396396
let program = Arc::new(program);
397-
let mut system_config = construct_configs::<E>(program_params);
397+
let system_config = construct_configs::<E>(program_params);
398398
let reg_init = system_config.mmu_config.initial_registers();
399399

400400
// IO is not used in this program, but it must have a particular size at the moment.
@@ -432,7 +432,7 @@ pub fn run_e2e_with_checkpoint<
432432
init_full_mem,
433433
platform,
434434
hints,
435-
&mut system_config,
435+
&system_config,
436436
pk,
437437
zkvm_fixed_traces,
438438
is_mock_proving,
@@ -451,13 +451,11 @@ pub fn run_e2e_with_checkpoint<
451451
if let Checkpoint::PrepWitnessGen = checkpoint {
452452
return (
453453
None,
454-
Box::new(move || {
455-
_ = generate_witness(&mut system_config, emul_result, &program, false)
456-
}),
454+
Box::new(move || _ = generate_witness(&system_config, emul_result, &program, false)),
457455
);
458456
}
459457

460-
let zkvm_witness = generate_witness(&mut system_config, emul_result, &program, is_mock_proving);
458+
let zkvm_witness = generate_witness(&system_config, emul_result, &program, is_mock_proving);
461459

462460
// proving
463461
let prover = ZKVMProver::new(pk);
@@ -498,7 +496,7 @@ pub fn run_e2e_proof<E: ExtensionField + LkMultiplicityKey, PCS: PolynomialCommi
498496
init_full_mem: InitMemState,
499497
platform: Platform,
500498
hints: Vec<u32>,
501-
system_config: &mut ConstraintSystemConfig<E>,
499+
system_config: &ConstraintSystemConfig<E>,
502500
pk: ZKVMProvingKey<E, PCS>,
503501
zkvm_fixed_traces: ZKVMFixedTraces<E>,
504502
is_mock_proving: bool,

ceno_zkvm/src/instructions.rs

+37-18
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,39 @@ pub trait Instruction<E: ExtensionField> {
7474
}
7575
}
7676

77+
pub struct GKRinfo {
78+
pub and_lookups: usize,
79+
pub xor_lookups: usize,
80+
pub range_lookups: usize,
81+
pub aux_wits: usize,
82+
}
83+
84+
impl GKRinfo {
85+
fn lookup_total(&self) -> usize {
86+
self.and_lookups + self.xor_lookups + self.range_lookups
87+
}
88+
}
89+
7790
pub trait GKRIOPInstruction<E: ExtensionField>
7891
where
7992
Self: Instruction<E>,
8093
{
8194
type Layout: ProtocolWitnessGenerator<E> + ProtocolBuilder;
95+
96+
fn construct_circuit_with_gkr_iop(
97+
cb: &mut CircuitBuilder<E>,
98+
) -> Result<Self::InstructionConfig, ZKVMError> {
99+
unimplemented!();
100+
}
101+
102+
fn phase1_witness_from_steps(
103+
layout: &Self::Layout,
104+
steps: &[StepRecord],
105+
) -> Vec<Vec<E::BaseField>>;
106+
107+
// Number of lookup arguments used by this GKR proof
108+
fn gkr_info() -> GKRinfo;
109+
82110
fn assign_instance_with_gkr_iop(
83111
config: &Self::InstructionConfig,
84112
instance: &mut [E::BaseField],
@@ -88,16 +116,11 @@ where
88116
aux_wits: &[E::BaseField],
89117
) -> Result<(), ZKVMError>;
90118

91-
fn phase1_witness_from_steps(
92-
layout: &Self::Layout,
93-
steps: &[StepRecord],
94-
) -> Vec<Vec<E::BaseField>>;
95-
96119
fn assign_instances_with_gkr_iop(
97120
config: &Self::InstructionConfig,
98121
num_witin: usize,
99122
steps: Vec<StepRecord>,
100-
gkr_layout: &mut Self::Layout,
123+
gkr_layout: &Self::Layout,
101124
) -> Result<
102125
(
103126
RowMajorMatrix<E::BaseField>,
@@ -124,17 +147,14 @@ where
124147
);
125148

126149
let (lookups, aux_wits) = {
127-
// Keccak-specific
150+
// Extract lookups and auxiliary witnesses from GKR protocol
151+
// Here we assume that the gkr_witness's last layer is a convenience layer which holds
152+
// the output records for all instances; further, we assume that the last ```Self::lookup_count()```
153+
// elements of this layer are the lookup arguments.
128154
let mut lookups = vec![vec![]; steps.len()];
129-
for witness in gkr_witness
130-
.layers
131-
.last()
132-
.unwrap()
133-
.bases
134-
.iter()
135-
.skip(100)
136-
.cloned()
137-
{
155+
let last_layer = gkr_witness.layers.last().unwrap().bases.clone();
156+
let len = last_layer.len();
157+
for witness in last_layer[len - Self::gkr_info().lookup_total()..].iter() {
138158
for i in 0..witness.len() {
139159
lookups[i].push(witness[i]);
140160
}
@@ -144,6 +164,7 @@ where
144164
let n_layers = gkr_witness.layers.len();
145165

146166
for i in 0..steps.len() {
167+
// Omit last layer, which stores outputs and not real witnesses
147168
for layer in gkr_witness.layers[..n_layers - 1].iter() {
148169
for base in layer.bases.iter() {
149170
aux_wits[i].push(base[i]);
@@ -154,8 +175,6 @@ where
154175
(lookups, aux_wits)
155176
};
156177

157-
// dbg!(&lookups);
158-
159178
raw_witin_iter
160179
.zip(
161180
steps

ceno_zkvm/src/instructions/riscv/dummy/dummy_ecall.rs

+67-66
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
error::ZKVMError,
1212
expression::{ToExpr, WitIn},
1313
instructions::{
14-
GKRIOPInstruction, Instruction,
14+
GKRIOPInstruction, GKRinfo, Instruction,
1515
riscv::{constants::UInt, insn_base::WriteRD},
1616
},
1717
set_val,
@@ -21,10 +21,7 @@ use ff_ext::FieldInto;
2121

2222
use gkr_iop::{
2323
ProtocolWitnessGenerator,
24-
precompiles::{
25-
AND_LOOKUPS_PER_ROUND, KeccakLayout, KeccakTrace, RANGE_LOOKUPS_PER_ROUND,
26-
XOR_LOOKUPS_PER_ROUND,
27-
},
24+
precompiles::{AND_LOOKUPS, KeccakLayout, KeccakTrace, RANGE_LOOKUPS, XOR_LOOKUPS},
2825
};
2926

3027
/// LargeEcallDummy can handle any instruction and produce its effects,
@@ -37,7 +34,7 @@ impl<E: ExtensionField, S: SyscallSpec> Instruction<E> for LargeEcallDummy<E, S>
3734
type InstructionConfig = LargeEcallConfig<E>;
3835

3936
fn name() -> String {
40-
format!("{}_DUMMY", S::NAME)
37+
S::NAME.to_owned()
4138
}
4239
fn construct_circuit(cb: &mut CircuitBuilder<E>) -> Result<Self::InstructionConfig, ZKVMError> {
4340
let dummy_insn = DummyConfig::construct_circuit(
@@ -78,45 +75,9 @@ impl<E: ExtensionField, S: SyscallSpec> Instruction<E> for LargeEcallDummy<E, S>
7875
})
7976
.collect::<Result<Vec<_>, _>>()?;
8077

81-
// Temporarily set this to < 24 to avoid cb.num_witin overflow
82-
let active_rounds = 24;
83-
84-
let mut lookups = Vec::with_capacity(
85-
active_rounds
86-
* (3 * AND_LOOKUPS_PER_ROUND + 3 * XOR_LOOKUPS_PER_ROUND + RANGE_LOOKUPS_PER_ROUND),
87-
);
88-
89-
let mut aux_wits = vec![];
90-
91-
if S::HAS_LOOKUPS {
92-
dbg!(lookups.capacity());
93-
94-
for round in 0..active_rounds {
95-
for i in 0..AND_LOOKUPS_PER_ROUND {
96-
let a = cb.create_witin(|| format!("and_lookup_{round}_{i}_a"));
97-
let b = cb.create_witin(|| format!("and_lookup_{round}_{i}_b"));
98-
let c = cb.create_witin(|| format!("and_lookup_{round}_{i}_c"));
99-
cb.lookup_and_byte(a.into(), b.into(), c.into())?;
100-
lookups.extend(vec![a, b, c]);
101-
}
102-
for i in 0..XOR_LOOKUPS_PER_ROUND {
103-
let a = cb.create_witin(|| format!("xor_lookup_{round}_{i}_a"));
104-
let b = cb.create_witin(|| format!("xor_lookup_{round}_{i}_b"));
105-
let c = cb.create_witin(|| format!("xor_lookup_{round}_{i}_c"));
106-
cb.lookup_xor_byte(a.into(), b.into(), c.into())?;
107-
lookups.extend(vec![a, b, c]);
108-
}
109-
for i in 0..RANGE_LOOKUPS_PER_ROUND {
110-
let wit = cb.create_witin(|| format!("range_lookup_{round}_{i}"));
111-
cb.assert_ux::<_, _, 16>(|| "nada", wit.into())?;
112-
lookups.push(wit);
113-
}
114-
}
115-
116-
for i in 0..40144 {
117-
aux_wits.push(cb.create_witin(|| format!("aux_wit{i}")));
118-
}
119-
}
78+
// Will be filled in by GKR Instruction trait
79+
let lookups = vec![];
80+
let aux_wits = vec![];
12081

12182
Ok(LargeEcallConfig {
12283
dummy_insn,
@@ -164,6 +125,57 @@ impl<E: ExtensionField, S: SyscallSpec> Instruction<E> for LargeEcallDummy<E, S>
164125
impl<E: ExtensionField> GKRIOPInstruction<E> for LargeEcallDummy<E, KeccakSpec> {
165126
type Layout = KeccakLayout<E>;
166127

128+
fn gkr_info() -> crate::instructions::GKRinfo {
129+
GKRinfo {
130+
and_lookups: 3 * AND_LOOKUPS,
131+
xor_lookups: 3 * XOR_LOOKUPS,
132+
range_lookups: RANGE_LOOKUPS,
133+
aux_wits: 40144,
134+
}
135+
}
136+
137+
fn construct_circuit_with_gkr_iop(
138+
cb: &mut CircuitBuilder<E>,
139+
) -> Result<Self::InstructionConfig, ZKVMError> {
140+
let mut partial_config = Self::construct_circuit(cb)?;
141+
142+
assert!(partial_config.lookups.is_empty());
143+
assert!(partial_config.aux_wits.is_empty());
144+
145+
// TODO: capacity
146+
let mut lookups = vec![];
147+
let mut aux_wits = vec![];
148+
149+
for i in 0..AND_LOOKUPS {
150+
let a = cb.create_witin(|| format!("and_lookup_{i}_a"));
151+
let b = cb.create_witin(|| format!("and_lookup_{i}_b"));
152+
let c = cb.create_witin(|| format!("and_lookup_{i}_c"));
153+
cb.lookup_and_byte(a.into(), b.into(), c.into())?;
154+
lookups.extend(vec![a, b, c]);
155+
}
156+
for i in 0..XOR_LOOKUPS {
157+
let a = cb.create_witin(|| format!("xor_lookup_{i}_a"));
158+
let b = cb.create_witin(|| format!("xor_lookup_{i}_b"));
159+
let c = cb.create_witin(|| format!("xor_lookup_{i}_c"));
160+
cb.lookup_xor_byte(a.into(), b.into(), c.into())?;
161+
lookups.extend(vec![a, b, c]);
162+
}
163+
for i in 0..RANGE_LOOKUPS {
164+
let wit = cb.create_witin(|| format!("range_lookup_{i}"));
165+
cb.assert_ux::<_, _, 16>(|| "nada", wit.into())?;
166+
lookups.push(wit);
167+
}
168+
169+
for i in 0..40144 {
170+
aux_wits.push(cb.create_witin(|| format!("aux_wit{i}")));
171+
}
172+
173+
partial_config.lookups = lookups;
174+
partial_config.aux_wits = aux_wits;
175+
176+
Ok(partial_config)
177+
}
178+
167179
fn phase1_witness_from_steps(
168180
layout: &Self::Layout,
169181
steps: &[StepRecord],
@@ -195,7 +207,6 @@ impl<E: ExtensionField> GKRIOPInstruction<E> for LargeEcallDummy<E, KeccakSpec>
195207
) -> Result<(), ZKVMError> {
196208
Self::assign_instance(config, instance, lk_multiplicity, step)?;
197209

198-
let active_rounds = 24;
199210
let mut wit_iter = lookups.iter().map(|f| f.to_canonical_u64());
200211
let mut var_iter = config.lookups.iter();
201212

@@ -206,29 +217,19 @@ impl<E: ExtensionField> GKRIOPInstruction<E> for LargeEcallDummy<E, KeccakSpec>
206217
let wit = wit_iter.next().unwrap();
207218
let var = var_iter.next().unwrap();
208219
set_val!(instance, var, wit);
209-
// set_val!(instance, var, 0);
210220
wit
211221
};
212222

213-
for _round in 0..active_rounds {
214-
for _i in 0..AND_LOOKUPS_PER_ROUND {
215-
lk_multiplicity.lookup_and_byte(pop_arg(), pop_arg());
216-
// lk_multiplicity.lookup_and_byte(0, 0);
217-
// pop_arg();
218-
// pop_arg();
219-
pop_arg();
220-
}
221-
for _i in 0..XOR_LOOKUPS_PER_ROUND {
222-
lk_multiplicity.lookup_xor_byte(pop_arg(), pop_arg());
223-
// lk_multiplicity.lookup_xor_byte(0, 0);
224-
// pop_arg();
225-
// pop_arg();
226-
pop_arg();
227-
}
228-
for _i in 0..RANGE_LOOKUPS_PER_ROUND {
229-
lk_multiplicity.assert_ux::<16>(pop_arg());
230-
// pop_arg();
231-
}
223+
for _i in 0..AND_LOOKUPS {
224+
lk_multiplicity.lookup_and_byte(pop_arg(), pop_arg());
225+
pop_arg();
226+
}
227+
for _i in 0..XOR_LOOKUPS {
228+
lk_multiplicity.lookup_xor_byte(pop_arg(), pop_arg());
229+
pop_arg();
230+
}
231+
for _i in 0..RANGE_LOOKUPS {
232+
lk_multiplicity.assert_ux::<16>(pop_arg());
232233
}
233234

234235
dbg!(aux_wits.len());

ceno_zkvm/src/instructions/riscv/rv32im.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ impl<E: ExtensionField> DummyExtraConfig<E> {
526526

527527
pub fn assign_opcode_circuit(
528528
&self,
529-
cs: &mut ZKVMConstraintSystem<E>,
529+
cs: &ZKVMConstraintSystem<E>,
530530
witness: &mut ZKVMWitnesses<E>,
531531
steps: GroupedSteps,
532532
) -> Result<(), ZKVMError> {

ceno_zkvm/src/scheme/prover.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,8 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
481481
);
482482
}
483483

484-
dbg!(sel_r.len());
484+
// dbg!(sel_r);
485+
// panic!();
485486

486487
let mut sel_w = build_eq_x_r_vec(&rt_w[log2_w_count..]);
487488
if num_instances < sel_w.len() {

0 commit comments

Comments
 (0)