Skip to content

Commit

Permalink
Merge branch 'main' into pedersen-secret-gen
Browse files Browse the repository at this point in the history
  • Loading branch information
davxy committed Jul 25, 2024
2 parents 81f3167 + c924bf6 commit 7429588
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 178 deletions.
58 changes: 25 additions & 33 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,19 @@ ark-ec = { version = "0.4", default-features = false }
ark-ff = { version = "0.4", default-features = false }
ark-std = { version = "0.4", default-features = false }
ark-serialize = { version = "0.4", default-features = false }
rand_core = { version = "0.6", default-features = false, optional = true }
zeroize = { version = "1.8", default-features = false }
digest = { version = "0.10", default-features = false }
sha2 = { version = "0.10", default-features = false }
rand_chacha = { version = "0.3", default-features = false }
rayon = { version = "1.10", default-features = false, optional = true }
zeroize = { version = "1.8", default-features = false }
hmac = {version = "0.12", default-features = false, optional = true }
digest = { version = "0.10", default-features = false }
merlin = { version = "3.0", default-features = false, optional = true }
# Waiting for crates.io
ring-proof = { package = "ring", git = "https://github.com/davxy/ring-proof", branch = "extended", default-features = false, optional = true }
# Curves
ark-secp256r1 = { version = "0.4.0", default-features = false, optional = true }
ark-ed25519 = { version = "0.4.0", default-features = false, optional = true }
ark-ed-on-bls12-381-bandersnatch = { version = "0.4.0", default-features = false, optional = true }
ark-bls12-381 = { version = "0.4.0", default-features = false, optional = true }
# Hashing
sha2 = { version = "0.10", default-features = false }
# Ring VRF (waiting for crates.io)
fflonk = { git = "https://github.com/w3f/fflonk", default-features = false, optional = true }
ring-proof = { package = "ring", git = "https://github.com/davxy/ring-proof", branch = "extended", default-features = false, optional = true }

[dev-dependencies]
ark-ed25519 = "0.4"
Expand All @@ -39,48 +35,44 @@ indexmap = { version = "2.2.6", features = ["serde"] }
[features]
default = [ "std" ]
std = [
"getrandom",
"ark-std/std",
"ark-std/getrandom",
"ark-ec/std",
"rand_core/std",
"fflonk/std",
"ring-proof/std",
]
getrandom = [
"rand_core",
"ark-std/getrandom"
]
curves = [
"secp256r1",
"ed25519",
"bandersnatch",
"ring-proof?/std",
]
secp256r1 = [
"ark-secp256r1",
"rfc-6979",
]
ed25519 = [ "ark-ed25519" ]
bandersnatch = [ "ark-ed-on-bls12-381-bandersnatch" ]
parallel = [
"ark-ec/parallel",
"ark-ff/parallel",
"ark-std/parallel",
"ring-proof?/parallel",
"fflonk?/parallel",
"rayon",
]
ring = [
"bandersnatch",
"fflonk",
"ring-proof",
"ark-bls12-381/curve",
"merlin",
]
rfc-6979 = [ "hmac" ]
full = [
"curves",
"secp256r1",
"ed25519",
"bandersnatch",
"ring",
]

# Optimizations
parallel = [
"ark-ec/parallel",
"ark-ff/parallel",
"ark-std/parallel",
"ring-proof?/parallel",
"rayon",
]
asm = [
"ark-ff/asm",
"ring-proof?/asm"
]

# Deterministic ring-proof (unsafe)
test-vectors = [
"ring-proof?/test-vectors"
]
3 changes: 3 additions & 0 deletions src/arkworks/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//! 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;
106 changes: 106 additions & 0 deletions src/arkworks/te_sw_map.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use crate::*;
use ark_ec::{
short_weierstrass::{Affine as WeierstrassAffine, SWCurveConfig},
twisted_edwards::{Affine as EdwardsAffine, MontCurveConfig, TECurveConfig},
CurveConfig,
};
use ark_ff::{Field, One};
use ark_std::borrow::Cow;

// Constants used in mapping TE form to SW form and vice versa
pub trait MapConfig: TECurveConfig + SWCurveConfig + MontCurveConfig {
const MONT_A_OVER_THREE: <Self as CurveConfig>::BaseField;
const MONT_B_INV: <Self as CurveConfig>::BaseField;
}

pub fn map_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;
let my = <C as MontCurveConfig>::COEFF_B * point.y;

