diff --git a/sdk/src/baby_jub_jub_impl.rs b/sdk/src/baby_jub_jub_impl.rs index 534c595..9c38719 100644 --- a/sdk/src/baby_jub_jub_impl.rs +++ b/sdk/src/baby_jub_jub_impl.rs @@ -6,7 +6,6 @@ pub struct BabyJubJub; impl StealthAddressOnCurve for BabyJubJub { type Projective = EdwardsProjective; - type Fr = Fr; } #[cfg(feature = "ffi")] diff --git a/sdk/src/bls12_377_impl.rs b/sdk/src/bls12_377_impl.rs index 09b531a..44f5e7f 100644 --- a/sdk/src/bls12_377_impl.rs +++ b/sdk/src/bls12_377_impl.rs @@ -4,7 +4,6 @@ use ark_bls12_377::{Bls12_377, Fr, G1Projective}; impl StealthAddressOnCurve for Bls12_377 { type Projective = G1Projective; - type Fr = Fr; } #[cfg(feature = "ffi")] diff --git a/sdk/src/bls12_381_impl.rs b/sdk/src/bls12_381_impl.rs index 10efc09..4eb4bc0 100644 --- a/sdk/src/bls12_381_impl.rs +++ b/sdk/src/bls12_381_impl.rs @@ -4,7 +4,6 @@ use ark_bls12_381::{Bls12_381, Fr, G1Projective}; impl StealthAddressOnCurve for Bls12_381 { type Projective = G1Projective; - type Fr = Fr; } #[cfg(feature = "ffi")] diff --git a/sdk/src/bn254_impl.rs b/sdk/src/bn254_impl.rs index 8f4157d..01346df 100644 --- a/sdk/src/bn254_impl.rs +++ b/sdk/src/bn254_impl.rs @@ -3,7 +3,6 @@ use ark_bn254::{Bn254, Fr, G1Projective}; impl StealthAddressOnCurve for Bn254 { type Projective = G1Projective; - type Fr = Fr; } #[cfg(feature = "ffi")] diff --git a/sdk/src/bw6_761_impl.rs b/sdk/src/bw6_761_impl.rs index 3de8bdf..196d49e 100644 --- a/sdk/src/bw6_761_impl.rs +++ b/sdk/src/bw6_761_impl.rs @@ -4,7 +4,6 @@ use ark_bw6_761::{Fr, G1Projective, BW6_761}; impl StealthAddressOnCurve for BW6_761 { type Projective = G1Projective; - type Fr = Fr; } #[cfg(feature = "ffi")] diff --git a/sdk/src/pallas_impl.rs b/sdk/src/pallas_impl.rs index 06c6d24..440646c 100644 --- a/sdk/src/pallas_impl.rs +++ b/sdk/src/pallas_impl.rs @@ -6,7 +6,6 @@ pub struct Pallas; impl StealthAddressOnCurve for Pallas { type Projective = Projective; - type Fr = Fr; } #[cfg(feature = "ffi")] diff --git a/sdk/src/secp256k1_impl.rs b/sdk/src/secp256k1_impl.rs index 58569a5..19946a6 100644 --- a/sdk/src/secp256k1_impl.rs +++ b/sdk/src/secp256k1_impl.rs @@ -6,7 +6,6 @@ pub struct Secp256k1; impl StealthAddressOnCurve for Secp256k1 { type Projective = Projective; - type Fr = Fr; } #[cfg(feature = "ffi")] diff --git a/sdk/src/secp256r1_impl.rs b/sdk/src/secp256r1_impl.rs index 8e4b0d0..f704c0f 100644 --- a/sdk/src/secp256r1_impl.rs +++ b/sdk/src/secp256r1_impl.rs @@ -6,7 +6,6 @@ pub struct Secp256r1; impl StealthAddressOnCurve for Secp256r1 { type Projective = Projective; - type Fr = Fr; } #[cfg(feature = "ffi")] diff --git a/sdk/src/stealth_addresses.rs b/sdk/src/stealth_addresses.rs index 74fff52..accc6b4 100644 --- a/sdk/src/stealth_addresses.rs +++ b/sdk/src/stealth_addresses.rs @@ -1,10 +1,10 @@ -use ark_ec::{CurveGroup, Group}; +use ark_ec::{AffineRepr, CurveGroup, Group}; use ark_ff::{Fp, FpConfig, PrimeField}; use ark_serialize::CanonicalSerialize; use ark_std::rand::rngs::OsRng; use ark_std::UniformRand; use std::fmt::Display; -use std::ops::{Add, Mul}; +use std::ops::Add; use tiny_keccak::{Hasher, Keccak}; /// A trait for types that have a view tag. @@ -13,7 +13,10 @@ pub trait HasViewTag { fn get_view_tag(&self) -> u64; } -impl, const N: usize> HasViewTag for Fp { +impl, const N: usize> HasViewTag for Fp +where + Fp: PrimeField, +{ fn get_view_tag(&self) -> u64 { self.0 .0[0] } @@ -37,18 +40,18 @@ where } } +// we want to route through CurveGroup -> Config -> ScalarField +type FrOf

