Skip to content

Commit

Permalink
Make GxHash DOS resistant thanks to seed randomization
Browse files Browse the repository at this point in the history
  • Loading branch information
ogxd committed Nov 18, 2023
1 parent 5270d7d commit 575c04c
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "gxhash"
authors = ["Olivier Giniaux"]
version = "2.1.0"
version = "2.2.0"
edition = "2021"
description = "GxHash non-cryptographic algorithm"
license = "MIT"
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ let mut hashset = GxHashSet::default();
hashset.insert("hello world");
```

> **Warning**
> This is a non-cryptographic hashing algorithm, thus it is not recommended to use it as a cryptographic algorithm (it is not a replacement for SHA).
## Compatibility
- ARM 64-bit using `NEON` intrinsics.
- x86-64 bit using `SSE2` + `AES` intrinsics.
Expand All @@ -40,6 +37,14 @@ hashset.insert("hello world");
> **Warning**
> Other platforms are currently not supported (there is no fallback)
## Security
### DOS Resistance ✅
Because GxHash is a seeded hashing algorithm, meaning that depending on the seed used, it will generate completely different hashes. The default `Hasher` (`GxHasher::default()`) randomizes the seed on creation, making it any `HashMap`/`HashSet` DOS resistant, as no attacker will be able to predict which hashes may collide without knowing the seed used.
### Multicollisions Resistance ✅
GxHash uses a 128-bit internal state (and even 256-bit with the `avx2` feature). This makes GxHash [a widepipe construction](https://en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd_construction#Wide_pipe_construction) when generating hashes of size 64-bit or smaller, which had amongst other properties to be inherently more resistant to multicollision attacks. See [this paper](https://www.iacr.org/archive/crypto2004/31520306/multicollisions.pdf) for more details.
### Cryptographic Properties ❌
GxHash is a non-cryptographic hashing algorithm, thus it is not recommended to use it as a cryptographic algorithm (it is not a replacement for SHA). It has not been assessed if GxHash is preimage resistant and wether how likely it is to be reversed.

## Benchmarks
Displayed numbers are throughput in Mibibytes of data hashed per second. Higher is better.
To run the benchmarks: `cargo bench --bench throughput`.
Expand Down
33 changes: 32 additions & 1 deletion src/hasher.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,51 @@
use std::hash::{Hasher, BuildHasherDefault};
use std::collections::{HashMap, HashSet};

use rand::Rng;

use crate::gxhash::*;
use crate::gxhash::platform::*;

/// A `Hasher` for hashing an arbitrary stream of bytes.
/// # Features
/// - The fastest [`Hasher`] of its class<sup>1</sup>, for all input sizes
/// - Highly collision resitant
/// - DOS resistant thanks to seed randomization when using [`GxHasher::default()`]
///
/// *<sup>1</sup>There might me faster alternatives, such as `fxhash` for very small input sizes, but that usually have low quality properties.*
pub struct GxHasher(State);

impl Default for GxHasher {
/// Create a new hasher with a random seed for DOS resistance.
///
/// # Example
///
/// ```
/// use std::hash::Hasher;
/// use gxhash::GxHasher;
///
/// let mut hasher = GxHasher::default();
///
/// hasher.write(b"Hello");
/// hasher.write_u32(123);
/// hasher.write_u8(42);
///
/// println!("Hash is {:x}!", hasher.finish());
/// ```
#[inline]
fn default() -> GxHasher {
GxHasher(unsafe { create_empty() })
let mut rng = rand::thread_rng();
let seed: i64 = rng.gen::<i64>();
GxHasher(unsafe { create_seed(seed) })
}
}

impl GxHasher {
/// Creates a new hasher using the provided seed.
///
/// # Warning ⚠️
/// Hardcoding a seed may make your [`Hasher`] vulnerable to DOS attacks.
/// It is recommended to use [`GxHasher::default()`] to create a DOS resistant [`Hasher`].
///
/// # Example
///
Expand Down

0 comments on commit 575c04c

Please sign in to comment.