mirror of
https://github.com/vacp2p/stealth-address-kit.git
synced 2026-01-08 22:27:58 -05:00
chore(repo): refactor into 2 crates, example and sdk (#10)
* chore: refactor into 2 crates, example and sdk * fix: cleanup * fix: readme
This commit is contained in:
committed by
GitHub
parent
3abd6ce6cc
commit
f2dccaeecc
2
.github/workflows/nightly-release.yml
vendored
2
.github/workflows/nightly-release.yml
vendored
@@ -39,6 +39,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: make deps
|
||||
- name: cross build
|
||||
working-directory: ./sdk
|
||||
run: |
|
||||
cross build --release --target ${{ matrix.target }} --features ${{ matrix.curve }}
|
||||
mkdir release
|
||||
@@ -84,6 +85,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: make deps
|
||||
- name: cross build
|
||||
working-directory: ./sdk
|
||||
run: |
|
||||
cross build --release --target ${{ matrix.target }} --features ${{ matrix.curve }}
|
||||
mkdir release
|
||||
|
||||
1907
Cargo.lock
generated
1907
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
56
Cargo.toml
56
Cargo.toml
@@ -1,51 +1,7 @@
|
||||
[package]
|
||||
name = "stealth_address_kit"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Stealth Address Kit: A Rust library for generating stealth addresses."
|
||||
license = "MIT"
|
||||
homepage = "https://vac.dev"
|
||||
[workspace]
|
||||
|
||||
[lib]
|
||||
name = "stealth_address_kit"
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[features]
|
||||
ffi = []
|
||||
bls12_381 = []
|
||||
bls12_377 = []
|
||||
secp256k1 = []
|
||||
secp256r1 = []
|
||||
bn254 = []
|
||||
pallas = []
|
||||
vesta = []
|
||||
bw6_761 = []
|
||||
default = ["all"]
|
||||
all = ["ffi", "secp256k1", "bls12_381", "bls12_377", "bn254", "secp256r1", "pallas", "vesta", "bw6_761"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rln = "0.3.4"
|
||||
ark-std = "0.4.0"
|
||||
num-bigint = "0.4.3"
|
||||
num-traits = "0.2.15"
|
||||
ark-ff = "0.4.1"
|
||||
ark-bn254 = "0.4.0"
|
||||
ark-bls12-381 = "0.4.0"
|
||||
ark-bls12-377 = "0.4.0"
|
||||
ark-secp256k1 = "0.4.0"
|
||||
ark-secp256r1 = "0.4.0"
|
||||
ark-pallas = "0.4.0"
|
||||
ark-vesta = "0.4.0"
|
||||
ark-bw6-761 = "0.4.0"
|
||||
tiny-keccak = { version = "=2.0.2", features = ["keccak"] }
|
||||
ark-ec = "0.4.1"
|
||||
ark-serialize = "0.4.1"
|
||||
cfg-if = "1.0.0"
|
||||
paste = "1.0.0"
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1.0.96"
|
||||
color-eyre = "0.6.2"
|
||||
members = [
|
||||
"sdk",
|
||||
"example"
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
8
Makefile
8
Makefile
@@ -1,4 +1,8 @@
|
||||
.PHONY: deps clean example
|
||||
|
||||
deps:
|
||||
cargo install cross --git https://github.com/cross-rs/cross.git --rev 1511a28
|
||||
@cargo install cross --git https://github.com/cross-rs/cross.git --rev 1511a28
|
||||
clean:
|
||||
cargo clean
|
||||
@cargo clean
|
||||
example:
|
||||
@cargo run -p stealth_address_kit_example
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# stealth-address-kit
|
||||
|
||||
Uses the [arkworks-rs](https://github.com/arkworks-rs/curves) suite of libraries, and utilities from [rln](https://github.com/vacp2p/zerokit)
|
||||
Uses the [arkworks-rs](https://github.com/arkworks-rs/curves) suite of libraries.
|
||||
|
||||
## Existing Implementations
|
||||
|
||||
@@ -16,7 +16,7 @@ Uses the [arkworks-rs](https://github.com/arkworks-rs/curves) suite of libraries
|
||||
## Usage
|
||||
|
||||
```rust
|
||||
use stealth_address_kit::{StealthAddressOnCurve};
|
||||
use stealth_address_kit::StealthAddressOnCurve;
|
||||
use ark_bn254::Bn254; // or ark_bls_12_381::Bls12_381 or ark_bls_12_377::Bls12_377, stealth_address_kit::Secp256k1, stealth_address_kit::Secp256r1, etc
|
||||
|
||||
fn main() {
|
||||
@@ -34,7 +34,7 @@ fn main() {
|
||||
panic!("View tags did not match");
|
||||
}
|
||||
|
||||
let derived_stealth_address = Bn254::derive_public_key(stealth_private_key_opt.unwrap());
|
||||
let derived_stealth_address = Bn254::derive_public_key(&stealth_private_key_opt.unwrap());
|
||||
assert_eq!(derived_stealth_address, stealth_address);
|
||||
}
|
||||
```
|
||||
@@ -45,7 +45,7 @@ fn main() {
|
||||
2. Create a new module in the `src` directory, with the curve name, suffixed by `_impl.rs`
|
||||
3. Implement the `StealthAddressOnCurve` trait for the curve
|
||||
4. Define the macro `define_curve_ffi`
|
||||
5. Add the curve to the `lib.rs` file, in the `mod` declaration
|
||||
5. Add the curve to the `lib.rs` file, in the `mod` declaration, as well as re-export if required
|
||||
6. Add the curve to the README
|
||||
7. Add the curve to the nightly release workflow
|
||||
|
||||
@@ -67,5 +67,4 @@ Check out the nightly releases.
|
||||
|
||||
## Attribution
|
||||
|
||||
- The original circuits for rln are located [here](https://github.com/Rate-Limting-Nullifier/circom-rln), by the PSE group
|
||||
- Inspired by the [erc-5564](https://eips.ethereum.org/EIPS/eip-5564) eip and the [poc](https://github.com/nerolation/EIP-Stealth-Address-ERC/blob/main/minimal_poc.ipynb) by Nerolation.
|
||||
|
||||
9
example/Cargo.toml
Normal file
9
example/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "stealth_address_kit_example"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
stealth_address_kit = { path = "../sdk", default-features = false, features = ["secp256r1"] }
|
||||
7
example/README.md
Normal file
7
example/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Example
|
||||
|
||||
Feel free to play around with the `curves` that are exported by the `stealth_address_kit` crate. The following example demonstrates how to generate a stealth address using the `secp256r1` curve.
|
||||
|
||||
Update the `Cargo.toml` file to include the features/curves that you would like to use.
|
||||
|
||||
Supported Curves: [here](../README.md#Existing-Implementations)
|
||||
78
example/src/main.rs
Normal file
78
example/src/main.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
use stealth_address_kit::Secp256r1;
|
||||
use stealth_address_kit::StealthAddressOnCurve;
|
||||
|
||||
type Curve = Secp256r1;
|
||||
|
||||
fn print_discriminator() {
|
||||
println!("{}", "+".repeat(100));
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let (spending_key, spending_public_key) = Curve::random_keypair();
|
||||
let (viewing_key, viewing_public_key) = Curve::random_keypair();
|
||||
|
||||
print_discriminator();
|
||||
println!("BOB PRE-COMPUTATION");
|
||||
print_discriminator();
|
||||
|
||||
println!("Spending Key: {}", &spending_key.to_string());
|
||||
println!("Spending Public Key: {}", &spending_public_key.to_string());
|
||||
println!("Viewing Key: {}", &viewing_key.to_string());
|
||||
println!("Viewing Public Key: {}", &viewing_public_key.to_string());
|
||||
|
||||
print_discriminator();
|
||||
|
||||
// generate ephemeral keypair
|
||||
let (ephemeral_private_key, ephemeral_public_key) = Curve::random_keypair();
|
||||
|
||||
print_discriminator();
|
||||
println!("ALICE COMPUTATION");
|
||||
print_discriminator();
|
||||
|
||||
println!(
|
||||
"Ephemeral Private Key: {}",
|
||||
&ephemeral_private_key.to_string()
|
||||
);
|
||||
println!(
|
||||
"Ephemeral Public Key: {}",
|
||||
&ephemeral_public_key.to_string()
|
||||
);
|
||||
|
||||
let (stealth_public_key, view_tag) = Curve::generate_stealth_address(
|
||||
viewing_public_key,
|
||||
spending_public_key,
|
||||
ephemeral_private_key,
|
||||
);
|
||||
|
||||
println!("Stealth Public Key: {}", &stealth_public_key.to_string());
|
||||
println!("View Tag: {}", &view_tag.to_string());
|
||||
|
||||
print_discriminator();
|
||||
|
||||
print_discriminator();
|
||||
println!("BOB COMPUTATION AFTER RECEIVING BROADCASTED KEY MATERIAL");
|
||||
print_discriminator();
|
||||
|
||||
let stealth_private_key_opt = Curve::generate_stealth_private_key(
|
||||
ephemeral_public_key,
|
||||
viewing_key,
|
||||
spending_key,
|
||||
view_tag,
|
||||
);
|
||||
|
||||
if let Some(stealth_private_key) = stealth_private_key_opt {
|
||||
let derived_stealth_public_key = Curve::derive_public_key(&stealth_private_key);
|
||||
|
||||
println!(
|
||||
"Derived Stealth Public Key: {}",
|
||||
&derived_stealth_public_key.to_string()
|
||||
);
|
||||
println!("Stealth Private Key: {}", &stealth_private_key.to_string());
|
||||
|
||||
assert_eq!(derived_stealth_public_key, stealth_public_key);
|
||||
|
||||
print_discriminator();
|
||||
} else {
|
||||
panic!("View tags did not match");
|
||||
};
|
||||
}
|
||||
51
sdk/Cargo.toml
Normal file
51
sdk/Cargo.toml
Normal file
@@ -0,0 +1,51 @@
|
||||
[package]
|
||||
name = "stealth_address_kit"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Stealth Address Kit: A Rust library for generating stealth addresses."
|
||||
license = "MIT"
|
||||
homepage = "https://vac.dev"
|
||||
|
||||
[lib]
|
||||
name = "stealth_address_kit"
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["staticlib", "rlib"]
|
||||
|
||||
[features]
|
||||
ffi = []
|
||||
bls12_381 = []
|
||||
bls12_377 = []
|
||||
secp256k1 = []
|
||||
secp256r1 = []
|
||||
bn254 = []
|
||||
pallas = []
|
||||
vesta = []
|
||||
bw6_761 = []
|
||||
default = ["secp256k1", "ffi"]
|
||||
all = ["ffi", "secp256k1", "bls12_381", "bls12_377", "bn254", "secp256r1", "pallas", "vesta", "bw6_761"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ark-std = "0.4.0"
|
||||
num-bigint = "0.4.3"
|
||||
num-traits = "0.2.15"
|
||||
ark-ff = "0.4.1"
|
||||
ark-bn254 = "0.4.0"
|
||||
ark-bls12-381 = "0.4.0"
|
||||
ark-bls12-377 = "0.4.0"
|
||||
ark-secp256k1 = "0.4.0"
|
||||
ark-secp256r1 = "0.4.0"
|
||||
ark-pallas = "0.4.0"
|
||||
ark-vesta = "0.4.0"
|
||||
ark-bw6-761 = "0.4.0"
|
||||
tiny-keccak = { version = "=2.0.2", features = ["keccak"] }
|
||||
ark-ec = "0.4.2"
|
||||
ark-serialize = "0.4.2"
|
||||
cfg-if = "1.0.0"
|
||||
paste = "1.0.0"
|
||||
rand = { version = "0.8.5", features = ["getrandom"] }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1.0.96"
|
||||
color-eyre = "0.6.2"
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::define_curve_tests;
|
||||
use crate::stealth_addresses::StealthAddressOnCurve;
|
||||
use crate::{define_curve_ffi, define_curve_tests};
|
||||
|
||||
use ark_bls12_377::{Bls12_377, Fr, G1Projective};
|
||||
|
||||
@@ -8,6 +8,8 @@ impl StealthAddressOnCurve for Bls12_377 {
|
||||
type Fr = Fr;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
use crate::define_curve_ffi;
|
||||
#[cfg(feature = "ffi")]
|
||||
define_curve_ffi!(bls12_377, Bls12_377, Fr, G1Projective, 32, 48);
|
||||
define_curve_tests!(ark_bls12_377::Bls12_377);
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::define_curve_tests;
|
||||
use crate::stealth_addresses::StealthAddressOnCurve;
|
||||
use crate::{define_curve_ffi, define_curve_tests};
|
||||
|
||||
use ark_bls12_381::{Bls12_381, Fr, G1Projective};
|
||||
|
||||
@@ -8,6 +8,8 @@ impl StealthAddressOnCurve for Bls12_381 {
|
||||
type Fr = Fr;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
use crate::define_curve_ffi;
|
||||
#[cfg(feature = "ffi")]
|
||||
define_curve_ffi!(bls12_381, Bls12_381, Fr, G1Projective, 32, 48);
|
||||
define_curve_tests!(Bls12_381);
|
||||
12
sdk/src/bn254_impl.rs
Normal file
12
sdk/src/bn254_impl.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
use crate::stealth_addresses::StealthAddressOnCurve;
|
||||
use crate::{define_curve_ffi, define_curve_tests};
|
||||
use ark_bn254::{Bn254, Fr, G1Projective};
|
||||
|
||||
impl StealthAddressOnCurve for Bn254 {
|
||||
type Projective = G1Projective;
|
||||
type Fr = Fr;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
define_curve_ffi!(bn254, Bn254, Fr, G1Projective, 32, 32);
|
||||
define_curve_tests!(Bn254);
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::define_curve_tests;
|
||||
use crate::stealth_addresses::StealthAddressOnCurve;
|
||||
use crate::{define_curve_ffi, define_curve_tests};
|
||||
|
||||
use ark_bw6_761::{Fr, G1Projective, BW6_761};
|
||||
|
||||
@@ -8,6 +8,8 @@ impl StealthAddressOnCurve for BW6_761 {
|
||||
type Fr = Fr;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
use crate::define_curve_ffi;
|
||||
#[cfg(feature = "ffi")]
|
||||
define_curve_ffi!(bw6_761, BW6_761, Fr, G1Projective, 48, 96);
|
||||
define_curve_tests!(BW6_761);
|
||||
@@ -20,3 +20,13 @@ mod vesta_impl;
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
mod ffi;
|
||||
|
||||
#[cfg(feature = "pallas")]
|
||||
pub use pallas_impl::Pallas;
|
||||
#[cfg(feature = "secp256k1")]
|
||||
pub use secp256k1_impl::Secp256k1;
|
||||
#[cfg(feature = "secp256r1")]
|
||||
pub use secp256r1_impl::Secp256r1;
|
||||
pub use stealth_addresses::StealthAddressOnCurve;
|
||||
#[cfg(feature = "vesta")]
|
||||
pub use vesta_impl::Vesta;
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::define_curve_tests;
|
||||
use crate::stealth_addresses::StealthAddressOnCurve;
|
||||
use crate::{define_curve_ffi, define_curve_tests};
|
||||
use ark_pallas::{Fr, Projective};
|
||||
|
||||
pub struct Pallas;
|
||||
@@ -9,6 +9,8 @@ impl StealthAddressOnCurve for Pallas {
|
||||
type Fr = Fr;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
use crate::define_curve_ffi;
|
||||
#[cfg(feature = "ffi")]
|
||||
define_curve_ffi!(pallas, Pallas, Fr, Projective, 32, 33);
|
||||
define_curve_tests!(Pallas);
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::define_curve_tests;
|
||||
use crate::stealth_addresses::StealthAddressOnCurve;
|
||||
use crate::{define_curve_ffi, define_curve_tests};
|
||||
use ark_secp256k1::{Fr, Projective};
|
||||
|
||||
pub struct Secp256k1;
|
||||
@@ -9,6 +9,8 @@ impl StealthAddressOnCurve for Secp256k1 {
|
||||
type Fr = Fr;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
use crate::define_curve_ffi;
|
||||
#[cfg(feature = "ffi")]
|
||||
define_curve_ffi!(secp256k1, Secp256k1, Fr, Projective, 32, 33);
|
||||
define_curve_tests!(Secp256k1);
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::define_curve_tests;
|
||||
use crate::stealth_addresses::StealthAddressOnCurve;
|
||||
use crate::{define_curve_ffi, define_curve_tests};
|
||||
use ark_secp256r1::{Fr, Projective};
|
||||
|
||||
pub struct Secp256r1;
|
||||
@@ -9,6 +9,8 @@ impl StealthAddressOnCurve for Secp256r1 {
|
||||
type Fr = Fr;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
use crate::define_curve_ffi;
|
||||
#[cfg(feature = "ffi")]
|
||||
define_curve_ffi!(secp256r1, Secp256r1, Fr, Projective, 32, 33);
|
||||
define_curve_tests!(Secp256r1);
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::define_curve_tests;
|
||||
use crate::stealth_addresses::StealthAddressOnCurve;
|
||||
use crate::{define_curve_ffi, define_curve_tests};
|
||||
use ark_vesta::{Fr, Projective};
|
||||
|
||||
pub struct Vesta;
|
||||
@@ -9,6 +9,8 @@ impl StealthAddressOnCurve for Vesta {
|
||||
type Fr = Fr;
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
use crate::define_curve_ffi;
|
||||
#[cfg(feature = "ffi")]
|
||||
define_curve_ffi!(vesta, Vesta, Fr, Projective, 32, 33);
|
||||
define_curve_tests!(Vesta);
|
||||
@@ -1,83 +0,0 @@
|
||||
use crate::stealth_addresses::StealthAddressOnCurve;
|
||||
use crate::{define_curve_ffi, define_curve_tests};
|
||||
use ark_bn254::{Bn254, Fr, G1Projective};
|
||||
#[allow(unused_imports)]
|
||||
use rln::ffi::*;
|
||||
use rln::hashers::{hash_to_field, poseidon_hash};
|
||||
|
||||
impl StealthAddressOnCurve for Bn254 {
|
||||
type Projective = G1Projective;
|
||||
type Fr = Fr;
|
||||
|
||||
fn hash_to_fr(input: &[u8]) -> Self::Fr {
|
||||
poseidon_hash(&[hash_to_field(input)])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ffi")]
|
||||
define_curve_ffi!(bn254, Bn254, Fr, G1Projective, 32, 32);
|
||||
define_curve_tests!(Bn254);
|
||||
|
||||
#[cfg(test)]
|
||||
mod rln_tests {
|
||||
use super::*;
|
||||
use ark_std::rand::thread_rng;
|
||||
use ark_std::UniformRand;
|
||||
use color_eyre::{Report, Result};
|
||||
use rln::public::RLN;
|
||||
use rln::utils::fr_to_bytes_le;
|
||||
use serde_json::json;
|
||||
use std::io::Cursor;
|
||||
|
||||
type Curve = ark_bn254::Bn254;
|
||||
|
||||
// this can only be tested for bn254 since that is the curve supported by RLN
|
||||
#[test]
|
||||
fn apply_stealth_membership_from_one_tree_to_another() -> Result<()> {
|
||||
let test_tree_height = 20;
|
||||
let resources = Cursor::new(json!({"resources_folder": "tree_height_20"}).to_string());
|
||||
let mut rln = RLN::new(test_tree_height, resources.clone())?;
|
||||
|
||||
let alice_leaf = Fr::rand(&mut thread_rng());
|
||||
let (alice_known_spending_sk, alice_known_spending_pk) = Curve::random_keypair();
|
||||
let alice_leaf_buffer = Cursor::new(fr_to_bytes_le(&alice_leaf));
|
||||
rln.set_leaf(0, alice_leaf_buffer)?;
|
||||
|
||||
// now the application sees that a user has been inserted into the tree
|
||||
let mut rln_app_tree = RLN::new(test_tree_height, resources)?;
|
||||
// the application generates a stealth address for alice
|
||||
let (ephemeral_private_key, ephemeral_public_key) = Curve::random_keypair();
|
||||
let (alice_stealth_address, view_tag) = Curve::generate_stealth_address(
|
||||
alice_known_spending_pk,
|
||||
alice_known_spending_pk,
|
||||
ephemeral_private_key,
|
||||
);
|
||||
|
||||
let parts = [alice_stealth_address.x, alice_stealth_address.y];
|
||||
let fr_parts = parts.map(|x| Fr::from(x.0));
|
||||
let alice_stealth_address_buffer = Cursor::new(fr_to_bytes_le(&poseidon_hash(&fr_parts)));
|
||||
rln_app_tree.set_leaf(0, alice_stealth_address_buffer)?;
|
||||
|
||||
// now alice's stealth address has been inserted into the tree, but alice has not
|
||||
// yet derived the secret for it -
|
||||
let alice_stealth_private_key_opt = Curve::generate_stealth_private_key(
|
||||
ephemeral_public_key,
|
||||
alice_known_spending_sk,
|
||||
alice_known_spending_sk,
|
||||
view_tag,
|
||||
);
|
||||
if alice_stealth_private_key_opt.is_none() {
|
||||
return Err(Report::msg("Invalid view tag"));
|
||||
}
|
||||
let alice_stealth_private_key = alice_stealth_private_key_opt.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
Curve::derive_public_key(&alice_stealth_private_key),
|
||||
alice_stealth_address
|
||||
);
|
||||
|
||||
// now alice may generate valid rln proofs for the rln app tree, using a address
|
||||
// derived from her address on the other tree
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user