Delete unused fished_yates_shuffle crate

This commit is contained in:
Michael Sproul 2019-06-12 16:55:01 +10:00
parent 8a9f7ff32b
commit 9e51a04139
No known key found for this signature in database
GPG Key ID: 77B1309D2E54E914
6 changed files with 0 additions and 374 deletions

View File

@ -21,7 +21,6 @@ members = [
"eth2/utils/swap_or_not_shuffle",
"eth2/utils/tree_hash",
"eth2/utils/tree_hash_derive",
"eth2/utils/fisher_yates_shuffle",
"eth2/utils/test_random_derive",
"beacon_node",
"beacon_node/store",

View File

@ -1,16 +0,0 @@
[package]
name = "fisher_yates_shuffle"
version = "0.1.0"
authors = ["Paul Hauner <paul@paulhauner.com>"]
edition = "2018"
[[bench]]
name = "benches"
harness = false
[dev-dependencies]
criterion = "0.2"
yaml-rust = "0.4.2"
[dependencies]
hashing = { path = "../hashing" }

View File

@ -1,55 +0,0 @@
use criterion::Criterion;
use criterion::{black_box, criterion_group, criterion_main, Benchmark};
use fisher_yates_shuffle::shuffle;
fn get_list(n: usize) -> Vec<usize> {
let mut list = Vec::with_capacity(n);
for i in 0..n {
list.push(i)
}
assert_eq!(list.len(), n);
list
}
fn shuffles(c: &mut Criterion) {
c.bench(
"whole list shuffle",
Benchmark::new("8 elements", move |b| {
let seed = vec![42; 32];
let list = get_list(8);
b.iter_with_setup(|| list.clone(), |list| black_box(shuffle(&seed, list)))
}),
);
c.bench(
"whole list shuffle",
Benchmark::new("16 elements", move |b| {
let seed = vec![42; 32];
let list = get_list(16);
b.iter_with_setup(|| list.clone(), |list| black_box(shuffle(&seed, list)))
}),
);
c.bench(
"whole list shuffle",
Benchmark::new("512 elements", move |b| {
let seed = vec![42; 32];
let list = get_list(512);
b.iter_with_setup(|| list.clone(), |list| black_box(shuffle(&seed, list)))
})
.sample_size(10),
);
c.bench(
"whole list shuffle",
Benchmark::new("16384 elements", move |b| {
let seed = vec![42; 32];
let list = get_list(16_384);
b.iter_with_setup(|| list.clone(), |list| black_box(shuffle(&seed, list)))
})
.sample_size(10),
);
}
criterion_group!(benches, shuffles);
criterion_main!(benches);

View File

@ -1,81 +0,0 @@
/// A library for performing deterministic, pseudo-random shuffling on a vector.
///
/// This library is designed to confirm to the Ethereum 2.0 specification.
extern crate hashing;
mod rng;
use self::rng::ShuffleRng;
#[derive(Debug)]
pub enum ShuffleErr {
ExceedsListLength,
}
/// Performs a deterministic, in-place shuffle of a vector.
///
/// The final order of the shuffle is determined by successive hashes
/// of the supplied `seed`.
///
/// This is a Fisher-Yates-Durtstenfeld shuffle.
pub fn shuffle<T>(seed: &[u8], mut list: Vec<T>) -> Result<Vec<T>, ShuffleErr> {
let mut rng = ShuffleRng::new(seed);
if list.len() > rng.rand_max as usize {
return Err(ShuffleErr::ExceedsListLength);
}
if list.is_empty() {
return Ok(list);
}
for i in 0..(list.len() - 1) {
let n = list.len() - i;
let j = rng.rand_range(n as u32) as usize + i;
list.swap(i, j);
}
Ok(list)
}
#[cfg(test)]
mod tests {
extern crate yaml_rust;
use self::yaml_rust::yaml;
use std::{fs::File, io::prelude::*, path::PathBuf};
use super::{hashing::hash, *};
#[test]
fn test_shuffling() {
let mut file = {
let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
file_path_buf.push("src/specs/shuffle_test_vectors.yaml");
File::open(file_path_buf).unwrap()
};
let mut yaml_str = String::new();
file.read_to_string(&mut yaml_str).unwrap();
let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap();
let doc = &docs[0];
let test_cases = doc["test_cases"].as_vec().unwrap();
for test_case in test_cases {
let input = test_case["input"].clone().into_vec().unwrap();
let output = test_case["output"].clone().into_vec().unwrap();
let seed_bytes = test_case["seed"].as_str().unwrap().as_bytes();
let seed = if seed_bytes.len() > 0 {
hash(seed_bytes)
} else {
vec![]
};
assert_eq!(shuffle(&seed, input).unwrap(), output);
}
}
}

View File

@ -1,90 +0,0 @@
use super::hashing::hash;
const SEED_SIZE_BYTES: usize = 32;
const RAND_BYTES: usize = 3; // 24 / 8
const RAND_MAX: u32 = 16_777_215; // 2 ** (rand_bytes * 8) - 1
/// A pseudo-random number generator which given a seed
/// uses successive blake2s hashing to generate "entropy".
pub struct ShuffleRng {
seed: Vec<u8>,
idx: usize,
pub rand_max: u32,
}
impl ShuffleRng {
/// Create a new instance given some "seed" bytes.
pub fn new(initial_seed: &[u8]) -> Self {
Self {
seed: hash(initial_seed),
idx: 0,
rand_max: RAND_MAX,
}
}
/// "Regenerates" the seed by hashing it.
fn rehash_seed(&mut self) {
self.seed = hash(&self.seed);
self.idx = 0;
}
/// Extracts 3 bytes from the `seed`. Rehashes seed if required.
fn rand(&mut self) -> u32 {
self.idx += RAND_BYTES;
if self.idx >= SEED_SIZE_BYTES {
self.rehash_seed();
self.rand()
} else {
int_from_byte_slice(&self.seed, self.idx - RAND_BYTES)
}
}
/// Generate a random u32 below the specified maximum `n`.
///
/// Provides a filtered result from a higher-level rng, by discarding
/// results which may bias the output. Because of this, execution time is
/// not linear and may potentially be infinite.
pub fn rand_range(&mut self, n: u32) -> u32 {
assert!(n < RAND_MAX, "RAND_MAX exceed");
let mut x = self.rand();
while x >= self.rand_max - (self.rand_max % n) {
x = self.rand();
}
x % n
}
}
/// Reads the next three bytes of `source`, starting from `offset` and
/// interprets those bytes as a 24 bit big-endian integer.
/// Returns that integer.
fn int_from_byte_slice(source: &[u8], offset: usize) -> u32 {
(u32::from(source[offset + 2]))
| (u32::from(source[offset + 1]) << 8)
| (u32::from(source[offset]) << 16)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_shuffling_int_from_slice() {
let mut x = int_from_byte_slice(&[0, 0, 1], 0);
assert_eq!((x as u32), 1);
x = int_from_byte_slice(&[0, 1, 1], 0);
assert_eq!(x, 257);
x = int_from_byte_slice(&[1, 1, 1], 0);
assert_eq!(x, 65793);
x = int_from_byte_slice(&[255, 1, 1], 0);
assert_eq!(x, 16711937);
x = int_from_byte_slice(&[255, 255, 255], 0);
assert_eq!(x, 16777215);
x = int_from_byte_slice(&[0x8f, 0xbb, 0xc7], 0);
assert_eq!(x, 9419719);
}
}

View File

@ -1,131 +0,0 @@
title: Shuffling Algorithm Tests
summary: Test vectors for shuffling a list based upon a seed.
test_suite: Shuffling
test_cases:
- input: []
output: []
seed: ''
- input: [0]
output: [0]
seed: ''
- input: [255]
output: [255]
seed: ''
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 1, 1, 5, 6, 6, 6, 2, 4, 4]
seed: ''
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [4, 9, 6, 8, 13, 3, 2, 11, 5, 1, 12, 7, 10]
seed: ''
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 1, 1, 5, 6, 6, 6, 2, 4, 65]
seed: ''
- input: []
output: []
seed: 4kn4driuctg8
- input: [0]
output: [0]
seed: 4kn4driuctg8
- input: [255]
output: [255]
seed: 4kn4driuctg8
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 4, 4, 2, 1, 1, 6, 5, 6, 6]
seed: 4kn4driuctg8
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [7, 6, 3, 12, 11, 1, 8, 13, 10, 5, 9, 4, 2]
seed: 4kn4driuctg8
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 4, 65, 2, 1, 1, 6, 5, 6, 6]
seed: 4kn4driuctg8
- input: []
output: []
seed: ytre1p
- input: [0]
output: [0]
seed: ytre1p
- input: [255]
output: [255]
seed: ytre1p
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 1, 1, 5, 6, 2, 6, 2, 4, 4]
seed: ytre1p
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [6, 2, 3, 4, 8, 5, 12, 9, 7, 11, 10, 1, 13]
seed: ytre1p
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 1, 1, 5, 6, 2, 6, 2, 4, 65]
seed: ytre1p
- input: []
output: []
seed: mytobcffnkvj
- input: [0]
output: [0]
seed: mytobcffnkvj
- input: [255]
output: [255]
seed: mytobcffnkvj
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 4, 1, 1, 6, 4, 6, 5, 6, 2]
seed: mytobcffnkvj
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [11, 5, 9, 7, 2, 4, 12, 10, 8, 1, 6, 3, 13]
seed: mytobcffnkvj
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 65, 1, 1, 6, 4, 6, 5, 6, 2]
seed: mytobcffnkvj
- input: []
output: []
seed: myzu3g7evxp5nkvj
- input: [0]
output: [0]
seed: myzu3g7evxp5nkvj
- input: [255]
output: [255]
seed: myzu3g7evxp5nkvj
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 1, 4, 2, 6, 5, 6, 4, 1]
seed: myzu3g7evxp5nkvj
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [2, 1, 11, 3, 9, 7, 8, 13, 4, 10, 5, 6, 12]
seed: myzu3g7evxp5nkvj
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 1, 4, 2, 6, 5, 6, 65, 1]
seed: myzu3g7evxp5nkvj
- input: []
output: []
seed: xdpli1jsx5xb
- input: [0]
output: [0]
seed: xdpli1jsx5xb
- input: [255]
output: [255]
seed: xdpli1jsx5xb
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 1, 2, 4, 6, 6, 5, 6, 1, 4]
seed: xdpli1jsx5xb
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [5, 8, 12, 9, 11, 4, 7, 13, 1, 3, 2, 10, 6]
seed: xdpli1jsx5xb
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [2, 1, 2, 65, 6, 6, 5, 6, 1, 4]
seed: xdpli1jsx5xb
- input: []
output: []
seed: oab3mbb3xe8qsx5xb
- input: [0]
output: [0]
seed: oab3mbb3xe8qsx5xb
- input: [255]
output: [255]
seed: oab3mbb3xe8qsx5xb
- input: [4, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 1, 1, 6, 2, 4, 4, 6, 5]
seed: oab3mbb3xe8qsx5xb
- input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
output: [1, 8, 5, 13, 2, 10, 7, 11, 12, 6, 3, 4, 9]
seed: oab3mbb3xe8qsx5xb
- input: [65, 6, 2, 6, 1, 4, 6, 2, 1, 5]
output: [6, 2, 1, 1, 6, 2, 4, 65, 6, 5]
seed: oab3mbb3xe8qsx5xb