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
11pub mod hasher;
13
14pub 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 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
33pub trait PoseidonInstructions<F: ScalarField> {
35 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 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 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}