• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #![allow(missing_docs, clippy::expect_used, clippy::unwrap_used)]
16 
17 use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput};
18 use rand::{Rng, SeedableRng};
19 
20 use crypto_provider::CryptoProvider;
21 use crypto_provider_default::CryptoProviderImpl;
22 use ukey2_connections::{
23     D2DConnectionContextV1, D2DHandshakeContext, InitiatorD2DHandshakeContext,
24     ServerD2DHandshakeContext,
25 };
26 use ukey2_rs::{HandshakeImplementation, NextProtocol};
27 
run_handshake_with_rng<C, R>( mut rng: R, next_protocols: Vec<NextProtocol>, ) -> (D2DConnectionContextV1<R>, D2DConnectionContextV1<R>) where C: CryptoProvider, R: rand::RngCore + rand::CryptoRng + rand::SeedableRng + Send,28 fn run_handshake_with_rng<C, R>(
29     mut rng: R,
30     next_protocols: Vec<NextProtocol>,
31 ) -> (D2DConnectionContextV1<R>, D2DConnectionContextV1<R>)
32 where
33     C: CryptoProvider,
34     R: rand::RngCore + rand::CryptoRng + rand::SeedableRng + Send,
35 {
36     let mut initiator_ctx = InitiatorD2DHandshakeContext::<C, R>::new_impl(
37         HandshakeImplementation::Spec,
38         R::from_rng(&mut rng).unwrap(),
39         next_protocols.clone(),
40     );
41     let mut server_ctx = ServerD2DHandshakeContext::<C, R>::new_impl(
42         HandshakeImplementation::Spec,
43         R::from_rng(&mut rng).unwrap(),
44         &next_protocols,
45     );
46     server_ctx
47         .handle_handshake_message(
48             initiator_ctx.get_next_handshake_message().expect("No message").as_slice(),
49         )
50         .expect("Failed to handle message");
51     initiator_ctx
52         .handle_handshake_message(
53             server_ctx.get_next_handshake_message().expect("No message").as_slice(),
54         )
55         .expect("Failed to handle message");
56     server_ctx
57         .handle_handshake_message(
58             initiator_ctx.get_next_handshake_message().expect("No message").as_slice(),
59         )
60         .expect("Failed to handle message");
61     assert!(initiator_ctx.is_handshake_complete());
62     assert!(server_ctx.is_handshake_complete());
63     (initiator_ctx.to_connection_context().unwrap(), server_ctx.to_connection_context().unwrap())
64 }
65 
cbc_criterion_benchmark(c: &mut Criterion)66 fn cbc_criterion_benchmark(c: &mut Criterion) {
67     let kib = 1024;
68     let mut group = c.benchmark_group("throughput");
69     let mut plaintext = Vec::new();
70     let (mut initiator_ctx, mut server_ctx) = run_handshake_with_rng::<CryptoProviderImpl, _>(
71         rand::rngs::StdRng::from_entropy(),
72         vec![NextProtocol::Aes256CbcHmacSha256],
73     );
74     for len in [10 * kib, 1024 * kib] {
75         let _ = group.throughput(Throughput::Bytes(len as u64));
76         plaintext.resize(len, 0);
77         rand::thread_rng().fill(&mut plaintext[..]);
78         let _ = group.bench_function(
79             format!("AES-CBC-256_HMAC-SHA256 UKEY2 encrypt/decrypt {}KiB", len / kib),
80             |b| {
81                 b.iter(|| {
82                     let msg = initiator_ctx
83                         .encode_message_to_peer::<CryptoProviderImpl, &[u8]>(&plaintext, None);
84                     black_box(
85                         server_ctx
86                             .decode_message_from_peer::<CryptoProviderImpl, &[u8]>(&msg, None),
87                     )
88                 })
89             },
90         );
91     }
92 }
93 
gcm_criterion_benchmark(c: &mut Criterion)94 fn gcm_criterion_benchmark(c: &mut Criterion) {
95     let kib = 1024;
96     let mut group = c.benchmark_group("throughput");
97     let mut plaintext = Vec::new();
98     let (mut initiator_ctx, mut server_ctx) = run_handshake_with_rng::<CryptoProviderImpl, _>(
99         rand::rngs::StdRng::from_entropy(),
100         vec![NextProtocol::Aes256GcmSiv],
101     );
102     for len in [10 * kib, 1024 * kib] {
103         let _ = group.throughput(Throughput::Bytes(len as u64));
104         plaintext.resize(len, 0);
105         rand::thread_rng().fill(&mut plaintext[..]);
106         let _ = group.bench_function(
107             format!("AES-GCM-SIV UKEY2 encrypt/decrypt {}KiB", len / kib),
108             |b| {
109                 b.iter(|| {
110                     let msg = initiator_ctx
111                         .encode_message_to_peer::<CryptoProviderImpl, &[u8]>(&plaintext, None);
112                     black_box(
113                         server_ctx
114                             .decode_message_from_peer::<CryptoProviderImpl, &[u8]>(&msg, None),
115                     )
116                 })
117             },
118         );
119     }
120 }
121 
122 criterion_group!(benches, cbc_criterion_benchmark, gcm_criterion_benchmark);
123 criterion_main!(benches);
124