halo2_base/poseidon/
mod.rs

1use crate::{
2    gates::{RangeChip, RangeInstructions},
3    poseidon::hasher::{spec::OptimizedPoseidonSpec, PoseidonHasher},
4    safe_types::{FixLenBytes, VarLenBytes, VarLenBytesVec},
5    utils::{BigPrimeField, ScalarField},
6    AssignedValue, Context,
7};
8
9use itertools::Itertools;
10
11/// Module for Poseidon hasher
12pub mod hasher;
13
14/// Chip for Poseidon hash.
15pub struct PoseidonChip<'a, F: ScalarField, const T: usize, const RATE: usize> {
16    range_chip: &'a RangeChip<F>,
17    hasher: PoseidonHasher<F, T, RATE>,
18}
19
20impl<'a, F: ScalarField, const T: usize, const RATE: usize> PoseidonChip<'a, F, T, RATE> {
21    /// Create a new PoseidonChip.
22    pub fn new(
23        ctx: &mut Context<F>,
24        spec: OptimizedPoseidonSpec<F, T, RATE>,
25        range_chip: &'a RangeChip<F>,
26    ) -> Self {
27        let mut hasher = PoseidonHasher::new(spec);
28        hasher.initialize_consts(ctx, range_chip.gate());
29        Self { range_chip, hasher }
30    }
31}
32
33/// Trait for Poseidon instructions
34pub trait PoseidonInstructions<F: ScalarField> {
35    /// Return hash of a [VarLenBytes]
36    fn hash_var_len_bytes<const MAX_LEN: usize>(
37        &self,
38        ctx: &mut Context<F>,
39        inputs: &VarLenBytes<F, MAX_LEN>,
40    ) -> AssignedValue<F>
41    where
42        F: BigPrimeField;
43
44    /// Return hash of a [VarLenBytesVec]
45    fn hash_var_len_bytes_vec(
46        &self,
47        ctx: &mut Context<F>,
48        inputs: &VarLenBytesVec<F>,
49    ) -> AssignedValue<F>
50    where
51        F: BigPrimeField;
52
53    /// Return hash of a [FixLenBytes]
54    fn hash_fix_len_bytes<const MAX_LEN: usize>(
55        &self,
56        ctx: &mut Context<F>,
57        inputs: &FixLenBytes<F, MAX_LEN>,
58    ) -> AssignedValue<F>
59    where
60        F: BigPrimeField;
61}
62
63impl<F: ScalarField, const T: usize, const RATE: usize> PoseidonInstructions<F>
64    for PoseidonChip<'_, F, T, RATE>
65{
66    fn hash_var_len_bytes<const MAX_LEN: usize>(
67        &self,
68        ctx: &mut Context<F>,
69        inputs: &VarLenBytes<F, MAX_LEN>,
70    ) -> AssignedValue<F>
71    where
72        F: BigPrimeField,
73    {
74        let inputs_len = inputs.len();
75        self.hasher.hash_var_len_array(
76            ctx,
77            self.range_chip,
78            inputs.bytes().map(|sb| *sb.as_ref()).as_ref(),
79            *inputs_len,
80        )
81    }
82
83    fn hash_var_len_bytes_vec(
84        &self,
85        ctx: &mut Context<F>,
86        inputs: &VarLenBytesVec<F>,
87    ) -> AssignedValue<F>
88    where
89        F: BigPrimeField,
90    {
91        let inputs_len = inputs.len();
92        self.hasher.hash_var_len_array(
93            ctx,
94            self.range_chip,
95            &inputs.bytes().iter().map(|sb| *sb.as_ref()).collect_vec(),
96            *inputs_len,
97        )
98    }
99
100    fn hash_fix_len_bytes<const MAX_LEN: usize>(
101        &self,
102        ctx: &mut Context<F>,
103        inputs: &FixLenBytes<F, MAX_LEN>,
104    ) -> AssignedValue<F>
105    where
106        F: BigPrimeField,
107    {
108        self.hasher.hash_fix_len_array(
109            ctx,
110            self.range_chip.gate(),
111            inputs.bytes().map(|sb| *sb.as_ref()).as_ref(),
112        )
113    }
114}