1use ark_ec::CurveConfig;
8use ark_ff::{BigInteger, Field, PrimeField};
9use ark_std::{
10 borrow::Borrow,
11 cmp::min,
12 iter::{once, repeat},
13 mem,
14 vec::Vec,
15};
16use sha2::{Digest, Sha512};
17
18pub fn fr_to_fq<F, P>(scalar: &P::ScalarField) -> F
22where
23 F: PrimeField,
24 P: CurveConfig<BaseField = F>,
25{
26 F::from_le_bytes_mod_order(&scalar.into_bigint().to_bytes_le())
37}
38
39pub fn fq_to_fr<F, P>(base: &F) -> P::ScalarField
43where
44 F: PrimeField,
45 P: CurveConfig<BaseField = F>,
46{
47 P::ScalarField::from_le_bytes_mod_order(&base.into_bigint().to_bytes_le())
48}
49
50pub fn fq_to_fr_with_mask<F, T>(base: &F) -> T
54where
55 F: PrimeField,
56 T: PrimeField,
57{
58 assert!(T::MODULUS_BIT_SIZE < F::MODULUS_BIT_SIZE);
59 let length = (T::MODULUS_BIT_SIZE >> 3) as usize;
60 T::from_le_bytes_mod_order(&base.into_bigint().to_bytes_le()[0..length])
62}
63
64#[inline]
68pub fn field_switching<F, T>(base: &F) -> T
69where
70 F: PrimeField,
71 T: PrimeField,
72{
73 let bytes = base.into_bigint().to_bytes_le();
74 let t = T::from_le_bytes_mod_order(&bytes);
75
76 let bytes_rec = t.into_bigint().to_bytes_le();
79 let length = min(bytes.len(), bytes_rec.len());
80 assert_eq!(bytes_rec[0..length], bytes[0..length],);
81 t
82}
83
84pub fn hash_to_field<B, F>(bytes: B) -> F
87where
88 B: AsRef<[u8]>,
89 F: PrimeField,
90{
91 let rand_byte_len = (F::MODULUS_BIT_SIZE + 7) as usize / 8 + 128 / 8;
95 let mut hasher = Sha512::default();
96 hasher.update(bytes.as_ref());
97 let output = &hasher.finalize()[0..rand_byte_len];
98
99 F::from_le_bytes_mod_order(output)
100}
101
102pub fn bytes_to_field_elements<B, F>(bytes: B) -> Vec<F>
132where
133 B: Borrow<[u8]>,
134 F: Field,
135{
136 let bytes = bytes.borrow();
137 let (primefield_bytes_len, extension_degree, field_bytes_len) = compile_time_checks::<F>();
138 if bytes.is_empty() {
139 return Vec::new();
140 }
141
142 let result_len = (field_bytes_len
145 .checked_add(bytes.len())
146 .expect("result len should fit into usize")
147 - 1)
148 / field_bytes_len
149 + 1;
150
151 let result = once(F::from(bytes.len() as u64)) .chain(bytes.chunks(field_bytes_len).map(|field_elem_bytes| {
153 F::from_base_prime_field_elems(
154 &field_elem_bytes.chunks(primefield_bytes_len)
155 .map(F::BasePrimeField::from_le_bytes_mod_order)
156 .chain(repeat(F::BasePrimeField::ZERO).take(
158 extension_degree - (field_elem_bytes.len()-1) / primefield_bytes_len - 1)
159 )
160 .collect::<Vec<_>>(),
161 )
162 .expect("failed to construct field element")
163 }))
164 .collect::<Vec<_>>();
165
166 assert_eq!(
168 result.len(),
169 result_len,
170 "invalid result len, expect {}, found {}",
171 result_len,
172 result.len()
173 );
174 result
175}
176
177pub fn bytes_from_field_elements<T, F>(elems: T) -> Vec<u8>
187where
188 T: Borrow<[F]>,
189 F: Field,
190{
191 let elems = elems.borrow();
192 let (primefield_bytes_len, _, field_bytes_len) = compile_time_checks::<F>();
193 if elems.is_empty() {
194 return Vec::new();
195 }
196
197 let (first_elem, elems) = elems.split_first().expect("elems should be non-empty");
198
199 let result_len = usize::try_from(u64::from_le_bytes(
201 first_elem
202 .to_base_prime_field_elements()
203 .next()
204 .expect("first base prime field elem should be non-empty")
205 .into_bigint()
206 .to_bytes_le()[..mem::size_of::<u64>()]
207 .try_into()
208 .expect("conversion from [u8] to u64 should succeed"),
209 ))
210 .expect("result len conversion from u64 to usize should succeed");
211
212 let result_capacity = field_bytes_len
213 .checked_mul(elems.len())
214 .expect("result capacity should fit into usize");
215
216 let result_len = min(result_len, result_capacity);
224
225 let mut result = Vec::with_capacity(result_capacity);
230 for elem in elems {
231 for primefield_elem in elem.to_base_prime_field_elements() {
232 let primefield_bytes = primefield_elem.into_bigint().to_bytes_le();
233 let (_, primefield_bytes) = primefield_bytes
234 .split_last() .expect("prime field elem bytes should be non-empty");
236 assert_eq!(
237 primefield_bytes.len(),
238 primefield_bytes_len,
239 "invalid prime field elem bytes len, expect {}, found {}",
240 primefield_bytes_len,
241 primefield_bytes.len()
242 );
243 result.extend_from_slice(primefield_bytes);
244 }
245 }
246
247 assert_eq!(
249 result.len(),
250 result_capacity,
251 "invalid result len, expect {}, found {}",
252 result_capacity,
253 result.len()
254 );
255
256 result.truncate(result_len);
257 result
258}
259
260fn compile_time_checks<F: Field>() -> (usize, usize, usize) {
278 assert!(
279 F::BasePrimeField::MODULUS_BIT_SIZE > 64,
280 "base prime field modulus bit len {} too small to hold a u64",
281 F::BasePrimeField::MODULUS_BIT_SIZE
282 );
283
284 let primefield_bytes_len = usize::try_from((F::BasePrimeField::MODULUS_BIT_SIZE - 1) / 8)
285 .expect("prime field modulus byte len should fit into usize");
286 let extension_degree =
287 usize::try_from(F::extension_degree()).expect("extension degree should fit into usize");
288 let field_bytes_len = primefield_bytes_len
289 .checked_mul(extension_degree)
290 .expect("field element byte len should fit into usize");
291 (primefield_bytes_len, extension_degree, field_bytes_len)
292}
293
294#[cfg(test)]
295mod tests {
296 use crate::test_rng;
297
298 use super::*;
299 use ark_bls12_377::Fq12 as Fq12_377;
300 use ark_bls12_381::Fq12 as Fq12_381;
301 use ark_bn254::Fq12 as Fq12_254;
302 use ark_ed_on_bls12_377::{EdwardsConfig as Param377, Fr as Fr377};
303 use ark_ed_on_bls12_381::{EdwardsConfig as Param381, Fr as Fr381};
304 use ark_ed_on_bn254::{EdwardsConfig as Param254, Fr as Fr254};
305 use ark_std::{rand::RngCore, UniformRand};
306
307 #[test]
308 fn test_bn254_scalar_conversion() {
309 let mut rng = test_rng();
310 for _ in 0..6 {
311 let jj = Fr254::rand(&mut rng);
312 let jj_bls = fr_to_fq::<_, Param254>(&jj);
313 assert!(jj.into_bigint() == jj_bls.into_bigint());
314 }
315 }
316
317 #[test]
318 fn test_jubjub_bls_scalar_conversion_377() {
319 let mut rng = test_rng();
320 for _ in 0..6 {
321 let jj = Fr377::rand(&mut rng);
322 let jj_bls = fr_to_fq::<_, Param377>(&jj);
323 assert!(jj.into_bigint() == jj_bls.into_bigint());
324 }
325 }
326
327 #[test]
328 fn test_jubjub_bls_scalar_conversion_381() {
329 let mut rng = test_rng();
330 for _ in 0..6 {
331 let jj = Fr381::rand(&mut rng);
332 let jj_bls = fr_to_fq::<_, Param381>(&jj);
333 assert!(jj.into_bigint() == jj_bls.into_bigint());
334 }
335 }
336
337 fn bytes_field_elems<F: Field>() {
338 let lengths = [0, 1, 2, 16, 31, 32, 33, 48, 65, 100, 200];
339 let trailing_zeros_lengths = [0, 1, 2, 5, 50];
340
341 let max_len = *lengths.iter().max().unwrap();
342 let max_trailing_zeros_len = *trailing_zeros_lengths.iter().max().unwrap();
343 let mut bytes = Vec::with_capacity(max_len + max_trailing_zeros_len);
344 let mut elems: Vec<F> = Vec::with_capacity(max_len);
345 let mut rng = test_rng();
346
347 for len in lengths {
348 for trailing_zeros_len in trailing_zeros_lengths {
349 bytes.resize(len + trailing_zeros_len, 0);
351 rng.fill_bytes(&mut bytes[..len]);
352 bytes[len..].fill(0);
353
354 let encoded_bytes: Vec<F> = bytes_to_field_elements(bytes.as_ref());
356 let result = bytes_from_field_elements(encoded_bytes);
357 assert_eq!(result, bytes);
358 }
359
360 elems.resize(len, F::zero());
363 elems.iter_mut().for_each(|e| *e = F::rand(&mut rng));
364 bytes_from_field_elements(elems.as_ref());
365 }
366 }
367
368 #[test]
369 fn test_bytes_field_elems() {
370 bytes_field_elems::<Fr381>();
371 bytes_field_elems::<Fr377>();
372 bytes_field_elems::<Fr254>();
373 bytes_field_elems::<Fq12_381>();
374 bytes_field_elems::<Fq12_377>();
375 bytes_field_elems::<Fq12_254>();
376 }
377}