Skip to content

Commit

Permalink
Merge pull request #68 from Chia-Network/chia-keys
Browse files Browse the repository at this point in the history
add new crate chia-bls
  • Loading branch information
arvidn authored Nov 10, 2022
2 parents 37599b0 + 928e443 commit 9ba3b3b
Show file tree
Hide file tree
Showing 19 changed files with 1,471 additions and 6 deletions.
22 changes: 21 additions & 1 deletion .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
run: |
pytest tests
benchmarks:
generator-benchmarks:
name: Generator performance
runs-on: benchmark
strategy:
Expand Down Expand Up @@ -121,3 +121,23 @@ jobs:
cd tests
./generate-programs.py
./run-programs.py
benchmarks:
name: rust benchmarks
runs-on: benchmark
strategy:
fail-fast: false

steps:
- uses: actions/checkout@v2
with:
fetch-depth: 1

- name: Set up rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable

- name: cargo bench
run: |
cargo bench --all
8 changes: 4 additions & 4 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ jobs:
uses: actions/upload-artifact@v3
with:
name: packages
path: ./target/wheels/
path: ./wheel/target/wheels/

check-typestubs:
name: Check chia_rs.pyi
Expand Down Expand Up @@ -280,7 +280,7 @@ jobs:
uses: actions/upload-artifact@v3
with:
name: packages
path: ./target/wheels/
path: ./wheel/target/wheels/

fmt:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -310,7 +310,7 @@ jobs:
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features --all
args: --all-features --workspace

fuzz_targets:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -338,7 +338,7 @@ jobs:
with:
toolchain: stable
- name: cargo test
run: cargo test
run: cargo test --workspace --all-features

upload:
name: Upload to PyPI - ${{ matrix.os.name }} ${{ matrix.python.major-dot-minor }} ${{ matrix.arch.name }}
Expand Down
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# the "wheel" crate is excluded from the workspace because pyo3 has problems with
# "cargo test" and "cargo bench"
[workspace]
members = ["wasm", "wheel", "chia_streamable_macro"]
members = ["wasm", "chia_streamable_macro", "chia-bls"]
exclude = ["wheel"]

[package]
name = "chia"
Expand Down
31 changes: 31 additions & 0 deletions chia-bls/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "chia-bls"
version = "0.1.0"
edition = "2021"

[dependencies]
tiny-bip39 = "=1.0.0"
anyhow = "=1.0.65"
# the newer sha2 crate doesn't implement the digest traits required by hkdf
sha2 = "=0.9.9"
bls12_381_plus = "=0.7.0"
num-bigint = "=0.4.3"
hkdf = "=0.11.0"
group = "=0.12.0"

[dev-dependencies]
hex = "^0.4.3"
rand = "^0.8.5"
criterion = "^0.4"

[[bench]]
name = "derive_key"
harness = false

[[bench]]
name = "sign"
harness = false

[[bench]]
name = "verify"
harness = false
76 changes: 76 additions & 0 deletions chia-bls/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
Library providing building blocks for a Chia wallet.

BIP39 mnemonic handling:

```
fn entropy_to_mnemonic(entropy: &[u8; 32]) -> String
fn mnemonic_to_entropy(mnemonic: &str) -> Result<[u8; 32], Error>
fn entropy_to_seed(entropy: &[u8; 32]) -> [u8; 64]
```

SecretKey

```
impl SecretKey {
pub fn from_seed(seed: &[u8; 64]) -> SecretKey
pub fn from_bytes(bytes: &[u8; 32]) -> Option<SecretKey>
pub fn to_bytes(&self) -> [u8; 32]
pub fn public_key(&self) -> PublicKey
pub fn derive_unhardened(&self, idx: u32) -> SecretKey
pub fn derive_hardened(&self, idx: u32) -> SecretKey
}
```

PublicKey

```
impl PublicKey {
pub fn from_bytes(bytes: &[u8; 48]) -> Option<PublicKey>
pub fn to_bytes(&self) -> [u8; 48]
pub fn derive_unhardened(&self, idx: u32) -> PublicKey
}
```

Unhardened Key derivation (`Key` can be both a secret- or public key)

```
fn master_to_wallet_unhardened_intermediate<Key: DerivableKey>(key: &Key) -> Key
fn master_to_wallet_unhardened<Key: DerivableKey>(key: &Key, idx: u32) -> Key
```

Hardened key derivation (only SecretKey)

```
fn master_to_wallet_hardened_intermediate(key: &SecretKey) -> SecretKey
fn master_to_wallet_hardened(key: &SecretKey, idx: u32) -> SecretKey
fn master_to_pool_singleton(key: &SecretKey, pool_wallet_idx: u32) -> SecretKey
fn master_to_pool_authentication(key: &SecretKey, pool_wallet_idx: u32, idx: u32) -> SecretKey
```

Signature

