chore: refactor common utilities and traits (#7)

* chore: refactor common utilities and traits

* chore: use bytes instead of string
This commit is contained in:
Aaryamann Challani
2024-05-25 17:20:12 +05:30
committed by GitHub
parent ff143a33f5
commit 3fcbda1d71
10 changed files with 137 additions and 198 deletions

View File

@@ -1,9 +1,7 @@
use crate::define_curve_tests;
use crate::stealth_commitments::{AffineWrapper, RawFr, StealthAddressOnCurve};
use crate::stealth_commitments::{AffineWrapper, StealthAddressOnCurve};
use ark_bls12_377::g1::{G1_GENERATOR_X, G1_GENERATOR_Y};
use ark_bls12_377::{Fq, Fr, G1Affine, G1Projective};
use ark_ff::PrimeField;
use tiny_keccak::{Hasher, Keccak};
#[allow(non_camel_case_types)]
pub struct Bls12_377_G1Affine(G1Affine);
@@ -12,6 +10,14 @@ impl AffineWrapper for Bls12_377_G1Affine {
fn new(x: Self::Fq, y: Self::Fq) -> Self {
Bls12_377_G1Affine(G1Affine::new(x, y))
}
fn get_generator_x() -> Self::Fq {
G1_GENERATOR_X
}
fn get_generator_y() -> Self::Fq {
G1_GENERATOR_Y
}
}
impl From<Bls12_377_G1Affine> for G1Projective {
@@ -20,32 +26,10 @@ impl From<Bls12_377_G1Affine> for G1Projective {
}
}
impl RawFr for Fr {
type Fr = Fr;
fn as_u64(&self) -> u64 {
self.0 .0[0]
}
}
impl StealthAddressOnCurve for ark_bls12_377::Bls12_377 {
type Projective = G1Projective;
type Affine = Bls12_377_G1Affine;
type Fr = Fr;
fn derive_public_key(private_key: &Self::Fr) -> Self::Projective {
let g1_generator_affine = Self::Affine::new(G1_GENERATOR_X, G1_GENERATOR_Y);
(Self::Projective::from(g1_generator_affine)) * *private_key
}
fn hash_to_fr(input: &[u8]) -> Self::Fr {
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())
}
}
define_curve_tests!(ark_bls12_377::Bls12_377);

View File

@@ -1,10 +1,7 @@
use crate::define_curve_tests;
use crate::stealth_commitments::{AffineWrapper, RawFr, StealthAddressOnCurve};
use crate::stealth_commitments::{AffineWrapper, StealthAddressOnCurve};
use ark_bls12_381::g1::{G1_GENERATOR_X, G1_GENERATOR_Y};
use ark_bls12_381::{Fq, Fr, G1Affine, G1Projective};
use ark_ff::PrimeField;
use tiny_keccak::{Hasher, Keccak};
#[allow(non_camel_case_types)]
pub struct Bls12_381_G1Affine(G1Affine);
@@ -13,6 +10,14 @@ impl AffineWrapper for Bls12_381_G1Affine {
fn new(x: Self::Fq, y: Self::Fq) -> Self {
Bls12_381_G1Affine(G1Affine::new(x, y))
}
fn get_generator_x() -> Self::Fq {
G1_GENERATOR_X
}
fn get_generator_y() -> Self::Fq {
G1_GENERATOR_Y
}
}
impl From<Bls12_381_G1Affine> for G1Projective {
@@ -21,32 +26,10 @@ impl From<Bls12_381_G1Affine> for G1Projective {
}
}
impl RawFr for Fr {
type Fr = Fr;
fn as_u64(&self) -> u64 {
self.0 .0[0]
}
}
impl StealthAddressOnCurve for ark_bls12_381::Bls12_381 {
type Projective = G1Projective;
type Affine = Bls12_381_G1Affine;
type Fr = Fr;
fn derive_public_key(private_key: &Self::Fr) -> Self::Projective {
let g1_generator_affine = Self::Affine::new(G1_GENERATOR_X, G1_GENERATOR_Y);
(Self::Projective::from(g1_generator_affine)) * *private_key
}
fn hash_to_fr(input: &[u8]) -> Self::Fr {
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())
}
}
define_curve_tests!(ark_bls12_381::Bls12_381);

View File

