Skip to content

Commit

Permalink
Update readme
Browse files Browse the repository at this point in the history
Signed-off-by: Denis Varlakov <[email protected]>
  • Loading branch information
survived committed Sep 23, 2024
1 parent 075d16d commit 2609949
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 65 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions Makefile

This file was deleted.

26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
Cryptographically-secure pseudo-random generator based on cryptographic hash function
![License](https://img.shields.io/crates/l/rand_hash.svg)
[![Docs](https://docs.rs/rand_hash/badge.svg)](https://docs.rs/rand_hash)
[![Crates io](https://img.shields.io/crates/v/rand_hash.svg)](https://crates.io/crates/rand_hash)
[![Discord](https://img.shields.io/discord/905194001349627914?logo=discord&logoColor=ffffff&label=Discord)][in Discord]

# Cryptographically-secure pseudo-random generator based on cryptographic hash function

`HashRng` is CSPRNG that takes any hashable data as seed and produces a stream
of randomness that has the same entropy as the seed. It uses `udigest` crate to
of randomness that has the same entropy as the seed. It uses [`udigest`](https://docs.rs/udigest) crate to
unambiguously hash the seed.

### Motivation
## Motivation
Usually, CSPRNGs have a fixed-size seed. For instance, [`ChaCha20Rng`](https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha20Rng.html)
has seed of 32 bytes. That means that when you want to derive randomness from data which
has entropy exceeding 32 bytes, you'll have to truncate the seed to 32 bytes (e.g. by hashing it),
Expand All @@ -14,24 +19,24 @@ parameter and make it less secure than desired.
`HashRng`, on other hand, takes advantage of full entropy of the seed. It does so by
hashing a counter and then the seed for each block, i.e. the output randomness is:

```
```text
HashRng(seed) = H(0, seed) || H(1, seed) || ...
```

### Security and performance considerations
## Security and performance considerations
`HashRng` internally uses u64 counter, which means that the period of the sequence is
2<sup>64</sup> times `Digest::OutputSize` (size of hash output).

Although we did not perform benchmarks, intuitively, `HashRng` is expected to be noticeably
slower than other CSPRNG based on permutations (such as `ChaCha20Rng`)

### Example
## Example
```rust
use rand::RngCore;

#[derive(udigest::Digestable)]
pub struct Seed<'a> {
nonce: &'a u8,
nonce: &'a [u8],
param_a: &'a str,
param_b: &'a str,
// ...
Expand All @@ -45,6 +50,11 @@ let seed = Seed {
};
let mut rng = rand_hash::HashRng::<sha2::Sha256, _>::from_seed(&seed);

let mut randomness = 0u8; 256;
let mut randomness = [0u8; 256];
rng.fill_bytes(&mut randomness);
```

## Join us in Discord!
Feel free to reach out to us [in Discord]!

[in Discord]: https://discordapp.com/channels/905194001349627914/1285268686147424388
52 changes: 1 addition & 51 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,4 @@
//! Cryptographically-secure pseudo-random generator based on cryptographic hash function
//!
//! [`HashRng`] is CSPRNG that takes any hashable data as seed and produces a stream
//! of randomness that has the same entropy as the seed. It uses [`udigest`] crate to
//! unambiguously hash the seed.
//!
//! ## Motivation
//! Usually, CSPRNGs have a fixed-size seed. For instance, [`ChaCha20Rng`](https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha20Rng.html)
//! has seed of 32 bytes. That means that when you want to derive randomness from data which
//! has entropy exceeding 32 bytes, you'll have to truncate the seed to 32 bytes (e.g. by hashing it),
//! so you won't be able to take advantage of exceeding entropy. This may influence security
//! parameter and make it less secure than desired.
//!
//! [`HashRng`], on other hand, takes advantage of full entropy of the seed. It does so by
//! hashing a counter and then the seed for each block, i.e. the output randomness is:
//!
//! ```text
//! HashRng(seed) = H(0, seed) || H(1, seed) || ...
//! ```
//!
//! ## Security and performance considerations
//! `HashRng` internally uses u64 counter, which means that the period of the sequence is
//! 2<sup>64</sup> times `Digest::OutputSize` (size of hash output).
//!
//! Although we did not perform benchmarks, intuitively, `HashRng` is expected to be noticeably
//! slower than other CSPRNG based on permutations (such as `ChaCha20Rng`)
//!
//! ## Example
//! ```rust
//! use rand::RngCore;
//!
//! #[derive(udigest::Digestable)]
//! pub struct Seed<'a> {
//! nonce: &'a [u8],
//! param_a: &'a str,
//! param_b: &'a str,
//! // ...
//! }
//!
//! let seed = Seed {
//! nonce: b"very unpredictable string",
//! param_a: "some other data containing entropy",
//! param_b: "something else",
//! // ...
//! };
//! let mut rng = rand_hash::HashRng::<sha2::Sha256, _>::from_seed(&seed);
//!
//! let mut randomness = [0u8; 256];
//! rng.fill_bytes(&mut randomness);
//! ```
#![doc = include_str!("../README.md")]
#![no_std]
#![forbid(unused_crate_dependencies, missing_docs)]
#![cfg_attr(
Expand Down

0 comments on commit 2609949

Please sign in to comment.