Add swap_or_not_shuffle and tests.
The implementation is not matching the EF implementation at this point.
This commit is contained in:
parent
c41b743d2d
commit
18e85a3cf8
@ -11,6 +11,7 @@ members = [
|
||||
"eth2/utils/honey-badger-split",
|
||||
"eth2/utils/slot_clock",
|
||||
"eth2/utils/ssz",
|
||||
"eth2/utils/swap_or_not_shuffle",
|
||||
"eth2/utils/fisher_yates_shuffle",
|
||||
"beacon_node",
|
||||
"beacon_node/db",
|
||||
|
13
eth2/utils/swap_or_not_shuffle/Cargo.toml
Normal file
13
eth2/utils/swap_or_not_shuffle/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "swap_or_not_shuffle"
|
||||
version = "0.1.0"
|
||||
authors = ["Paul Hauner <paul@paulhauner.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bytes = "0.4"
|
||||
hashing = { path = "../hashing" }
|
||||
|
||||
[dev-dependencies]
|
||||
yaml-rust = "0.4.2"
|
||||
hex = "0.3"
|
115
eth2/utils/swap_or_not_shuffle/src/lib.rs
Normal file
115
eth2/utils/swap_or_not_shuffle/src/lib.rs
Normal file
@ -0,0 +1,115 @@
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
use hashing::hash;
|
||||
use std::cmp::max;
|
||||
use std::io::Cursor;
|
||||
|
||||
pub fn get_permutated_index(
|
||||
index: usize,
|
||||
list_size: usize,
|
||||
seed: &[u8],
|
||||
shuffle_round_count: usize,
|
||||
) -> usize {
|
||||
let mut index = index;
|
||||
for round in 0..shuffle_round_count {
|
||||
let pivot = bytes_to_int64(&hash_with_round(seed, round)[..]) as usize % list_size;
|
||||
let flip = (pivot - index) % list_size;
|
||||
let position = max(index, flip);
|
||||
let source = hash_with_round_and_position(seed, round, position);
|
||||
let byte = source[(position % 256) / 8];
|
||||
let bit = (byte >> (position % 8)) % 2;
|
||||
index = if bit == 1 { flip } else { index }
|
||||
}
|
||||
index
|
||||
}
|
||||
|
||||
fn hash_with_round_and_position(seed: &[u8], round: usize, position: usize) -> Vec<u8> {
|
||||
let mut seed = seed.to_vec();
|
||||
seed.append(&mut int_to_bytes1(round as u64));
|
||||
seed.append(&mut int_to_bytes4(position as u64 / 256));
|
||||
hash(&seed[..])
|
||||
}
|
||||
|
||||
fn hash_with_round(seed: &[u8], round: usize) -> Vec<u8> {
|
||||
let mut seed = seed.to_vec();
|
||||
seed.append(&mut int_to_bytes1(round as u64));
|
||||
hash(&seed[..])
|
||||
}
|
||||
|
||||
fn int_to_bytes1(int: u64) -> Vec<u8> {
|
||||
let mut bytes = BytesMut::with_capacity(8);
|
||||
bytes.put_u64_le(int);
|
||||
vec![bytes[0]]
|
||||
}
|
||||
|
||||
fn int_to_bytes4(int: u64) -> Vec<u8> {
|
||||
let mut bytes = BytesMut::with_capacity(8);
|
||||
bytes.put_u64_le(int);
|
||||
bytes[0..4].to_vec()
|
||||
}
|
||||
|
||||
fn bytes_to_int64(bytes: &[u8]) -> u64 {
|
||||
let mut cursor = Cursor::new(bytes);
|
||||
cursor.get_u64_le()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use hex;
|
||||
use std::{fs::File, io::prelude::*, path::PathBuf};
|
||||
use yaml_rust::yaml;
|
||||
|
||||
#[test]
|
||||
fn test_shuffling() {
|
||||
let mut file = {
|
||||
let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
file_path_buf.push("src/specs/permutated_index_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 (i, test_case) in test_cases.iter().enumerate() {
|
||||
let index = test_case["index"].as_i64().unwrap() as usize;
|
||||
let list_size = test_case["list_size"].as_i64().unwrap() as usize;
|
||||
let permutated_index = test_case["permutated_index"].as_i64().unwrap() as usize;
|
||||
let shuffle_round_count = test_case["shuffle_round_count"].as_i64().unwrap() as usize;
|
||||
let seed_string = test_case["seed"].clone().into_string().unwrap();
|
||||
let seed = hex::decode(seed_string.replace("0x", "")).unwrap();
|
||||
|
||||
println!("case: {}", i);
|
||||
|
||||
assert_eq!(
|
||||
permutated_index,
|
||||
get_permutated_index(index, list_size, &seed[..], shuffle_round_count),
|
||||
"Failure on case #{} index: {}, list_size: {}, round_count: {}, seed: {}",
|
||||
i,
|
||||
index,
|
||||
list_size,
|
||||
shuffle_round_count,
|
||||
seed_string,
|
||||
);
|
||||
|
||||
/*
|
||||
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);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
fork: tchaikovsky
|
||||
summary: Test vectors for list shuffling using `get_permutated_index`
|
||||
test_suite: permutated_index
|
||||
title: Permutated Index Tests
|
||||
version: 1.0
|
||||
test_cases:
|
||||
- {index: 0, list_size: 1024, permutated_index: 216, seed: '0xc0c7f226fbd574a8c63dc26864c27833ea931e7c70b34409ba765f3d2031633d',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 1024, list_size: 1024, permutated_index: 433, seed: '0xb20420b2b7b1c64600cbe962544052d0bbe13da403950d198d4f4ea28762953f',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 806, list_size: 704, permutated_index: 584, seed: '0x3a4cfce20efb7d7eca50291470043d6e8a2c62956e687571607d3f0e5bd0af3f',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 1681, list_size: 2154, permutated_index: 1628, seed: '0xbb99b3ecc0ea15a403456ce708c05ceeeddc0a4205caf072ba06ff9bde03f37e',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3253, list_size: 621, permutated_index: 31, seed: '0x1a51109676d549c1bea3b81edd82df68cc03a97ff58a8970c63ca86dd3b8b8a6',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 749, list_size: 3081, permutated_index: 1221, seed: '0x6cddea1279bf4a2725c781ce6aba348d383556e23fcb9e73c23ad33cfb50f4c0',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 2415, list_size: 2184, permutated_index: 394, seed: '0xa84b128c2885960e5f1b39822ee5dab30ad1580cdabb175a4b1512cac5566866',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 339, list_size: 3728, permutated_index: 427, seed: '0xe22c8444f460c9dcfc34a3c13f211e63c56e9e1187f31a56a4230d8d5bf5e584',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 4073, list_size: 2365, permutated_index: 2089, seed: '0x946af91cce976e1346e3970815107154b58b1eff411bfca3342ea0d8282a8630',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3438, list_size: 720, permutated_index: 559, seed: '0x5f3c5270d20810c104b75e25bf89c0066deebc3461937fc0e72ae04ee74f2456',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 1394, list_size: 388, permutated_index: 311, seed: '0xdf6fdc34adb35f3fc2880d220e520120a032bbaa0f4bd7a5fcf1c2269de21075',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 1604, list_size: 1816, permutated_index: 863, seed: '0xc9b0c76e11f4c3c3c38b447aca5352d93132ad5678da420ca2e69d92588e0fba',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 671, list_size: 798, permutated_index: 318, seed: '0x45c31aeb3eb29ccdf3327d0f3dd4592cdfb2fad3703229c6c2e720dc792f9f77',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3161, list_size: 4020, permutated_index: 1590, seed: '0xb2a397fd8ea36dbfcec0d733d0af7ec3a03d789a66231f3bc7cafa5e966e5657',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3414, list_size: 3557, permutated_index: 2643, seed: '0x524e6dee54d1b8b5882ad8e55c18a30462ac02c4bb86c27d26cbe52951395b1a',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 2693, list_size: 3414, permutated_index: 2230, seed: '0x3b776c7fc8bdad6030de943c4e3f938202ac553f44381dc67a74aac23523cb45',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 1319, list_size: 3413, permutated_index: 2830, seed: '0xd2f7b2d24ebc6bf2d63ef189efccabc4a16bb17cd80e4be4083e61b31931bad6',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 637, list_size: 1421, permutated_index: 370, seed: '0xe8bc30a4ce7b26b6897c2221a3358f25fdc1d82baa8089c1f242aa48c6611180',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3101, list_size: 525, permutated_index: 157, seed: '0xe930adeecaf3084b2b85f9b1dfebe34f6300047fda0ab6a746b6b0206febb825',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3596, list_size: 3688, permutated_index: 3621, seed: '0xf88bf52143b20d6c78caf7caf8e7b3453287b210d000b5f57e9834388d4bc2b8',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 2866, list_size: 307, permutated_index: 191, seed: '0x83fa10a34b029546c2ebabb8075f0670a78b38e0419aaead5d1cc8f40f58044b',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3307, list_size: 3458, permutated_index: 3099, seed: '0x193c08b580dd95a1355574dbf78665190a6133191e91ab35b1106e8984dfc0df',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 399, list_size: 3, permutated_index: 1, seed: '0x4f880b431c2a14f66354bf0192292ffae0bf39b39f12e0540b97591af0a2980d',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 1912, list_size: 3028, permutated_index: 1139, seed: '0x33201395d301ee43054417c6056404c586c907dfc5fceb66ebef541d143b00a3',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3902, list_size: 3079, permutated_index: 790, seed: '0xfbf4c5f45eabf289fdcfe0a3aba33a185fb1a4ae2f2b6f78daf61f5d356971e0',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 38, list_size: 115, permutated_index: 109, seed: '0x7aca86322db56927d727101e31c93f616f746317d29aa10d88f371592963de92',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3295, list_size: 960, permutated_index: 14, seed: '0xfe274230a112bc68614882645339fda2f134501a042079d620ec65cf8d3fa675',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 1535, list_size: 3974, permutated_index: 2568, seed: '0xa848af32d85c6d37c26e61a57e96780fcebc350ad1845e83fe5e4679ac820440',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 2623, list_size: 431, permutated_index: 236, seed: '0x49c2391e025ec272c812510cb07c055f6201e84479499326330628888e31a0de',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3164, list_size: 3981, permutated_index: 233, seed: '0x09f413b7a36ec680ee8b19bbb9a39c4e207326155864bc8be5d6dd92f30d8556',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 1826, list_size: 2643, permutated_index: 1395, seed: '0x797db811486e7a213e0145d6c946e5121aa6a8f761d1647d093fb976f2497361',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 290, list_size: 3570, permutated_index: 361, seed: '0xa6dc019009eda2e48bbeb4b7c56d4aa5da7d5f8721b3a79b35beacbe48c662d6',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 3192, list_size: 67, permutated_index: 61, seed: '0x040024c55ab879e5f61521013c5f45eb3b705c02c53c9c6ddf259716ff02e49a',
|
||||
shuffle_round_count: 90}
|
||||
- {index: 2984, list_size: 822, permutated_index: 57, seed: '0xe4ad255d7e90dbefdbc991adf603e5a4a5a4c57c5705ec697a74e6c7161191b1',
|
||||
shuffle_round_count: 90}
|
Loading…
Reference in New Issue
Block a user