Skip to content

Commit

Permalink
Show what the shake128 version looks like
Browse files Browse the repository at this point in the history
  • Loading branch information
burdges committed Mar 19, 2019
1 parent eb1f162 commit 29a4a83
Showing 1 changed file with 22 additions and 31 deletions.
53 changes: 22 additions & 31 deletions vdf/src/create_discriminant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,9 @@ include!(concat!(env!("OUT_DIR"), "/constants.rs"));

use classgroup::BigNumExt;
use num_traits::Zero;
use sha2::{digest::FixedOutput, Digest, Sha256};
use sha3::{digest::{Input, ExtendableOutput, XofReader}, Shake128};
use std::u16;

fn random_bytes_from_seed(seed: &[u8], byte_count: usize) -> Vec<u8> {
assert!(byte_count <= 32 * ((1 << 16) - 1));
let mut blob = Vec::with_capacity(byte_count);
let mut extra: u16 = 0;
while blob.len() < byte_count {
let mut hasher = Sha256::new();
hasher.input(seed);
let extra_bits: [u8; 2] = [((extra & 0xFF00) >> 8) as _, (extra & 0xFF) as _];
hasher.input(&extra_bits);
blob.extend_from_slice(&hasher.fixed_result()[..]);
extra += 1;
}
blob.resize(byte_count, 0);
blob
}

/// Create a discriminant from a seed (a byte string) and a bit length (a
/// `u16`). The discriminant is guaranteed to be a negative prime number that
/// fits in `length` bits, except with negligible probability (less than
Expand All @@ -62,27 +46,31 @@ fn random_bytes_from_seed(seed: &[u8], byte_count: usize) -> Vec<u8> {
///
/// This function is guaranteed not to panic for any inputs whatsoever, unless
/// memory allocation fails and the allocator in use panics in that case.
pub fn create_discriminant<T: BigNumExt>(seed: &[u8], length: u16) -> T {
let (mut n, residue) = {
// The number of “extra” bits (that don’t evenly fit in a byte)
let extra: u8 = (length as u8) & 7;

// The number of random bytes needed (the number of bytes that hold `length`
// bits, plus 2).
let random_bytes_len = ((usize::from(length) + 7) >> 3) + 2;
let random_bytes = random_bytes_from_seed(seed, random_bytes_len);
let (n, last_2) = random_bytes.split_at(random_bytes_len - 2);
let numerator = (usize::from(last_2[0]) << 8) + usize::from(last_2[1]);
pub fn create_discriminant<T: BigNumExt>(seed: &[u8], bit_length: u16) -> T {
let mut h = Shake128::default().chain(seed).xof_result();

let mut n = {
// The number of extra bits that do not evenly fit in a byte)
let extra: u8 = (bit_length as u8) & 7;

let byte_length = (usize::from(bit_length) + 7) >> 3;
let mut n = vec![0u8; byte_length];
h.read(&mut n);

// If there are any extra bits, right shift `n` so that it fits
// in `length` bits, discarding the least significant bits.
let n = T::from(n) >> usize::from((8 - extra) & 7);
(n, RESIDUES[numerator % RESIDUES.len()])
T::from(&n[..]) >> usize::from((8 - extra) & 7)
};
n.setbit(usize::from(length - 1));
n.setbit(usize::from(bit_length - 1));
debug_assert!(n >= Zero::zero());
let rem = n.frem_u32(M);

let residue = {
let mut numerator = [0u8; 2];
h.read(&mut numerator);
RESIDUES[u16::from_le_bytes(numerator) as usize % RESIDUES.len()]
};

// HACK HACK `rust-gmp` doesn’t expose += and -= with i32 or i64
if residue > rem {
n = n + u64::from(residue - rem);
Expand Down Expand Up @@ -125,6 +113,8 @@ pub fn create_discriminant<T: BigNumExt>(seed: &[u8], length: u16) -> T {
}
}


/*
#[cfg(test)]
mod test {
use super::*;
Expand Down Expand Up @@ -197,3 +187,4 @@ mod test {
);
}
}
*/

0 comments on commit 29a4a83

Please sign in to comment.