@@ -2,13 +2,17 @@ use crate::{
2
2
circuit_builder:: { CircuitBuilder , ConstraintSystem } ,
3
3
error:: ZKVMError ,
4
4
expression:: Expression ,
5
- instructions:: Instruction ,
5
+ instructions:: { Instruction , riscv :: dummy :: LargeEcallDummy } ,
6
6
state:: StateCircuit ,
7
7
tables:: { RMMCollections , TableCircuit } ,
8
8
witness:: LkMultiplicity ,
9
9
} ;
10
- use ceno_emul:: { CENO_PLATFORM , Platform , StepRecord } ;
10
+ use ceno_emul:: { CENO_PLATFORM , KeccakSpec , Platform , StepRecord } ;
11
11
use ff_ext:: ExtensionField ;
12
+ use gkr_iop:: {
13
+ ProtocolWitnessGenerator ,
14
+ precompiles:: { KeccakLayout , KeccakTrace } ,
15
+ } ;
12
16
use itertools:: { Itertools , chain} ;
13
17
use mpcs:: PolynomialCommitmentScheme ;
14
18
use multilinear_extensions:: {
@@ -130,6 +134,13 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> VerifyingKey<E, PCS>
130
134
}
131
135
}
132
136
137
+ #[ derive( Clone ) ]
138
+ pub struct KeccakGKRIOP < E > {
139
+ pub chip : gkr_iop:: chip:: Chip ,
140
+ pub layout : KeccakLayout < E > ,
141
+ pub circuit : gkr_iop:: gkr:: GKRCircuit ,
142
+ }
143
+
133
144
#[ derive( Clone , Debug ) ]
134
145
pub struct ProgramParams {
135
146
pub platform : Platform ,
@@ -154,6 +165,7 @@ pub struct ZKVMConstraintSystem<E: ExtensionField> {
154
165
pub ( crate ) circuit_css : BTreeMap < String , ConstraintSystem < E > > ,
155
166
pub ( crate ) initial_global_state_expr : Expression < E > ,
156
167
pub ( crate ) finalize_global_state_expr : Expression < E > ,
168
+ pub keccak_gkr_iop : Option < KeccakGKRIOP < E > > ,
157
169
pub params : ProgramParams ,
158
170
}
159
171
@@ -164,6 +176,7 @@ impl<E: ExtensionField> Default for ZKVMConstraintSystem<E> {
164
176
initial_global_state_expr : Expression :: ZERO ,
165
177
finalize_global_state_expr : Expression :: ZERO ,
166
178
params : ProgramParams :: default ( ) ,
179
+ keccak_gkr_iop : None ,
167
180
}
168
181
}
169
182
}
@@ -175,6 +188,25 @@ impl<E: ExtensionField> ZKVMConstraintSystem<E> {
175
188
..Default :: default ( )
176
189
}
177
190
}
191
+
192
+ pub fn register_keccakf_circuit (
193
+ & mut self ,
194
+ ) -> <LargeEcallDummy < E , KeccakSpec > as Instruction < E > >:: InstructionConfig {
195
+ // Add GKR-IOP instance
196
+ let params = gkr_iop:: precompiles:: KeccakParams { } ;
197
+ let ( layout, chip) = <KeccakLayout < E > as gkr_iop:: ProtocolBuilder >:: build ( params) ;
198
+ let circuit = chip. gkr_circuit ( ) ;
199
+
200
+ assert ! ( self . keccak_gkr_iop. is_none( ) ) ;
201
+ self . keccak_gkr_iop = Some ( KeccakGKRIOP {
202
+ layout,
203
+ chip,
204
+ circuit,
205
+ } ) ;
206
+
207
+ self . register_opcode_circuit :: < LargeEcallDummy < E , KeccakSpec > > ( )
208
+ }
209
+
178
210
pub fn register_opcode_circuit < OC : Instruction < E > > ( & mut self ) -> OC :: InstructionConfig {
179
211
let mut cs = ConstraintSystem :: new ( || format ! ( "riscv_opcode/{}" , OC :: name( ) ) ) ;
180
212
let mut circuit_builder =
@@ -220,6 +252,14 @@ pub struct ZKVMFixedTraces<E: ExtensionField> {
220
252
}
221
253
222
254
impl < E : ExtensionField > ZKVMFixedTraces < E > {
255
+ pub fn register_keccakf_circuit ( & mut self , _cs : & ZKVMConstraintSystem < E > ) {
256
+ assert ! (
257
+ self . circuit_fixed_traces
258
+ . insert( LargeEcallDummy :: <E , KeccakSpec >:: name( ) , None )
259
+ . is_none( )
260
+ ) ;
261
+ }
262
+
223
263
pub fn register_opcode_circuit < OC : Instruction < E > > ( & mut self , _cs : & ZKVMConstraintSystem < E > ) {
224
264
assert ! ( self . circuit_fixed_traces. insert( OC :: name( ) , None ) . is_none( ) ) ;
225
265
}
@@ -244,6 +284,7 @@ impl<E: ExtensionField> ZKVMFixedTraces<E> {
244
284
245
285
#[ derive( Default , Clone ) ]
246
286
pub struct ZKVMWitnesses < E : ExtensionField > {
287
+ keccak_trace : <KeccakLayout < E > as gkr_iop:: ProtocolWitnessGenerator < E > >:: Trace ,
247
288
witnesses_opcodes : BTreeMap < String , RowMajorMatrix < E :: BaseField > > ,
248
289
witnesses_tables : BTreeMap < String , RMMCollections < E :: BaseField > > ,
249
290
lk_mlts : BTreeMap < String , LkMultiplicity > ,
@@ -263,6 +304,44 @@ impl<E: ExtensionField> ZKVMWitnesses<E> {
263
304
self . lk_mlts . get ( name)
264
305
}
265
306
307
+ pub fn assign_keccakf_circuit (
308
+ & mut self ,
309
+ css : & mut ZKVMConstraintSystem < E > ,
310
+ config : & <LargeEcallDummy < E , KeccakSpec > as Instruction < E > >:: InstructionConfig ,
311
+ records : Vec < StepRecord > ,
312
+ ) -> Result < ( ) , ZKVMError > {
313
+ // Ugly copy paste from assign_opcode_circuit, but we need to use the row major matrix
314
+ let cs = css
315
+ . get_cs ( & LargeEcallDummy :: < E , KeccakSpec > :: name ( ) )
316
+ . unwrap ( ) ;
317
+ let ( witness, logup_multiplicity) = LargeEcallDummy :: < E , KeccakSpec > :: assign_instances (
318
+ config,
319
+ cs. num_witin as usize ,
320
+ records,
321
+ ) ?;
322
+
323
+ // GKR-IOP-specific trace from row major witness
324
+ self . keccak_trace = KeccakTrace :: from ( witness. clone ( ) ) ;
325
+
326
+ assert ! (
327
+ self . witnesses_opcodes
328
+ . insert( LargeEcallDummy :: <E , KeccakSpec >:: name( ) , witness)
329
+ . is_none( )
330
+ ) ;
331
+ assert ! (
332
+ !self
333
+ . witnesses_tables
334
+ . contains_key( & LargeEcallDummy :: <E , KeccakSpec >:: name( ) )
335
+ ) ;
336
+ assert ! (
337
+ self . lk_mlts
338
+ . insert( LargeEcallDummy :: <E , KeccakSpec >:: name( ) , logup_multiplicity)
339
+ . is_none( )
340
+ ) ;
341
+
342
+ Ok ( ( ) )
343
+ }
344
+
266
345
pub fn assign_opcode_circuit < OC : Instruction < E > > (
267
346
& mut self ,
268
347
cs : & ZKVMConstraintSystem < E > ,
0 commit comments