diff --git a/ec/src/hashing/curve_maps/swu.rs b/ec/src/hashing/curve_maps/swu/mod.rs similarity index 95% rename from ec/src/hashing/curve_maps/swu.rs rename to ec/src/hashing/curve_maps/swu/mod.rs index c989ece48..47330c52c 100644 --- a/ec/src/hashing/curve_maps/swu.rs +++ b/ec/src/hashing/curve_maps/swu/mod.rs @@ -35,8 +35,8 @@ pub fn parity(element: &F) -> bool { } impl MapToCurve> for SWUMap

{ - /// Checks if `P` represents a valid map. - fn check_parameters() -> Result<(), HashToCurveError> { + /// Constructs a new map if `P` represents a valid map. + fn new() -> Result { // Verifying that ZETA is a non-square if P::ZETA.legendre().is_qr() { return Err(HashToCurveError::MapToCurveError( @@ -49,13 +49,13 @@ impl MapToCurve> for SWUMap

{ return Err(HashToCurveError::MapToCurveError("Simplified SWU requires a * b != 0 in the short Weierstrass form of y^2 = x^3 + a*x + b ".to_string())); } - Ok(()) + Ok(SWUMap(PhantomData)) } /// Map an arbitrary base field element to a curve point. /// Based on /// . - fn map_to_curve(point: P::BaseField) -> Result, HashToCurveError> { + fn map_to_curve(&self, point: P::BaseField) -> Result, HashToCurveError> { // 1. tv1 = inv0(Z^2 * u^4 + Z * u^2) // 2. x1 = (-B / A) * (1 + tv1) // 3. If tv1 == 0, set x1 = B / (Z * A) @@ -256,12 +256,15 @@ mod test { /// elements should be mapped to curve successfully. everything can be mapped #[test] fn map_field_to_curve_swu() { - SWUMap::::check_parameters().unwrap(); + let test_map_to_curve = SWUMap::::new().unwrap(); let mut map_range: Vec> = vec![]; for current_field_element in 0..127 { - let point = F127::from(current_field_element as u64); - map_range.push(SWUMap::::map_to_curve(point).unwrap()); + map_range.push( + test_map_to_curve + .map_to_curve(F127::from(current_field_element as u64)) + .unwrap(), + ); } let mut counts = HashMap::new(); diff --git a/ec/src/hashing/curve_maps/wb.rs b/ec/src/hashing/curve_maps/wb/mod.rs similarity index 96% rename from ec/src/hashing/curve_maps/wb.rs rename to ec/src/hashing/curve_maps/wb/mod.rs index 46b635b1c..10ddbb0f7 100644 --- a/ec/src/hashing/curve_maps/wb.rs +++ b/ec/src/hashing/curve_maps/wb/mod.rs @@ -79,13 +79,13 @@ pub trait WBConfig: SWCurveConfig + Sized { } pub struct WBMap { - swu_field_curve_hasher: PhantomData>, + swu_field_curve_hasher: SWUMap, curve_params: PhantomData P>, } impl MapToCurve> for WBMap

{ - /// Checks if `P` represents a valid map. - fn check_parameters() -> Result<(), HashToCurveError> { + /// Constructs a new map if `P` represents a valid map. + fn new() -> Result { match P::ISOGENY_MAP.apply(P::IsogenousCurve::GENERATOR) { Ok(point_on_curve) => { if !point_on_curve.is_on_curve() { @@ -95,18 +95,21 @@ impl MapToCurve> for WBMap

{ Err(e) => return Err(e), } - SWUMap::::check_parameters().unwrap(); // Or ? - Ok(()) + Ok(WBMap { + swu_field_curve_hasher: SWUMap::::new().unwrap(), + curve_params: PhantomData, + }) } /// Map random field point to a random curve point /// inspired from /// fn map_to_curve( + &self, element: as AffineRepr>::BaseField, ) -> Result, HashToCurveError> { // first we need to map the field point to the isogenous curve - let point_on_isogenious_curve = SWUMap::::map_to_curve(element).unwrap(); + let point_on_isogenious_curve = self.swu_field_curve_hasher.map_to_curve(element).unwrap(); P::ISOGENY_MAP.apply(point_on_isogenious_curve) } } diff --git a/ec/src/hashing/map_to_curve_hasher.rs b/ec/src/hashing/map_to_curve_hasher.rs index e0f46f323..c4ffc9189 100644 --- a/ec/src/hashing/map_to_curve_hasher.rs +++ b/ec/src/hashing/map_to_curve_hasher.rs @@ -7,11 +7,11 @@ use ark_std::marker::PhantomData; /// Trait for mapping a random field element to a random curve point. pub trait MapToCurve: Sized { - /// Checks whether supplied parameters represent a valid map. - fn check_parameters() -> Result<(), HashToCurveError>; + /// Constructs a new mapping. + fn new() -> Result; /// Map an arbitary field element to a corresponding curve point. - fn map_to_curve(point: T::BaseField) -> Result; + fn map_to_curve(&self, point: T::BaseField) -> Result; } /// Helper struct that can be used to construct elements on the elliptic curve @@ -24,7 +24,8 @@ where M2C: MapToCurve, { field_hasher: H2F, - _phantom: PhantomData<(T, M2C)>, + curve_mapper: M2C, + _params_t: PhantomData, } impl HashToCurve for MapToCurveBasedHasher @@ -34,11 +35,13 @@ where M2C: MapToCurve, { fn new(domain: &[u8]) -> Result { - #[cfg(test)] - M2C::check_parameters()?; + let field_hasher = H2F::new(domain); + let curve_mapper = M2C::new()?; + let _params_t = PhantomData; Ok(MapToCurveBasedHasher { - field_hasher: H2F::new(domain), - _phantom: PhantomData, + field_hasher, + curve_mapper, + _params_t, }) } @@ -58,8 +61,8 @@ where let rand_field_elems = self.field_hasher.hash_to_field::<2>(msg); - let rand_curve_elem_0 = M2C::map_to_curve(rand_field_elems[0])?; - let rand_curve_elem_1 = M2C::map_to_curve(rand_field_elems[1])?; + let rand_curve_elem_0 = self.curve_mapper.map_to_curve(rand_field_elems[0])?; + let rand_curve_elem_1 = self.curve_mapper.map_to_curve(rand_field_elems[1])?; let rand_curve_elem = (rand_curve_elem_0 + rand_curve_elem_1).into(); let rand_subgroup_elem = rand_curve_elem.clear_cofactor();