diff --git a/Cargo.toml b/Cargo.toml index 7d841019..31d956c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,10 @@ bench = false doctest = false required-features = ["executable"] +[[bench]] +name = "dsa" +harness = false + [[bench]] name = "hash" harness = false diff --git a/benches/README.md b/benches/README.md index 3113d620..ff5e437b 100644 --- a/benches/README.md +++ b/benches/README.md @@ -54,3 +54,76 @@ 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 the conjecture on the security of the toy protocol 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 + +##### Public Key + +| Function | Falcon512 | RPO-STARK | +| ------------------- | --------- | --------- | +| Apple M1 Pro | | | +| Apple M2 Max | | | +| Amazon Graviton 3 | | +| AMD Ryzen 9 5950X | | | +| AMD EPYC 9R14 | | | +| Intel Core i5-8279U | 594 µs | 9 µs | +| Intel Xeon 8375C | | | + +##### Secret Key + +| Function | Falcon512 | RPO-STARK | +| ------------------- | --------- | --------- | +| Apple M1 Pro | | | +| Apple M2 Max | | | +| Amazon Graviton 3 | | +| AMD Ryzen 9 5950X | | | +| AMD EPYC 9R14 | | | +| Intel Core i5-8279U | 584 ms | 865 ns | +| Intel Xeon 8375C | | | + +#### Signature Generation + +| Function | Falcon512 | RPO-STARK | +| ------------------- | --------- | --------- | +| Apple M1 Pro | | | +| Apple M2 Max | | | +| Amazon Graviton 3 | | +| AMD Ryzen 9 5950X | | | +| AMD EPYC 9R14 | | | +| Intel Core i5-8279U | 1.8 ms | 130 ms | +| Intel Xeon 8375C | | | + +#### Signature Verification + +| Function | Falcon512 | RPO-STARK | +| ------------------- | --------- | --------- | +| Apple M1 Pro | | | +| Apple M2 Max | | | +| Amazon Graviton 3 | | +| AMD Ryzen 9 5950X | | | +| AMD EPYC 9R14 | | | +| Intel Core i5-8279U | 1.2 ms | 7.9 ms | +| Intel Xeon 8375C | | | + +### 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 + ``` \ No newline at end of file diff --git a/benches/dsa.rs b/benches/dsa.rs new file mode 100644 index 00000000..5c5da0a2 --- /dev/null +++ b/benches/dsa.rs @@ -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);