= + <<

::Projective as CurveGroup>::Affine as AffineRepr>::ScalarField; + /// A trait for implementing stealth addresses on elliptic curves. pub trait StealthAddressOnCurve { /// The projective representation of the elliptic curve point. type Projective: Display + Add - + Mul + From<::Affine> + CurveGroup; - /// The scalar field of the elliptic curve. - type Fr: Add + PrimeField + HasViewTag; - /// Derives a public key from a given private key. /// /// # Arguments @@ -59,7 +62,7 @@ pub trait StealthAddressOnCurve { /// /// The derived public key. #[inline] - fn derive_public_key(private_key: &Self::Fr) -> Self::Projective { + fn derive_public_key(private_key: &FrOf) -> Self::Projective { Self::Projective::generator() * *private_key } @@ -69,7 +72,7 @@ pub trait StealthAddressOnCurve { /// /// A tuple containing the private key and the derived public key. #[inline] - fn random_keypair() -> (Self::Fr, Self::Projective) { + fn random_keypair() -> (FrOf, Self::Projective) { let private_key = Self::generate_random_fr(); let public_key = Self::derive_public_key(&private_key); (private_key, public_key) @@ -81,8 +84,8 @@ pub trait StealthAddressOnCurve { /// /// A random scalar field element. #[inline] - fn generate_random_fr() -> Self::Fr { - Self::Fr::rand(&mut OsRng) + fn generate_random_fr() -> FrOf { + FrOf::::rand(&mut OsRng) } /// Hashes an input byte slice to a scalar field element. @@ -95,14 +98,17 @@ pub trait StealthAddressOnCurve { /// /// A scalar field element derived from the hash of the input. #[inline] - fn hash_to_fr(input: &[u8]) -> Self::Fr { + fn hash_to_fr(input: &[u8]) -> FrOf + where + FrOf: HasViewTag, + { let mut hash = [0; 32]; let mut hasher = Keccak::v256(); hasher.update(input); hasher.finalize(&mut hash); // We export the hash as a field element - Self::Fr::from_le_bytes_mod_order(hash.as_slice()) + FrOf::::from_le_bytes_mod_order(hash.as_slice()) } /// Computes a shared elliptic curve point given a private key and a public key. @@ -117,7 +123,7 @@ pub trait StealthAddressOnCurve { /// The computed shared elliptic curve point. #[inline] fn compute_shared_point( - private_key: Self::Fr, + private_key: FrOf, public_key: Self::Projective, ) -> Self::Projective { public_key * private_key @@ -138,8 +144,11 @@ pub trait StealthAddressOnCurve { fn generate_stealth_address( viewing_public_key: Self::Projective, spending_public_key: Self::Projective, - ephemeral_private_key: Self::Fr, - ) -> (Self::Projective, u64) { + ephemeral_private_key: FrOf, + ) -> (Self::Projective, u64) + where + FrOf: HasViewTag, + { let q = Self::compute_shared_point(ephemeral_private_key, viewing_public_key); let q_hashed = Self::hash_to_fr(&q.to_bytes()); let q_hashed_in_g1 = Self::derive_public_key(&q_hashed); @@ -162,10 +171,13 @@ pub trait StealthAddressOnCurve { #[inline] fn generate_stealth_private_key( ephemeral_public_key: Self::Projective, - viewing_key: Self::Fr, - spending_key: Self::Fr, + viewing_key: FrOf, + spending_key: FrOf, expected_view_tag: u64, - ) -> Option { + ) -> Option> + where + FrOf: HasViewTag, + { let q_receiver = Self::compute_shared_point(viewing_key, ephemeral_public_key); let q_receiver_hashed = Self::hash_to_fr(&q_receiver.to_bytes()); if q_receiver_hashed.get_view_tag() == expected_view_tag { diff --git a/sdk/src/vesta_impl.rs b/sdk/src/vesta_impl.rs index c37716c..893dae3 100644 --- a/sdk/src/vesta_impl.rs +++ b/sdk/src/vesta_impl.rs @@ -6,7 +6,6 @@ pub struct Vesta; impl StealthAddressOnCurve for Vesta { type Projective = Projective; - type Fr = Fr; } #[cfg(feature = "ffi")]