1use super::{Permutation, RescueParameter, RescueVector};
10use ark_crypto_primitives::sponge::{
11 Absorb, CryptographicSponge, FieldBasedCryptographicSponge, FieldElementSize, SpongeExt,
12};
13use ark_ff::PrimeField;
14use ark_std::{vec, vec::Vec};
15
16#[derive(Clone, Default, Debug)]
17pub struct RescueSponge<F: RescueParameter, const RATE: usize> {
20 pub(crate) state: RescueVector<F>,
21 pub(crate) permutation: Permutation<F>,
22}
23
24impl<F: RescueParameter, const RATE: usize> SpongeExt for RescueSponge<F, RATE> {
25 type State = RescueVector<F>;
26
27 fn from_state(state: Self::State, permutation: &Self::Config) -> Self {
28 Self {
29 state,
30 permutation: permutation.clone(),
31 }
32 }
33
34 fn into_state(self) -> Self::State {
35 self.state
36 }
37}
38
39impl<T: RescueParameter + PrimeField, const RATE: usize> CryptographicSponge
40 for RescueSponge<T, RATE>
41{
42 type Config = Permutation<T>;
44
45 fn new(permutation: &Self::Config) -> Self {
47 Self {
48 state: RescueVector::default(),
49 permutation: permutation.clone(),
50 }
51 }
52
53 fn absorb(&mut self, input: &impl Absorb) {
57 let input_field_elements = input.to_sponge_field_elements_as_vec();
58
59 input_field_elements.chunks(RATE).for_each(|chunk| {
61 self.state.add_assign_elems(chunk);
62 self.state = self.permutation.eval(&self.state)
63 });
64 }
65
66 fn squeeze_bytes(&mut self, _num_bytes: usize) -> Vec<u8> {
69 unimplemented!("Currently we only support squeezing native field elements!")
70 }
71
72 fn squeeze_bits(&mut self, _num_bits: usize) -> Vec<bool> {
75 unimplemented!("Currently we only support squeezing native field elements!")
76 }
77
78 fn squeeze_field_elements_with_sizes<F: PrimeField>(
81 &mut self,
82 _sizes: &[FieldElementSize],
83 ) -> Vec<F> {
84 unimplemented!("Currently we only support squeezing native field elements!")
85 }
86
87 fn squeeze_field_elements<F: PrimeField>(&mut self, _num_elements: usize) -> Vec<F> {
90 unimplemented!("Currently we only support squeezing native field elements!")
91 }
92
93 fn fork(&self, domain: &[u8]) -> Self {
95 let mut new_sponge = self.clone();
96
97 let mut input = Absorb::to_sponge_bytes_as_vec(&domain.len());
98 input.extend_from_slice(domain);
99 new_sponge.absorb(&input);
100
101 new_sponge
102 }
103}
104
105impl<T: RescueParameter, const RATE: usize> FieldBasedCryptographicSponge<T>
108 for RescueSponge<T, RATE>
109{
110 fn squeeze_native_field_elements(&mut self, num_elements: usize) -> Vec<T> {
112 let mut result = vec![];
114 let mut remaining = num_elements;
115 loop {
117 let extract = remaining.min(RATE);
118 result.extend_from_slice(&self.state.vec[0..extract]);
119 remaining -= extract;
120 if remaining == 0 {
121 break;
122 }
123 self.state = self.permutation.eval(&self.state)
124 }
125 result
126 }
127
128 fn squeeze_native_field_elements_with_sizes(&mut self, _sizes: &[FieldElementSize]) -> Vec<T> {
131 unimplemented!("Currently we only support squeezing native field elements!")
132 }
133}
134
135#[cfg(test)]
136mod test {
137 use super::*;
138 use ark_bls12_381::Fr;
139 use ark_crypto_primitives::{
140 absorb, collect_sponge_bytes, collect_sponge_field_elements, sponge::AbsorbWithLength,
141 };
142 use ark_ff::{One, UniformRand};
143 use jf_utils::test_rng;
144
145 fn assert_different_encodings<F: RescueParameter, A: Absorb>(a: &A, b: &A) {
146 let bytes1 = a.to_sponge_bytes_as_vec();
147 let bytes2 = b.to_sponge_bytes_as_vec();
148 assert_ne!(bytes1, bytes2);
149
150 let sponge_param = Permutation::default();
151 let mut sponge1 = RescueSponge::<F, 3>::new(&sponge_param);
152 let mut sponge2 = RescueSponge::<F, 3>::new(&sponge_param);
153
154 sponge1.absorb(&a);
155 sponge2.absorb(&b);
156
157 assert_ne!(
158 sponge1.squeeze_native_field_elements(3),
159 sponge2.squeeze_native_field_elements(3)
160 );
161 }
162
163 #[test]
164 fn single_field_element() {
165 let mut rng = test_rng();
166 let elem1 = Fr::rand(&mut rng);
167 let elem2 = elem1 + Fr::one();
168
169 assert_different_encodings::<Fr, _>(&elem1, &elem2)
170 }
171
172 #[test]
173 fn list_with_constant_size_element() {
174 let mut rng = test_rng();
175 let lst1: Vec<_> = (0..1024 * 8).map(|_| Fr::rand(&mut rng)).collect();
176 let mut lst2 = lst1.to_vec();
177 lst2[3] += Fr::one();
178
179 assert_different_encodings::<Fr, _>(&lst1, &lst2)
180 }
181
182 struct VariableSizeList(Vec<u8>);
183
184 impl Absorb for VariableSizeList {
185 fn to_sponge_bytes(&self, dest: &mut Vec<u8>) {
186 self.0.to_sponge_bytes_with_length(dest)
187 }
188
189 fn to_sponge_field_elements<F: PrimeField>(&self, dest: &mut Vec<F>) {
190 self.0.to_sponge_field_elements_with_length(dest)
191 }
192 }
193
194 #[test]
195 fn list_with_nonconstant_size_element() {
196 let lst1 = vec![
197 VariableSizeList(vec![1u8, 2, 3, 4]),
198 VariableSizeList(vec![5, 6]),
199 ];
200 let lst2 = vec![
201 VariableSizeList(vec![1u8, 2]),
202 VariableSizeList(vec![3, 4, 5, 6]),
203 ];
204
205 assert_different_encodings::<Fr, _>(&lst1, &lst2);
206 }
207
208 #[test]
209 fn test_macros() {
210 let sponge_param = Permutation::default();
211 let mut sponge1 = RescueSponge::<Fr, 3>::new(&sponge_param);
212 sponge1.absorb(&vec![1u8, 2, 3, 4, 5, 6]);
213 sponge1.absorb(&Fr::from(114514u128));
214
215 let mut sponge2 = RescueSponge::<Fr, 3>::new(&sponge_param);
216 absorb!(&mut sponge2, vec![1u8, 2, 3, 4, 5, 6], Fr::from(114514u128));
217
218 let expected = sponge1.squeeze_native_field_elements(3);
219 let actual = sponge2.squeeze_native_field_elements(3);
220
221 assert_eq!(actual, expected);
222
223 let mut expected = Vec::new();
224 vec![6u8, 5, 4, 3, 2, 1].to_sponge_bytes(&mut expected);
225 Fr::from(42u8).to_sponge_bytes(&mut expected);
226
227 let actual = collect_sponge_bytes!(vec![6u8, 5, 4, 3, 2, 1], Fr::from(42u8));
228
229 assert_eq!(actual, expected);
230
231 let mut expected: Vec<Fr> = Vec::new();
232 vec![6u8, 5, 4, 3, 2, 1].to_sponge_field_elements(&mut expected);
233 Fr::from(42u8).to_sponge_field_elements(&mut expected);
234
235 let actual: Vec<Fr> =
236 collect_sponge_field_elements!(vec![6u8, 5, 4, 3, 2, 1], Fr::from(42u8));
237
238 assert_eq!(actual, expected);
239 }
240}