From 840f6a29ec6cb4636d76282a4b00e9bb850145fe Mon Sep 17 00:00:00 2001 From: Davide Galassi Date: Fri, 13 Sep 2024 17:12:58 +0200 Subject: [PATCH] Expose utilities (#35) --- src/arkworks/mod.rs | 6 --- src/codec.rs | 2 +- src/lib.rs | 4 +- src/ring.rs | 2 +- src/suites/bandersnatch.rs | 63 ++++++++++++++++++++++++--- src/{utils.rs => utils/common.rs} | 39 +++-------------- src/{arkworks => utils}/elligator2.rs | 5 ++- src/utils/mod.rs | 39 +++++++++++++++++ src/{arkworks => utils}/te_sw_map.rs | 11 ++--- 9 files changed, 113 insertions(+), 58 deletions(-) delete mode 100644 src/arkworks/mod.rs rename src/{utils.rs => utils/common.rs} (84%) rename src/{arkworks => utils}/elligator2.rs (97%) create mode 100644 src/utils/mod.rs rename src/{arkworks => utils}/te_sw_map.rs (87%) diff --git a/src/arkworks/mod.rs b/src/arkworks/mod.rs deleted file mode 100644 index 3772695..0000000 --- a/src/arkworks/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Features expected to land into Arkworks at some point in the future - -/// Elligator 2 hash-to-curve. -pub mod elligator2; -/// Twisted Edwards to Short Weierstrass mapping. -pub mod te_sw_map; diff --git a/src/codec.rs b/src/codec.rs index 49bfe6b..22aa2cf 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -1,5 +1,5 @@ use ark_ec::short_weierstrass::SWCurveConfig; -use arkworks::te_sw_map; +use utils::te_sw_map; use super::*; diff --git a/src/lib.rs b/src/lib.rs index 02116db..7176b39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,12 +32,10 @@ pub mod utils; #[cfg(feature = "ring")] pub mod ring; -#[allow(unused)] -mod arkworks; - #[cfg(test)] mod testing; +// Re-export stuff that may be useful downstream pub mod prelude { pub use ark_ec; pub use ark_ff; diff --git a/src/ring.rs b/src/ring.rs index 0f6e11e..7e391ab 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -1,4 +1,4 @@ -use crate::arkworks::te_sw_map::SWMapping; +use crate::utils::te_sw_map::SWMapping; use crate::*; use ark_ec::short_weierstrass::SWCurveConfig; use pedersen::{PedersenSuite, Proof as PedersenProof}; diff --git a/src/suites/bandersnatch.rs b/src/suites/bandersnatch.rs index 8e7ff32..49363d0 100644 --- a/src/suites/bandersnatch.rs +++ b/src/suites/bandersnatch.rs @@ -48,7 +48,7 @@ //! with `h2c_suite_ID_string` = `"Bandersnatch_XMD:SHA-512_ELL2_RO_"` //! and domain separation tag `DST = "ECVRF_" || h2c_suite_ID_string || suite_string`. -use crate::{arkworks::te_sw_map::*, pedersen::PedersenSuite, *}; +use crate::{pedersen::PedersenSuite, utils::te_sw_map::*, *}; use ark_ff::MontFp; pub mod weierstrass { @@ -156,9 +156,7 @@ pub mod edwards { }; } - impl arkworks::elligator2::Elligator2Config - for ark_ed_on_bls12_381_bandersnatch::BandersnatchConfig - { + impl utils::elligator2::Elligator2Config for ark_ed_on_bls12_381_bandersnatch::BandersnatchConfig { const Z: ark_ed_on_bls12_381_bandersnatch::Fq = MontFp!("5"); /// This must be equal to 1/(MontCurveConfig::COEFF_B)^2; @@ -234,17 +232,17 @@ impl MapConfig for ark_ed_on_bls12_381_bandersnatch::BandersnatchConfig { #[cfg(test)] mod tests { - use crate::{testing, utils::te_sw_map::*}; + use crate::{testing, utils::*}; use ark_ed_on_bls12_381_bandersnatch::{BandersnatchConfig, SWAffine}; #[test] fn sw_to_te_roundtrip() { let org_point = testing::random_val::(None); - let te_point = map_sw_to_te::(&org_point).unwrap(); + let te_point = sw_to_te::(&org_point).unwrap(); assert!(te_point.is_on_curve()); - let sw_point = map_te_to_sw::(&te_point).unwrap(); + let sw_point = te_to_sw::(&te_point).unwrap(); assert!(sw_point.is_on_curve()); assert_eq!(org_point, sw_point); @@ -404,3 +402,54 @@ mod test_vectors_ring_sw { testing::test_vectors_process::(VECTOR_ID); } } + +#[test] +fn blinding_base_sw_te_rountrip() { + use crate::utils::*; + let sw = weierstrass::BandersnatchSha512Tai::BLINDING_BASE; + let ed = sw_to_te(&sw).unwrap(); + assert_eq!(ed, edwards::BandersnatchSha512Ell2::BLINDING_BASE); + let sw2 = te_to_sw(&ed).unwrap(); + assert_eq!(sw, sw2); +} + +#[cfg(all(test, feature = "ring"))] +#[test] +fn accumulator_base_sw_te_roundtrip() { + use crate::{ring::RingSuite, utils::*}; + let sw = weierstrass::BandersnatchSha512Tai::ACCUMULATOR_BASE; + let ed = sw_to_te(&sw).unwrap(); + assert_eq!(ed, edwards::BandersnatchSha512Ell2::ACCUMULATOR_BASE); + let sw2 = te_to_sw(&ed).unwrap(); + assert_eq!(sw, sw2); +} + +#[cfg(all(test, feature = "ring"))] +#[test] +fn padding_point_sw_te_roundtrip() { + use crate::utils::*; + // Fixed padding point + let sw = { + const X: weierstrass::BaseField = MontFp!( + "25448400713078632486748382313960039031302935774474538965225823993599751298535" + ); + const Y: weierstrass::BaseField = MontFp!( + "24382892199244280513693545286348030912870264650402775682704689602954457435722" + ); + weierstrass::AffinePoint::new_unchecked(X, Y) + }; + let ed = sw_to_te(&sw).unwrap(); + let sw2 = te_to_sw(&ed).unwrap(); + assert_eq!(sw, sw2); +} + +#[test] +fn generator_roundtrip() { + use crate::utils::*; + let sw1 = weierstrass::AffinePoint::generator(); + let ed1 = sw_to_te(&sw1).unwrap(); + let ed2 = edwards::AffinePoint::generator(); + assert_eq!(ed1, ed2); + let sw2 = te_to_sw(&ed1).unwrap(); + assert_eq!(sw1, sw2); +} diff --git a/src/utils.rs b/src/utils/common.rs similarity index 84% rename from src/utils.rs rename to src/utils/common.rs index 37ae214..5cdd69d 100644 --- a/src/utils.rs +++ b/src/utils/common.rs @@ -1,8 +1,5 @@ use crate::*; -#[allow(unused)] -pub(crate) use crate::arkworks::{elligator2, te_sw_map}; - use ark_ec::AffineRepr; use ark_ff::PrimeField; use digest::{Digest, FixedOutputReset}; @@ -10,33 +7,6 @@ use digest::{Digest, FixedOutputReset}; #[cfg(not(feature = "std"))] use ark_std::vec::Vec; -#[macro_export] -macro_rules! suite_types { - ($suite:ident) => { - #[allow(dead_code)] - pub type Secret = $crate::Secret<$suite>; - #[allow(dead_code)] - pub type Public = $crate::Public<$suite>; - #[allow(dead_code)] - pub type Input = $crate::Input<$suite>; - #[allow(dead_code)] - pub type Output = $crate::Output<$suite>; - #[allow(dead_code)] - pub type AffinePoint = $crate::AffinePoint<$suite>; - #[allow(dead_code)] - pub type ScalarField = $crate::ScalarField<$suite>; - #[allow(dead_code)] - pub type BaseField = $crate::BaseField<$suite>; - #[allow(dead_code)] - pub type IetfProof = $crate::ietf::Proof<$suite>; - #[allow(dead_code)] - pub type PedersenProof = $crate::pedersen::Proof<$suite>; - #[cfg(feature = "ring")] - #[allow(dead_code)] - pub type RingProof = $crate::ring::Proof<$suite>; - }; -} - // Generic hash wrapper. pub(crate) fn hash(data: &[u8]) -> digest::Output { H::new().chain_update(data).finalize() @@ -44,7 +14,7 @@ pub(crate) fn hash(data: &[u8]) -> digest::Output { /// Generic HMAC wrapper. #[cfg(feature = "rfc-6979")] -pub(crate) fn hmac(sk: &[u8], data: &[u8]) -> Vec { +fn hmac(sk: &[u8], data: &[u8]) -> Vec { use hmac::{Mac, SimpleHmac}; SimpleHmac::::new_from_slice(sk) .expect("HMAC can take key of any size") @@ -115,6 +85,7 @@ pub fn hash_to_curve_tai_rfc_9381(data: &[u8]) -> Option( data: &[u8], h2c_suite_id: &[u8], @@ -122,8 +93,8 @@ pub fn hash_to_curve_ell2_rfc_9380( where ::Hasher: Default + Clone + FixedOutputReset + 'static, crate::CurveConfig: ark_ec::twisted_edwards::TECurveConfig, - crate::CurveConfig: crate::arkworks::elligator2::Elligator2Config, - crate::arkworks::elligator2::Elligator2Map>: + crate::CurveConfig: crate::utils::elligator2::Elligator2Config, + crate::utils::elligator2::Elligator2Map>: ark_ec::hashing::map_to_curve_hasher::MapToCurve< as AffineRepr>::Group>, { use ark_ec::hashing::HashToCurve; @@ -140,7 +111,7 @@ where let hasher = ark_ec::hashing::map_to_curve_hasher::MapToCurveBasedHasher::< as AffineRepr>::Group, ark_ff::field_hashers::DefaultFieldHasher<::Hasher, SEC_PARAM>, - crate::arkworks::elligator2::Elligator2Map>, + crate::utils::elligator2::Elligator2Map>, >::new(&dst) .ok()?; diff --git a/src/arkworks/elligator2.rs b/src/utils/elligator2.rs similarity index 97% rename from src/arkworks/elligator2.rs rename to src/utils/elligator2.rs index e1f6756..770e46f 100644 --- a/src/arkworks/elligator2.rs +++ b/src/utils/elligator2.rs @@ -1,8 +1,11 @@ -//! Elligator2 has been merged upstream, still we're waiting for new version on crates.io (v.0.4.3) +//! Elligator2 has been merged into arkworks upstream, still we're waiting +//! for new version on crates.io (v.0.4.3) //! //! Relevant PRs: //! - Elligator2 hash-to-curve for Twisted Edwards curves: https://github.com/arkworks-rs/algebra/pull/659 //! - Elligator2 hash-to-curve for Bandersnatch: https://github.com/arkworks-rs/algebra/pull/758 +//! +//! This is mostly a verbatim copy of such PRs contribution. use ark_ec::{ hashing::{curve_maps::swu::parity, map_to_curve_hasher::MapToCurve, HashToCurveError}, diff --git a/src/utils/mod.rs b/src/utils/mod.rs new file mode 100644 index 0000000..3089a9c --- /dev/null +++ b/src/utils/mod.rs @@ -0,0 +1,39 @@ +//! Features expected to land into Arkworks at some point in the future + +/// Elligator 2 hash-to-curve. +pub(crate) mod elligator2; +/// Twisted Edwards to Short Weierstrass mapping. +pub(crate) mod te_sw_map; +// Common utilities +pub(crate) mod common; + +pub(crate) use common::*; + +pub use te_sw_map::{sw_to_te, te_to_sw, SWMapping}; + +#[macro_export] +macro_rules! suite_types { + ($suite:ident) => { + #[allow(dead_code)] + pub type Secret = $crate::Secret<$suite>; + #[allow(dead_code)] + pub type Public = $crate::Public<$suite>; + #[allow(dead_code)] + pub type Input = $crate::Input<$suite>; + #[allow(dead_code)] + pub type Output = $crate::Output<$suite>; + #[allow(dead_code)] + pub type AffinePoint = $crate::AffinePoint<$suite>; + #[allow(dead_code)] + pub type ScalarField = $crate::ScalarField<$suite>; + #[allow(dead_code)] + pub type BaseField = $crate::BaseField<$suite>; + #[allow(dead_code)] + pub type IetfProof = $crate::ietf::Proof<$suite>; + #[allow(dead_code)] + pub type PedersenProof = $crate::pedersen::Proof<$suite>; + #[cfg(feature = "ring")] + #[allow(dead_code)] + pub type RingProof = $crate::ring::Proof<$suite>; + }; +} diff --git a/src/arkworks/te_sw_map.rs b/src/utils/te_sw_map.rs similarity index 87% rename from src/arkworks/te_sw_map.rs rename to src/utils/te_sw_map.rs index a4c84d0..677f228 100644 --- a/src/arkworks/te_sw_map.rs +++ b/src/utils/te_sw_map.rs @@ -1,4 +1,3 @@ -use crate::*; use ark_ec::{ short_weierstrass::{Affine as WeierstrassAffine, SWCurveConfig}, twisted_edwards::{Affine as EdwardsAffine, MontCurveConfig, TECurveConfig}, @@ -13,7 +12,8 @@ pub trait MapConfig: TECurveConfig + SWCurveConfig + MontCurveConfig { const MONT_B_INV: ::BaseField; } -pub fn map_sw_to_te(point: &WeierstrassAffine) -> Option> { +/// Map a a point in Short Weierstrass form into its corresponding point in Twisted Edwards form. +pub fn sw_to_te(point: &WeierstrassAffine) -> Option> { // First map the point from SW to Montgomery // (Bx - A/3, By) let mx = ::COEFF_B * point.x - C::MONT_A_OVER_THREE; @@ -30,7 +30,8 @@ pub fn map_sw_to_te(point: &WeierstrassAffine) -> Option(point: &EdwardsAffine) -> Option> { +/// Map a a point in Twisted Edwards form into its corresponding point in Short Weierstrass form. +pub fn te_to_sw(point: &EdwardsAffine) -> Option> { // Map from TE to Montgomery: (1+y)/(1-y), (1+y)/(x(1-y)) let v_denom = <::BaseField as One>::one() - point.y; let w_denom = point.x - point.x * point.y; @@ -79,14 +80,14 @@ impl SWMapping for EdwardsAffine { fn from_sw(sw: WeierstrassAffine) -> Self { const ERR_MSG: &str = "SW to TE is expected to be implemented only for curves supporting the mapping"; - map_sw_to_te(&sw).expect(ERR_MSG) + sw_to_te(&sw).expect(ERR_MSG) } #[inline(always)] fn into_sw(self) -> WeierstrassAffine { const ERR_MSG: &str = "TE to SW is expected to be implemented only for curves supporting the mapping"; - map_te_to_sw(&self).expect(ERR_MSG) + te_to_sw(&self).expect(ERR_MSG) } #[inline(always)]