reorganize module
This commit is contained in:
104
_archive/rhai_engine/rhaibook/patterns/static-hash.md
Normal file
104
_archive/rhai_engine/rhaibook/patterns/static-hash.md
Normal file
@@ -0,0 +1,104 @@
|
||||
Static Hashing
|
||||
==============
|
||||
|
||||
{{#include ../links.md}}
|
||||
|
||||
To counter [DOS] attacks, the _hasher_ used by Rhai, [`ahash`], automatically generates a different
|
||||
_seed_ for hashing during each compilation and execution run.
|
||||
|
||||
This means that hash values generated by the hasher will not be _stable_ – they change
|
||||
during each compile, and during each run.
|
||||
|
||||
For certain niche scenarios, however, dynamic hashes are undesirable.
|
||||
|
||||
So, when _static hashing_ is employed, all hashing uses a fixed, predictable seed all the time.
|
||||
|
||||
```admonish abstract.small "Hashing seed"
|
||||
|
||||
A hashing seed requires four 64-bit numbers (i.e. `u64`).
|
||||
```
|
||||
|
||||
```admonish tip.small "Tip: Static hashes are consistent and predictable"
|
||||
|
||||
Under static hashing, the same function signature _always_ generate the same hash value,
|
||||
given the same seed.
|
||||
```
|
||||
|
||||
```admonish warning.small "Warning: Safety considerations"
|
||||
|
||||
A fixed hashing seed enlarges the attack surface of Rhai to malicious intent
|
||||
(e.g. [DOS] attacks).
|
||||
```
|
||||
|
||||
|
||||
Set at Run-Time
|
||||
---------------
|
||||
|
||||
Call the static function `rhai::config::hashing::set_ahash_seed` with four `u64` numbers that make
|
||||
up the hashing seed.
|
||||
|
||||
The seed specified is always used to initialize the hasher.
|
||||
|
||||
```rust
|
||||
// Set specific hashing seed - do this BEFORE anything else!
|
||||
rhai::config::hashing::set_ahash_seed(Some([123, 456, 789, 42]))?;
|
||||
|
||||
// ... from now on, all hashing will be predictable
|
||||
let engine = Engine::new();
|
||||
```
|
||||
|
||||
```admonish danger.small "Warning: Only call once"
|
||||
|
||||
`rhai::config::hashing::set_ahash_seed` can only ever be called _once_,
|
||||
and must be called _BEFORE_ performing any operation on Rhai (e.g. creating
|
||||
an [`Engine`]).
|
||||
|
||||
Calling it a second time simply returns an error.
|
||||
```
|
||||
|
||||
|
||||
Set at Compile Time
|
||||
-------------------
|
||||
|
||||
The hashing seed can also be provided, at _compile time_, via the environment variable
|
||||
`RHAI_AHASH_SEED`, with four `u64` numbers that must be specified in Rust array literal format.
|
||||
|
||||
```admonish warning.small "Warning"
|
||||
|
||||
If a hashing seed is also set via `rhai::config::hashing::set_ahash_seed`,
|
||||
this environment variable has no effect.
|
||||
```
|
||||
|
||||
```sh
|
||||
RHAI_AHASH_SEED="[123, 456, 789, 42]" cargo build ...
|
||||
```
|
||||
|
||||
The seed specified in `RHAI_AHASH_SEED` is always used to initialize the hasher.
|
||||
|
||||
If the environment variable is missing, or it contains all zeros (i.e. `[0, 0, 0, 0]`),
|
||||
then static hashing is disabled.
|
||||
|
||||
|
||||
TL;DR
|
||||
-----
|
||||
|
||||
~~~admonish question "Why can't we tell `ahash` to use a static (fixed) seed?"
|
||||
|
||||
For static hashing seed, [`ahash`] requires:
|
||||
|
||||
* `default-features = false`
|
||||
* `runtime-rng` feature is _not_ set (default on)
|
||||
* `compile-time-rng` feature is _not_ set
|
||||
|
||||
#### The bane of additive Cargo features
|
||||
|
||||
However, [`ahash`] is also extremely popular, used by many many other crates,
|
||||
most notably [`hashbrown`](https://crates.io/crates/hashbrown).
|
||||
|
||||
Chances are that there are dependency crates that in turn depend on [`ahash`] with
|
||||
default features. Since cargo features are _additive_, it is almost certain that [`ahash`]
|
||||
will use a runtime-generated seed for large projects.
|
||||
|
||||
Hence, there exists a need to tell [`ahash`] to use a fixed seed, even when its feature flags
|
||||
say otherwise.
|
||||
~~~
|
Reference in New Issue
Block a user