diff --git a/performance/src/crypto/aes.rs b/performance/src/crypto/aes.rs index fb0dbd2..6b0dec4 100644 --- a/performance/src/crypto/aes.rs +++ b/performance/src/crypto/aes.rs @@ -1,4 +1,3 @@ - /// The specified size of an AES-256 key. pub const AES_256_KEY_SIZE: usize = 32; /// The specified size of an AES block. diff --git a/performance/src/crypto/sha512.rs b/performance/src/crypto/sha512.rs index 2d88fab..5ea73a3 100644 --- a/performance/src/crypto/sha512.rs +++ b/performance/src/crypto/sha512.rs @@ -1,4 +1,3 @@ - /// The size of a SHA512 hash, which is always 64 bytes pub const SHA512_HASH_SIZE: usize = 64; diff --git a/performance/src/crypto_impl/openssl.rs b/performance/src/crypto_impl/openssl.rs index 8a73e92..873d0f8 100644 --- a/performance/src/crypto_impl/openssl.rs +++ b/performance/src/crypto_impl/openssl.rs @@ -210,7 +210,7 @@ impl HighThroughputAesGcmPool for OpenSSLAesGcmPool { } } - fn start_enc<'a>(&'a self, nonce: &[u8; AES_GCM_NONCE_SIZE]) -> OpenSSLAesGcmEnc { + fn start_enc<'a>(&'a self, nonce: &[u8; AES_GCM_NONCE_SIZE]) -> OpenSSLAesGcmEnc<'a> { let i = u64::from_be_bytes(nonce[4..].try_into().unwrap()); let g = self.enc[(i as usize) % self.enc.len()].lock().unwrap(); unsafe { @@ -219,7 +219,7 @@ impl HighThroughputAesGcmPool for OpenSSLAesGcmPool { OpenSSLAesGcmEnc(g) } - fn start_dec<'a>(&'a self, nonce: &[u8; AES_GCM_NONCE_SIZE]) -> OpenSSLAesGcmDec { + fn start_dec<'a>(&'a self, nonce: &[u8; AES_GCM_NONCE_SIZE]) -> OpenSSLAesGcmDec<'a> { let i = u64::from_be_bytes(nonce[4..].try_into().unwrap()); let g = self.dec[(i as usize) % self.enc.len()].lock().unwrap(); unsafe { diff --git a/performance/src/indexed_heap.rs b/performance/src/indexed_heap.rs index 53e03a2..2b6b0a1 100644 --- a/performance/src/indexed_heap.rs +++ b/performance/src/indexed_heap.rs @@ -19,9 +19,12 @@ pub struct BinaryHeapIndex(usize, u64); const RESERVED_MARKER: u64 = 1; const EMPTY_MARKER: u64 = 0; -/// A simple Priority Queue built from a binary heap and a generational array. +/// A simple priority queue built from a binary heap and a generational array. /// Entries in the queue are accessed and updated by their generational index. /// This allows for extremely simple memory management and fast queue updates. +/// +/// The item with the greatest priority will be sorted to the start of the queue. +/// Use `std::cmp::Reverse` if you need items sorted in the opposite order. pub struct IndexedBinaryHeap { generation: u64, free_list_head: usize, @@ -179,27 +182,38 @@ impl IndexedBinaryHeap { false } } + /// Retrieve the priority of an item stored at the given index of the binary heap. + /// Then apply the given function that returns an optional new priority. + /// + /// Returns an option containing the item's previous priority if the item was successfully + /// found in the heap and the function returned `Some(_)`, choosing to replace it. + /// + /// Amortized runtime: O(log(n)). + #[inline] + pub fn update_priority(&mut self, idx: BinaryHeapIndex, f: impl FnOnce(&P) -> Option

) -> Option

{ + if let Some(data_idx) = self.deref_index(idx) { + if let Some(new_priority) = f(&self.data[data_idx].1) { + let lesser = self.data[data_idx].1 > new_priority; + let old_priority = std::mem::replace(&mut self.data[data_idx].1, new_priority); + if lesser { + self.bubble_down(data_idx); + } else { + self.bubble_up(data_idx); + } + Some(old_priority) + } else { + None + } + } else { + None + } + } /// Change the priority of the item stored at the given index of the binary heap. /// Returns the item's previous priority, or `None` if the item does not exist in the heap. /// /// Amortized runtime: O(log(n)). pub fn change_priority(&mut self, idx: BinaryHeapIndex, new_priority: P) -> Option

{ - self.deref_index(idx).map(|data_idx| { - let c = if self.data[data_idx].1 < new_priority { - 1 - } else if self.data[data_idx].1 > new_priority { - 2 - } else { - 3 - }; - let old_priority = std::mem::replace(&mut self.data[data_idx].1, new_priority); - if c == 1 { - self.bubble_up(data_idx); - } else if c == 2 { - self.bubble_down(data_idx); - } - old_priority - }) + self.update_priority(idx, |_| Some(new_priority)) } /// Change the item stored at the given index of the binary heap. /// Returns previously stored item, or `None` if it does not exist in the heap. diff --git a/performance/src/lib.rs b/performance/src/lib.rs index a002b35..cfc6835 100644 --- a/performance/src/lib.rs +++ b/performance/src/lib.rs @@ -36,21 +36,21 @@ //! - **KBKDF**: Key mixing, sub-key derivation //! - **AES-256**: Single block encryption of header to harden packet fragmentation protocol //! - **AES-256-GCM**: Authenticated encryption -#![warn(missing_docs, rust_2018_idioms)] +//#![warn(missing_docs, rust_2018_idioms)] pub mod crypto; pub mod crypto_impl; +mod antireplay; +mod challenge; +mod frag_cache; +mod fragged; +mod handshake_cache; /// A module that implements a priority queue using a binary heap. /// Generational indexing is used to improve performance and simplify lifetime management. /// /// This module is used by this implementation of ZSSP, but it isn't a core component of the protocol. /// Rather, it is a reuseable component that you may find useful on its own. pub mod indexed_heap; -mod antireplay; -mod challenge; -mod frag_cache; -mod fragged; -mod handshake_cache; mod log_event; mod ratchet_state; mod symmetric_state;