Skip to content

Commit

Permalink
[#4] Add Api Benchmarks (#5)
Browse files Browse the repository at this point in the history
* [#4] WIP

* * initial implementation of Api benchmarks

* * cleanup benchmarks file

* * cargo fmt

* Update to name the Ed25519Signature

* formatting

* * include `cargo bench` in README.md
  • Loading branch information
clintfred authored and coltfred committed Oct 5, 2018
1 parent 27644ef commit df159dc
Show file tree
Hide file tree
Showing 6 changed files with 329 additions and 25 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ debug = true
[dev-dependencies]
proptest = "0.8.3"
hex = "0.3.2"
criterion = "0.2"

[features]
unstable = []

[[bench]]
name = "api_benchmark"
harness = false
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ $ cargo build
$ cargo test
```

#### Running benchmarks
```
$ cargo bench
```

# Relation to Proxy Re-Encryption

In the academic literature, _transform encryption_ is referred to as _proxy re-encryption_. A proxy re-encryption (PRE) scheme is a public-key encryption scheme, where each participant has a pair of related keys, one public and one private, which are mathematically related. Alice encrypts a message to Bob using his public key, and Bob decrypts the encrypted message using his public key to retrieve the original message.
Expand Down
297 changes: 297 additions & 0 deletions benches/api_benchmark.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
#[macro_use]
extern crate criterion;
extern crate recrypt;

use criterion::Criterion;
use recrypt::api::Api;
use recrypt::api::CryptoOps;
use recrypt::api::Ed25519Ops;
use recrypt::api::KeyGenOps;
use std::cell::RefCell;

fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("generate key pair", |b| {
let mut api = Api::new();
b.iter(|| api.generate_key_pair());
});

c.bench_function("generate plaintext", |b| {
let mut api = Api::new();
b.iter(|| api.gen_plaintext());
});

c.bench_function("generate ed25519 keypair", |b| {
let mut api = Api::new();
b.iter(|| {
api.generate_ed25519_key_pair();
});
});

c.bench_function("generate transform key", |b| {
let api = RefCell::new(Api::new());
let (pvsk, pbsk) = api.borrow_mut().generate_ed25519_key_pair();
b.iter_with_setup(
|| {
let (from_pvk, _) = api.borrow_mut().generate_key_pair().unwrap();
let (_, to_pbk) = api.borrow_mut().generate_key_pair().unwrap();
(from_pvk, to_pbk)
},
|(from, to)| {
api.borrow_mut()
.generate_transform_key(&from, to, pbsk, &pvsk)
.unwrap();
},
);
});

c.bench_function("compute public key", |b| {
let api = RefCell::new(Api::new());
b.iter_with_setup(
|| {
let (pvk, _) = api.borrow_mut().generate_key_pair().unwrap();
pvk
},
|pvk| api.borrow_mut().compute_public_key(&pvk),
);
});

c.bench_function("derive symmetric key", |b| {
let api = RefCell::new(Api::new());
b.iter_with_setup(
|| api.borrow_mut().gen_plaintext(),
|pt| api.borrow_mut().derive_symmetric_key(&pt),
);
});

c.bench_function("encrypt (level 0)", |b| {
let api = RefCell::new(Api::new());
let (_, pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (pvsk, pbsk) = api.borrow_mut().generate_ed25519_key_pair();
b.iter_with_setup(
|| api.borrow_mut().gen_plaintext(),
|pt| {
api.borrow_mut().encrypt(&pt, pbk, pbsk, &pvsk).unwrap();
},
);
});

c.bench_function("decrypt (level 0)", |b| {
let mut api = Api::new();
let (pvk, pbk) = api.generate_key_pair().unwrap();
let (pvsk, pbsk) = api.generate_ed25519_key_pair();
let pt = api.gen_plaintext();
let encrypted_value = api.encrypt(&pt, pbk, pbsk, &pvsk).unwrap();
b.iter(|| api.decrypt(encrypted_value.clone(), &pvk).unwrap());
});

c.bench_function("transform (level 1)", |b| {
let api = RefCell::new(Api::new());
let (level_0_pvk, level_0_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (_, level_1_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (pvsk, pbsk) = api.borrow_mut().generate_ed25519_key_pair();
let tk = api
.borrow_mut()
.generate_transform_key(&level_0_pvk, level_1_pbk, pbsk, &pvsk)
.unwrap();
b.iter_with_setup(
|| {
let pt = api.borrow_mut().gen_plaintext();
api.borrow_mut()
.encrypt(&pt, level_0_pbk, pbsk, &pvsk)
.unwrap()
},
|ev| {
api.borrow_mut()
.transform(ev, tk.clone(), pbsk, &pvsk)
.unwrap()
},
);
});

c.bench_function("decrypt (level 1)", |b| {
let api = RefCell::new(Api::new());
let (pvsk, pbsk) = api.borrow_mut().generate_ed25519_key_pair();
let (level_0_pvk, level_0_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (level_1_pvk, level_1_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let tk = api
.borrow_mut()
.generate_transform_key(&level_0_pvk, level_1_pbk, pbsk, &pvsk)
.unwrap();
b.iter_with_setup(
|| {
let pt = api.borrow_mut().gen_plaintext();
let ev = api
.borrow_mut()
.encrypt(&pt, level_0_pbk, pbsk, &pvsk)
.unwrap();
api.borrow_mut()
.transform(ev, tk.clone(), pbsk, &pvsk)
.unwrap()
},
|ev| {
api.borrow_mut().decrypt(ev, &level_1_pvk).unwrap();
},
);
});

c.bench_function("transform (level 2)", |b| {
let api = RefCell::new(Api::new());
let (level_0_pvk, level_0_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (level_1_pvk, level_1_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (_, level_2_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (pvsk, pbsk) = api.borrow_mut().generate_ed25519_key_pair();
let tk_0_to_1 = api
.borrow_mut()
.generate_transform_key(&level_0_pvk, level_1_pbk, pbsk, &pvsk)
.unwrap();
let tk_1_to_2 = api
.borrow_mut()
.generate_transform_key(&level_1_pvk, level_2_pbk, pbsk, &pvsk)
.unwrap();
b.iter_with_setup(
|| {
let pt = api.borrow_mut().gen_plaintext();
api.borrow_mut()
.encrypt(&pt, level_0_pbk, pbsk, &pvsk)
.unwrap()
},
|ev| {
let ev_to_1 = api
.borrow_mut()
.transform(ev, tk_0_to_1.clone(), pbsk, &pvsk)
.unwrap();
api.borrow_mut()
.transform(ev_to_1, tk_1_to_2.clone(), pbsk, &pvsk)
.unwrap();
},
);
});

c.bench_function("decrypt (level 2)", |b| {
let api = RefCell::new(Api::new());
let (pvsk, pbsk) = api.borrow_mut().generate_ed25519_key_pair();
let (level_0_pvk, level_0_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (level_1_pvk, level_1_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (level_2_pvk, level_2_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let tk_0_to_1 = api
.borrow_mut()
.generate_transform_key(&level_0_pvk, level_1_pbk, pbsk, &pvsk)
.unwrap();
let tk_1_to_2 = api
.borrow_mut()
.generate_transform_key(&level_1_pvk, level_2_pbk, pbsk, &pvsk)
.unwrap();
b.iter_with_setup(
|| {
let pt = api.borrow_mut().gen_plaintext();
let ev_to_0 = api
.borrow_mut()
.encrypt(&pt, level_0_pbk, pbsk, &pvsk)
.unwrap();
let ev_to_1 = api
.borrow_mut()
.transform(ev_to_0, tk_0_to_1.clone(), pbsk, &pvsk)
.unwrap();
api.borrow_mut()
.transform(ev_to_1, tk_1_to_2.clone(), pbsk, &pvsk)
.unwrap()
},
|ev_to_2| {
api.borrow_mut().decrypt(ev_to_2, &level_2_pvk).unwrap();
},
);
});

c.bench_function("transform (level 3)", |b| {
let api = RefCell::new(Api::new());
let (level_0_pvk, level_0_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (level_1_pvk, level_1_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (level_2_pvk, level_2_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (_, level_3_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (pvsk, pbsk) = api.borrow_mut().generate_ed25519_key_pair();
let tk_0_to_1 = api
.borrow_mut()
.generate_transform_key(&level_0_pvk, level_1_pbk, pbsk, &pvsk)
.unwrap();
let tk_1_to_2 = api
.borrow_mut()
.generate_transform_key(&level_1_pvk, level_2_pbk, pbsk, &pvsk)
.unwrap();
let tk_2_to_3 = api
.borrow_mut()
.generate_transform_key(&level_2_pvk, level_3_pbk, pbsk, &pvsk)
.unwrap();
b.iter_with_setup(
|| {
let pt = api.borrow_mut().gen_plaintext();
api.borrow_mut()
.encrypt(&pt, level_0_pbk, pbsk, &pvsk)
.unwrap()
},
|ev| {
let ev_to_1 = api
.borrow_mut()
.transform(ev, tk_0_to_1.clone(), pbsk, &pvsk)
.unwrap();
let ev_to_2 = api
.borrow_mut()
.transform(ev_to_1, tk_1_to_2.clone(), pbsk, &pvsk)
.unwrap();
api.borrow_mut()
.transform(ev_to_2, tk_2_to_3.clone(), pbsk, &pvsk)
.unwrap();
},
);
});

c.bench_function("decrypt (level 3)", |b| {
let api = RefCell::new(Api::new());
let (pvsk, pbsk) = api.borrow_mut().generate_ed25519_key_pair();
let (level_0_pvk, level_0_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (level_1_pvk, level_1_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (level_2_pvk, level_2_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let (level_3_pvk, level_3_pbk) = api.borrow_mut().generate_key_pair().unwrap();
let tk_0_to_1 = api
.borrow_mut()
.generate_transform_key(&level_0_pvk, level_1_pbk, pbsk, &pvsk)
.unwrap();
let tk_1_to_2 = api
.borrow_mut()
.generate_transform_key(&level_1_pvk, level_2_pbk, pbsk, &pvsk)
.unwrap();
let tk_2_to_3 = api
.borrow_mut()
.generate_transform_key(&level_2_pvk, level_3_pbk, pbsk, &pvsk)
.unwrap();
b.iter_with_setup(
|| {
let pt = api.borrow_mut().gen_plaintext();
let ev_to_0 = api
.borrow_mut()
.encrypt(&pt, level_0_pbk, pbsk, &pvsk)
.unwrap();
let ev_to_1 = api
.borrow_mut()
.transform(ev_to_0, tk_0_to_1.clone(), pbsk, &pvsk)
.unwrap();
let ev_to_2 = api
.borrow_mut()
.transform(ev_to_1, tk_1_to_2.clone(), pbsk, &pvsk)
.unwrap();
api.borrow_mut()
.transform(ev_to_2, tk_2_to_3.clone(), pbsk, &pvsk)
.unwrap()
},
|ev_to_3| {
api.borrow_mut().decrypt(ev_to_3, &level_3_pvk).unwrap();
},
);
});
}

criterion_group! {
name = benches;
config = Criterion::default().sample_size(20);
targets = criterion_benchmark
}
criterion_main!(benches);
18 changes: 9 additions & 9 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use internal;
use internal::bytedecoder::{BytesDecoder, DecodeErr};
use internal::curve;
pub use internal::ed25519::{
Ed25519, Ed25519Signing, PrivateSigningKey, PublicSigningKey, Signature,
Ed25519, Ed25519Signature, Ed25519Signing, PrivateSigningKey, PublicSigningKey,
};
use internal::fp::fr_256::Fr256;
use internal::fp12elem::Fp12Elem;
Expand Down Expand Up @@ -248,7 +248,7 @@ pub enum EncryptedValue {
encrypted_message: EncryptedMessage,
auth_hash: AuthHash,
public_signing_key: PublicSigningKey,
signature: Signature,
signature: Ed25519Signature,
},
/// Value which has been encrypted and then transformed n times for n > 0.
/// `ephemeral_public_key` - public key of the ephemeral private key that was used to encrypt
Expand All @@ -263,7 +263,7 @@ pub enum EncryptedValue {
auth_hash: AuthHash,
transform_blocks: NonEmptyVec<TransformBlock>,
public_signing_key: PublicSigningKey,
signature: Signature,
signature: Ed25519Signature,
},
}

Expand Down Expand Up @@ -500,7 +500,7 @@ pub struct TransformKey {
encrypted_temp_key: EncryptedTempKey,
hashed_temp_key: HashedValue,
public_signing_key: PublicSigningKey,
signature: Signature,
signature: Ed25519Signature,
_internal_key: internal::SignedValue<internal::ReencryptionKey<Fp256>>,
}

Expand All @@ -520,7 +520,7 @@ impl TransformKey {
pub fn public_signing_key(&self) -> &PublicSigningKey {
&self.public_signing_key
}
pub fn signature(&self) -> &Signature {
pub fn signature(&self) -> &Ed25519Signature {
&self.signature
}
fn try_from_internal(
Expand All @@ -545,7 +545,7 @@ impl TransformKey {
encrypted_temp_key: EncryptedTempKey, //The encrypted K value, which is used to go from the reencrypted value to the encrypted value
hashed_temp_key: HashedValue,
public_signing_key: PublicSigningKey,
signature: Signature,
signature: Ed25519Signature,
) -> TransformKey {
let reencryption_key = internal::ReencryptionKey {
re_public_key: ephemeral_public_key._internal_key,
Expand Down Expand Up @@ -1055,14 +1055,14 @@ pub(crate) mod test {

pub struct DummyEd25519;
impl Ed25519Signing for DummyEd25519 {
fn sign<T: Hashable>(&self, _t: &T, _private_key: &PrivateSigningKey) -> Signature {
Signature::new([0; 64])
fn sign<T: Hashable>(&self, _t: &T, _private_key: &PrivateSigningKey) -> Ed25519Signature {
Ed25519Signature::new([0; 64])
}

fn verify<T: Hashable>(
&self,
_t: &T,
_signature: &Signature,
_signature: &Ed25519Signature,
_public_key: &PublicSigningKey,
) -> bool {
true
Expand Down
Loading

0 comments on commit df159dc

Please sign in to comment.