250 lines
8.2 KiB
Rust
250 lines
8.2 KiB
Rust
//
|
|
// Copyright 2020-2021 Signal Messenger, LLC.
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
use criterion::{criterion_group, criterion_main, Criterion};
|
|
use futures_util::FutureExt;
|
|
use libsignal_protocol::*;
|
|
use rand::rngs::OsRng;
|
|
|
|
#[path = "../tests/support/mod.rs"]
|
|
mod support;
|
|
|
|
pub fn session_encrypt_result(c: &mut Criterion) -> Result<(), SignalProtocolError> {
|
|
let (alice_session_record, bob_session_record) = support::initialize_sessions_v3()?;
|
|
|
|
let alice_address = ProtocolAddress::new("+14159999999".to_owned(), 1);
|
|
let bob_address = ProtocolAddress::new("+14158888888".to_owned(), 1);
|
|
|
|
let mut alice_store = support::test_in_memory_protocol_store()?;
|
|
let mut bob_store = support::test_in_memory_protocol_store()?;
|
|
|
|
alice_store
|
|
.store_session(&bob_address, &alice_session_record, None)
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
bob_store
|
|
.store_session(&alice_address, &bob_session_record, None)
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
|
|
let message_to_decrypt = support::encrypt(&mut alice_store, &bob_address, "a short message")
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
|
|
c.bench_function("session decrypt first message", |b| {
|
|
b.iter(|| {
|
|
let mut bob_store = bob_store.clone();
|
|
support::decrypt(&mut bob_store, &alice_address, &message_to_decrypt)
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
})
|
|
});
|
|
|
|
let _ = support::decrypt(&mut bob_store, &alice_address, &message_to_decrypt)
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
let message_to_decrypt = support::encrypt(&mut alice_store, &bob_address, "a short message")
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
|
|
c.bench_function("session encrypt", |b| {
|
|
b.iter(|| {
|
|
support::encrypt(&mut alice_store, &bob_address, "a short message")
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
})
|
|
});
|
|
c.bench_function("session decrypt", |b| {
|
|
b.iter(|| {
|
|
let mut bob_store = bob_store.clone();
|
|
support::decrypt(&mut bob_store, &alice_address, &message_to_decrypt)
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
})
|
|
});
|
|
|
|
// Archive on Alice's side...
|
|
let mut state = alice_store
|
|
.load_session(&bob_address, None)
|
|
.now_or_never()
|
|
.expect("sync")?
|
|
.expect("already decrypted successfully");
|
|
state.archive_current_state()?;
|
|
alice_store
|
|
.store_session(&bob_address, &state, None)
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
|
|
// ...then initialize a new session...
|
|
let bob_signed_pre_key_pair = KeyPair::generate(&mut OsRng);
|
|
|
|
let bob_signed_pre_key_public = bob_signed_pre_key_pair.public_key.serialize();
|
|
let bob_signed_pre_key_signature = bob_store
|
|
.get_identity_key_pair(None)
|
|
.now_or_never()
|
|
.expect("sync")?
|
|
.private_key()
|
|
.calculate_signature(&bob_signed_pre_key_public, &mut OsRng)?;
|
|
|
|
let signed_pre_key_id = 22;
|
|
|
|
let bob_pre_key_bundle = PreKeyBundle::new(
|
|
bob_store
|
|
.get_local_registration_id(None)
|
|
.now_or_never()
|
|
.expect("sync")?,
|
|
1, // device id
|
|
None, // pre key
|
|
signed_pre_key_id, // signed pre key id
|
|
bob_signed_pre_key_pair.public_key,
|
|
bob_signed_pre_key_signature.to_vec(),
|
|
*bob_store
|
|
.get_identity_key_pair(None)
|
|
.now_or_never()
|
|
.expect("sync")?
|
|
.identity_key(),
|
|
)?;
|
|
|
|
bob_store
|
|
.save_signed_pre_key(
|
|
signed_pre_key_id,
|
|
&SignedPreKeyRecord::new(
|
|
signed_pre_key_id,
|
|
/*timestamp*/ 42,
|
|
&bob_signed_pre_key_pair,
|
|
&bob_signed_pre_key_signature,
|
|
),
|
|
None,
|
|
)
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
|
|
// initialize_sessions_v3 makes up its own identity keys,
|
|
// so we need to reset here to avoid it looking like the identity changed.
|
|
alice_store.identity_store.reset();
|
|
bob_store.identity_store.reset();
|
|
|
|
process_prekey_bundle(
|
|
&bob_address,
|
|
&mut alice_store.session_store,
|
|
&mut alice_store.identity_store,
|
|
&bob_pre_key_bundle,
|
|
&mut OsRng,
|
|
None,
|
|
)
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
|
|
let original_message_to_decrypt = message_to_decrypt;
|
|
|
|
// ...send another message to archive on Bob's side...
|
|
let message_to_decrypt = support::encrypt(&mut alice_store, &bob_address, "a short message")
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
let _ = support::decrypt(&mut bob_store, &alice_address, &message_to_decrypt)
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
// ...and prepare another message to benchmark decrypting.
|
|
let message_to_decrypt = support::encrypt(&mut alice_store, &bob_address, "a short message")
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
|
|
c.bench_function("session decrypt with archived state", |b| {
|
|
b.iter(|| {
|
|
let mut bob_store = bob_store.clone();
|
|
support::decrypt(&mut bob_store, &alice_address, &message_to_decrypt)
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
})
|
|
});
|
|
|
|
// Reset once more to go back to the original message.
|
|
bob_store.identity_store.reset();
|
|
|
|
c.bench_function("session decrypt using previous state", |b| {
|
|
b.iter(|| {
|
|
let mut bob_store = bob_store.clone();
|
|
support::decrypt(&mut bob_store, &alice_address, &original_message_to_decrypt)
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
})
|
|
});
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn session_encrypt_decrypt_result(c: &mut Criterion) -> Result<(), SignalProtocolError> {
|
|
let (alice_session_record, bob_session_record) = support::initialize_sessions_v3()?;
|
|
|
|
let alice_address = ProtocolAddress::new("+14159999999".to_owned(), 1);
|
|
let bob_address = ProtocolAddress::new("+14158888888".to_owned(), 1);
|
|
|
|
let mut alice_store = support::test_in_memory_protocol_store()?;
|
|
let mut bob_store = support::test_in_memory_protocol_store()?;
|
|
|
|
alice_store
|
|
.store_session(&bob_address, &alice_session_record, None)
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
bob_store
|
|
.store_session(&alice_address, &bob_session_record, None)
|
|
.now_or_never()
|
|
.expect("sync")?;
|
|
|
|
c.bench_function("session encrypt+decrypt 1 way", |b| {
|
|
b.iter(|| {
|
|
let ctext = support::encrypt(&mut alice_store, &bob_address, "a short message")
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
let _ptext = support::decrypt(&mut bob_store, &alice_address, &ctext)
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
})
|
|
});
|
|
|
|
c.bench_function("session encrypt+decrypt ping pong", |b| {
|
|
b.iter(|| {
|
|
let ctext = support::encrypt(&mut alice_store, &bob_address, "a short message")
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
let _ptext = support::decrypt(&mut bob_store, &alice_address, &ctext)
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
|
|
let ctext = support::encrypt(&mut bob_store, &alice_address, "a short message")
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
let _ptext = support::decrypt(&mut alice_store, &bob_address, &ctext)
|
|
.now_or_never()
|
|
.expect("sync")
|
|
.expect("success");
|
|
})
|
|
});
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn session_encrypt(mut c: &mut Criterion) {
|
|
session_encrypt_result(&mut c).expect("success");
|
|
}
|
|
|
|
pub fn session_encrypt_decrypt(mut c: &mut Criterion) {
|
|
session_encrypt_decrypt_result(&mut c).expect("success");
|
|
}
|
|
|
|
criterion_group!(benches, session_encrypt, session_encrypt_decrypt);
|
|
|
|
criterion_main!(benches);
|