poseidon377/
hash.rs

1use crate::{Fq, Instance};
2
3/// Hash a single [`Fq`] element with the provided `domain_separator`.
4pub fn hash_1(domain_separator: &Fq, value: Fq) -> Fq {
5    let params = &crate::RATE_1_PARAMS;
6    let mut state = Instance::new(&params);
7    state.n_to_1_fixed_hash(&[*domain_separator, value])
8}
9
10/// Hash two [`Fq`] elements with the provided `domain_separator`.
11pub fn hash_2(domain_separator: &Fq, value: (Fq, Fq)) -> Fq {
12    let params = &crate::RATE_2_PARAMS;
13    let mut state = Instance::new(params);
14    state.n_to_1_fixed_hash(&[*domain_separator, value.0, value.1])
15}
16
17/// Hash three [`Fq`] elements with the provided `domain_separator`.
18pub fn hash_3(domain_separator: &Fq, value: (Fq, Fq, Fq)) -> Fq {
19    let params = &crate::RATE_3_PARAMS;
20    let mut state = Instance::new(params);
21    state.n_to_1_fixed_hash(&[*domain_separator, value.0, value.1, value.2])
22}
23
24/// Hash four [`Fq`] elements with the provided `domain_separator`.
25pub fn hash_4(domain_separator: &Fq, value: (Fq, Fq, Fq, Fq)) -> Fq {
26    let params = &crate::RATE_4_PARAMS;
27    let mut state = Instance::new(params);
28    state.n_to_1_fixed_hash(&[*domain_separator, value.0, value.1, value.2, value.3])
29}
30
31/// Hash five [`Fq`] elements with the provided `domain_separator`.
32pub fn hash_5(domain_separator: &Fq, value: (Fq, Fq, Fq, Fq, Fq)) -> Fq {
33    let params = &crate::RATE_5_PARAMS;
34    let mut state = Instance::new(params);
35    state.n_to_1_fixed_hash(&[
36        *domain_separator,
37        value.0,
38        value.1,
39        value.2,
40        value.3,
41        value.4,
42    ])
43}
44
45/// Hash six [`Fq`] elements with the provided `domain_separator`.
46pub fn hash_6(domain_separator: &Fq, value: (Fq, Fq, Fq, Fq, Fq, Fq)) -> Fq {
47    let params = &crate::RATE_6_PARAMS;
48    let mut state = Instance::new(params);
49    state.n_to_1_fixed_hash(&[
50        *domain_separator,
51        value.0,
52        value.1,
53        value.2,
54        value.3,
55        value.4,
56        value.5,
57    ])
58}
59
60/// Hash seven [`Fq`] elements with the provided `domain_separator`.
61pub fn hash_7(domain_separator: &Fq, value: (Fq, Fq, Fq, Fq, Fq, Fq, Fq)) -> Fq {
62    let params = &crate::RATE_7_PARAMS;
63    let mut state = Instance::new(params);
64    state.n_to_1_fixed_hash(&[
65        *domain_separator,
66        value.0,
67        value.1,
68        value.2,
69        value.3,
70        value.4,
71        value.5,
72        value.6,
73    ])
74}
75
76#[cfg(test)]
77mod test {
78    use core::str::FromStr;
79
80    use super::*;
81
82    #[test]
83    fn rate_1() {
84        let domain_sep = Fq::from_le_bytes_mod_order(b"Penumbra_TestVec");
85
86        let input = Fq::from_str(
87            "7553885614632219548127688026174585776320152166623257619763178041781456016062",
88        )
89        .unwrap();
90        let output = hash_1(&domain_sep, input);
91
92        let expected_output = Fq::from_str(
93            "2337838243217876174544784248400816541933405738836087430664765452605435675740",
94        )
95        .unwrap();
96
97        assert_eq!(output, expected_output);
98    }
99
100    #[test]
101    fn rate_2() {
102        let domain_sep = Fq::from_le_bytes_mod_order(b"Penumbra_TestVec");
103
104        let input = (
105            Fq::from_str(
106                "7553885614632219548127688026174585776320152166623257619763178041781456016062",
107            )
108            .unwrap(),
109            Fq::from_str(
110                "2337838243217876174544784248400816541933405738836087430664765452605435675740",
111            )
112            .unwrap(),
113        );
114
115        let output = hash_2(&domain_sep, input);
116
117        let expected_output = Fq::from_str(
118            "4318449279293553393006719276941638490334729643330833590842693275258805886300",
119        )
120        .unwrap();
121
122        assert_eq!(output, expected_output);
123    }
124
125    #[test]
126    fn rate_3() {
127        let domain_sep = Fq::from_le_bytes_mod_order(b"Penumbra_TestVec");
128
129        let input = (
130            Fq::from_str(
131                "7553885614632219548127688026174585776320152166623257619763178041781456016062",
132            )
133            .unwrap(),
134            Fq::from_str(
135                "2337838243217876174544784248400816541933405738836087430664765452605435675740",
136            )
137            .unwrap(),
138            Fq::from_str(
139                "4318449279293553393006719276941638490334729643330833590842693275258805886300",
140            )
141            .unwrap(),
142        );
143
144        let output = hash_3(&domain_sep, input);
145
146        let expected_output = Fq::from_str(
147            "2884734248868891876687246055367204388444877057000108043377667455104051576315",
148        )
149        .unwrap();
150
151        assert_eq!(output, expected_output);
152    }
153
154    #[test]
155    fn rate_4() {
156        let domain_sep = Fq::from_le_bytes_mod_order(b"Penumbra_TestVec");
157
158        let input = (
159            Fq::from_str(
160                "7553885614632219548127688026174585776320152166623257619763178041781456016062",
161            )
162            .unwrap(),
163            Fq::from_str(
164                "2337838243217876174544784248400816541933405738836087430664765452605435675740",
165            )
166            .unwrap(),
167            Fq::from_str(
168                "4318449279293553393006719276941638490334729643330833590842693275258805886300",
169            )
170            .unwrap(),
171            Fq::from_str(
172                "2884734248868891876687246055367204388444877057000108043377667455104051576315",
173            )
174            .unwrap(),
175        );
176
177        let output = hash_4(&domain_sep, input);
178
179        let expected_output = Fq::from_str(
180            "5235431038142849831913898188189800916077016298531443239266169457588889298166",
181        )
182        .unwrap();
183
184        assert_eq!(output, expected_output);
185    }
186
187    #[test]
188    fn rate_5() {
189        let domain_sep = Fq::from_le_bytes_mod_order(b"Penumbra_TestVec");
190
191        let input = (
192            Fq::from_str(
193                "7553885614632219548127688026174585776320152166623257619763178041781456016062",
194            )
195            .unwrap(),
196            Fq::from_str(
197                "2337838243217876174544784248400816541933405738836087430664765452605435675740",
198            )
199            .unwrap(),
200            Fq::from_str(
201                "4318449279293553393006719276941638490334729643330833590842693275258805886300",
202            )
203            .unwrap(),
204            Fq::from_str(
205                "2884734248868891876687246055367204388444877057000108043377667455104051576315",
206            )
207            .unwrap(),
208            Fq::from_str(
209                "5235431038142849831913898188189800916077016298531443239266169457588889298166",
210            )
211            .unwrap(),
212        );
213
214        let output = hash_5(&domain_sep, input);
215
216        let expected_output = Fq::from_str(
217            "66948599770858083122195578203282720327054804952637730715402418442993895152",
218        )
219        .unwrap();
220
221        assert_eq!(output, expected_output);
222    }
223
224    #[test]
225    fn rate_6() {
226        let domain_sep = Fq::from_le_bytes_mod_order(b"Penumbra_TestVec");
227
228        let input = (
229            Fq::from_str(
230                "7553885614632219548127688026174585776320152166623257619763178041781456016062",
231            )
232            .unwrap(),
233            Fq::from_str(
234                "2337838243217876174544784248400816541933405738836087430664765452605435675740",
235            )
236            .unwrap(),
237            Fq::from_str(
238                "4318449279293553393006719276941638490334729643330833590842693275258805886300",
239            )
240            .unwrap(),
241            Fq::from_str(
242                "2884734248868891876687246055367204388444877057000108043377667455104051576315",
243            )
244            .unwrap(),
245            Fq::from_str(
246                "5235431038142849831913898188189800916077016298531443239266169457588889298166",
247            )
248            .unwrap(),
249            Fq::from_str(
250                "66948599770858083122195578203282720327054804952637730715402418442993895152",
251            )
252            .unwrap(),
253        );
254
255        let output = hash_6(&domain_sep, input);
256
257        let expected_output = Fq::from_str(
258            "6797655301930638258044003960605211404784492298673033525596396177265014216269",
259        )
260        .unwrap();
261
262        assert_eq!(output, expected_output);
263    }
264}