```
impl Signature {
pub fn from_bytes(buf: &[u8; 96]) -> Option<Signature>
pub fn to_bytes(&self) -> [u8; 96]
pub fn aggregate(&mut self, sig: &Signature)
}
impl Default for Signature {
fn default() -> Self
}
```

sign and verify (using the Augmented scheme)

```
pub fn sign<Msg: AsRef<[u8]>>(sk: &SecretKey, msg: Msg) -> Signature
pub fn aggregate<Sig: Borrow<Signature>, I>(sigs: I) -> Signature
where I: IntoIterator<Item = Sig>
pub fn verify<Msg: AsRef<[u8]>>(sig: &Signature, key: &PublicKey, msg: Msg) -> bool
pub fn aggregate_verify<Pk: Borrow<PublicKey>, Msg: Borrow<[u8]>, I>(sig: &Signature, data: I) -> bool
where I: IntoIterator<Item = (Pk, Msg)>
```
46 changes: 46 additions & 0 deletions chia-bls/benches/derive_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use chia_bls::derivable_key::DerivableKey;
use chia_bls::secret_key::SecretKey;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
use std::time::Instant;

fn key_derivation_benchmark(c: &mut Criterion) {
let mut rng = StdRng::seed_from_u64(1337);
let mut data = [0u8; 32];
rng.fill(data.as_mut_slice());

let sk = SecretKey::from_seed(&data);
let pk = sk.public_key();

c.bench_function("secret key, unhardened", |b| {
b.iter_custom(|iters| {
let start = Instant::now();
for i in 0..iters {
black_box(sk.derive_unhardened(i as u32));
}
start.elapsed()
})
});
c.bench_function("secret key, hardened", |b| {
b.iter_custom(|iters| {
let start = Instant::now();
for i in 0..iters {
black_box(sk.derive_hardened(i as u32));
}
start.elapsed()
})
});
c.bench_function("public key, unhardened", |b| {
b.iter_custom(|iters| {
let start = Instant::now();
for i in 0..iters {
black_box(pk.derive_unhardened(i as u32));
}
start.elapsed()
})
});
}

criterion_group!(key_derivation, key_derivation_benchmark);
criterion_main!(key_derivation);
29 changes: 29 additions & 0 deletions chia-bls/benches/sign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use chia_bls::secret_key::SecretKey;
use chia_bls::signature::sign;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};

fn sign_benchmark(c: &mut Criterion) {
let mut rng = StdRng::seed_from_u64(1337);
let mut data = [0u8; 32];
rng.fill(data.as_mut_slice());

let sk = SecretKey::from_seed(&data);
let small_msg = b"The quick brown fox jumps over the lazy dog";
let large_msg = [42_u8; 4096];

c.bench_function("sign, small msg", |b| {
b.iter(|| {
sign(&sk, black_box(&small_msg));
});
});
c.bench_function("sign, 4kiB msg", |b| {
b.iter(|| {
sign(&sk, black_box(&large_msg));
});
});
}

criterion_group!(signing, sign_benchmark);
criterion_main!(signing);
33 changes: 33 additions & 0 deletions chia-bls/benches/verify.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use chia_bls::secret_key::SecretKey;
use chia_bls::signature;
use chia_bls::signature::sign;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};

fn verify_benchmark(c: &mut Criterion) {
let mut rng = StdRng::seed_from_u64(1337);
let mut data = [0u8; 32];
rng.fill(data.as_mut_slice());

let sk = SecretKey::from_seed(&data);
let pk = sk.public_key();
let msg_small = b"The quick brown fox jumps over the lazy dog";
let msg_large = [42_u8; 4096];
let sig_small = sign(&sk, &msg_small);
let sig_large = sign(&sk, &msg_large);

c.bench_function("verify, small msg", |b| {
b.iter(|| {
signature::verify(&sig_small, &pk, black_box(&msg_small));
});
});
c.bench_function("verify, 4kiB msg", |b| {
b.iter(|| {
signature::verify(&sig_large, &pk, black_box(&msg_large));
});
});
}

criterion_group!(verify, verify_benchmark);
criterion_main!(verify);
3 changes: 3 additions & 0 deletions chia-bls/fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target
corpus
artifacts
32 changes: 32 additions & 0 deletions chia-bls/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "chia-bls-fuzz"
version = "0.0.0"
authors = ["Automatically generated"]
publish = false
edition = "2018"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.4"
pyo3 = { version = ">=0.17.2", features = ["auto-initialize"]}

[dependencies.chia-bls]
path = ".."

# Prevent this from interfering with workspaces
[workspace]
members = ["."]

[[bin]]
name = "derive"
path = "fuzz_targets/derive.rs"
test = false
doc = false

[[bin]]
name = "blspy-fidelity"
path = "fuzz_targets/blspy-fidelity.rs"
test = false
doc = false
Loading

0 comments on commit 9ba3b3b

Please sign in to comment.