Skip to content

Commit

Permalink
Expose utilities (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
davxy authored Sep 13, 2024
1 parent d848703 commit 840f6a2
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 58 deletions.
6 changes: 0 additions & 6 deletions src/arkworks/mod.rs

This file was deleted.

2 changes: 1 addition & 1 deletion src/codec.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ark_ec::short_weierstrass::SWCurveConfig;
use arkworks::te_sw_map;
use utils::te_sw_map;

use super::*;

Expand Down
4 changes: 1 addition & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/ring.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down
63 changes: 56 additions & 7 deletions src/suites/bandersnatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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::<SWAffine>(None);

let te_point = map_sw_to_te::<BandersnatchConfig>(&org_point).unwrap();
let te_point = sw_to_te::<BandersnatchConfig>(&org_point).unwrap();
assert!(te_point.is_on_curve());

let sw_point = map_te_to_sw::<BandersnatchConfig>(&te_point).unwrap();
let sw_point = te_to_sw::<BandersnatchConfig>(&te_point).unwrap();
assert!(sw_point.is_on_curve());

assert_eq!(org_point, sw_point);
Expand Down Expand Up @@ -404,3 +402,54 @@ mod test_vectors_ring_sw {
testing::test_vectors_process::<V>(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);
}
39 changes: 5 additions & 34 deletions src/utils.rs → src/utils/common.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,20 @@
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};

#[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<H: Digest>(data: &[u8]) -> digest::Output<H> {
H::new().chain_update(data).finalize()
}

/// Generic HMAC wrapper.
#[cfg(feature = "rfc-6979")]
pub(crate) fn hmac<H: Digest + digest::core_api::BlockSizeUser>(sk: &[u8], data: &[u8]) -> Vec<u8> {
fn hmac<H: Digest + digest::core_api::BlockSizeUser>(sk: &[u8], data: &[u8]) -> Vec<u8> {
use hmac::{Mac, SimpleHmac};
SimpleHmac::<H>::new_from_slice(sk)
.expect("HMAC can take key of any size")
Expand Down Expand Up @@ -115,15 +85,16 @@ pub fn hash_to_curve_tai_rfc_9381<S: Suite>(data: &[u8]) -> Option<AffinePoint<S
/// is given by the h2c_suite_ID_string parameter.
///
/// The input `data` is defined to be `salt || alpha` according to the RFC 9281.
#[allow(unused)]
pub fn hash_to_curve_ell2_rfc_9380<S: Suite>(
data: &[u8],
h2c_suite_id: &[u8],
) -> Option<AffinePoint<S>>
where
<S as Suite>::Hasher: Default + Clone + FixedOutputReset + 'static,
crate::CurveConfig<S>: ark_ec::twisted_edwards::TECurveConfig,
crate::CurveConfig<S>: crate::arkworks::elligator2::Elligator2Config,
crate::arkworks::elligator2::Elligator2Map<crate::CurveConfig<S>>:
crate::CurveConfig<S>: crate::utils::elligator2::Elligator2Config,
crate::utils::elligator2::Elligator2Map<crate::CurveConfig<S>>:
ark_ec::hashing::map_to_curve_hasher::MapToCurve<<AffinePoint<S> as AffineRepr>::Group>,
{
use ark_ec::hashing::HashToCurve;
Expand All @@ -140,7 +111,7 @@ where
let hasher = ark_ec::hashing::map_to_curve_hasher::MapToCurveBasedHasher::<
<AffinePoint<S> as AffineRepr>::Group,
ark_ff::field_hashers::DefaultFieldHasher<<S as Suite>::Hasher, SEC_PARAM>,
crate::arkworks::elligator2::Elligator2Map<crate::CurveConfig<S>>,
crate::utils::elligator2::Elligator2Map<crate::CurveConfig<S>>,
>::new(&dst)
.ok()?;

Expand Down
5 changes: 4 additions & 1 deletion src/arkworks/elligator2.rs → src/utils/elligator2.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand Down
39 changes: 39 additions & 0 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -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>;
};
}
11 changes: 6 additions & 5 deletions src/arkworks/te_sw_map.rs → src/utils/te_sw_map.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::*;
use ark_ec::{
short_weierstrass::{Affine as WeierstrassAffine, SWCurveConfig},
twisted_edwards::{Affine as EdwardsAffine, MontCurveConfig, TECurveConfig},
Expand All @@ -13,7 +12,8 @@ pub trait MapConfig: TECurveConfig + SWCurveConfig + MontCurveConfig {
const MONT_B_INV: <Self as CurveConfig>::BaseField;
}

pub fn map_sw_to_te<C: MapConfig>(point: &WeierstrassAffine<C>) -> Option<EdwardsAffine<C>> {
/// Map a a point in Short Weierstrass form into its corresponding point in Twisted Edwards form.
pub fn sw_to_te<C: MapConfig>(point: &WeierstrassAffine<C>) -> Option<EdwardsAffine<C>> {
// First map the point from SW to Montgomery
// (Bx - A/3, By)
let mx = <C as MontCurveConfig>::COEFF_B * point.x - C::MONT_A_OVER_THREE;
Expand All @@ -30,7 +30,8 @@ pub fn map_sw_to_te<C: MapConfig>(point: &WeierstrassAffine<C>) -> Option<Edward
Some(EdwardsAffine::new_unchecked(v, w))
}

pub fn map_te_to_sw<C: MapConfig>(point: &EdwardsAffine<C>) -> Option<WeierstrassAffine<C>> {
/// Map a a point in Twisted Edwards form into its corresponding point in Short Weierstrass form.
pub fn te_to_sw<C: MapConfig>(point: &EdwardsAffine<C>) -> Option<WeierstrassAffine<C>> {
// Map from TE to Montgomery: (1+y)/(1-y), (1+y)/(x(1-y))
let v_denom = <<C as CurveConfig>::BaseField as One>::one() - point.y;
let w_denom = point.x - point.x * point.y;
Expand Down Expand Up @@ -79,14 +80,14 @@ impl<C: MapConfig> SWMapping<C> for EdwardsAffine<C> {
fn from_sw(sw: WeierstrassAffine<C>) -> 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<C> {
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)]
Expand Down

0 comments on commit 840f6a2

Please sign in to comment.