Skip to content

Commit

Permalink
chore: add signatures benchmarks (#354)
Browse files Browse the repository at this point in the history
  • Loading branch information
Al-Kindi-0 authored Dec 13, 2024
1 parent 335c50f commit cae87a2
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- [BREAKING] Refactor error messages and use `thiserror` to derive errors (#344).
- [BREAKING] Updated Winterfell dependency to v0.11 (#346).
- Added RPO-STARK based DSA (#349).
- Added benchmarks for DSA implementations (#354).

## 0.12.0 (2024-10-30)

Expand Down
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[package]
name = "miden-crypto"
version = "0.13.0"
version = "0.14.0"
description = "Miden Cryptographic primitives"
authors = ["miden contributors"]
readme = "README.md"
license = "MIT"
repository = "https://github.com/0xPolygonMiden/crypto"
documentation = "https://docs.rs/miden-crypto/0.13.0"
documentation = "https://docs.rs/miden-crypto/0.14.0"
categories = ["cryptography", "no-std"]
keywords = ["miden", "crypto", "hash", "merkle"]
edition = "2021"
Expand All @@ -19,6 +19,10 @@ bench = false
doctest = false
required-features = ["executable"]

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

[[bench]]
name = "hash"
harness = false
Expand Down Expand Up @@ -63,11 +67,13 @@ std = [
[dependencies]
blake3 = { version = "1.5", default-features = false }
clap = { version = "4.5", optional = true, features = ["derive"] }
getrandom = { version = "0.2", features = ["js"] }
num = { version = "0.4", default-features = false, features = ["alloc", "libm"] }
num-complex = { version = "0.4", default-features = false }
rand = { version = "0.8", default-features = false }
rand_chacha = { version = "0.3", default-features = false }
rand_core = { version = "0.6", default-features = false }
rand-utils = {git = 'https://github.com/Al-Kindi-0/winterfell', package = "winter-rand-utils" , branch = 'al-zk', optional = true }
rayon = { version = "1.10", optional = true }
serde = { version = "1.0", default-features = false, optional = true, features = ["derive"] }
sha3 = { version = "0.10", default-features = false }
Expand All @@ -78,8 +84,6 @@ winter-prover = {git = 'https://github.com/Al-Kindi-0/winterfell', branch = 'al-
winter-verifier = {git = 'https://github.com/Al-Kindi-0/winterfell', branch = 'al-zk' }
winter-math = {git = 'https://github.com/Al-Kindi-0/winterfell', branch = 'al-zk' }
winter-utils = {git = 'https://github.com/Al-Kindi-0/winterfell', branch = 'al-zk' }
rand-utils = {git = 'https://github.com/Al-Kindi-0/winterfell', package = "winter-rand-utils" , branch = 'al-zk', optional = true }
getrandom = { version = "0.2", features = ["js"] }

[dev-dependencies]
assert_matches = { version = "1.5", default-features = false }
Expand Down
58 changes: 52 additions & 6 deletions benches/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Miden VM Hash Functions
# Benchmarks

## Miden VM Hash Functions
In the Miden VM, we make use of different hash functions. Some of these are "traditional" hash functions, like `BLAKE3`, which are optimized for out-of-STARK performance, while others are algebraic hash functions, like `Rescue Prime`, and are more optimized for a better performance inside the STARK. In what follows, we benchmark several such hash functions and compare against other constructions that are used by other proving systems. More precisely, we benchmark:

* **BLAKE3** as specified [here](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf) and implemented [here](https://github.com/BLAKE3-team/BLAKE3) (with a wrapper exposed via this crate).
Expand All @@ -8,13 +10,13 @@ In the Miden VM, we make use of different hash functions. Some of these are "tra
* **Rescue Prime Optimized (RPO)** as specified [here](https://eprint.iacr.org/2022/1577) and implemented in this crate.
* **Rescue Prime Extended (RPX)** a variant of the [xHash](https://eprint.iacr.org/2023/1045) hash function as implemented in this crate.

## Comparison and Instructions
### Comparison and Instructions

### Comparison
#### Comparison
We benchmark the above hash functions using two scenarios. The first is a 2-to-1 $(a,b)\mapsto h(a,b)$ hashing where both $a$, $b$ and $h(a,b)$ are the digests corresponding to each of the hash functions.
The second scenario is that of sequential hashing where we take a sequence of length $100$ field elements and hash these to produce a single digest. The digests are $4$ field elements in a prime field with modulus $2^{64} - 2^{32} + 1$ (i.e., 32 bytes) for Poseidon, Rescue Prime and RPO, and an array `[u8; 32]` for SHA3 and BLAKE3.

#### Scenario 1: 2-to-1 hashing `h(a,b)`
##### Scenario 1: 2-to-1 hashing `h(a,b)`

| Function | BLAKE3 | SHA3 | Poseidon | Rp64_256 | RPO_256 | RPX_256 |
| ------------------- | ------ | ------- | --------- | --------- | ------- | ------- |
Expand All @@ -26,7 +28,7 @@ The second scenario is that of sequential hashing where we take a sequence of le
| Intel Core i5-8279U | 68 ns | 536 ns | 2.0 µs | 13.6 µs | 8.5 µs | 4.4 µs |
| Intel Xeon 8375C | 67 ns | | | | 8.2 µs | |

#### Scenario 2: Sequential hashing of 100 elements `h([a_0,...,a_99])`
##### Scenario 2: Sequential hashing of 100 elements `h([a_0,...,a_99])`

| Function | BLAKE3 | SHA3 | Poseidon | Rp64_256 | RPO_256 | RPX_256 |
| ------------------- | -------| ------- | --------- | --------- | ------- | ------- |
Expand All @@ -42,7 +44,7 @@ Notes:
- On Graviton 3, RPO256 and RPX256 are run with SVE acceleration enabled.
- On AMD EPYC 9R14, RPO256 and RPX256 are run with AVX2 acceleration enabled.

### Instructions
#### Instructions
Before you can run the benchmarks, you'll need to make sure you have Rust [installed](https://www.rust-lang.org/tools/install). After that, to run the benchmarks for RPO and BLAKE3, clone the current repository, and from the root directory of the repo run the following:

```
Expand All @@ -54,3 +56,47 @@ To run the benchmarks for Rescue Prime, Poseidon and SHA3, clone the following [
```
cargo bench hash
```

## Miden VM DSA

We make use of the following digital signature algorithms (DSA) in the Miden VM:

* **RPO-Falcon512** as specified [here](https://falcon-sign.info/falcon.pdf) with the one difference being the use of the RPO hash function for the hash-to-point algorithm (Algorithm 3 in the previous reference) instead of SHAKE256.
* **RPO-STARK** as specified [here](https://eprint.iacr.org/2024/1553), where the parameters are the ones for the unique-decoding regime (UDR) with the two differences:
* We rely on Conjecture 1 in the [ethSTARK](https://eprint.iacr.org/2021/582) paper.
* The number of FRI queries is $30$ and the grinding factor is $12$ bits. Thus using the previous point we can argue that the modified version achieves at least $102$ bits of average-case existential unforgeability security against $2^{113}$-query bound adversaries that can obtain up to $2^{64}$ signatures under the same public key.



### Comparison and Instructions

#### Comparison


##### Key Generation

| DSA | RPO-Falcon512 | RPO-STARK |
| ------------------- | :-----------: | :-------: |
| Apple M1 Pro | 590 ms | 6 µs |
| Intel Core i5-8279U | 585 ms | 10 µs |

##### Signature Generation

| DSA | RPO-Falcon512 | RPO-STARK |
| ------------------- | :-----------: | :-------: |
| Apple M1 Pro | 1.5 ms | 78 ms |
| Intel Core i5-8279U | 1.8 ms | 130 ms |

##### Signature Verification

| DSA | RPO-Falcon512 | RPO-STARK |
| ------------------- | :-----------: | :-------: |
| Apple M1 Pro | 0.7 ms | 4.5 ms |
| Intel Core i5-8279U | 1.2 ms | 7.9 ms |

#### Instructions
Before you can run the benchmarks, you'll need to make sure you have Rust [installed](https://www.rust-lang.org/tools/install). After that, to run the benchmarks, clone the current repository, and from the root directory of the repo run the following:

```
cargo bench --bench dsa
```
88 changes: 88 additions & 0 deletions benches/dsa.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use miden_crypto::dsa::{
rpo_falcon512::SecretKey as FalconSecretKey, rpo_stark::SecretKey as RpoStarkSecretKey,
};
use rand_utils::rand_array;

fn key_gen_falcon(c: &mut Criterion) {
c.bench_function("Falcon public key generation", |bench| {
bench.iter_batched(|| FalconSecretKey::new(), |sk| sk.public_key(), BatchSize::SmallInput)
});

c.bench_function("Falcon secret key generation", |bench| {
bench.iter_batched(|| {}, |_| FalconSecretKey::new(), BatchSize::SmallInput)
});
}

fn key_gen_rpo_stark(c: &mut Criterion) {
c.bench_function("RPO-STARK public key generation", |bench| {
bench.iter_batched(
|| RpoStarkSecretKey::random(),
|sk| sk.public_key(),
BatchSize::SmallInput,
)
});

c.bench_function("RPO-STARK secret key generation", |bench| {
bench.iter_batched(|| {}, |_| RpoStarkSecretKey::random(), BatchSize::SmallInput)
});
}

fn signature_gen_falcon(c: &mut Criterion) {
c.bench_function("Falcon signature generation", |bench| {
bench.iter_batched(
|| (FalconSecretKey::new(), rand_array().into()),
|(sk, msg)| sk.sign(msg),
BatchSize::SmallInput,
)
});
}

fn signature_gen_rpo_stark(c: &mut Criterion) {
c.bench_function("RPO-STARK signature generation", |bench| {
bench.iter_batched(
|| (RpoStarkSecretKey::random(), rand_array().into()),
|(sk, msg)| sk.sign(msg),
BatchSize::SmallInput,
)
});
}

fn signature_ver_falcon(c: &mut Criterion) {
c.bench_function("Falcon signature verification", |bench| {
bench.iter_batched(
|| {
let sk = FalconSecretKey::new();
let msg = rand_array().into();
(sk.public_key(), msg, sk.sign(msg))
},
|(pk, msg, sig)| pk.verify(msg, &sig),
BatchSize::SmallInput,
)
});
}

fn signature_ver_rpo_stark(c: &mut Criterion) {
c.bench_function("RPO-STARK signature verification", |bench| {
bench.iter_batched(
|| {
let sk = RpoStarkSecretKey::random();
let msg = rand_array().into();
(sk.public_key(), msg, sk.sign(msg))
},
|(pk, msg, sig)| pk.verify(msg, &sig),
BatchSize::SmallInput,
)
});
}

criterion_group!(
dsa_group,
key_gen_falcon,
key_gen_rpo_stark,
signature_gen_falcon,
signature_gen_rpo_stark,
signature_ver_falcon,
signature_ver_rpo_stark
);
criterion_main!(dsa_group);

0 comments on commit cae87a2

Please sign in to comment.