Skip to content
Closed
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
964 changes: 703 additions & 261 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ opt-level = 3
lto = "fat"
strip = true

[dev-dependencies]
criterion = "0.4"

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

[dependencies]
tokio = { version = "1.7", features = [
"rt-multi-thread",
Expand All @@ -35,6 +42,9 @@ hex = "0.4.3"
percent-encoding = "2.1.0"
binascii = "0.1"
lazy_static = "1.4.0"
blowfish = "0.9.1"
cipher = "0.4.3"
crypto-common = {version = "0.1.6", features = ["rand_core"] }

openssl = { version = "0.10.41", features = ["vendored"] }

Expand Down
71 changes: 71 additions & 0 deletions benches/bench_connection_cookie.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use std::net::{IpAddr, Ipv4Addr, SocketAddr};

use criterion::{criterion_group, criterion_main, Criterion};
use torrust_tracker::udp::connection_cookie::{
ConnectionCookie, EncryptedConnectionCookie, HashedConnectionCookie, WitnessConnectionCookie,
};

pub fn benchmark_hashed_connection_cookie(bench: &mut Criterion) {
use HashedConnectionCookie as BenchConnectionCookie;

let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0);
let cookie = BenchConnectionCookie::make_connection_cookie(&remote_address);

bench.bench_function("Make Hashed Cookie", |b| {
b.iter(|| {
let _ = BenchConnectionCookie::make_connection_cookie(&remote_address);
})
});

bench.bench_function("Check Hashed Cookie", |b| {
b.iter(|| {
let _ = BenchConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap();
})
});
}

pub fn benchmark_witness_connection_cookie(bench: &mut Criterion) {
use WitnessConnectionCookie as BenchConnectionCookie;

let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0);
let cookie = BenchConnectionCookie::make_connection_cookie(&remote_address);

bench.bench_function("Make Witness Cookie", |b| {
b.iter(|| {
let _ = BenchConnectionCookie::make_connection_cookie(&remote_address);
})
});

bench.bench_function("Check Witness Cookie", |b| {
b.iter(|| {
let _ = BenchConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap();
})
});
}

pub fn benchmark_encrypted_connection_cookie(bench: &mut Criterion) {
use EncryptedConnectionCookie as BenchConnectionCookie;

let remote_address = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0);
let cookie = BenchConnectionCookie::make_connection_cookie(&remote_address);

bench.bench_function("Make Encrypted Cookie", |b| {
b.iter(|| {
let _ = BenchConnectionCookie::make_connection_cookie(&remote_address);
})
});

bench.bench_function("Check Encrypted Cookie", |b| {
b.iter(|| {
let _ = BenchConnectionCookie::check_connection_cookie(&remote_address, &cookie).unwrap();
})
});
}

criterion_group!(
benches,
benchmark_hashed_connection_cookie,
benchmark_witness_connection_cookie,
benchmark_encrypted_connection_cookie,
);
criterion_main!(benches);
31 changes: 31 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,34 @@ pub mod ephemeral_instance_keys {
pub static ref RANDOM_SEED: Seed = Rng::gen(&mut ThreadRng::default());
}
}

pub mod block_ciphers {

use blowfish::BlowfishLE;
use cipher::KeyInit;
use rand::rngs::StdRng;
use rand::SeedableRng;

pub type Cipher = BlowfishLE;

pub mod ephemeral_instance {
use super::*;
use crate::ephemeral_instance_keys::RANDOM_SEED;

lazy_static! {
pub static ref BLOCK_CIPHER_BLOWFISH: Cipher = <BlowfishLE as KeyInit>::new(&<BlowfishLE as KeyInit>::generate_key(
<StdRng as SeedableRng>::from_seed(*RANDOM_SEED)
));
}
}

pub mod testing {
use super::*;

lazy_static! {
pub static ref TEST_BLOCK_CIPHER_BLOWFISH: Cipher = <BlowfishLE as KeyInit>::new(
&<BlowfishLE as KeyInit>::generate_key(<StdRng as SeedableRng>::from_seed([0u8; 32]))
);
}
}
}
7 changes: 6 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Arc;
use log::info;
use torrust_tracker::tracker::statistics::StatsTracker;
use torrust_tracker::tracker::tracker::TorrentTracker;
use torrust_tracker::{ephemeral_instance_keys, logging, setup, static_time, Configuration};
use torrust_tracker::{block_ciphers, ephemeral_instance_keys, logging, setup, static_time, Configuration};

