Skip to content

Commit b8e8476

Browse files
committed
wip
1 parent 639ee44 commit b8e8476

27 files changed

+302
-480
lines changed

ceno_host/tests/test_elf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ fn test_ceno_rt_keccak() -> Result<()> {
231231
let steps = run(&mut state)?;
232232

233233
// Expect the program to have written successive states between Keccak permutations.
234-
const ITERATIONS: usize = 3;
234+
const ITERATIONS: usize = 4;
235235
let keccak_outs = sample_keccak_f(ITERATIONS);
236236

237237
let all_messages = read_all_messages(&state);

ceno_zkvm/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ gkr_iop = { path = "../gkr_iop" }
2323
mpcs = { path = "../mpcs" }
2424
multilinear_extensions = { version = "0", path = "../multilinear_extensions" }
2525
p3 = { path = "../p3" }
26-
subprotocols = {path = "../subprotocols"}
26+
subprotocols = { path = "../subprotocols" }
2727
sumcheck = { version = "0", path = "../sumcheck" }
2828
transcript = { path = "../transcript" }
2929
witness = { path = "../witness" }

ceno_zkvm/src/instructions.rs

+37-19
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
use ceno_emul::StepRecord;
22
use ff_ext::ExtensionField;
3-
use gkr_iop::{
4-
ProtocolBuilder, ProtocolWitnessGenerator,
5-
gkr::{GKRCircuitWitness, layer::LayerWitness},
6-
precompiles::KeccakLayout,
7-
};
3+
use gkr_iop::{ProtocolBuilder, ProtocolWitnessGenerator, gkr::GKRCircuitWitness};
84
use itertools::Itertools;
95
use multilinear_extensions::util::max_usable_threads;
106
use rayon::{
@@ -87,31 +83,34 @@ impl GKRinfo {
8783
}
8884
}
8985

86+
// Trait that should be implemented by opcodes which use the
87+
// GKR-IOP prover. Presently, such opcodes should also implement
88+
// the Instruction trait and in general methods of GKRIOPInstruction
89+
// will call corresponding methods of Instruction and do something extra
90+
// with respect to syncing state between GKR-IOP and old-style circuits/witnesses
9091
pub trait GKRIOPInstruction<E: ExtensionField>
9192
where
9293
Self: Instruction<E>,
9394
{
9495
type Layout: ProtocolWitnessGenerator<E> + ProtocolBuilder;
9596

97+
/// Similar to Instruction::construct_circuit; generally
98+
/// meant to extend InstructionConfig with GKR-specific
99+
/// fields
100+
#[allow(unused_variables)]
96101
fn construct_circuit_with_gkr_iop(
97102
cb: &mut CircuitBuilder<E>,
98103
) -> Result<Self::InstructionConfig, ZKVMError> {
99104
unimplemented!();
100105
}
101106

102-
// Returns index of `i-th` GKR-IOP output-eval in PCS
103-
fn output_map(i: usize) -> usize {
104-
unimplemented!();
105-
}
106-
107+
/// Should generate phase1 witness for GKR from step records
107108
fn phase1_witness_from_steps(
108109
layout: &Self::Layout,
109110
steps: &[StepRecord],
110111
) -> Vec<Vec<E::BaseField>>;
111112

112-
// Number of lookup arguments used by this GKR proof
113-
fn gkr_info() -> GKRinfo;
114-
113+
/// Similar to Instruction::assign_instance, but with access to GKR lookups and wits
115114
fn assign_instance_with_gkr_iop(
116115
config: &Self::InstructionConfig,
117116
instance: &mut [E::BaseField],
@@ -121,6 +120,8 @@ where
121120
aux_wits: &[E::BaseField],
122121
) -> Result<(), ZKVMError>;
123122

123+
/// Similar to Instruction::assign_instances, but with access to the GKR layout.
124+
#[allow(clippy::type_complexity)]
124125
fn assign_instances_with_gkr_iop(
125126
config: &Self::InstructionConfig,
126127
num_witin: usize,
@@ -146,10 +147,8 @@ where
146147
RowMajorMatrix::<E::BaseField>::new(steps.len(), num_witin, Self::padding_strategy());
147148
let raw_witin_iter = raw_witin.par_batch_iter_mut(num_instance_per_batch);
148149

149-
let gkr_witness = gkr_layout.gkr_witness(
150-
&Self::phase1_witness_from_steps(gkr_layout, &steps),
151-
&vec![],
152-
);
150+
let gkr_witness =
151+
gkr_layout.gkr_witness(&Self::phase1_witness_from_steps(gkr_layout, &steps), &[]);
153152

154153
let (lookups, aux_wits) = {
155154
// Extract lookups and auxiliary witnesses from GKR protocol
@@ -159,7 +158,10 @@ where
159158
let mut lookups = vec![vec![]; steps.len()];
160159
let last_layer = gkr_witness.layers.last().unwrap().bases.clone();
161160
let len = last_layer.len();
162-
for witness in last_layer[len - Self::gkr_info().lookup_total()..].iter() {
161+
for witness in last_layer
162+
.iter()
163+
.skip(len - Self::gkr_info().lookup_total())
164+
{
163165
for i in 0..witness.len() {
164166
lookups[i].push(witness[i]);
165167
}
@@ -194,7 +196,6 @@ where
194196
.chunks_mut(num_witin)
195197
.zip(steps)
196198
.map(|(instance, (i, step))| {
197-
// dbg!(i, step);
198199
Self::assign_instance_with_gkr_iop(
199200
config,
200201
instance,
@@ -211,4 +212,21 @@ where
211212
raw_witin.padding_by_strategy();
212213
Ok((raw_witin, gkr_witness, lk_multiplicity))
213214
}
215+
216+
/// Lookup and witness counts used by GKR proof
217+
fn gkr_info() -> GKRinfo;
218+
219+
/// Returns corresponding column in RMM for the i-th
220+
/// output evaluation of the GKR proof
221+
#[allow(unused_variables)]
222+
fn output_evals_map(i: usize) -> usize {
223+
unimplemented!();
224+
}
225+
226+
/// Returns corresponding column in RMM for the i-th
227+
/// witness of the GKR proof
228+
#[allow(unused_variables)]
229+
fn witness_map(i: usize) -> usize {
230+
unimplemented!();
231+
}
214232
}

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

+1-10
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ impl<E: ExtensionField, S: SyscallSpec> Instruction<E> for LargeEcallDummy<E, S>
112112

113113
// Assign memory.
114114
for ((addr, value, writer), op) in config.mem_writes.iter().zip_eq(&ops.mem_ops) {
115-
dbg!(&op.value.before);
116115
set_val!(instance, value.before, op.value.before as u64);
117116
set_val!(instance, value.after, op.value.after as u64);
118117
set_val!(instance, addr, u64::from(op.addr));
@@ -174,14 +173,10 @@ impl<E: ExtensionField> GKRIOPInstruction<E> for LargeEcallDummy<E, KeccakSpec>
174173
partial_config.lookups = lookups;
175174
partial_config.aux_wits = aux_wits;
176175

177-
dbg!(&partial_config.mem_writes[0].1.after);
178-
dbg!(&partial_config.mem_writes[1].1.before);
179-
dbg!(&partial_config.lookups[0]);
180-
181176
Ok(partial_config)
182177
}
183178

184-
fn output_map(i: usize) -> usize {
179+
fn output_evals_map(i: usize) -> usize {
185180
if i < 50 {
186181
27 + 6 * i
187182
} else if i < 100 {
@@ -225,9 +220,6 @@ impl<E: ExtensionField> GKRIOPInstruction<E> for LargeEcallDummy<E, KeccakSpec>
225220
let mut wit_iter = lookups.iter().map(|f| f.to_canonical_u64());
226221
let mut var_iter = config.lookups.iter();
227222

228-
dbg!(wit_iter.clone().count());
229-
dbg!(var_iter.clone().count());
230-
231223
let mut pop_arg = || -> u64 {
232224
let wit = wit_iter.next().unwrap();
233225
let var = var_iter.next().unwrap();
@@ -247,7 +239,6 @@ impl<E: ExtensionField> GKRIOPInstruction<E> for LargeEcallDummy<E, KeccakSpec>
247239
lk_multiplicity.assert_ux::<16>(pop_arg());
248240
}
249241

250-
dbg!(aux_wits.len());
251242
for (aux_wit_var, aux_wit) in zip_eq(config.aux_wits.iter(), aux_wits) {
252243
set_val!(instance, aux_wit_var, (aux_wit.to_canonical_u64()));
253244
}

ceno_zkvm/src/instructions/riscv/rv32im.rs

-8
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,6 @@ pub struct DummyExtraConfig<E: ExtensionField> {
466466
impl<E: ExtensionField> DummyExtraConfig<E> {
467467
pub fn construct_circuits(cs: &mut ZKVMConstraintSystem<E>) -> Self {
468468
let ecall_config = cs.register_opcode_circuit::<EcallDummy<E>>();
469-
// let keccak_config = cs.register_opcode_circuit::<LargeEcallDummy<E, KeccakSpec>>();
470469
let keccak_config = cs.register_keccakf_circuit();
471470
let secp256k1_add_config =
472471
cs.register_opcode_circuit::<LargeEcallDummy<E, Secp256k1AddSpec>>();
@@ -511,7 +510,6 @@ impl<E: ExtensionField> DummyExtraConfig<E> {
511510
) {
512511
fixed.register_opcode_circuit::<EcallDummy<E>>(cs);
513512
fixed.register_keccakf_circuit(cs);
514-
// fixed.register_opcode_circuit::<LargeEcallDummy<E, KeccakSpec>>(cs);
515513
fixed.register_opcode_circuit::<LargeEcallDummy<E, Secp256k1AddSpec>>(cs);
516514
fixed.register_opcode_circuit::<LargeEcallDummy<E, Secp256k1DecompressSpec>>(cs);
517515
fixed.register_opcode_circuit::<LargeEcallDummy<E, Secp256k1DoubleSpec>>(cs);
@@ -566,12 +564,6 @@ impl<E: ExtensionField> DummyExtraConfig<E> {
566564

567565
witness.assign_keccakf_circuit(cs, &self.keccak_config, keccak_steps)?;
568566

569-
// witness.assign_opcode_circuit::<LargeEcallDummy<E, KeccakSpec>>(
570-
// cs,
571-
// &self.keccak_config,
572-
// keccak_steps,
573-
//)?;
574-
575567
witness.assign_opcode_circuit::<LargeEcallDummy<E, Secp256k1AddSpec>>(
576568
cs,
577569
&self.secp256k1_add_config,

ceno_zkvm/src/keygen.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::{
22
error::ZKVMError,
3-
instructions::riscv::dummy::LargeEcallDummy,
43
structs::{ZKVMConstraintSystem, ZKVMFixedTraces, ZKVMProvingKey},
54
};
65
use ff_ext::ExtensionField;

ceno_zkvm/src/scheme.rs

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub struct ZKVMOpcodeProof<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>
5757
}
5858

5959
#[derive(Clone, Serialize)]
60+
// WARN/TODO: depends on serde's `arc` feature which might not behave correctly
6061
pub struct GKROpcodeProof<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> {
6162
output_evals: Vec<E>,
6263
prover_output: GKRProverOutput<E, Evaluation<E>>,

ceno_zkvm/src/scheme/prover.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{
77
sync::Arc,
88
};
99

10-
use itertools::{Itertools, chain, enumerate, izip};
10+
use itertools::{Itertools, enumerate, izip};
1111
use mpcs::PolynomialCommitmentScheme;
1212
use multilinear_extensions::{
1313
mle::{IntoMLE, MultilinearExtension},
@@ -27,10 +27,7 @@ use witness::{RowMajorMatrix, next_pow2_instance_padding};
2727
use crate::{
2828
error::ZKVMError,
2929
expression::Instance,
30-
instructions::{
31-
Instruction,
32-
riscv::{dummy::LargeEcallDummy, ecall::EcallDummy},
33-
},
30+
instructions::{Instruction, riscv::dummy::LargeEcallDummy},
3431
scheme::{
3532
GKROpcodeProof,
3633
constants::{MAINCONSTRAIN_SUMCHECK_BATCH_SIZE, NUM_FANIN, NUM_FANIN_LOGUP},
@@ -261,6 +258,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
261258
/// 1: witness layer inferring from input -> output
262259
/// 2: proof (sumcheck reduce) from output to input
263260
#[allow(clippy::too_many_arguments)]
261+
#[allow(clippy::type_complexity)]
264262
#[tracing::instrument(skip_all, name = "create_opcode_proof", fields(circuit_name=name,profiling_2), level="trace")]
265263
pub fn create_opcode_proof(
266264
&self,
@@ -695,6 +693,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
695693
opening_dur.elapsed(),
696694
);
697695
exit_span!(pcs_open_span);
696+
698697
let wits_commit = PCS::get_pure_commitment(&wits_commit);
699698

700699
let gkr_opcode_proof = if let Some((gkr_iop_pk, gkr_wit)) = gkr_iop_pk {
@@ -711,25 +710,26 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMProver<E, PCS> {
711710
.iter()
712711
.map(|base| PointAndEval {
713712
point: point.clone(),
714-
eval: subprotocols::utils::evaluate_mle_ext(&base, &point),
713+
eval: subprotocols::utils::evaluate_mle_ext(base, &point),
715714
})
716715
.collect_vec();
717716

718-
// out_evals from point and output polynomials instead of *_records which is combined
719-
720717
let prover_output = gkr_circuit
721-
.prove(gkr_wit, &out_evals, &vec![], transcript)
718+
.prove(gkr_wit, &out_evals, &[], transcript)
722719
.expect("Failed to prove phase");
723720
// unimplemented!("cannot fully handle GKRIOP component yet")
724721

725722
dbg!(&prover_output.opening_evaluations.len());
723+
let _gkr_open_point = prover_output.opening_evaluations[0].point.clone();
724+
// TODO: open polynomials for GKR proof
725+
726726
let output_evals = out_evals.into_iter().map(|pae| pae.eval).collect_vec();
727727

728728
Some(GKROpcodeProof {
729729
output_evals,
730730
prover_output,
731731
circuit: gkr_circuit,
732-
_marker: PhantomData::default(),
732+
_marker: PhantomData,
733733
})
734734
} else {
735735
None

ceno_zkvm/src/scheme/verifier.rs

+3-15
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,6 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMVerifier<E, PCS>
276276
cs.lk_expressions.len(),
277277
);
278278

279-
// dbg!(&cs.r_expressions);
280-
281279
let (log2_r_count, log2_w_count, log2_lk_count) = (
282280
ceil_log2(r_counts_per_instance),
283281
ceil_log2(w_counts_per_instance),
@@ -332,8 +330,6 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMVerifier<E, PCS>
332330
logup_q_evals[0].point.clone(),
333331
);
334332

335-
// dbg!(&rt_r, &rt_w, &rt_lk);
336-
337333
let alpha_pow = get_challenge_pows(
338334
MAINCONSTRAIN_SUMCHECK_BATCH_SIZE + cs.assert_zero_sumcheck_expressions.len(),
339335
transcript,
@@ -422,26 +418,18 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMVerifier<E, PCS>
422418
for (i, gkr_out_eval) in gkr_iop.output_evals.iter().enumerate() {
423419
assert_eq!(
424420
*gkr_out_eval,
425-
proof.wits_in_evals[LargeEcallDummy::<E, KeccakSpec>::output_map(i)],
421+
proof.wits_in_evals[LargeEcallDummy::<E, KeccakSpec>::output_evals_map(i)],
426422
"{i}"
427423
);
428-
if *gkr_out_eval
429-
== proof.wits_in_evals[LargeEcallDummy::<E, KeccakSpec>::output_map(i)]
430-
{
431-
matches += 1;
432-
} else {
433-
dbg!(i);
434-
}
435424
}
436-
dbg!(matches);
437425
// Verify GKR proof
438426
let point = Arc::new(input_opening_point.clone());
439427
let out_evals = gkr_iop
440428
.output_evals
441429
.iter()
442430
.map(|eval| gkr_iop::evaluation::PointAndEval {
443431
point: point.clone(),
444-
eval: eval.clone(),
432+
eval: *eval,
445433
})
446434
.collect_vec();
447435

@@ -450,7 +438,7 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> ZKVMVerifier<E, PCS>
450438
.verify(
451439
gkr_iop.prover_output.gkr_proof.clone(),
452440
&out_evals,
453-
&vec![],
441+
&[],
454442
transcript,
455443
)
456444
.expect("GKR-IOP verify failure");

ceno_zkvm/src/structs.rs

-8
Original file line numberDiff line numberDiff line change
@@ -374,12 +374,10 @@ impl<E: ExtensionField> ZKVMWitnesses<E> {
374374

375375
pub fn assign_keccakf_circuit(
376376
&mut self,
377-
// TODO: do without mutability requirement
378377
css: &ZKVMConstraintSystem<E>,
379378
config: &<LargeEcallDummy<E, KeccakSpec> as Instruction<E>>::InstructionConfig,
380379
records: Vec<StepRecord>,
381380
) -> Result<(), ZKVMError> {
382-
// Ugly copy paste from assign_opcode_circuit, but we need to use the row major matrix
383381
let cs = css
384382
.get_cs(&LargeEcallDummy::<E, KeccakSpec>::name())
385383
.unwrap();
@@ -392,12 +390,6 @@ impl<E: ExtensionField> ZKVMWitnesses<E> {
392390
)?;
393391
self.keccak_gkr_wit = gkr_witness;
394392

395-
// // Intercept row-major matrix, convert into KeccakTrace and obtain phase1_wit
396-
// self.keccak_phase1wit = css
397-
// .keccak_gkr_iop
398-
// .layout
399-
// .phase1_witness(KeccakTrace::from(witness.clone()));
400-
401393
assert!(
402394
self.witnesses_opcodes
403395
.insert(LargeEcallDummy::<E, KeccakSpec>::name(), witness)

examples/examples/ceno_rt_keccak.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ extern crate ceno_rt;
66
use ceno_rt::{info_out, syscalls::syscall_keccak_permute};
77
use core::slice;
88

9-
const ITERATIONS: usize = 2;
9+
const ITERATIONS: usize = 4;
1010

1111
fn main() {
1212
let mut state = [0_u64; 25];
1313

1414
for _ in 0..ITERATIONS {
1515
syscall_keccak_permute(&mut state);
16-
// log_state(&state);
16+
log_state(&state);
1717
}
1818
}
1919

0 commit comments

Comments
 (0)