mirror of
https://github.com/zerotier/zssp.git
synced 2026-05-22 16:28:40 -07:00
added binary heap function
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/// The size of a SHA512 hash, which is always 64 bytes
|
||||
pub const SHA512_HASH_SIZE: usize = 64;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<T, P> {
|
||||
generation: u64,
|
||||
free_list_head: usize,
|
||||
@@ -179,27 +182,38 @@ impl<T, P: Ord> IndexedBinaryHeap<T, P> {
|
||||
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<P>) -> Option<P> {
|
||||
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<P> {
|
||||
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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user