// sphinx_benchmark_test.rs - sphinx cryptographic packet format tests // Copyright (C) 2018 David Anthony Stainton. // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #[macro_use] extern crate criterion; extern crate rand; extern crate ecdh_wrapper; extern crate sphinxcrypto; use criterion::Criterion; use self::rand::Rng; use self::rand::os::OsRng; use ecdh_wrapper::PrivateKey; use sphinxcrypto::server::sphinx_packet_unwrap; use sphinxcrypto::client::{new_packet, PathHop}; use sphinxcrypto::constants::{MAX_HOPS, NODE_ID_SIZE, RECIPIENT_ID_SIZE, SURB_ID_SIZE}; use sphinxcrypto::commands::{RoutingCommand, Delay, SURBReply, Recipient}; struct NodeParams { pub id: [u8; NODE_ID_SIZE], pub private_key: PrivateKey, } fn os_rng() -> OsRng { OsRng::new().expect("failure to create an OS RNG") } fn new_node(rng: &mut R) -> NodeParams { let mut id = [0u8; NODE_ID_SIZE]; rng.fill_bytes(&mut id); let keypair = PrivateKey::generate(rng).unwrap(); return NodeParams{ id: id, private_key: keypair, }; } fn new_path_vector(rng: &mut R, num_hops: u8, is_surb: bool) -> (Vec, Vec) { const DELAY_BASE: u32 = 123; // Generate the keypairs and node identifiers for the "nodes". let mut nodes = vec![]; let mut i = 0; while i < num_hops { nodes.push(new_node(rng)); i += 1; } // Assemble the path vector. let mut path = vec![]; i = 0; while i < num_hops { let mut commands: Vec = vec![]; if i < num_hops - 1 { // Non-terminal hop, add the delay. let delay = RoutingCommand::Delay( Delay{ delay: DELAY_BASE * (i as u32 + 1), } ); commands.push(delay); } else { // Terminal hop, add the recipient. let mut rcpt_id = [0u8; RECIPIENT_ID_SIZE]; rng.fill_bytes(&mut rcpt_id); let rcpt = RoutingCommand::Recipient( Recipient{ id: rcpt_id, } ); commands.push(rcpt); if is_surb { let mut surb_id = [0u8; SURB_ID_SIZE]; rng.fill_bytes(&mut surb_id); let surb_reply = RoutingCommand::SURBReply( SURBReply{ id: surb_id, } ); commands.push(surb_reply); } } let hop = PathHop { id: nodes[i as usize].id, public_key: nodes[i as usize].private_key.public_key(), commands: Some(commands), }; path.push(hop); i += 1; } return (nodes, path); } fn criterion_sphinx_unwrap_benchmark(c: &mut Criterion) { let s = String::from("We must defend our own privacy if we expect to have any. \ We must come together and create systems which allow anonymous transactions to take place. \ People have been defending their own privacy for centuries with whispers, darkness, envelopes, \ closed doors, secret handshakes, and couriers. The technologies of the past did not allow for strong \ privacy, but electronic technologies do."); let _s_len = s.len(); let payload = s.into_bytes(); let mut r = os_rng(); let is_surb = false; let _tuple = new_path_vector(&mut r, MAX_HOPS as u8, is_surb); let nodes = _tuple.0; let path = _tuple.1; let packet = new_packet(&mut r, path, payload).unwrap(); c.bench_function("sphinx unwrap", move |b| b.iter(|| { let _unwrap_tuple = sphinx_packet_unwrap(&nodes[0].private_key, &mut packet.clone()); })); } criterion_group!(benches, criterion_sphinx_unwrap_benchmark); criterion_main!(benches);