1mod expand_msg;
6
7use core::num::NonZeroU16;
8
9pub use expand_msg::{xmd::*, xof::*, *};
10
11use elliptic_curve::{
12 array::{Array, ArraySize, typenum::NonZero},
13 ops::Reduce,
14};
15
16#[doc(hidden)]
26pub fn hash_to_field<const N: usize, E, K, T, L>(
27 data: &[&[u8]],
28 domain: &[&[u8]],
29) -> Result<[T; N], E::Error>
30where
31 E: ExpandMsg<K>,
32 T: Reduce<Array<u8, L>>,
33 L: ArraySize + NonZero,
34{
35 let len_in_bytes = const {
37 assert!(
38 L::USIZE.saturating_mul(N) <= u16::MAX as usize,
39 "The product of `L` and `N` must not exceed `u16::MAX`."
40 );
41 NonZeroU16::new(L::U16 * N as u16).expect("N is greater than 0")
42 };
43 let mut tmp = Array::<u8, L>::default();
44 let mut expander = E::expand_message(data, domain, len_in_bytes)?;
45 Ok(core::array::from_fn(|_| {
46 expander
47 .fill_bytes(&mut tmp)
48 .expect("never exceeds `len_in_bytes`");
49 T::reduce(&tmp)
50 }))
51}