vid/utils/
bytes_to_field.rs1use std::{
2 borrow::Borrow,
3 iter::Take,
4 marker::PhantomData,
5 vec::{IntoIter, Vec},
6};
7
8use ark_ff::{BigInteger, PrimeField};
9
10pub fn bytes_to_field<I, F>(bytes: I) -> impl Iterator<Item = F>
36where
37 F: PrimeField,
38 I: IntoIterator,
39 I::Item: Borrow<u8>,
40{
41 BytesToField::new(bytes.into_iter())
42}
43
44pub fn field_to_bytes<I, F>(elems: I) -> impl Iterator<Item = u8>
70where
71 F: PrimeField,
72 I: IntoIterator,
73 I::Item: Borrow<F>,
74{
75 FieldToBytes::new(elems.into_iter())
76}
77
78struct BytesToField<I, F> {
79 bytes_iter: I,
80 elem_byte_capacity: usize,
81 _phantom: PhantomData<F>,
82}
83
84impl<I, F> BytesToField<I, F>
85where
86 F: PrimeField,
87{
88 fn new(bytes_iter: I) -> Self {
89 Self {
90 bytes_iter,
91 elem_byte_capacity: elem_byte_capacity::<F>(),
92 _phantom: PhantomData,
93 }
94 }
95}
96
97impl<I, F> Iterator for BytesToField<I, F>
98where
99 I: Iterator,
100 I::Item: Borrow<u8>,
101 F: PrimeField,
102{
103 type Item = F;
104
105 fn next(&mut self) -> Option<Self::Item> {
106 let mut elem_bytes = Vec::with_capacity(self.elem_byte_capacity);
107 for _ in 0..elem_bytes.capacity() {
108 if let Some(byte) = self.bytes_iter.next() {
109 elem_bytes.push(*byte.borrow());
110 } else {
111 break;
112 }
113 }
114 if elem_bytes.is_empty() {
115 None
116 } else {
117 Some(F::from_le_bytes_mod_order(&elem_bytes))
118 }
119 }
120}
121
122struct FieldToBytes<I, F> {
123 elems_iter: I,
124 bytes_iter: Take<IntoIter<u8>>,
125 elem_byte_capacity: usize,
126 _phantom: PhantomData<F>,
127}
128
129impl<I, F> FieldToBytes<I, F>
130where
131 F: PrimeField,
132{
133 fn new(elems_iter: I) -> Self {
134 Self {
135 elems_iter,
136 bytes_iter: Vec::new().into_iter().take(0),
137 elem_byte_capacity: elem_byte_capacity::<F>(),
138 _phantom: PhantomData,
139 }
140 }
141}
142
143impl<I, F> Iterator for FieldToBytes<I, F>
144where
145 I: Iterator,
146 I::Item: Borrow<F>,
147 F: PrimeField,
148{
149 type Item = u8;
150
151 fn next(&mut self) -> Option<Self::Item> {
152 if let Some(byte) = self.bytes_iter.next() {
153 return Some(byte);
154 }
155 if let Some(elem) = self.elems_iter.next() {
156 self.bytes_iter = elem
157 .borrow()
158 .into_bigint()
159 .to_bytes_le()
160 .into_iter()
161 .take(self.elem_byte_capacity);
162 return self.bytes_iter.next();
163 }
164 None
165 }
166}
167
168pub fn elem_byte_capacity<F: PrimeField>() -> usize {
176 usize::try_from((F::MODULUS_BIT_SIZE - 1) / 8)
177 .expect("prime field modulus byte len should fit into usize")
178}
179
180#[cfg(test)]
181mod tests {
182 use ark_bls12_381::Fr as Fr381;
183 use ark_bn254::Fr as Fr254;
184 use rand::RngCore;
185
186 use super::{bytes_to_field, field_to_bytes, PrimeField, Vec};
187
188 fn bytes_to_field_iter<F: PrimeField>() {
189 let byte_lens = [0, 1, 2, 16, 31, 32, 33, 48, 65, 100, 200, 5000];
190
191 let max_len = *byte_lens.iter().max().unwrap();
192 let mut bytes = Vec::with_capacity(max_len);
193 let mut rng = jf_utils::test_rng();
195
196 for len in byte_lens {
197 bytes.resize(len, 0);
199 rng.fill_bytes(&mut bytes);
200
201 let owned: Vec<_> = field_to_bytes(bytes_to_field::<_, F>(bytes.clone()))
204 .take(bytes.len())
205 .collect();
206 assert_eq!(owned, bytes);
207
208 let elems: Vec<_> = bytes_to_field::<_, F>(bytes.iter()).collect();
211 let borrowed: Vec<_> = field_to_bytes::<_, F>(elems.iter())
212 .take(bytes.len())
213 .collect();
214 assert_eq!(borrowed, bytes);
215 }
216
217 let bytes = Vec::new();
219 assert!(bytes.is_empty());
220 let mut elems_iter = bytes_to_field::<_, F>(bytes.iter());
221 assert!(elems_iter.next().is_none());
222
223 let bytes = [42u8; 1];
225 let mut elems_iter = bytes_to_field::<_, F>(bytes.iter());
226 assert_eq!(elems_iter.next().unwrap(), F::from(42u64));
227 assert!(elems_iter.next().is_none());
228 }
229
230 #[test]
231 fn test_bytes_field_elems_iter() {
232 bytes_to_field_iter::<Fr254>();
233 bytes_to_field_iter::<Fr381>();
234 }
235}