@@ -1,8 +1,7 @@
use crate::define_curve_tests;
use crate::stealth_commitments::{AffineWrapper, RawFr, StealthAddressOnCurve};
use crate::stealth_commitments::{AffineWrapper, StealthAddressOnCurve};
use ark_bn254::g1::{G1_GENERATOR_X, G1_GENERATOR_Y};
use ark_bn254::{Fq, Fr, G1Affine, G1Projective};
use rln::hashers::{hash_to_field, poseidon_hash};
impl AffineWrapper for G1Affine {
@@ -10,12 +9,13 @@ impl AffineWrapper for G1Affine {
fn new(x: Self::Fq, y: Self::Fq) -> Self {
G1Affine::new(x, y)
}
}
impl RawFr for Fr {
type Fr = Fr;
fn as_u64(&self) -> u64 {
self.0 .0[0]
fn get_generator_x() -> Self::Fq {
G1_GENERATOR_X
}
fn get_generator_y() -> Self::Fq {
G1_GENERATOR_Y
}
}
@@ -24,11 +24,6 @@ impl StealthAddressOnCurve for ark_bn254::Bn254 {
type Affine = G1Affine;
type Fr = Fr;
fn derive_public_key(private_key: &Self::Fr) -> Self::Projective {
let g1_generator_affine = Self::Affine::new(G1_GENERATOR_X, G1_GENERATOR_Y);
(Self::Projective::from(g1_generator_affine)) * *private_key
}
fn hash_to_fr(input: &[u8]) -> Self::Fr {
poseidon_hash(&[hash_to_field(input)])
}

View File

@@ -1,5 +1,5 @@
mod macros;
mod stealth_commitments;
mod test_gen_macro;
#[cfg(feature = "bls12_377")]
mod bls12_377_impl;

View File

@@ -1,8 +1,6 @@
use crate::define_curve_tests;
use crate::stealth_commitments::{AffineWrapper, RawFr, StealthAddressOnCurve};
use ark_ff::PrimeField;
use crate::stealth_commitments::{AffineWrapper, StealthAddressOnCurve};
use ark_pallas::{Affine, Fq, Fr, Projective, G_GENERATOR_X, G_GENERATOR_Y};
use tiny_keccak::{Hasher, Keccak};
#[allow(non_camel_case_types)]
pub struct PallasAffine(Affine);
@@ -11,6 +9,14 @@ impl AffineWrapper for PallasAffine {
fn new(x: Self::Fq, y: Self::Fq) -> Self {
PallasAffine(Affine::new(x, y))
}
fn get_generator_x() -> Self::Fq {
G_GENERATOR_X
}
fn get_generator_y() -> Self::Fq {
G_GENERATOR_Y
}
}
impl From<PallasAffine> for Projective {
@@ -19,34 +25,12 @@ impl From<PallasAffine> for Projective {
}
}
impl RawFr for Fr {
type Fr = Fr;
fn as_u64(&self) -> u64 {
self.0 .0[0]
}
}
pub struct Pallas;
impl StealthAddressOnCurve for Pallas {
type Projective = Projective;
type Affine = PallasAffine;
type Fr = Fr;
fn derive_public_key(private_key: &Self::Fr) -> Self::Projective {
let generator_affine = Self::Affine::new(G_GENERATOR_X, G_GENERATOR_Y);
(Self::Projective::from(generator_affine)) * *private_key
}
fn hash_to_fr(input: &[u8]) -> Self::Fr {
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())
}
}
define_curve_tests!(Pallas);

View File

@@ -1,53 +1,37 @@
use crate::define_curve_tests;
use crate::stealth_commitments::{AffineWrapper, RawFr, StealthAddressOnCurve};
use ark_ff::PrimeField;
use ark_secp256k1::{Affine as G1Affine, Fq, Fr, Projective as G1Projective};
use crate::stealth_commitments::{AffineWrapper, StealthAddressOnCurve};
use ark_secp256k1::{Affine, Fq, Fr, Projective};
use ark_secp256k1::{G_GENERATOR_X, G_GENERATOR_Y};
use tiny_keccak::{Hasher, Keccak};
#[allow(non_camel_case_types)]
pub struct Secp256k1_G1Affine(G1Affine);
impl AffineWrapper for Secp256k1_G1Affine {
pub struct Secp256k1_Affine(Affine);
impl AffineWrapper for Secp256k1_Affine {
type Fq = Fq;
fn new(x: Self::Fq, y: Self::Fq) -> Self {
Secp256k1_G1Affine(G1Affine::new(x, y))
Secp256k1_Affine(Affine::new(x, y))
}
fn get_generator_x() -> Self::Fq {
G_GENERATOR_X
}
fn get_generator_y() -> Self::Fq {
G_GENERATOR_Y
}
}
impl From<Secp256k1_G1Affine> for G1Projective {
fn from(value: Secp256k1_G1Affine) -> Self {
G1Projective::from(value.0)
}
}
impl RawFr for Fr {
type Fr = Fr;
fn as_u64(&self) -> u64 {
self.0 .0[0]
impl From<Secp256k1_Affine> for Projective {
fn from(value: Secp256k1_Affine) -> Self {
Projective::from(value.0)
}
}
pub struct Secp256k1;
impl StealthAddressOnCurve for Secp256k1 {
type Projective = G1Projective;
type Affine = Secp256k1_G1Affine;
type Projective = Projective;
type Affine = Secp256k1_Affine;
type Fr = Fr;
fn derive_public_key(private_key: &Self::Fr) -> Self::Projective {
let g1_generator_affine = Self::Affine::new(G_GENERATOR_X, G_GENERATOR_Y);
(Self::Projective::from(g1_generator_affine)) * *private_key
}
fn hash_to_fr(input: &[u8]) -> Self::Fr {
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())
}
}
define_curve_tests!(Secp256k1);

View File

@@ -1,53 +1,37 @@
use crate::define_curve_tests;
use crate::stealth_commitments::{AffineWrapper, RawFr, StealthAddressOnCurve};
use ark_ff::PrimeField;
use ark_secp256r1::{Affine as G1Affine, Fq, Fr, Projective as G1Projective};
use crate::stealth_commitments::{AffineWrapper, StealthAddressOnCurve};
use ark_secp256r1::{Affine, Fq, Fr, Projective};
use ark_secp256r1::{G_GENERATOR_X, G_GENERATOR_Y};
use tiny_keccak::{Hasher, Keccak};
#[allow(non_camel_case_types)]
pub struct Secp256r1_G1Affine(G1Affine);
impl AffineWrapper for Secp256r1_G1Affine {
pub struct Secp256r1_Affine(Affine);
impl AffineWrapper for Secp256r1_Affine {
type Fq = Fq;
fn new(x: Self::Fq, y: Self::Fq) -> Self {
Secp256r1_G1Affine(G1Affine::new(x, y))
Secp256r1_Affine(Affine::new(x, y))
}
fn get_generator_x() -> Self::Fq {
G_GENERATOR_X
}
fn get_generator_y() -> Self::Fq {
G_GENERATOR_Y
}
}
impl From<Secp256r1_G1Affine> for G1Projective {
fn from(value: Secp256r1_G1Affine) -> Self {
G1Projective::from(value.0)
}
}
impl RawFr for Fr {
type Fr = Fr;
fn as_u64(&self) -> u64 {
self.0 .0[0]
impl From<Secp256r1_Affine> for Projective {
fn from(value: Secp256r1_Affine) -> Self {
Projective::from(value.0)
}
}
pub struct Secp256r1;
impl StealthAddressOnCurve for Secp256r1 {
type Projective = G1Projective;
type Affine = Secp256r1_G1Affine;
type Projective = Projective;
type Affine = Secp256r1_Affine;
type Fr = Fr;
fn derive_public_key(private_key: &Self::Fr) -> Self::Projective {
let g1_generator_affine = Self::Affine::new(G_GENERATOR_X, G_GENERATOR_Y);
(Self::Projective::from(g1_generator_affine)) * *private_key
}
fn hash_to_fr(input: &[u8]) -> Self::Fr {
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())
}
}
define_curve_tests!(Secp256r1);

View File

@@ -1,26 +1,63 @@
use ark_ec::CurveGroup;
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 tiny_keccak::{Hasher, Keccak};
pub trait AffineWrapper {
type Fq: ark_ff::PrimeField;
fn new(x: Self::Fq, y: Self::Fq) -> Self;
fn get_generator_x() -> Self::Fq;
fn get_generator_y() -> Self::Fq;
}
pub trait RawFr {
type Fr;
fn as_u64(&self) -> u64;
pub trait HasViewTag {
fn get_view_tag(&self) -> u64;
}
// Implement HasViewTag for any Fp type
impl<P: FpConfig<N>, const N: usize> HasViewTag for Fp<P, N> {
fn get_view_tag(&self) -> u64 {
self.0 .0[0]
}
}
pub trait ToBytesFromProjective {
fn to_bytes(&self) -> Vec<u8>;
}
// Implement ToBytesFromProjective for any ProjectiveCurve
impl<G: CurveGroup> ToBytesFromProjective for G
where
G::Affine: CanonicalSerialize,
{
fn to_bytes(&self) -> Vec<u8> {
let affine = self.into_affine();
let mut bytes = Vec::new();
affine.serialize_uncompressed(&mut bytes).unwrap();
bytes
}
}
pub trait StealthAddressOnCurve {
type Projective: Display
+ Add<Output = Self::Projective>
+ Mul<Self::Fr, Output = Self::Projective>;
+ Mul<Self::Fr, Output = Self::Projective>
+ From<Self::Affine>
+ ark_ec::CurveGroup;
type Affine: AffineWrapper;
type Fr: Add<Self::Fr, Output = Self::Fr> + ark_ff::PrimeField + RawFr;
fn derive_public_key(private_key: &Self::Fr) -> Self::Projective;
type Fr: Add<Self::Fr, Output = Self::Fr> + ark_ff::PrimeField + HasViewTag;
fn derive_public_key(private_key: &Self::Fr) -> Self::Projective {
let generator_affine = Self::Affine::new(
Self::Affine::get_generator_x(),
Self::Affine::get_generator_y(),
);
(Self::Projective::from(generator_affine)) * *private_key
}
fn random_keypair() -> (Self::Fr, Self::Projective) {
let private_key = Self::generate_random_fr();
@@ -31,7 +68,15 @@ pub trait StealthAddressOnCurve {
let mut rng = OsRng;
Self::Fr::rand(&mut rng)
}
fn hash_to_fr(input: &[u8]) -> Self::Fr;
fn hash_to_fr(input: &[u8]) -> Self::Fr {
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())
}
fn compute_shared_point(
private_key: Self::Fr,
public_key: Self::Projective,
@@ -45,11 +90,9 @@ pub trait StealthAddressOnCurve {
ephemeral_private_key: Self::Fr,
) -> (Self::Projective, u64) {
let q = Self::compute_shared_point(ephemeral_private_key, viewing_public_key);
let inputs = q.to_string();
let q_hashed = Self::hash_to_fr(inputs.as_bytes());
let q_hashed = Self::hash_to_fr(&q.to_bytes());
let q_hashed_in_g1 = Self::derive_public_key(&q_hashed);
let view_tag = q_hashed.as_u64();
let view_tag = q_hashed.get_view_tag();
(q_hashed_in_g1 + spending_public_key, view_tag)
}
@@ -61,11 +104,10 @@ pub trait StealthAddressOnCurve {
) -> Option<Self::Fr> {
let q_receiver = Self::compute_shared_point(viewing_key, ephemeral_public_key);
let inputs_receiver = q_receiver.to_string();
let q_receiver_hashed = Self::hash_to_fr(inputs_receiver.as_bytes());
let q_receiver_hashed = Self::hash_to_fr(&q_receiver.to_bytes());
// Check if retrieved view tag matches the expected view tag
let view_tag = q_receiver_hashed.as_u64();
let view_tag = q_receiver_hashed.get_view_tag();
if view_tag == expected_view_tag {
let stealth_private_key = spending_key + q_receiver_hashed;
Some(stealth_private_key)

View File

@@ -1,9 +1,6 @@
use crate::define_curve_tests;
use crate::stealth_commitments::{AffineWrapper, RawFr, StealthAddressOnCurve};
use ark_ff::PrimeField;
use crate::stealth_commitments::{AffineWrapper, StealthAddressOnCurve};
use ark_vesta::{Affine, Fq, Fr, Projective, G_GENERATOR_X, G_GENERATOR_Y};
use tiny_keccak::{Hasher, Keccak};
#[allow(non_camel_case_types)]
pub struct VestaAffine(Affine);
@@ -12,6 +9,14 @@ impl AffineWrapper for VestaAffine {
fn new(x: Self::Fq, y: Self::Fq) -> Self {
VestaAffine(Affine::new(x, y))
}
fn get_generator_x() -> Self::Fq {
G_GENERATOR_X
}
fn get_generator_y() -> Self::Fq {
G_GENERATOR_Y
}
}
impl From<VestaAffine> for Projective {
@@ -20,34 +25,12 @@ impl From<VestaAffine> for Projective {
}
}
impl RawFr for Fr {
type Fr = Fr;
fn as_u64(&self) -> u64 {
self.0 .0[0]
}
}
pub struct Vesta;
impl StealthAddressOnCurve for Vesta {
type Projective = Projective;
type Affine = VestaAffine;
type Fr = Fr;
fn derive_public_key(private_key: &Self::Fr) -> Self::Projective {
let generator_affine = Self::Affine::new(G_GENERATOR_X, G_GENERATOR_Y);
(Self::Projective::from(generator_affine)) * *private_key
}
fn hash_to_fr(input: &[u8]) -> Self::Fr {
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())
}
}
define_curve_tests!(Vesta);