openvm_circuit/system/poseidon2/
mod.rs1use std::sync::Arc;
12
13use openvm_circuit_primitives::Chip;
14use openvm_poseidon2_air::{Poseidon2Config, Poseidon2SubAir};
15use openvm_stark_backend::{
16 config::{StarkGenericConfig, Val},
17 interaction::{BusIndex, LookupBus},
18 p3_field::{Field, PrimeField32},
19 AirRef, ChipUsageGetter,
20};
21
22#[cfg(test)]
23pub mod tests;
24
25pub mod air;
26mod chip;
27pub use chip::*;
28
29use crate::{
30 arch::hasher::{Hasher, HasherChip},
31 system::poseidon2::air::Poseidon2PeripheryAir,
32};
33pub mod columns;
34pub mod trace;
35
36pub const PERIPHERY_POSEIDON2_WIDTH: usize = 16;
37pub const PERIPHERY_POSEIDON2_CHUNK_SIZE: usize = 8;
38
39#[derive(Chip)]
40#[chip(where = "F: Field")]
41pub enum Poseidon2PeripheryChip<F: Field> {
42 Register0(Poseidon2PeripheryBaseChip<F, 0>),
43 Register1(Poseidon2PeripheryBaseChip<F, 1>),
44}
45impl<F: PrimeField32> Poseidon2PeripheryChip<F> {
46 pub fn new(
47 poseidon2_config: Poseidon2Config<F>,
48 bus_idx: BusIndex,
49 max_constraint_degree: usize,
50 ) -> Self {
51 if max_constraint_degree >= 7 {
52 Self::Register0(Poseidon2PeripheryBaseChip::new(poseidon2_config, bus_idx))
53 } else {
54 Self::Register1(Poseidon2PeripheryBaseChip::new(poseidon2_config, bus_idx))
55 }
56 }
57}
58
59pub fn new_poseidon2_periphery_air<SC: StarkGenericConfig>(
60 poseidon2_config: Poseidon2Config<Val<SC>>,
61 direct_bus: LookupBus,
62 max_constraint_degree: usize,
63) -> AirRef<SC> {
64 if max_constraint_degree >= 7 {
65 Arc::new(Poseidon2PeripheryAir::<Val<SC>, 0>::new(
66 Arc::new(Poseidon2SubAir::new(poseidon2_config.constants.into())),
67 direct_bus,
68 ))
69 } else {
70 Arc::new(Poseidon2PeripheryAir::<Val<SC>, 1>::new(
71 Arc::new(Poseidon2SubAir::new(poseidon2_config.constants.into())),
72 direct_bus,
73 ))
74 }
75}
76
77impl<F: PrimeField32> ChipUsageGetter for Poseidon2PeripheryChip<F> {
78 fn air_name(&self) -> String {
79 match self {
80 Poseidon2PeripheryChip::Register0(chip) => chip.air_name(),
81 Poseidon2PeripheryChip::Register1(chip) => chip.air_name(),
82 }
83 }
84
85 fn current_trace_height(&self) -> usize {
86 match self {
87 Poseidon2PeripheryChip::Register0(chip) => chip.current_trace_height(),
88 Poseidon2PeripheryChip::Register1(chip) => chip.current_trace_height(),
89 }
90 }
91
92 fn trace_width(&self) -> usize {
93 match self {
94 Poseidon2PeripheryChip::Register0(chip) => chip.trace_width(),
95 Poseidon2PeripheryChip::Register1(chip) => chip.trace_width(),
96 }
97 }
98}
99
100impl<F: PrimeField32> Hasher<PERIPHERY_POSEIDON2_CHUNK_SIZE, F> for Poseidon2PeripheryChip<F> {
101 fn compress(
102 &self,
103 lhs: &[F; PERIPHERY_POSEIDON2_CHUNK_SIZE],
104 rhs: &[F; PERIPHERY_POSEIDON2_CHUNK_SIZE],
105 ) -> [F; PERIPHERY_POSEIDON2_CHUNK_SIZE] {
106 match self {
107 Poseidon2PeripheryChip::Register0(chip) => chip.compress(lhs, rhs),
108 Poseidon2PeripheryChip::Register1(chip) => chip.compress(lhs, rhs),
109 }
110 }
111}
112
113impl<F: PrimeField32> HasherChip<PERIPHERY_POSEIDON2_CHUNK_SIZE, F> for Poseidon2PeripheryChip<F> {
114 fn compress_and_record(
115 &self,
116 lhs: &[F; PERIPHERY_POSEIDON2_CHUNK_SIZE],
117 rhs: &[F; PERIPHERY_POSEIDON2_CHUNK_SIZE],
118 ) -> [F; PERIPHERY_POSEIDON2_CHUNK_SIZE] {
119 match self {
120 Poseidon2PeripheryChip::Register0(chip) => chip.compress_and_record(lhs, rhs),
121 Poseidon2PeripheryChip::Register1(chip) => chip.compress_and_record(lhs, rhs),
122 }
123 }
124}