// Then we map the TE point to Montgamory
// (x,y) -> (x/y,(x−1)/(x+1))
let v_denom = my.inverse()?;
let x_p_1 = mx + <<C as CurveConfig>::BaseField as One>::one();
let w_denom = x_p_1.inverse()?;
let v = mx * v_denom;
let w = (mx - <<C as CurveConfig>::BaseField as One>::one()) * w_denom;

Some(EdwardsAffine::new_unchecked(v, w))
}

pub fn map_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;
let v_denom_inv = v_denom.inverse()?;
let w_denom_inv = w_denom.inverse()?;
let v_w_num = <<C as CurveConfig>::BaseField as One>::one() + point.y;
let v = v_w_num * v_denom_inv;
let w = v_w_num * w_denom_inv;

// Map Montgamory to SW: ((x+A/3)/B,y/B)
let x = C::MONT_B_INV * (v + C::MONT_A_OVER_THREE);
let y = C::MONT_B_INV * w;

Some(WeierstrassAffine::new_unchecked(x, y))
}

pub trait SWMapping<C: SWCurveConfig> {
fn from_sw(sw: WeierstrassAffine<C>) -> Self;

fn into_sw(self) -> WeierstrassAffine<C>;

fn to_sw_slice(slice: &[Self]) -> Cow<[WeierstrassAffine<C>]>
where
Self: Sized;
}

impl<C: SWCurveConfig> SWMapping<C> for WeierstrassAffine<C> {
#[inline(always)]
fn from_sw(sw: WeierstrassAffine<C>) -> Self {
sw
}

#[inline(always)]
fn into_sw(self) -> WeierstrassAffine<C> {
self
}

#[inline(always)]
fn to_sw_slice(slice: &[Self]) -> Cow<[WeierstrassAffine<C>]> {
Cow::Borrowed(slice)
}
}

impl<C: MapConfig> SWMapping<C> for EdwardsAffine<C> {
#[inline(always)]
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)
}

#[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)
}

#[inline(always)]
fn to_sw_slice(slice: &[Self]) -> Cow<[WeierstrassAffine<C>]> {
let pks;
#[cfg(feature = "parallel")]
{
use rayon::prelude::*;
pks = slice.par_iter().map(|p| p.into_sw()).collect();
}
#[cfg(not(feature = "parallel"))]
{
pks = slice.iter().map(|p| p.into_sw()).collect();
}
Cow::Owned(pks)
}
}
7 changes: 4 additions & 3 deletions src/codec.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use ark_ec::short_weierstrass::SWCurveConfig;
use arkworks::te_sw_map;

use super::*;

Expand Down Expand Up @@ -53,13 +54,13 @@ impl<S: Suite> Codec<S> for Sec1Codec
where
BaseField<S>: ark_ff::PrimeField,
CurveConfig<S>: SWCurveConfig,
AffinePoint<S>: utils::SWMapping<CurveConfig<S>>,
AffinePoint<S>: te_sw_map::SWMapping<CurveConfig<S>>,
{
const BIG_ENDIAN: bool = true;

fn point_encode(pt: &AffinePoint<S>, buf: &mut Vec<u8>) {
use ark_ff::biginteger::BigInteger;
use utils::SWMapping;
use te_sw_map::SWMapping;

if pt.is_zero() {
buf.push(0x00);
Expand All @@ -78,7 +79,7 @@ where

fn point_decode(buf: &[u8]) -> Result<AffinePoint<S>, Error> {
use ark_ff::biginteger::BigInteger;
use utils::SWMapping;
use te_sw_map::SWMapping;
type SWAffine<C> = ark_ec::short_weierstrass::Affine<C>;

if buf.len() == 1 && buf[0] == 0x00 {
Expand Down
9 changes: 4 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub mod utils;
#[cfg(feature = "ring")]
pub mod ring;

#[allow(unused)]
mod arkworks;

#[cfg(test)]
Expand Down Expand Up @@ -210,12 +211,10 @@ impl<S: Suite> Secret<S> {
Self::from_scalar(scalar)
}

/// Construct an ephemeral `Secret` using system randomness.
#[cfg(feature = "getrandom")]
pub fn ephemeral() -> Self {
use rand_core::RngCore;
/// Construct an ephemeral `Secret` using some random generator.
pub fn from_rand(rng: &mut impl ark_std::rand::RngCore) -> Self {
let mut seed = [0u8; 32];
rand_core::OsRng.fill_bytes(&mut seed);
rng.fill_bytes(&mut seed);
Self::from_seed(&seed)
}

Expand Down
Loading

0 comments on commit 7429588

Please sign in to comment.