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}