Skip to content

Commit

Permalink
Make the const-random dependency optional (#18)
Browse files Browse the repository at this point in the history
* Add a `compile-time-rng` feature. This makes the `const-random` dependency optional.
  • Loading branch information
koute authored and tkaitchuck committed Sep 19, 2019
1 parent 69cce66 commit b1225f4
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
9 changes: 8 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ doctest = true
bench = true
doc = true

[features]
default = ["compile-time-rng"]

# Disabling this feature will make the `ABuildHasher::new` use a preset seed
# and disable the `Default` impl for `AHasher`
compile-time-rng = ["const-random"]

[[bench]]
name = "ahash"
path = "tests/bench.rs"
Expand All @@ -41,7 +48,7 @@ debug-assertions = false
codegen-units = 1

[dependencies]
const-random = "0.1.6"
const-random = { version = "0.1.6", optional = true }
no-panic = { version = "0.1.10", optional = true }

[dev-dependencies]
Expand Down
8 changes: 8 additions & 0 deletions src/aes_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ pub struct AHasher {
}

impl AHasher {
/// Creates a new hasher keyed to the provided key.
#[inline]
pub fn new_with_key(key: u64) -> AHasher {
AHasher { buffer: [key, !key] }
}

/// Creates a new hasher keyed to the provided keys.
/// # Example
///
Expand Down Expand Up @@ -183,12 +189,14 @@ mod tests {
use std::collections::HashMap;
use std::hash::BuildHasherDefault;

#[cfg(feature = "compile-time-rng")]
#[test]
fn test_builder() {
let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default();
map.insert(1, 3);
}

#[cfg(feature = "compile-time-rng")]
#[test]
fn test_default() {
let hasher_a = AHasher::default();
Expand Down
23 changes: 20 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
//! It uses two rounds of AES per hash. So it should not be considered cryptographically secure.
#![cfg_attr(not(test), no_std)]
//#![feature(core_intrinsics)]
extern crate const_random;
#[cfg(all(test, feature = "no_panic"))]
extern crate no_panic;

Expand All @@ -25,7 +24,9 @@ mod fallback_hash;
#[cfg(test)]
mod hash_quality_test;

#[cfg(feature = "compile-time-rng")]
use const_random::const_random;

use core::hash::BuildHasher;
use core::sync::atomic::AtomicUsize;
use core::sync::atomic::Ordering;
Expand All @@ -44,9 +45,13 @@ pub use crate::fallback_hash::AHasher;
///This constant come from Kunth's prng
const MULTIPLE: u64 = 6364136223846793005;

///Const random provides randomized starting key with no runtime cost.
// Const random provides randomized starting key with no runtime cost.
#[cfg(feature = "compile-time-rng")]
static SEED: AtomicUsize = AtomicUsize::new(const_random!(u64));

#[cfg(not(feature = "compile-time-rng"))]
static SEED: AtomicUsize = AtomicUsize::new(MULTIPLE as usize);

/// Provides a default [Hasher] compile time generated constants for keys.
/// This is typically used in conjunction with [`BuildHasherDefault`] to create
/// [AHasher]s in order to hash the keys of the map.
Expand All @@ -64,13 +69,16 @@ static SEED: AtomicUsize = AtomicUsize::new(const_random!(u64));
/// [BuildHasherDefault]: std::hash::BuildHasherDefault
/// [Hasher]: std::hash::Hasher
/// [HashMap]: std::collections::HashMap
#[cfg(feature = "compile-time-rng")]
impl Default for AHasher {
/// Constructs a new [AHasher] with compile time generated constants for keys.
/// This means the keys will be the same from one instance to another,
/// but different from build to the next. So if it is possible for a potential
/// attacker to have access to the compiled binary it would be better
/// to specify keys generated at runtime.
///
/// This is defined only if the `compile-time-rng` feature is enabled.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -131,11 +139,13 @@ impl Default for ABuildHasher {
impl BuildHasher for ABuildHasher {
type Hasher = AHasher;

/// Constructs a new [AHasher] with keys based on compile time generated constants and the location
/// Constructs a new [AHasher] with keys based on compile time generated constants** and the location
/// of the this object in memory. This means that two different [BuildHasher]s will will generate
/// [AHasher]s that will return different hashcodes, but [Hasher]s created from the same [BuildHasher]
/// will generate the same hashes for the same input data.
///
/// ** - only if the `compile-time-rng` feature is enabled.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -209,6 +219,7 @@ mod test {
hash_test_final_wrapper(2, "");
}

#[cfg(feature = "compile-time-rng")]
#[test]
fn test_default_builder() {
let mut map = HashMap::<u32, u64, BuildHasherDefault<AHasher>>::default();
Expand All @@ -226,4 +237,10 @@ mod test {
let bytes: u64 = as_array!(input, 8).convert();
assert_eq!(bytes, 0x6464646464646464);
}

#[test]
fn test_ahasher_construction() {
let _ = AHasher::new_with_key(1234);
let _ = AHasher::new_with_keys(1245, 5678);
}
}

0 comments on commit b1225f4

Please sign in to comment.