Skip to main content

RandomState

Struct RandomState 

Source
pub struct RandomState<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> { /* private fields */ }
Expand description

A [std::hash::RandomState] compatible hasher that initializes a RapidHasher with a random seed and random global secrets.

This is designed to provide some HashDoS resistance by using a random seed per hashmap, and a global random set of secrets.

§Performance

Enabling the std feature will make RandomState slightly faster to initialize by avoiding a global atomic load/store and using thread-locals instead.

Note that GlobalState will be even faster to initialize than RandomState, as it does not generate a new seed for every instantiation. GlobalState also randomizes the seed and secrets on the first instantiation, so it can still provide minimal DoS resistance, but then re-uses that same randomized seed and secrets for subsequent instantiations. If you are creating many instances of RandomState in a tight loop, you may want to consider using GlobalState instead.

§Portability

On most target platforms, the secrets are randomly initialized once and cached globally for the lifetime of the program. With the getrandom_04 feature this uses OS/platform entropy directly; with std it uses the standard library’s secure RNG; with neither it falls back to ASLR-based entropy alone. A fresh seed is generated for each new instance of RandomState from a thread-local or global counter mixed with ASLR entropy.

Some targets have no ambient entropy or ASLR at all, and seeding on them is otherwise fully deterministic between boots. Enable the getrandom_04 feature to get true randomisation for HashDoS resistance on these targets:

  • wasm32 with WASI (wasm32-wasip1/wasm32-wasip2): enabling rapidhash’s getrandom_04 feature is sufficient; entropy comes from the WASI host.
  • wasm32 in the browser or node (wasm32-unknown-unknown): enable rapidhash’s getrandom_04 feature, add getrandom = { version = "0.4", features = ["wasm_js"] } to the top-level binary’s dependencies, and build with RUSTFLAGS='--cfg getrandom_backend="wasm_js"'. Without the backend flag the build fails with instructions, rather than silently falling back to deterministic seeding.
  • Embedded and other no_std targets with a hardware RNG: enable rapidhash’s getrandom_04 feature and register a custom backend that reads from the platform’s RNG.

Older or exotic platforms that getrandom does not support can also use the custom backend mechanism to supply their own entropy source.

On targets without atomic pointer support (e.g. thumbv6m-none-eabi), the global secrets cannot be randomized and fall back to the default secrets. With the getrandom_04 feature each RandomState still draws a fresh random per-map seed directly from the entropy source, retaining minimal HashDoS resistance; without it these platforms have none. If stronger support for these platforms is important to your application, please raise a GitHub issue.

§Example

use std::collections::HashMap;
use std::hash::Hasher;

use rapidhash::quality::RandomState;

let mut map = HashMap::with_hasher(RandomState::default());
map.insert(42, "the answer");

Implementations§

Source§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Source

pub fn new() -> Self

Create a new random state with a fresh per-instance seed and the global secrets.

A new seed is generated for every RandomState instance. With the std feature this uses a fast thread-local counter mixed with stack-pointer (ASLR) entropy, where each thread’s counter is initialized from the process-wide random seed and a global thread counter; without std it uses a global atomic counter initialized from the process-wide random seed. On targets with neither, each instance draws its seed from getrandom when the getrandom_04 feature is enabled, or falls back to ASLR alone.

The secrets are randomized once and then cached globally for the lifetime of the program. The one-time randomization is derived from OS/platform entropy with the getrandom_04 feature, or the standard library’s secure RNG with the std feature (the same source std uses to seed its own hashers); with neither it falls back to mixing ASLR and other weaker sources of entropy.

On platforms that do not support atomic pointers, the secrets will be the default rapidhash secrets, which are not randomized. Therefore, targets without atomic pointer support only have minimal HashDoS resistance when the getrandom_04 feature provides random seeds.

Trait Implementations§

Source§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> BuildHasher for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Source§

type Hasher = RapidHasher<'static, AVALANCHE, SPONGE, COMPACT, PROTECTED>

Type of the hasher that will be created.
Source§

fn build_hasher(&self) -> Self::Hasher

Creates a new hasher. Read more
1.71.0 · Source§

fn hash_one<T>(&self, x: T) -> u64
where T: Hash, Self: Sized, Self::Hasher: Hasher,

Calculates the hash of a single value. Read more
Source§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Clone for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Copy for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Source§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Debug for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Default for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Warning that RandomState only randomizes the seed on platforms that support atomic pointers.

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Eq for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Source§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> PartialEq for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> StructuralPartialEq for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Auto Trait Implementations§

§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Freeze for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> RefUnwindSafe for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Send for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Sync for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Unpin for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> UnsafeUnpin for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

§

impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> UnwindSafe for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.