288 lines
8.5 KiB
Rust
288 lines
8.5 KiB
Rust
|
//
|
||
|
// Copyright 2021 Signal Messenger, LLC.
|
||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||
|
//
|
||
|
|
||
|
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||
|
use futures_util::FutureExt;
|
||
|
use libsignal_protocol::*;
|
||
|
use rand::rngs::OsRng;
|
||
|
use rand::Rng;
|
||
|
use uuid::Uuid;
|
||
|
|
||
|
#[path = "../tests/support/mod.rs"]
|
||
|
mod support;
|
||
|
|
||
|
pub fn v1(c: &mut Criterion) {
|
||
|
let mut rng = OsRng;
|
||
|
|
||
|
let alice_address = ProtocolAddress::new("9d0652a3-dcc3-4d11-975f-74d61598733f".to_owned(), 1);
|
||
|
let bob_address = ProtocolAddress::new("796abedb-ca4e-4f18-8803-1fde5b921f9f".to_owned(), 1);
|
||
|
|
||
|
let mut alice_store = support::test_in_memory_protocol_store().expect("brand new store");
|
||
|
let mut bob_store = support::test_in_memory_protocol_store().expect("brand new store");
|
||
|
|
||
|
let bob_pre_key_bundle = support::create_pre_key_bundle(&mut bob_store, &mut rng)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid");
|
||
|
|
||
|
process_prekey_bundle(
|
||
|
&bob_address,
|
||
|
&mut alice_store.session_store,
|
||
|
&mut alice_store.identity_store,
|
||
|
&bob_pre_key_bundle,
|
||
|
&mut rng,
|
||
|
None,
|
||
|
)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid");
|
||
|
|
||
|
let trust_root = KeyPair::generate(&mut rng);
|
||
|
let server_key = KeyPair::generate(&mut rng);
|
||
|
|
||
|
let server_cert =
|
||
|
ServerCertificate::new(1, server_key.public_key, &trust_root.private_key, &mut rng)
|
||
|
.expect("valid");
|
||
|
|
||
|
let expires = 1605722925;
|
||
|
|
||
|
let sender_cert = SenderCertificate::new(
|
||
|
alice_address.name().to_string(),
|
||
|
None,
|
||
|
*alice_store
|
||
|
.get_identity_key_pair(None)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid")
|
||
|
.public_key(),
|
||
|
alice_address.device_id(),
|
||
|
expires,
|
||
|
server_cert,
|
||
|
&server_key.private_key,
|
||
|
&mut rng,
|
||
|
)
|
||
|
.expect("valid");
|
||
|
|
||
|
let message = b"hello";
|
||
|
let usmc = UnidentifiedSenderMessageContent::new(
|
||
|
CiphertextMessageType::Plaintext,
|
||
|
sender_cert,
|
||
|
message.to_vec(),
|
||
|
ContentHint::Default,
|
||
|
None,
|
||
|
)
|
||
|
.expect("valid");
|
||
|
|
||
|
let mut encrypt_it = || {
|
||
|
sealed_sender_encrypt_from_usmc(
|
||
|
&bob_address,
|
||
|
&usmc,
|
||
|
&mut alice_store.identity_store,
|
||
|
None,
|
||
|
&mut rng,
|
||
|
)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid")
|
||
|
};
|
||
|
let encrypted = encrypt_it();
|
||
|
|
||
|
let mut decrypt_it = || {
|
||
|
sealed_sender_decrypt_to_usmc(&encrypted, &mut bob_store.identity_store, None)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid")
|
||
|
};
|
||
|
assert_eq!(message, decrypt_it().contents().expect("valid"));
|
||
|
|
||
|
c.bench_function("v1/encrypt", |b| b.iter(&mut encrypt_it));
|
||
|
c.bench_function("v1/decrypt", |b| b.iter(&mut decrypt_it));
|
||
|
}
|
||
|
|
||
|
pub fn v2(c: &mut Criterion) {
|
||
|
let mut rng = OsRng;
|
||
|
|
||
|
let alice_address = ProtocolAddress::new("9d0652a3-dcc3-4d11-975f-74d61598733f".to_owned(), 1);
|
||
|
let bob_address = ProtocolAddress::new("796abedb-ca4e-4f18-8803-1fde5b921f9f".to_owned(), 1);
|
||
|
|
||
|
let mut alice_store = support::test_in_memory_protocol_store().expect("brand new store");
|
||
|
let mut bob_store = support::test_in_memory_protocol_store().expect("brand new store");
|
||
|
|
||
|
let bob_pre_key_bundle = support::create_pre_key_bundle(&mut bob_store, &mut rng)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid");
|
||
|
|
||
|
process_prekey_bundle(
|
||
|
&bob_address,
|
||
|
&mut alice_store.session_store,
|
||
|
&mut alice_store.identity_store,
|
||
|
&bob_pre_key_bundle,
|
||
|
&mut rng,
|
||
|
None,
|
||
|
)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid");
|
||
|
|
||
|
let trust_root = KeyPair::generate(&mut rng);
|
||
|
let server_key = KeyPair::generate(&mut rng);
|
||
|
|
||
|
let server_cert =
|
||
|
ServerCertificate::new(1, server_key.public_key, &trust_root.private_key, &mut rng)
|
||
|
.expect("valid");
|
||
|
|
||
|
let expires = 1605722925;
|
||
|
|
||
|
let sender_cert = SenderCertificate::new(
|
||
|
alice_address.name().to_string(),
|
||
|
None,
|
||
|
*alice_store
|
||
|
.get_identity_key_pair(None)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid")
|
||
|
.public_key(),
|
||
|
alice_address.device_id(),
|
||
|
expires,
|
||
|
server_cert,
|
||
|
&server_key.private_key,
|
||
|
&mut rng,
|
||
|
)
|
||
|
.expect("valid");
|
||
|
|
||
|
let message = b"hello";
|
||
|
let usmc = UnidentifiedSenderMessageContent::new(
|
||
|
CiphertextMessageType::Plaintext,
|
||
|
sender_cert,
|
||
|
message.to_vec(),
|
||
|
ContentHint::Default,
|
||
|
None,
|
||
|
)
|
||
|
.expect("valid");
|
||
|
|
||
|
let mut encrypt_it = || {
|
||
|
sealed_sender_multi_recipient_encrypt(
|
||
|
&[&bob_address],
|
||
|
&alice_store
|
||
|
.session_store
|
||
|
.load_existing_sessions(&[&bob_address])
|
||
|
.expect("present"),
|
||
|
&usmc,
|
||
|
&mut alice_store.identity_store,
|
||
|
None,
|
||
|
&mut rng,
|
||
|
)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid")
|
||
|
};
|
||
|
let outgoing = encrypt_it();
|
||
|
|
||
|
let incoming = sealed_sender_multi_recipient_fan_out(&outgoing)
|
||
|
.expect("valid")
|
||
|
.into_iter()
|
||
|
.next()
|
||
|
.expect("at least one destination");
|
||
|
|
||
|
let mut decrypt_it = || {
|
||
|
sealed_sender_decrypt_to_usmc(&incoming, &mut bob_store.identity_store, None)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid")
|
||
|
};
|
||
|
assert_eq!(message, decrypt_it().contents().expect("valid"));
|
||
|
|
||
|
c.bench_function("v2/encrypt", |b| b.iter(&mut encrypt_it));
|
||
|
c.bench_function("v2/decrypt", |b| b.iter(&mut decrypt_it));
|
||
|
|
||
|
// Fill out additional recipients.
|
||
|
let mut recipients = vec![bob_address.clone()];
|
||
|
while recipients.len() < 10 {
|
||
|
let next_address = ProtocolAddress::new(Uuid::from_bytes(rng.gen()).to_string(), 1);
|
||
|
|
||
|
let mut next_store = support::test_in_memory_protocol_store().expect("brand new store");
|
||
|
|
||
|
let next_pre_key_bundle = support::create_pre_key_bundle(&mut next_store, &mut rng)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid");
|
||
|
|
||
|
process_prekey_bundle(
|
||
|
&next_address,
|
||
|
&mut alice_store.session_store,
|
||
|
&mut alice_store.identity_store,
|
||
|
&next_pre_key_bundle,
|
||
|
&mut rng,
|
||
|
None,
|
||
|
)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid");
|
||
|
|
||
|
recipients.push(next_address);
|
||
|
}
|
||
|
|
||
|
let mut group = c.benchmark_group("v2/encrypt/multi-recipient");
|
||
|
for recipient_count in [2, 5, 10] {
|
||
|
group.bench_with_input(
|
||
|
BenchmarkId::from_parameter(recipient_count),
|
||
|
&recipient_count,
|
||
|
|b, &recipient_count| {
|
||
|
let recipients: Vec<_> = recipients.iter().take(recipient_count).collect();
|
||
|
b.iter(|| {
|
||
|
sealed_sender_multi_recipient_encrypt(
|
||
|
&recipients,
|
||
|
&alice_store
|
||
|
.session_store
|
||
|
.load_existing_sessions(&recipients)
|
||
|
.expect("present"),
|
||
|
&usmc,
|
||
|
&mut alice_store.identity_store,
|
||
|
None,
|
||
|
&mut rng,
|
||
|
)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid")
|
||
|
});
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
group.finish();
|
||
|
|
||
|
let mut group = c.benchmark_group("v2/encrypt/multi-device");
|
||
|
for device_count in [2, 5, 10] {
|
||
|
group.bench_with_input(
|
||
|
BenchmarkId::from_parameter(device_count),
|
||
|
&device_count,
|
||
|
|b, &device_count| {
|
||
|
let recipients: Vec<_> = vec![&bob_address; device_count];
|
||
|
b.iter(|| {
|
||
|
sealed_sender_multi_recipient_encrypt(
|
||
|
&recipients,
|
||
|
&alice_store
|
||
|
.session_store
|
||
|
.load_existing_sessions(&recipients)
|
||
|
.expect("present"),
|
||
|
&usmc,
|
||
|
&mut alice_store.identity_store,
|
||
|
None,
|
||
|
&mut rng,
|
||
|
)
|
||
|
.now_or_never()
|
||
|
.expect("sync")
|
||
|
.expect("valid")
|
||
|
});
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
group.finish();
|
||
|
}
|
||
|
|
||
|
criterion_group!(benches, v1, v2);
|
||
|
|
||
|
criterion_main!(benches);
|