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