Skip to content

Commit

Permalink
Merge pull request anoma#48 from nucypher/benchmark-primitives-size
Browse files Browse the repository at this point in the history
  • Loading branch information
piotr-roslaniec authored Feb 6, 2023
2 parents 530de97 + 6f1b7d4 commit 58515cf
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 10 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion ferveo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ ark-ed-on-bls12-381 = "0.3.0"
group-threshold-cryptography = { path = "../tpke" }
ferveo-common = { path = "../ferveo-common" }
subproductdomain = { path = "../subproductdomain" }
rand_core = "0.6.4"

[dependencies.digest]
version = "0.10.0"
Expand All @@ -66,4 +67,4 @@ harness = false

[profile.release]
opt-level = 3
lto = true
lto = true
9 changes: 9 additions & 0 deletions ferveo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ferveo

## Benchmarks

### Benchmarking primitives size

```sh
cargo run --example bench_primitives_size
```
144 changes: 144 additions & 0 deletions ferveo/examples/bench_primitives_size.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use ark_serialize::CanonicalSerialize;
use std::collections::BTreeSet;

use ark_bls12_381::Bls12_381 as EllipticCurve;
use ferveo::*;
use ferveo_common::ExternalValidator;
use itertools::iproduct;
use rand::prelude::StdRng;
use rand_core::SeedableRng;
use std::fs::{create_dir_all, OpenOptions};
use std::io::prelude::*;
use std::path::PathBuf;

const OUTPUT_DIR_PATH: &str = "/tmp/benchmark_setup";
const OUTPUT_FILE_NAME: &str = "results.md";

pub fn create_or_truncate_output_file() -> std::io::Result<()> {
let file_path = PathBuf::from(OUTPUT_DIR_PATH).join(OUTPUT_FILE_NAME);
eprintln!("Creating output file at {}", file_path.display());

let dir_path = PathBuf::from(OUTPUT_DIR_PATH);
create_dir_all(dir_path).unwrap();

let mut file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(file_path)?;
file.sync_all()?;

writeln!(file, "|shares_num|threshold|pvss_transcript_size_bytes|",)?;
writeln!(file, "|---|---|---|---|")
}

pub fn save_data(
shares_num: usize,
threshold: usize,
transcript_size_bytes: usize,
) {
let file_path = PathBuf::from(OUTPUT_DIR_PATH).join(OUTPUT_FILE_NAME);

eprintln!("Appending to file: {}", file_path.display());
let mut file = OpenOptions::new().append(true).open(&file_path).unwrap();
writeln!(
file,
"{}|{}|{}|",
shares_num, threshold, transcript_size_bytes
)
.unwrap();
}

// TODO: Find a way to deduplicate the following methods with benchmarks and test setup

fn gen_keypairs(num: u32) -> Vec<ferveo_common::Keypair<EllipticCurve>> {
let rng = &mut ark_std::test_rng();
(0..num)
.map(|_| ferveo_common::Keypair::<EllipticCurve>::new(rng))
.collect()
}

fn gen_validators(
keypairs: &[ferveo_common::Keypair<EllipticCurve>],
) -> Vec<ExternalValidator<EllipticCurve>> {
(0..keypairs.len())
.map(|i| ExternalValidator {
address: format!("validator_{}", i),
public_key: keypairs[i].public(),
})
.collect()
}

fn setup_dkg(
validator: usize,
shares_num: u32,
security_threshold: u32,
) -> PubliclyVerifiableDkg<EllipticCurve> {
let keypairs = gen_keypairs(shares_num);
let validators = gen_validators(&keypairs);
let me = validators[validator].clone();
PubliclyVerifiableDkg::new(
validators,
Params {
tau: 0,
security_threshold,
shares_num,
retry_after: 1,
},
&me,
keypairs[validator],
)
.expect("Setup failed")
}

fn setup(
shares_num: u32,
security_threshold: u32,
rng: &mut StdRng,
) -> PubliclyVerifiableDkg<EllipticCurve> {
let mut transcripts = vec![];
for i in 0..shares_num {
let mut dkg = setup_dkg(i as usize, shares_num, security_threshold);
transcripts.push(dkg.share(rng).expect("Test failed"));
}

let mut dkg = setup_dkg(0, shares_num, security_threshold);
for (sender, pvss) in transcripts.into_iter().enumerate() {
dkg.apply_message(dkg.validators[sender].validator.clone(), pvss)
.expect("Setup failed");
}
dkg
}

