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:
Aaryamann Challani
2024-05-27 12:55:11 +05:30
committed by GitHub
parent 3abd6ce6cc
commit f2dccaeecc
23 changed files with 255 additions and 2005 deletions

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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"

View File

@@ -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

View File

@@ -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
View 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
View 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
View 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
View 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"

View File

@@ -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);

View File

@@ -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
View 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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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(())
}
}