Skip to content

Commit fce4a2c

Browse files
committed
gkr_iop config attempt (wip)
1 parent 5e18d9a commit fce4a2c

File tree

14 files changed

+214
-21
lines changed

14 files changed

+214
-21
lines changed

Cargo.lock

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

ceno_zkvm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ serde_json.workspace = true
1919
base64 = "0.22"
2020
ceno_emul = { path = "../ceno_emul" }
2121
ff_ext = { path = "../ff_ext" }
22+
gkr_iop = { path = "../gkr_iop" }
2223
mpcs = { path = "../mpcs" }
2324
multilinear_extensions = { version = "0", path = "../multilinear_extensions" }
2425
p3 = { path = "../p3" }

ceno_zkvm/src/instructions.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,8 @@ pub trait Instruction<E: ExtensionField> {
6666
raw_witin.padding_by_strategy();
6767
Ok((raw_witin, lk_multiplicity))
6868
}
69+
70+
fn add_gkr_iop() {
71+
unimplemented!();
72+
}
6973
}

ceno_zkvm/src/instructions/riscv.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub mod jump;
1818
pub mod logic;
1919
pub mod logic_imm;
2020
pub mod mul;
21+
pub mod precompiles;
2122
pub mod shift;
2223
pub mod shift_imm;
2324
pub mod slt;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use std::{cell::RefCell, marker::PhantomData, sync::RwLock};
2+
3+
use ceno_emul::{Change, InsnKind, KECCAK_WORDS, StepRecord, WORD_SIZE};
4+
use ff_ext::ExtensionField;
5+
use itertools::Itertools;
6+
7+
use super::super::insn_base::WriteMEM;
8+
use crate::{
9+
Value,
10+
circuit_builder::CircuitBuilder,
11+
error::ZKVMError,
12+
expression::{ToExpr, WitIn},
13+
instructions::{
14+
Instruction,
15+
riscv::{constants::UInt, insn_base::WriteRD},
16+
},
17+
set_val,
18+
witness::LkMultiplicity,
19+
};
20+
21+
use gkr_iop::{
22+
ProtocolBuilder, ProtocolWitnessGenerator,
23+
chip::Chip,
24+
gkr::GKRCircuit,
25+
precompiles::{KeccakLayout, KeccakParams},
26+
};
27+
28+
pub struct KeccakF<E>(PhantomData<E>);
29+
pub struct KeccakFConfig<E> {
30+
chip: Chip,
31+
layout: KeccakLayout<E>,
32+
gkr_circuit: GKRCircuit,
33+
// phase1_wits:
34+
}
35+
36+
impl<E: ExtensionField> Instruction<E> for KeccakF<E> {
37+
type InstructionConfig = KeccakFConfig<E>;
38+
39+
fn name() -> String {
40+
format!("keccakf")
41+
}
42+
43+
fn construct_circuit(cb: &mut CircuitBuilder<E>) -> Result<Self::InstructionConfig, ZKVMError> {
44+
let params = KeccakParams {};
45+
let (layout, chip) = KeccakLayout::build(params);
46+
let gkr_circuit = chip.gkr_circuit();
47+
48+
Ok(KeccakFConfig {
49+
chip,
50+
layout,
51+
gkr_circuit,
52+
// phase1_wits:
53+
})
54+
}
55+
56+
fn assign_instance(
57+
config: &Self::InstructionConfig,
58+
instance: &mut [E::BaseField],
59+
lk_multiplicity: &mut LkMultiplicity,
60+
step: &StepRecord,
61+
) -> Result<(), ZKVMError> {
62+
// let ops = &step.syscall().expect("syscall step");
63+
64+
// // Assign instruction.
65+
// config
66+
// .dummy_insn
67+
// .assign_instance(instance, lk_multiplicity, step)?;
68+
69+
// set_val!(instance, config.start_addr, u64::from(ops.mem_ops[0].addr));
70+
71+
// // Assign registers.
72+
// for ((value, writer), op) in config.reg_writes.iter().zip_eq(&ops.reg_ops) {
73+
// value.assign_value(instance, Value::new_unchecked(op.value.after));
74+
// writer.assign_op(instance, lk_multiplicity, step.cycle(), op)?;
75+
// }
76+
77+
// // Assign memory.
78+
// for ((value, writer), op) in config.mem_writes.iter().zip_eq(&ops.mem_ops) {
79+
// set_val!(instance, value.before, op.value.before as u64);
80+
// set_val!(instance, value.after, op.value.after as u64);
81+
// writer.assign_op(instance, lk_multiplicity, step.cycle(), op)?;
82+
// }
83+
84+
Ok(())
85+
}
86+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod keccakf_circuit;

ceno_zkvm/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub mod e2e;
1616
pub mod expression;
1717
pub mod gadgets;
1818
mod keygen;
19+
pub mod precompiles;
1920
pub mod state;
2021
pub mod stats;
2122
pub mod structs;

ceno_zkvm/src/structs.rs

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@ use crate::{
22
circuit_builder::{CircuitBuilder, ConstraintSystem},
33
error::ZKVMError,
44
expression::Expression,
5-
instructions::Instruction,
5+
instructions::{
6+
Instruction,
7+
riscv::{dummy::LargeEcallDummy, precompiles::keccakf_circuit},
8+
},
69
state::StateCircuit,
710
tables::{RMMCollections, TableCircuit},
811
witness::LkMultiplicity,
912
};
10-
use ceno_emul::{CENO_PLATFORM, Platform, StepRecord};
13+
use ceno_emul::{CENO_PLATFORM, KeccakSpec, Platform, StepRecord};
1114
use ff_ext::ExtensionField;
15+
use gkr_iop::{
16+
ProtocolWitnessGenerator,
17+
precompiles::{KeccakLayout, KeccakTrace},
18+
};
1219
use itertools::{Itertools, chain};
1320
use mpcs::PolynomialCommitmentScheme;
1421
use multilinear_extensions::{
@@ -130,6 +137,13 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> VerifyingKey<E, PCS>
130137
}
131138
}
132139