#[tokio::main]
async fn main() {
Expand All @@ -15,6 +15,11 @@ async fn main() {
// Initialize the Ephemeral Instance Random Seed
lazy_static::initialize(&ephemeral_instance_keys::RANDOM_SEED);

// Initialize the Block Ciphers
lazy_static::initialize(&block_ciphers::ephemeral_instance::BLOCK_CIPHER_BLOWFISH);
#[cfg(test)]
lazy_static::initialize(&block_ciphers::testing::TEST_BLOCK_CIPHER_BLOWFISH);

// Initialize Torrust config
let config = match Configuration::load_from_file(CONFIG_PATH) {
Ok(config) => Arc::new(config),
Expand Down
81 changes: 81 additions & 0 deletions src/protocol/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,85 @@ pub mod keys {
}
}
}

pub mod block_ciphers {
use cipher::generic_array::GenericArray;
use cipher::BlockSizeUser;

pub(super) use crate::block_ciphers::ephemeral_instance::BLOCK_CIPHER_BLOWFISH as INSTANCE_BLOCK_CIPHER;
#[allow(unused_imports)]
pub(super) use crate::block_ciphers::testing::TEST_BLOCK_CIPHER_BLOWFISH as TEST_BLOCK_CIPHER;
use crate::block_ciphers::Cipher;

pub trait BlockCipherKeeper {
type BlockCipher: cipher::BlockCipher;
fn get_block_cipher() -> &'static Self::BlockCipher;
}

pub type CipherArray = GenericArray<u8, <Cipher as BlockSizeUser>::BlockSize>;

pub struct DefaultBlockCipher;
pub struct InstanceBlockCipher;

impl BlockCipherKeeper for DefaultBlockCipher {
type BlockCipher = Cipher;
fn get_block_cipher() -> &'static Self::BlockCipher {
&self::detail::DEFAULT_BLOCK_CIPHER
}
}

impl BlockCipherKeeper for InstanceBlockCipher {
type BlockCipher = Cipher;
fn get_block_cipher() -> &'static Self::BlockCipher {
&INSTANCE_BLOCK_CIPHER
}
}

#[cfg(test)]
mod tests {
use cipher::BlockEncrypt;

use super::{BlockCipherKeeper, CipherArray, DefaultBlockCipher, InstanceBlockCipher, TEST_BLOCK_CIPHER};
use crate::block_ciphers::Cipher;

pub struct TestBlockCipher;

impl BlockCipherKeeper for TestBlockCipher {
type BlockCipher = Cipher;

fn get_block_cipher() -> &'static Self::BlockCipher {
&TEST_BLOCK_CIPHER
}
}

#[test]
fn when_testing_the_default_and_test_block_ciphers_should_be_the_same() {
let mut array = CipherArray::from([0u8; 8]);
let mut array2 = CipherArray::from([0u8; 8]);

DefaultBlockCipher::get_block_cipher().encrypt_block(&mut array);
TestBlockCipher::get_block_cipher().encrypt_block(&mut array2);

assert_eq!(array, array2)
}

#[test]
fn when_testing_the_default_and_instance_block_ciphers_should_be_the_different() {
let mut array = CipherArray::from([0u8; 8]);
let mut array2 = CipherArray::from([0u8; 8]);

DefaultBlockCipher::get_block_cipher().encrypt_block(&mut array);
InstanceBlockCipher::get_block_cipher().encrypt_block(&mut array2);

assert_ne!(array, array2)
}
}

mod detail {
#[cfg(not(test))]
pub(super) use super::INSTANCE_BLOCK_CIPHER as DEFAULT_BLOCK_CIPHER;
#[cfg(test)]
pub(super) use super::TEST_BLOCK_CIPHER as DEFAULT_BLOCK_CIPHER;
}
}
}
6 changes: 4 additions & 2 deletions src/tracker/peer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ mod test {
};

use crate::peer::TorrentPeer;
use crate::udp::connection_cookie::{into_connection_id, make_connection_cookie};
use crate::udp::connection_cookie::{into_connection_id, ConnectionCookie, DefaultConnectionCookie};
// todo: duplicate functions is PR 82. Remove duplication once both PR are merged.

fn sample_ipv4_remote_addr() -> SocketAddr {
Expand All @@ -152,7 +152,9 @@ mod test {
let info_hash_aquatic = aquatic_udp_protocol::InfoHash([0u8; 20]);

let default_request = AnnounceRequest {
connection_id: into_connection_id(&make_connection_cookie(&sample_ipv4_remote_addr())),
connection_id: into_connection_id(&DefaultConnectionCookie::make_connection_cookie(
&sample_ipv4_remote_addr(),
)),
transaction_id: TransactionId(0i32),
info_hash: info_hash_aquatic,
peer_id: AquaticPeerId(*b"-qB00000000000000000"),
Expand Down
Loading