From d06ffb580944d409accd1333fd9839aae16a4474 Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Mon, 21 Jun 2021 19:08:24 -0700 Subject: [PATCH] Add PRE and some internal benchmarks --- umbral-pre/bench/bench.rs | 159 +++++++++++++++++++++++++++++++++++++- umbral-pre/src/bench.rs | 30 +++++++ 2 files changed, 186 insertions(+), 3 deletions(-) diff --git a/umbral-pre/bench/bench.rs b/umbral-pre/bench/bench.rs index d10f5e58..e6c0b7f3 100644 --- a/umbral-pre/bench/bench.rs +++ b/umbral-pre/bench/bench.rs @@ -1,7 +1,14 @@ use criterion::measurement::Measurement; use criterion::{criterion_group, criterion_main, BenchmarkGroup, Criterion}; -use umbral_pre::bench::unsafe_hash_to_point; +use umbral_pre::bench::{ + capsule_from_public_key, capsule_open_original, capsule_open_reencrypted, get_cfrag, + unsafe_hash_to_point, +}; +use umbral_pre::{ + decrypt_original, decrypt_reencrypted, encrypt, generate_kfrags, reencrypt, SecretKey, Signer, + VerifiedCapsuleFrag, +}; fn bench_unsafe_hash_to_point<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) { let data = b"abcdefg"; @@ -11,11 +18,157 @@ fn bench_unsafe_hash_to_point<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, }); } -fn bench_all(c: &mut Criterion) { +fn bench_capsule_from_public_key<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) { + let delegating_sk = SecretKey::random(); + let delegating_pk = delegating_sk.public_key(); + group.bench_function("Capsule::from_public_key", |b| { + b.iter(|| capsule_from_public_key(&delegating_pk)) + }); +} + +fn bench_capsule_open_original<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) { + let delegating_sk = SecretKey::random(); + let delegating_pk = delegating_sk.public_key(); + let plaintext = b"peace at dawn"; + let (capsule, _ciphertext) = encrypt(&delegating_pk, plaintext).unwrap(); + group.bench_function("Capsule::open_original", |b| { + b.iter(|| capsule_open_original(&capsule, &delegating_sk)) + }); +} + +fn bench_capsule_open_reencrypted<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) { + let delegating_sk = SecretKey::random(); + let delegating_pk = delegating_sk.public_key(); + + let signing_sk = SecretKey::random(); + let signer = Signer::new(&signing_sk); + + let receiving_sk = SecretKey::random(); + let receiving_pk = receiving_sk.public_key(); + + let (capsule, _key_seed) = capsule_from_public_key(&delegating_pk); + + let threshold: usize = 2; + let num_frags: usize = threshold + 1; + + let kfrags = generate_kfrags( + &delegating_sk, + &receiving_pk, + &signer, + threshold, + num_frags, + true, + true, + ); + + let vcfrags: Vec<_> = kfrags + .iter() + .map(|kfrag| reencrypt(&capsule, &kfrag)) + .collect(); + + let cfrags: Vec<_> = vcfrags[0..threshold] + .iter() + .map(|vcfrag| get_cfrag(&vcfrag).clone()) + .collect(); + + group.bench_function("Capsule::open_reencrypted", |b| { + b.iter(|| capsule_open_reencrypted(&capsule, &receiving_sk, &delegating_pk, &cfrags)) + }); +} + +fn bench_pre<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) { + let delegating_sk = SecretKey::random(); + let delegating_pk = delegating_sk.public_key(); + let plaintext = b"peace at dawn"; + + // Encryption + + group.bench_function("encrypt", |b| { + b.iter(|| encrypt(&delegating_pk, &plaintext[..])) + }); + + // Decryption with the original key + + let (capsule, ciphertext) = encrypt(&delegating_pk, plaintext).unwrap(); + group.bench_function("decrypt_original", |b| { + b.iter(|| decrypt_original(&delegating_sk, &capsule, &ciphertext[..])) + }); + + // Kfrag generation + + let threshold: usize = 2; + let num_frags: usize = threshold + 1; + + let signing_sk = SecretKey::random(); + let signer = Signer::new(&signing_sk); + + let receiving_sk = SecretKey::random(); + let receiving_pk = receiving_sk.public_key(); + + group.bench_function("generate_kfrags", |b| { + b.iter(|| { + generate_kfrags( + &delegating_sk, + &receiving_pk, + &signer, + threshold, + num_frags, + true, + true, + ) + }) + }); + + // Reencryption + + let verified_kfrags = generate_kfrags( + &delegating_sk, + &receiving_pk, + &signer, + threshold, + num_frags, + true, + true, + ); + + let vkfrag = verified_kfrags[0].clone(); + + group.bench_function("reencrypt", |b| b.iter(|| reencrypt(&capsule, &vkfrag))); + + // Decryption of the reencrypted data + + let verified_cfrags: Vec = verified_kfrags[0..threshold] + .iter() + .map(|vkfrag| reencrypt(&capsule, &vkfrag)) + .collect(); + + group.bench_function("decrypt_reencrypted", |b| { + b.iter(|| { + decrypt_reencrypted( + &receiving_sk, + &delegating_pk, + &capsule, + &verified_cfrags, + &ciphertext, + ) + }) + }); +} + +fn group_internals(c: &mut Criterion) { let mut group = c.benchmark_group("internals"); bench_unsafe_hash_to_point(&mut group); + bench_capsule_from_public_key(&mut group); + bench_capsule_open_original(&mut group); + bench_capsule_open_reencrypted(&mut group); + group.finish(); +} + +fn group_pre(c: &mut Criterion) { + let mut group = c.benchmark_group("PRE API"); + bench_pre(&mut group); group.finish(); } -criterion_group!(benches, bench_all); +criterion_group!(benches, group_internals, group_pre); criterion_main!(benches); diff --git a/umbral-pre/src/bench.rs b/umbral-pre/src/bench.rs index f6ad98e1..70d15f5b 100644 --- a/umbral-pre/src/bench.rs +++ b/umbral-pre/src/bench.rs @@ -2,4 +2,34 @@ //! This module re-exports some internals for the purposes of benchmarking. //! Should not be used by regular users. +use crate::capsule::{Capsule, OpenReencryptedError}; +use crate::capsule_frag::{CapsuleFrag, VerifiedCapsuleFrag}; +use crate::curve::CurvePoint; +use crate::keys::{PublicKey, SecretKey}; + pub use crate::hashing::unsafe_hash_to_point; + +/// Exported `Capsule::from_public_key()` for benchmark purposes. +pub fn capsule_from_public_key(delegating_pk: &PublicKey) -> (Capsule, CurvePoint) { + Capsule::from_public_key(delegating_pk) +} + +/// Exported `Capsule::open_original()` for benchmark purposes. +pub fn capsule_open_original(capsule: &Capsule, delegating_sk: &SecretKey) -> CurvePoint { + capsule.open_original(delegating_sk) +} + +/// Exported `Capsule::open_reencrypted()` for benchmark purposes. +pub fn capsule_open_reencrypted( + capsule: &Capsule, + receiving_sk: &SecretKey, + delegating_pk: &PublicKey, + cfrags: &[CapsuleFrag], +) -> Result { + capsule.open_reencrypted(receiving_sk, delegating_pk, cfrags) +} + +/// Extracts the internal [`CapsuleFrag`] from a [`VerifiedCapsuleFrag`]. +pub fn get_cfrag(verified_cfrag: &VerifiedCapsuleFrag) -> &CapsuleFrag { + &verified_cfrag.cfrag +}