From a6981231c10a8daf5b4df496f221510384981386 Mon Sep 17 00:00:00 2001 From: Igor Katson Date: Thu, 1 Jul 2021 17:18:07 +0100 Subject: [PATCH] Add system hasher --- Cargo.lock | 37 +++++++++++++++++++++ crates/librqbit/Cargo.toml | 1 + crates/librqbit/src/file_ops.rs | 4 +-- crates/librqbit/src/peer_binary_protocol.rs | 1 - crates/librqbit/src/sha1w.rs | 28 +++++++++++++++- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7f0a89..534a12b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,6 +148,24 @@ dependencies = [ "syn", ] +[[package]] +name = "commoncrypto" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" +dependencies = [ + "commoncrypto-sys", +] + +[[package]] +name = "commoncrypto-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" +dependencies = [ + "libc", +] + [[package]] name = "core-foundation" version = "0.9.1" @@ -173,6 +191,18 @@ dependencies = [ "libc", ] +[[package]] +name = "crypto-hash" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a77162240fd97248d19a564a565eb563a3f592b386e4136fb300909e67dddca" +dependencies = [ + "commoncrypto", + "hex", + "openssl", + "winapi", +] + [[package]] name = "digest" version = "0.9.0" @@ -444,6 +474,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" + [[package]] name = "http" version = "0.2.4" @@ -604,6 +640,7 @@ dependencies = [ "bincode", "bitvec", "byteorder", + "crypto-hash", "futures", "log", "openssl", diff --git a/crates/librqbit/Cargo.toml b/crates/librqbit/Cargo.toml index 7beaf75..55c5040 100644 --- a/crates/librqbit/Cargo.toml +++ b/crates/librqbit/Cargo.toml @@ -22,6 +22,7 @@ size_format = "1" rand = "0.8" openssl = "0.10" warp = "0.3" +crypto-hash = "0.3" uuid = {version = "0.8", features = ["v4"]} futures = "0.3" diff --git a/crates/librqbit/src/file_ops.rs b/crates/librqbit/src/file_ops.rs index c75e77c..7c52879 100644 --- a/crates/librqbit/src/file_ops.rs +++ b/crates/librqbit/src/file_ops.rs @@ -121,7 +121,7 @@ impl<'a> FileOps<'a> { let mut read_buffer = vec![0u8; 65536]; for piece_info in self.lengths.iter_piece_infos() { - let mut computed_hash = sha1w::Sha1Openssl::new(); + let mut computed_hash = sha1w::Sha1System::new(); let mut piece_remaining = piece_info.len as usize; let mut some_files_broken = false; let mut at_least_one_file_required = current_file.full_file_required; @@ -221,7 +221,7 @@ impl<'a> FileOps<'a> { piece_index: ValidPieceIndex, last_received_chunk: &ChunkInfo, ) -> anyhow::Result { - let mut h = sha1w::Sha1Openssl::new(); + let mut h = sha1w::Sha1System::new(); let piece_length = self.lengths.piece_length(piece_index); let mut absolute_offset = self.lengths.piece_offset(piece_index); let mut buf = vec![0u8; std::cmp::min(65536, piece_length as usize)]; diff --git a/crates/librqbit/src/peer_binary_protocol.rs b/crates/librqbit/src/peer_binary_protocol.rs index 9e844ce..d873033 100644 --- a/crates/librqbit/src/peer_binary_protocol.rs +++ b/crates/librqbit/src/peer_binary_protocol.rs @@ -266,7 +266,6 @@ where PREAMBLE_LEN } Message::Piece(p) => { - // below code is wrong, need to serialize len_prefix let block_len = p.block.as_ref().len(); let payload_len = 8 + block_len; let msg_len = PREAMBLE_LEN + payload_len; diff --git a/crates/librqbit/src/sha1w.rs b/crates/librqbit/src/sha1w.rs index c26a17d..976a1e3 100644 --- a/crates/librqbit/src/sha1w.rs +++ b/crates/librqbit/src/sha1w.rs @@ -1,8 +1,10 @@ +use std::io::Write; + // Wrapper for sha1 libraries. // Sha1 computation is the majority of CPU usage of this library. // openssl seems 2-3x faster, so using it for now, but // leaving the pure-rust impl here too. Maybe someday make them -// runtime swappable. +// runtime swappable or enabled with a feature. pub trait ISha1 { fn new() -> Self; @@ -47,3 +49,27 @@ impl ISha1 for Sha1Openssl { self.inner.finish() } } + +pub struct Sha1System { + inner: crypto_hash::Hasher, +} + +impl ISha1 for Sha1System { + fn new() -> Self { + Self { + inner: crypto_hash::Hasher::new(crypto_hash::Algorithm::SHA1), + } + } + + fn update(&mut self, buf: &[u8]) { + self.inner.write_all(buf).unwrap(); + } + + fn finish(mut self) -> [u8; 20] { + let result = self.inner.finish(); + assert_eq!(result.len(), 20); + let mut result_arr = [0u8; 20]; + result_arr.copy_from_slice(&result); + result_arr + } +}