Skip to content

Commit

Permalink
Use Shake128 instead of SHA2
Browse files Browse the repository at this point in the history
Shake128 provides an XoF which you need here.  Blake2x works too.

SHA3 is slow, due to NIST competition rules being silly,
but Shake128 is fast.
  • Loading branch information
burdges committed Mar 19, 2019
1 parent 249afbe commit 0e779f3
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 29 deletions.
1 change: 1 addition & 0 deletions vdf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ description = "An implementation of Verifiable Delay Functions (VDFs) in Rust"
classgroup = { path = "../classgroup", version = "^0.1.0" }
num-traits = "0.2"
sha2 = "0.8"
sha3 = "0.8"
bit-vec = "0.5"

[dev-dependencies]
Expand Down
44 changes: 15 additions & 29 deletions vdf/src/proof_wesolowski.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use super::proof_of_time::{iterate_squarings, serialize};
use classgroup::{gmp_classgroup::GmpClassGroup, BigNum, BigNumExt, ClassGroup};
use sha2::{digest::FixedOutput, Digest, Sha256};
use sha3::{digest::{Input, ExtendableOutput, XofReader}, Shake128};
use std::{cmp::Eq, collections::HashMap, hash::Hash, mem, u64, usize};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -66,6 +66,7 @@ impl super::VDF for WesolowskiVDF {
.map_err(|()| super::InvalidProof)
}
}

/// To quote the original Python code:
///
/// > Create `L` and `k` parameters from papers, based on how many iterations
Expand All @@ -88,24 +89,6 @@ pub fn approximate_parameters(t: f64) -> (usize, u8, u64) {
(l as _, k as _, w as _)
}

fn u64_to_bytes(q: u64) -> [u8; 8] {
if false {
// This use of `std::mem::transumte` is correct, but still not justified.
unsafe { std::mem::transmute(q.to_be()) }
} else {
[
(q >> 56) as u8,
(q >> 48) as u8,
(q >> 40) as u8,
(q >> 32) as u8,
(q >> 24) as u8,
(q >> 16) as u8,
(q >> 8) as u8,
q as u8,
]
}
}

/// As on page 10 of Wesolowski's paper, we uniformly sample a prime
/// from amongt the first 2^129 primes. According to the prime number
/// theorem, the prime counting function `π(x)` can be approximated
Expand All @@ -116,7 +99,7 @@ fn u64_to_bytes(q: u64) -> [u8; 8] {
/// `Li(x) - π(x) = O(\sqrt(x) \log x)` where `Li(x)` is the
/// [offset logarithmic integral](https://en.wikipedia.org/wiki/Logarithmic_integral_function),
/// so `Li(2^y) - Li(2) = \int_2^{2^y} dt/ln t = 2^y / y` and
/// `y = 134` gives at least 128 bits of security.
/// again `y = 134` gives at least 128 bits of security.
///
/// We may however have use for extra security margin against
/// an adversary with some influence over the random oracle.
Expand All @@ -126,19 +109,22 @@ fn u64_to_bytes(q: u64) -> [u8; 8] {
///
/// > Creates a random prime based on input s.
fn hash_prime<T: BigNum>(seed: &[&[u8]]) -> T {
let mut j = 0u64;
let mut h = Shake128::default();
h.input(b"prime");
for i in seed {
h.input(i);
}
let mut h = h.xof_result();
let mut o = [0u8; 16];
loop {
let mut hasher = Sha256::new();
hasher.input(b"prime");
hasher.input(u64_to_bytes(j));
for i in seed {
hasher.input(i);
}
let n = T::from(&hasher.fixed_result()[..16]);
let mut b = [0u8; 16]; // Ideally 17
h.read(&mut b);
assert_ne!(o, b);
let n = T::from(&b[..]);
if n.probab_prime(2) {
break n;
}
j += 1;
o = b;
}
}

Expand Down

0 comments on commit 0e779f3

Please sign in to comment.