Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend benchmarks #134

Merged
merged 4 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,13 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Benchmark
run: cargo bench --bench client --bench server
if: ${{ matrix.os == 'windows-latest' }}

- name: Benchmark
run: cargo bench
if: ${{ matrix.os != 'windows-latest' }}

# interop:
# needs: test
Expand Down
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,17 @@ serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
rayon = "1.3.0"
criterion = "0.5"
psm = "0.1.24"
bytesize = "1.3.0"

[[bench]]
name = "client"
harness = false

[[bench]]
name = "client_stack"
harness = false

[[bench]]
name = "server"
harness = false
Expand Down
6 changes: 5 additions & 1 deletion benches/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use bertie::{
// SHA384_Aes256Gcm_RsaPssRsaSha256_X25519,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519Kyber768Draft00,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519MlKem768,
SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256,
SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519,
SignatureScheme,
Expand All @@ -41,7 +43,7 @@ fn mb_per_second(d: Duration) -> f64 {

const ITERATIONS: usize = 1000;
const NUM_PAYLOAD_BYTES: usize = 0x4000;
const CIPHERSUITES: [Algorithms; 4] = [
const CIPHERSUITES: [Algorithms; 6] = [
// SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256,
// SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519,
// SHA256_Aes128Gcm_RsaPssRsaSha256_P256,
Expand All @@ -50,6 +52,8 @@ const CIPHERSUITES: [Algorithms; 4] = [
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519,
SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256,
SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519Kyber768Draft00,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519MlKem768,
// SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256,
// SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519,
// SHA384_Aes256Gcm_RsaPssRsaSha256_P256,
Expand Down
202 changes: 202 additions & 0 deletions benches/client_stack.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
#![allow(dead_code)]

use bytesize::ByteSize;
use rand::thread_rng;
use std::alloc;
use std::net::TcpListener;

use bertie::{
stream::BertieStream,
tls13crypto::{
Algorithms,
// SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256,
// SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519,
// SHA256_Aes128Gcm_RsaPssRsaSha256_P256,
// SHA256_Aes128Gcm_RsaPssRsaSha256_X25519,
// SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256,
// SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519,
// SHA384_Aes256Gcm_RsaPssRsaSha256_P256,
// SHA384_Aes256Gcm_RsaPssRsaSha256_X25519,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519Kyber768Draft00,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519MlKem768,
SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256,
SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519,
SignatureScheme,
},
};
const STACK_SIZE: usize = 8000 * 1024; // ~8MB of stack
const STACK_ALIGN: usize = 4096;

macro_rules! measure {
($name:literal, $fut: expr) => {
let layout = alloc::Layout::from_size_align(STACK_SIZE, STACK_ALIGN).unwrap();

unsafe {
let paintstack = alloc::alloc(layout);
assert!(!paintstack.is_null(), "allocations must succeed!");
for i in (0..STACK_SIZE).step_by(4) {
*paintstack.add(i) = 0xfe;
*paintstack.add(i + 1) = 0xca;
*paintstack.add(i + 2) = 0xfe;
*paintstack.add(i + 3) = 0xca;
}

psm::on_stack(paintstack, STACK_SIZE, || {
let _ = $fut;
});

for i in (0..STACK_SIZE).step_by(4) {
let s = std::slice::from_raw_parts(paintstack.add(i), 4);
if s != [0xfe, 0xca, 0xfe, 0xca] {
let highest_stack_usage = STACK_SIZE - i;
println!(
"[{: <14}] Highest stack usage: {}",
$name,
ByteSize(highest_stack_usage.try_into().unwrap())
);
break;
}
}
alloc::dealloc(paintstack, layout);
}
};
}

const CIPHERSUITES: [Algorithms; 6] = [
// SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_P256,
// SHA256_Aes128Gcm_EcdsaSecp256r1Sha256_X25519,
// SHA256_Aes128Gcm_RsaPssRsaSha256_P256,
// SHA256_Aes128Gcm_RsaPssRsaSha256_X25519,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_P256,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519,
SHA256_Chacha20Poly1305_RsaPssRsaSha256_P256,
SHA256_Chacha20Poly1305_RsaPssRsaSha256_X25519,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519Kyber768Draft00,
SHA256_Chacha20Poly1305_EcdsaSecp256r1Sha256_X25519MlKem768,
// SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_P256,
// SHA384_Aes256Gcm_EcdsaSecp256r1Sha256_X25519,
// SHA384_Aes256Gcm_RsaPssRsaSha256_P256,
// SHA384_Aes256Gcm_RsaPssRsaSha256_X25519,
];

/// Measure stack usage of the TLS protocol from the view of the client.
fn protocol() {
println!("Client Stack Usage:");
println!("===================");

for ciphersuite in CIPHERSUITES {
println!("\nCiphersuite: {ciphersuite}");
let (tx, rx) = std::sync::mpsc::channel();

// Server thread.
let server = std::thread::spawn(move || {
// We use an ephemeral (free) port (by using ":0") ...
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let port = listener.local_addr().unwrap().port();

// ... and let the client thread know.
tx.send(port).unwrap();

let (stream, _) = listener.accept().unwrap();

// tls13server(stream, "127.0.0.1", Some(algorithms)).unwrap();

let (cert_file, key_file) = match ciphersuite.signature() {
SignatureScheme::EcdsaSecp256r1Sha256 => (
"./tests/assets/p256_cert.der",
"./tests/assets/p256_key.der",
),
SignatureScheme::RsaPssRsaSha256 => {
("./tests/assets/rsa_cert.der", "./tests/assets/rsa_key.der")
}
_ => unreachable!("Unknown ciphersuite {:?}", ciphersuite),
};
let mut server =
BertieStream::server("127.0.0.1", port, stream, ciphersuite, cert_file, key_file)
.unwrap();

server.connect(&mut thread_rng()).unwrap();
server
});

// Client thread.
let port = rx.recv().unwrap();

let mut client;
let layout = alloc::Layout::from_size_align(STACK_SIZE, STACK_ALIGN).unwrap();
unsafe {
let paintstack = alloc::alloc(layout);
assert!(!paintstack.is_null(), "allocations must succeed!");
for i in (0..STACK_SIZE).step_by(4) {
*paintstack.add(i) = 0xfe;
*paintstack.add(i + 1) = 0xca;
*paintstack.add(i + 2) = 0xfe;
*paintstack.add(i + 3) = 0xca;
}

client = psm::on_stack(paintstack, STACK_SIZE, || {
BertieStream::client("127.0.0.1", port, ciphersuite, &mut thread_rng()).unwrap()
});

for i in (0..STACK_SIZE).step_by(4) {
let s = std::slice::from_raw_parts(paintstack.add(i), 4);
if s != [0xfe, 0xca, 0xfe, 0xca] {
let highest_stack_usage = STACK_SIZE - i;
println!(
"[{: <14}] Highest stack usage: {}",
"Client Connect",
ByteSize(highest_stack_usage.try_into().unwrap())
);
break;
}
}
alloc::dealloc(paintstack, layout);
}

measure!("Client Write", || client
.write("GET / HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n".as_bytes()));

// Exchange a message on the TLS channel.
let msg =
"Hello from the Bertie server. Congratulations on the successful interop.".as_bytes();
let mut server = server.join().unwrap();
server.write(msg).unwrap();

let data;
let layout = alloc::Layout::from_size_align(STACK_SIZE, STACK_ALIGN).unwrap();
unsafe {
let paintstack = alloc::alloc(layout);
assert!(!paintstack.is_null(), "allocations must succeed!");
for i in (0..STACK_SIZE).step_by(4) {
*paintstack.add(i) = 0xfe;
*paintstack.add(i + 1) = 0xca;
*paintstack.add(i + 2) = 0xfe;
*paintstack.add(i + 3) = 0xca;
}

data = psm::on_stack(paintstack, STACK_SIZE, || client.read().unwrap());

for i in (0..STACK_SIZE).step_by(4) {
let s = std::slice::from_raw_parts(paintstack.add(i), 4);
if s != [0xfe, 0xca, 0xfe, 0xca] {
let highest_stack_usage = STACK_SIZE - i;
println!(
"[{: <14}] Highest stack usage: {}",
"Client Read",
ByteSize(highest_stack_usage.try_into().unwrap())
);
break;
}
}
alloc::dealloc(paintstack, layout);
}

assert_eq!(data, msg);
}
}

fn main() {
protocol();
}
Loading