@@ -2,13 +2,17 @@ use crate::{
22 circuit_builder:: { CircuitBuilder , ConstraintSystem } ,
33 error:: ZKVMError ,
44 expression:: Expression ,
5- instructions:: Instruction ,
5+ instructions:: { Instruction , riscv :: dummy :: LargeEcallDummy } ,
66 state:: StateCircuit ,
77 tables:: { RMMCollections , TableCircuit } ,
88 witness:: LkMultiplicity ,
99} ;
10- use ceno_emul:: { CENO_PLATFORM , Platform , StepRecord } ;
10+ use ceno_emul:: { CENO_PLATFORM , KeccakSpec , Platform , StepRecord } ;
1111use ff_ext:: ExtensionField ;
12+ use gkr_iop:: {
13+ ProtocolWitnessGenerator ,
14+ precompiles:: { KeccakLayout , KeccakTrace } ,
15+ } ;
1216use itertools:: { Itertools , chain} ;
1317use mpcs:: PolynomialCommitmentScheme ;
1418use multilinear_extensions:: {
@@ -130,6 +134,13 @@ impl<E: ExtensionField, PCS: PolynomialCommitmentScheme<E>> VerifyingKey<E, PCS>
130134 }
131135}
132136
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+
133144#[ derive( Clone , Debug ) ]
134145pub struct ProgramParams {
135146 pub platform : Platform ,
@@ -154,6 +165,7 @@ pub struct ZKVMConstraintSystem<E: ExtensionField> {
154165 pub ( crate ) circuit_css : BTreeMap < String , ConstraintSystem < E > > ,
155166 pub ( crate ) initial_global_state_expr : Expression < E > ,
156167 pub ( crate ) finalize_global_state_expr : Expression < E > ,
168+ pub keccak_gkr_iop : Option < KeccakGKRIOP < E > > ,
157169 pub params : ProgramParams ,
158170}
159171
@@ -164,6 +176,7 @@ impl<E: ExtensionField> Default for ZKVMConstraintSystem<E> {
164176 initial_global_state_expr : Expression :: ZERO ,
165177 finalize_global_state_expr : Expression :: ZERO ,
166178 params : ProgramParams :: default ( ) ,
179+ keccak_gkr_iop : None ,
167180 }
168181 }
169182}
@@ -175,6 +188,25 @@ impl<E: ExtensionField> ZKVMConstraintSystem<E> {
175188 ..Default :: default ( )
176189 }
177190 }
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+
178210 pub fn register_opcode_circuit < OC : Instruction < E > > ( & mut self ) -> OC :: InstructionConfig {
179211 let mut cs = ConstraintSystem :: new ( || format ! ( "riscv_opcode/{}" , OC :: name( ) ) ) ;
180212 let mut circuit_builder =
@@ -220,6 +252,14 @@ pub struct ZKVMFixedTraces<E: ExtensionField> {
220252}
221253
222254impl < 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+
223263 pub fn register_opcode_circuit < OC : Instruction < E > > ( & mut self , _cs : & ZKVMConstraintSystem < E > ) {
224264 assert ! ( self . circuit_fixed_traces. insert( OC :: name( ) , None ) . is_none( ) ) ;
225265 }
@@ -244,6 +284,7 @@ impl<E: ExtensionField> ZKVMFixedTraces<E> {
244284
245285#[ derive( Default , Clone ) ]
246286pub struct ZKVMWitnesses < E : ExtensionField > {
287+ keccak_trace : <KeccakLayout < E > as gkr_iop:: ProtocolWitnessGenerator < E > >:: Trace ,
247288 witnesses_opcodes : BTreeMap < String , RowMajorMatrix < E :: BaseField > > ,
248289 witnesses_tables : BTreeMap < String , RMMCollections < E :: BaseField > > ,
249290 lk_mlts : BTreeMap < String , LkMultiplicity > ,
@@ -263,6 +304,44 @@ impl<E: ExtensionField> ZKVMWitnesses<E> {
263304 self . lk_mlts . get ( name)
264305 }
265306
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+
266345 pub fn assign_opcode_circuit < OC : Instruction < E > > (
267346 & mut self ,
268347 cs : & ZKVMConstraintSystem < E > ,
0 commit comments