Skip to content

Commit

Permalink
Switch the random generator from ChaCha20 to ChaCha8
Browse files Browse the repository at this point in the history
See rust-random/rand#932 - it seems that 8 iterations
is more than enough to provide good security, while providing a substantial
speedup over the 20 iteration version.
  • Loading branch information
irh committed Jan 9, 2022
1 parent 4d095f8 commit 01face4
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ The Koto project adheres to
```
- The `number2` and `number4` functions have been renamed to
`num2` and `num4`.
- The number of rounds used by the generator (ChaCha) has been reduced from
20 to 8.
- The random module is provided as a `ValueMap` rather than a `Value`,
meaning that its now added to the prelude via `add_map` like other modules.
- Map equality comparisons now don't rely on maps having keys in the same order.
Expand Down
10 changes: 5 additions & 5 deletions koto/tests/libs/random.koto
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ from test import assert, assert_eq, assert_ne, assert_near
@tests =
@pre_test: ||
# random.seed seeds the default generator
random.seed 0
random.seed 1

@test bool: ||
rng_bool = import random.bool
assert rng_bool()
assert not rng_bool()

@test number: ||
assert_near random.number(), 0.024, 0.001
assert_near random.number(), 0.982, 0.001
assert_near random.number(), 0.402, 0.001
assert_near random.number(), 0.080, 0.001

@test num2_num4: ||
assert_near random.num2(), (make_num2 0.024, 0.982), 0.001
assert_near random.num4(), (make_num4 0.006, 0.861, 0.823, 0.186), 0.001
assert_near random.num2(), (make_num2 0.402, 0.080), 0.001
assert_near random.num4(), (make_num4 0.211, 0.597, 0.387, 0.219), 0.001

@test pick_list: ||
x = ["foo", "bar", "baz"]
Expand Down
14 changes: 7 additions & 7 deletions libs/random/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use {
RuntimeResult, Value, ValueMap, ValueTuple,
},
rand::{Rng, SeedableRng},
rand_chacha::ChaCha20Rng,
rand_chacha::ChaCha8Rng,
std::{cell::RefCell, rc::Rc},
};

Expand All @@ -20,9 +20,9 @@ pub fn make_module() -> ValueMap {
result.add_fn("generator", |vm, args| {
match vm.get_args(args) {
// No seed, make RNG from entropy
[] => Ok(ChaChaRng::make_external_value(ChaCha20Rng::from_entropy())),
[] => Ok(ChaChaRng::make_external_value(ChaCha8Rng::from_entropy())),
// RNG from seed
[Value::Number(n)] => Ok(ChaChaRng::make_external_value(ChaCha20Rng::seed_from_u64(
[Value::Number(n)] => Ok(ChaChaRng::make_external_value(ChaCha8Rng::seed_from_u64(
n.to_bits(),
))),
unexpected => unexpected_type_error_with_slice(
Expand Down Expand Up @@ -70,14 +70,14 @@ thread_local! {
Rc::new(RefCell::new(meta))
};

static THREAD_RNG: RefCell<ChaChaRng> = RefCell::new(ChaChaRng(ChaCha20Rng::from_entropy()));
static THREAD_RNG: RefCell<ChaChaRng> = RefCell::new(ChaChaRng(ChaCha8Rng::from_entropy()));
}

#[derive(Debug)]
struct ChaChaRng(ChaCha20Rng);
struct ChaChaRng(ChaCha8Rng);

impl ChaChaRng {
fn make_external_value(rng: ChaCha20Rng) -> Value {
fn make_external_value(rng: ChaCha8Rng) -> Value {
let result =
ExternalValue::with_shared_meta_map(ChaChaRng(rng), RNG_META.with(|meta| meta.clone()));

Expand Down Expand Up @@ -151,7 +151,7 @@ impl ChaChaRng {
use Value::*;
match args {
[Number(n)] => {
self.0 = ChaCha20Rng::seed_from_u64(n.to_bits());
self.0 = ChaCha8Rng::seed_from_u64(n.to_bits());
Ok(Empty)
}
unexpected => {
Expand Down

0 comments on commit 01face4

Please sign in to comment.