-
Notifications
You must be signed in to change notification settings - Fork 2.7k
A random beacon #96
A random beacon #96
Changes from 1 commit
a83059a
82a178d
1d28d9a
69c88c3
b12a708
e48e86d
8e3cc51
53e2fdf
27ecd6f
5eca74a
5d5f194
7cece3b
8c2396d
6b6c240
a79dab2
1fd6b3e
51b4a8c
8ada9f7
c4f5f42
d11f5ca
53eb893
d228593
a90fbe3
d352727
19f7258
ff2fa3c
c674963
c49d8a9
74a59b9
23ca1b2
1bb150b
2e9fa09
e4c2b27
90dd1a5
f197714
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,68 +25,51 @@ fn sub_mix<T>(seeds: &[T]) -> T where | |
| (seeds[0] & seeds[1]) | (seeds[1] & seeds[2]) | (seeds[0] & seeds[2]) | ||
| } | ||
|
|
||
| /// 3x3 mixing. | ||
| /// Mix a slice. | ||
| pub fn mix<T>(seeds: &[T]) -> Result<T, ()> where | ||
| T: BitAnd<Output = T> + BitOr<Output = T>, | ||
| T: Default + Copy | ||
| { | ||
| Ok(mix_iter(seeds.iter().cloned())) | ||
| /* | ||
| let max_depth = (0..12) | ||
| .scan(1, |a, _| { *a *= 3; Some(*a) }) | ||
| .position(|v| seeds.len() == v) | ||
| .ok_or(())?; | ||
| assert!(max_depth <= 11); | ||
|
|
||
| let mut accum = [[T::default(); 3]; 12]; | ||
| for i in 0..seeds.len() / 3 { | ||
| // first level: | ||
| accum[0][i % 3] = sub_mix(&seeds[i * 3..i * 3 + 3]); | ||
|
|
||
| let mut index_at_depth = i; | ||
| for depth in 0..12 { | ||
| if index_at_depth % 3 != 2 { | ||
| break; | ||
| } | ||
| index_at_depth /= 3; | ||
| Ok(seeds.iter().cloned().mixed()) | ||
| } | ||
|
|
||
| // end of the threesome at depth. | ||
| accum[depth + 1][index_at_depth] = sub_mix(&accum[depth]); | ||
| } | ||
| } | ||
| Ok(accum[max_depth][0]) | ||
| */ | ||
| /// The mixed trait for mixing a ssequence. | ||
|
||
| pub trait Mixed { | ||
| /// The items in the sequence and simultaneously the return of the mixing. | ||
| type Item; | ||
| /// The output of the mixing algorithm on the sequence. | ||
| fn mixed(self) -> Self::Item; | ||
| } | ||
|
|
||
| pub fn mix_iter<T, I>(seeds: I) -> T where | ||
| T: BitAnd<Output = T> + BitOr<Output = T>, | ||
| T: Default + Copy, | ||
| I: Iterator<Item = T> | ||
| impl<I, T> Mixed for I where | ||
| I: Iterator<Item = T>, | ||
| T: BitAnd<Output = T> + BitOr<Output = T> + Default + Copy | ||
| { | ||
| let mut accum = [[T::default(); 3]; 13]; | ||
| let mut max_depth = 0; | ||
| for (i, seed) in seeds.enumerate() { | ||
| accum[0][i % 3] = seed; | ||
| let mut index_at_depth = i; | ||
| for depth in 0..13 { | ||
| if index_at_depth % 3 != 2 { | ||
| break; | ||
| } | ||
| index_at_depth /= 3; | ||
|
|
||
| // end of the threesome at depth. | ||
| accum[depth + 1][index_at_depth % 3] = sub_mix(&accum[depth]); | ||
| max_depth = cmp::max(max_depth, depth + 1); | ||
| if max_depth == 12 { | ||
| break; | ||
| type Item = T; | ||
| fn mixed(self) -> Self::Item { | ||
| let mut accum = [[T::default(); 3]; 13]; | ||
|
||
| let mut max_depth = 0; | ||
| for (i, seed) in self.enumerate() { | ||
| accum[0][i % 3] = seed; | ||
| let mut index_at_depth = i; | ||
| for depth in 0..13 { | ||
| if index_at_depth % 3 != 2 { | ||
| break; | ||
| } | ||
| index_at_depth /= 3; | ||
|
|
||
| // end of the threesome at depth. | ||
| accum[depth + 1][index_at_depth % 3] = sub_mix(&accum[depth]); | ||
| max_depth = cmp::max(max_depth, depth + 1); | ||
| if max_depth == 12 { | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| accum[max_depth][0] | ||
|
||
| } | ||
| accum[max_depth][0] | ||
| } | ||
|
|
||
|
|
||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so for the first 81 blocks the random seed won't be random at all -- I wonder if it's better to use a
filter_mapso that the early randomness is much more manipulable but not dominated by zero hashes. In polkadot we should have an initial epoch shuffle which ends after randomness is well-seeded.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it'll still be a bit random. but sure, lower security. thankfully it doesn't really matter.