fn main() {
let rng = &mut StdRng::seed_from_u64(0);

create_or_truncate_output_file().unwrap();

let share_num_vec = [2, 4, 8, 16, 32, 64];
let threshold_ratio_vec = [0.51, 0.66, 0.8, 1.0];

// Create benchmark parameters without duplicates
let configs = iproduct!(&share_num_vec, &threshold_ratio_vec)
.map(|(shares_num, threshold_ratio)| {
let threshold =
(*shares_num as f64 * threshold_ratio).ceil() as u32;
(shares_num, threshold)
})
.collect::<BTreeSet<_>>();

println!("Running benchmarks for {:?}", configs);

for (shares_num, threshold) in configs {
println!("shares_num: {}, threshold: {}", shares_num, threshold);
let dkg = setup(*shares_num as u32, threshold, rng);
let mut transcript_bytes = vec![];
dkg.vss[&0].serialize(&mut transcript_bytes).unwrap();

save_data(
*shares_num as usize,
threshold as usize,
transcript_bytes.len(),
);
}
}
9 changes: 3 additions & 6 deletions ferveo/src/vss/pvss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl<E: PairingEngine, T> PubliclyVerifiableSS<E, T> {
) -> Result<Self> {
// Our random polynomial, \phi(x) = s + \sum_{i=1}^{t-1} a_i x^i
let mut phi = DensePolynomial::<E::Fr>::rand(
(dkg.params.shares_num - dkg.params.security_threshold) as usize,
(dkg.params.security_threshold - 1) as usize,
rng,
);
phi.coeffs[0] = *s; // setting the first coefficient to secret value
Expand Down Expand Up @@ -320,10 +320,7 @@ mod test_pvss {
// check that the chosen secret coefficient is correct
assert_eq!(pvss.coeffs[0], G1::prime_subgroup_generator().mul(s));
//check that a polynomial of the correct degree was created
assert_eq!(
pvss.coeffs.len(),
dkg.params.security_threshold as usize + 1
);
assert_eq!(pvss.coeffs.len(), dkg.params.security_threshold as usize);
// check that the correct number of shares were created
assert_eq!(pvss.shares.len(), dkg.validators.len());
// check that the prove of knowledge is correct
Expand Down Expand Up @@ -384,7 +381,7 @@ mod test_pvss {
//check that a polynomial of the correct degree was created
assert_eq!(
aggregate.coeffs.len(),
dkg.params.security_threshold as usize + 1
dkg.params.security_threshold as usize
);
// check that the correct number of shares were created
assert_eq!(aggregate.shares.len(), dkg.validators.len());
Expand Down
4 changes: 3 additions & 1 deletion tpke/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# tpke

## Benchmarking WASM
## Benchmarks

### Benchmarking WASM

Based on `centurion.rs` (docs)[https://github.com/bheisler/criterion.rs/blob/version-0.4/book/src/user_guide/wasi.md#webasseblywasi-benchmarking]

Expand Down
4 changes: 2 additions & 2 deletions tpke/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ pub fn setup_simple<E: PairingEngine>(
let pubkey_shares =
subproductdomain::fast_multiexp(&evals.evals, g.into_projective());
let pubkey_share = g.mul(evals.evals[0]);
assert!(pubkey_shares[0] == E::G1Affine::from(pubkey_share));
debug_assert!(pubkey_shares[0] == E::G1Affine::from(pubkey_share));

// Y, but only when b = 1 - private key shares of participants
let privkey_shares =
Expand All @@ -224,7 +224,7 @@ pub fn setup_simple<E: PairingEngine>(
let privkey = h.mul(x);

let secret = threshold_poly.evaluate(&E::Fr::zero());
assert_eq!(secret, x);
debug_assert!(secret == x);

let mut private_contexts = vec![];
let mut public_contexts = vec![];
Expand Down

0 comments on commit 58515cf

Please sign in to comment.