140+
#[derive(Clone)]
141+
pub struct KeccakGKRIOP<E> {
142+
pub chip: gkr_iop::chip::Chip,
143+
pub layout: KeccakLayout<E>,
144+
pub circuit: gkr_iop::gkr::GKRCircuit,
145+
}
146+
133147
#[derive(Clone, Debug)]
134148
pub struct ProgramParams {
135149
pub platform: Platform,
@@ -154,6 +168,7 @@ pub struct ZKVMConstraintSystem<E: ExtensionField> {
154168
pub(crate) circuit_css: BTreeMap<String, ConstraintSystem<E>>,
155169
pub(crate) initial_global_state_expr: Expression<E>,
156170
pub(crate) finalize_global_state_expr: Expression<E>,
171+
pub keccak_gkr_iop: Option<KeccakGKRIOP<E>>,
157172
pub params: ProgramParams,
158173
}
159174

@@ -164,6 +179,7 @@ impl<E: ExtensionField> Default for ZKVMConstraintSystem<E> {
164179
initial_global_state_expr: Expression::ZERO,
165180
finalize_global_state_expr: Expression::ZERO,
166181
params: ProgramParams::default(),
182+
keccak_gkr_iop: None,
167183
}
168184
}
169185
}
@@ -175,6 +191,25 @@ impl<E: ExtensionField> ZKVMConstraintSystem<E> {
175191
..Default::default()
176192
}
177193
}
194+
195+
pub fn register_keccakf_circuit(
196+
&mut self,
197+
) -> <LargeEcallDummy<E, KeccakSpec> as Instruction<E>>::InstructionConfig {
198+
// Add GKR-IOP instance
199+
let params = gkr_iop::precompiles::KeccakParams {};
200+
let (layout, chip) = <KeccakLayout<E> as gkr_iop::ProtocolBuilder>::build(params);
201+
let circuit = chip.gkr_circuit();
202+
203+
assert!(self.keccak_gkr_iop.is_none());
204+
self.keccak_gkr_iop = Some(KeccakGKRIOP {
205+
layout,
206+
chip,
207+
circuit,
208+
});
209+
210+
self.register_opcode_circuit::<LargeEcallDummy<E, KeccakSpec>>()
211+
}
212+
178213
pub fn register_opcode_circuit<OC: Instruction<E>>(&mut self) -> OC::InstructionConfig {
179214
let mut cs = ConstraintSystem::new(|| format!("riscv_opcode/{}", OC::name()));
180215
let mut circuit_builder =
@@ -220,6 +255,14 @@ pub struct ZKVMFixedTraces<E: ExtensionField> {
220255
}
221256

222257
impl<E: ExtensionField> ZKVMFixedTraces<E> {
258+
pub fn register_keccakf_circuit(&mut self, _cs: &ZKVMConstraintSystem<E>) {
259+
assert!(
260+
self.circuit_fixed_traces
261+
.insert(LargeEcallDummy::<E, KeccakSpec>::name(), None)
262+
.is_none()
263+
);
264+
}
265+
223266
pub fn register_opcode_circuit<OC: Instruction<E>>(&mut self, _cs: &ZKVMConstraintSystem<E>) {
224267
assert!(self.circuit_fixed_traces.insert(OC::name(), None).is_none());
225268
}
@@ -244,6 +287,7 @@ impl<E: ExtensionField> ZKVMFixedTraces<E> {
244287

245288
#[derive(Default, Clone)]
246289
pub struct ZKVMWitnesses<E: ExtensionField> {
290+
keccak_trace: <KeccakLayout<E> as gkr_iop::ProtocolWitnessGenerator<E>>::Trace,
247291
witnesses_opcodes: BTreeMap<String, RowMajorMatrix<E::BaseField>>,
248292
witnesses_tables: BTreeMap<String, RMMCollections<E::BaseField>>,
249293
lk_mlts: BTreeMap<String, LkMultiplicity>,
@@ -263,6 +307,44 @@ impl<E: ExtensionField> ZKVMWitnesses<E> {
263307
self.lk_mlts.get(name)
264308
}
265309

310+
pub fn assign_keccakf_circuit(
311+
&mut self,
312+
css: &mut ZKVMConstraintSystem<E>,
313+
config: &<LargeEcallDummy<E, KeccakSpec> as Instruction<E>>::InstructionConfig,
314+
records: Vec<StepRecord>,
315+
) -> Result<(), ZKVMError> {
316+
// Ugly copy paste from assign_opcode_circuit, but we need to use the row major matrix
317+
let cs = css
318+
.get_cs(&LargeEcallDummy::<E, KeccakSpec>::name())
319+
.unwrap();
320+
let (witness, logup_multiplicity) = LargeEcallDummy::<E, KeccakSpec>::assign_instances(
321+
config,
322+
cs.num_witin as usize,
323+
records,
324+
)?;
325+
326+
// GKR-IOP-specific trace from row major witness
327+
self.keccak_trace = KeccakTrace::from(witness.clone());
328+
329+
assert!(
330+
self.witnesses_opcodes
331+
.insert(LargeEcallDummy::<E, KeccakSpec>::name(), witness)
332+
.is_none()
333+
);
334+
assert!(
335+
!self
336+
.witnesses_tables
337+
.contains_key(&LargeEcallDummy::<E, KeccakSpec>::name())
338+
);
339+
assert!(
340+
self.lk_mlts
341+
.insert(LargeEcallDummy::<E, KeccakSpec>::name(), logup_multiplicity)
342+
.is_none()
343+
);
344+
345+
Ok(())
346+
}
347+
266348
pub fn assign_opcode_circuit<OC: Instruction<E>>(
267349
&mut self,
268350
cs: &ZKVMConstraintSystem<E>,

gkr_iop/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ version.workspace = true
1212
[dependencies]
1313
ark-std.workspace = true
1414
ff_ext = { path = "../ff_ext" }
15+
witness = { path = "../witness" }
1516
itertools.workspace = true
1617
multilinear_extensions = { version = "0.1.0", path = "../multilinear_extensions" }
1718
ndarray.workspace = true

gkr_iop/src/chip/protocol.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ use super::Chip;
44

55
impl Chip {
66
/// Extract information from Chip that required in the GKR phase.
7-
pub fn gkr_circuit(&'_ self) -> GKRCircuit<'_> {
7+
pub fn gkr_circuit(&self) -> GKRCircuit {
88
GKRCircuit {
9-
layers: &self.layers,
9+
layers: self.layers.clone(),
1010
n_challenges: self.n_challenges,
1111
n_evaluations: self.n_evaluations,
12-
base_openings: &self.base_openings,
13-
ext_openings: &self.ext_openings,
12+
base_openings: self.base_openings.clone(),
13+
ext_openings: self.ext_openings.clone(),
1414
}
1515
}
1616
}

gkr_iop/src/gkr.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use ff_ext::ExtensionField;
2-
use itertools::{Itertools, chain, izip};
2+
use itertools::{chain, izip, Itertools};
33
use layer::{Layer, LayerWitness};
44
use subprotocols::{expression::Point, sumcheck::SumcheckProof};
55
use transcript::Transcript;
@@ -13,13 +13,13 @@ pub mod layer;
1313
pub mod mock;
1414

1515
#[derive(Clone, Debug)]
16-
pub struct GKRCircuit<'a> {
17-
pub layers: &'a [Layer],
16+
pub struct GKRCircuit {
17+
pub layers: Vec<Layer>,
1818

1919
pub n_challenges: usize,
2020
pub n_evaluations: usize,
21-
pub base_openings: &'a [(usize, EvalExpression)],
22-
pub ext_openings: &'a [(usize, EvalExpression)],
21+
pub base_openings: Vec<(usize, EvalExpression)>,
22+
pub ext_openings: Vec<(usize, EvalExpression)>,
2323
}
2424

2525
#[derive(Clone, Debug)]
@@ -42,7 +42,7 @@ pub struct Evaluation<E: ExtensionField> {
4242

4343
pub struct GKRClaims<Evaluation>(pub Vec<Evaluation>);
4444

45-
impl GKRCircuit<'_> {
45+
impl GKRCircuit {
4646
pub fn prove<E>(
4747
&self,
4848
circuit_wit: GKRCircuitWitness<E>,
@@ -56,7 +56,7 @@ impl GKRCircuit<'_> {
5656
let mut evaluations = out_evals.to_vec();
5757
evaluations.resize(self.n_evaluations, PointAndEval::default());
5858
let mut challenges = challenges.to_vec();
59-
let sumcheck_proofs = izip!(self.layers, circuit_wit.layers)
59+
let sumcheck_proofs = izip!(&self.layers, circuit_wit.layers)
6060
.map(|(layer, layer_wit)| {
6161
layer.prove(layer_wit, &mut evaluations, &mut challenges, transcript)
6262
})
@@ -85,7 +85,7 @@ impl GKRCircuit<'_> {
8585
let mut challenges = challenges.to_vec();
8686
let mut evaluations = out_evals.to_vec();
8787
evaluations.resize(self.n_evaluations, PointAndEval::default());
88-
for (layer, layer_proof) in izip!(self.layers, sumcheck_proofs) {
88+
for (layer, layer_proof) in izip!(self.layers.clone(), sumcheck_proofs) {
8989
layer.verify(layer_proof, &mut evaluations, &mut challenges, transcript)?;
9090
}
9191

@@ -99,7 +99,7 @@ impl GKRCircuit<'_> {
9999
evaluations: &[PointAndEval<E>],
100100
challenges: &[E],
101101
) -> Vec<Evaluation<E>> {
102-
chain!(self.base_openings, self.ext_openings)
102+
chain!(&self.base_openings, &self.ext_openings)
103103
.map(|(poly, eval)| {
104104
let poly = *poly;
105105
let PointAndEval { point, eval: value } = eval.evaluate(evaluations, challenges);

gkr_iop/src/gkr/mock.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::marker::PhantomData;
22

33
use ff_ext::ExtensionField;
4-
use itertools::{Itertools, izip};
4+
use itertools::{izip, Itertools};
55
use rand::rngs::OsRng;
66
use subprotocols::{
77
expression::{Expression, VectorType},
@@ -12,7 +12,7 @@ use thiserror::Error;
1212

1313
use crate::{evaluation::EvalExpression, utils::SliceIterator};
1414

15-
use super::{GKRCircuit, GKRCircuitWitness, layer::LayerType};
15+
use super::{layer::LayerType, GKRCircuit, GKRCircuitWitness};
1616

1717
pub struct MockProver<E: ExtensionField>(PhantomData<E>);
1818

@@ -35,7 +35,7 @@ pub enum MockProverError<F: ExtensionField> {
3535

3636
impl<E: ExtensionField> MockProver<E> {
3737
pub fn check(
38-
circuit: GKRCircuit<'_>,
38+
circuit: GKRCircuit,
3939
circuit_wit: &GKRCircuitWitness<E>,
4040
mut evaluations: Vec<VectorType<E>>,
4141
mut challenges: Vec<E>,

0 commit comments

Comments
 (0)