openvm_keccak256_circuit/
extension.rs
1use derive_more::derive::From;
2use openvm_circuit::{
3 arch::{
4 SystemConfig, SystemPort, VmExtension, VmInventory, VmInventoryBuilder, VmInventoryError,
5 },
6 system::phantom::PhantomChip,
7};
8use openvm_circuit_derive::{AnyEnum, InstructionExecutor, VmConfig};
9use openvm_circuit_primitives::bitwise_op_lookup::BitwiseOperationLookupBus;
10use openvm_circuit_primitives_derive::{Chip, ChipUsageGetter};
11use openvm_instructions::*;
12use openvm_rv32im_circuit::{
13 Rv32I, Rv32IExecutor, Rv32IPeriphery, Rv32Io, Rv32IoExecutor, Rv32IoPeriphery, Rv32M,
14 Rv32MExecutor, Rv32MPeriphery,
15};
16use openvm_stark_backend::p3_field::PrimeField32;
17use serde::{Deserialize, Serialize};
18use strum::IntoEnumIterator;
19
20use crate::*;
21
22#[derive(Clone, Debug, VmConfig, derive_new::new, Serialize, Deserialize)]
23pub struct Keccak256Rv32Config {
24 #[system]
25 pub system: SystemConfig,
26 #[extension]
27 pub rv32i: Rv32I,
28 #[extension]
29 pub rv32m: Rv32M,
30 #[extension]
31 pub io: Rv32Io,
32 #[extension]
33 pub keccak: Keccak256,
34}
35
36impl Default for Keccak256Rv32Config {
37 fn default() -> Self {
38 Self {
39 system: SystemConfig::default().with_continuations(),
40 rv32i: Rv32I,
41 rv32m: Rv32M::default(),
42 io: Rv32Io,
43 keccak: Keccak256,
44 }
45 }
46}
47
48#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
49pub struct Keccak256;
50
51#[derive(ChipUsageGetter, Chip, InstructionExecutor, From, AnyEnum)]
52pub enum Keccak256Executor<F: PrimeField32> {
53 Keccak256(KeccakVmChip<F>),
54}
55
56#[derive(From, ChipUsageGetter, Chip, AnyEnum)]
57pub enum Keccak256Periphery<F: PrimeField32> {
58 BitwiseOperationLookup(SharedBitwiseOperationLookupChip<8>),
59 Phantom(PhantomChip<F>),
60}
61
62impl<F: PrimeField32> VmExtension<F> for Keccak256 {
63 type Executor = Keccak256Executor<F>;
64 type Periphery = Keccak256Periphery<F>;
65
66 fn build(
67 &self,
68 builder: &mut VmInventoryBuilder<F>,
69 ) -> Result<VmInventory<Self::Executor, Self::Periphery>, VmInventoryError> {
70 let mut inventory = VmInventory::new();
71 let SystemPort {
72 execution_bus,
73 program_bus,
74 memory_bridge,
75 } = builder.system_port();
76 let bitwise_lu_chip = if let Some(&chip) = builder
77 .find_chip::<SharedBitwiseOperationLookupChip<8>>()
78 .first()
79 {
80 chip.clone()
81 } else {
82 let bitwise_lu_bus = BitwiseOperationLookupBus::new(builder.new_bus_idx());
83 let chip = SharedBitwiseOperationLookupChip::new(bitwise_lu_bus);
84 inventory.add_periphery_chip(chip.clone());
85 chip
86 };
87 let offline_memory = builder.system_base().offline_memory();
88 let address_bits = builder.system_config().memory_config.pointer_max_bits;
89
90 let keccak_chip = KeccakVmChip::new(
91 execution_bus,
92 program_bus,
93 memory_bridge,
94 address_bits,
95 bitwise_lu_chip,
96 Rv32KeccakOpcode::CLASS_OFFSET,
97 offline_memory,
98 );
99 inventory.add_executor(
100 keccak_chip,
101 Rv32KeccakOpcode::iter().map(|x| x.global_opcode()),
102 )?;
103
104 Ok(inventory)
105 }
106}