2023-05-22 23:04:26 -07:00
|
|
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
2020-06-05 09:35:14 -07:00
|
|
|
//
|
2023-05-22 23:04:26 -07:00
|
|
|
// This source code is dual-licensed under either the MIT license found in the
|
|
|
|
|
// LICENSE-MIT file in the root directory of this source tree or the Apache
|
2021-12-03 14:38:11 -08:00
|
|
|
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
2023-05-22 23:04:26 -07:00
|
|
|
// of this source tree. You may select, at your option, one of the above-listed
|
|
|
|
|
// licenses.
|
2020-06-05 09:35:14 -07:00
|
|
|
|
2021-08-12 06:25:07 +02:00
|
|
|
use core::cmp::min;
|
2022-01-06 00:10:57 +01:00
|
|
|
use std::vec::Vec;
|
2020-06-05 09:35:14 -07:00
|
|
|
|
2022-01-06 06:19:02 +01:00
|
|
|
use rand::{CryptoRng, Error, RngCore};
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
/// A simple implementation of `RngCore` for testing purposes.
|
|
|
|
|
///
|
|
|
|
|
/// This generates a cyclic sequence (i.e. cycles over an initial buffer)
|
2022-01-04 00:50:40 +01:00
|
|
|
#[derive(Clone, Debug)]
|
2020-06-05 09:35:14 -07:00
|
|
|
pub struct CycleRng {
|
|
|
|
|
v: Vec<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl CycleRng {
|
2022-01-06 06:19:02 +01:00
|
|
|
/// Create a `CycleRng`, yielding a sequence starting with `initial` and
|
|
|
|
|
/// looping thereafter
|
2020-06-05 09:35:14 -07:00
|
|
|
pub fn new(initial: Vec<u8>) -> Self {
|
|
|
|
|
CycleRng { v: initial }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn rotate_left<T>(data: &mut [T], steps: usize) {
|
|
|
|
|
if data.is_empty() {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let steps = steps % data.len();
|
|
|
|
|
|
|
|
|
|
data[..steps].reverse();
|
|
|
|
|
data[steps..].reverse();
|
|
|
|
|
data.reverse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl RngCore for CycleRng {
|
|
|
|
|
fn next_u32(&mut self) -> u32 {
|
|
|
|
|
unimplemented!()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn next_u64(&mut self) -> u64 {
|
|
|
|
|
unimplemented!()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn fill_bytes(&mut self, dest: &mut [u8]) {
|
|
|
|
|
let len = min(self.v.len(), dest.len());
|
2022-12-10 23:21:56 +01:00
|
|
|
dest[..len].copy_from_slice(&self.v[..len]);
|
2020-06-05 09:35:14 -07:00
|
|
|
rotate_left(&mut self.v, len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
|
|
|
|
|
self.fill_bytes(dest);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This is meant for testing only
|
|
|
|
|
impl CryptoRng for CycleRng {}
|