ark_ec/hashing/
map_to_curve_hasher.rs1use crate::{
2 hashing::{HashToCurve, HashToCurveError},
3 AffineRepr, CurveGroup,
4};
5use ark_ff::field_hashers::HashToField;
6use ark_std::marker::PhantomData;
7
8pub trait MapToCurve<T: CurveGroup>: Sized {
10 fn check_parameters() -> Result<(), HashToCurveError>;
12
13 fn map_to_curve(point: T::BaseField) -> Result<T::Affine, HashToCurveError>;
15}
16
17pub struct MapToCurveBasedHasher<T, H2F, M2C>
26where
27 T: CurveGroup,
28 H2F: HashToField<T::BaseField>,
29 M2C: MapToCurve<T>,
30{
31 field_hasher: H2F,
32 _phantom: PhantomData<(T, M2C)>,
33}
34
35impl<T, H2F, M2C> HashToCurve<T> for MapToCurveBasedHasher<T, H2F, M2C>
36where
37 T: CurveGroup,
38 H2F: HashToField<T::BaseField>,
39 M2C: MapToCurve<T>,
40{
41 fn new(domain: &[u8]) -> Result<Self, HashToCurveError> {
42 #[cfg(test)]
43 M2C::check_parameters()?;
44 Ok(Self {
45 field_hasher: H2F::new(domain),
46 _phantom: PhantomData,
47 })
48 }
49
50 fn hash(&self, msg: &[u8]) -> Result<T::Affine, HashToCurveError> {
55 let rand_field_elems = self.field_hasher.hash_to_field::<2>(msg);
65
66 let rand_curve_elem_0 = M2C::map_to_curve(rand_field_elems[0])?;
67 let rand_curve_elem_1 = M2C::map_to_curve(rand_field_elems[1])?;
68
69 let rand_curve_elem = (rand_curve_elem_0 + rand_curve_elem_1).into();
70 let rand_subgroup_elem = rand_curve_elem.clear_cofactor();
71
72 Ok(rand_subgroup_elem)
73 }
74}