[cryptography] caring harder requires solving once for the most demanding threat model, to the benefit of all lesser models

David Leon Gil coruus at gmail.com
Tue Oct 21 15:40:30 EDT 2014

On Wed, Oct 15, 2014 at 7:13 AM, ianG <iang at iang.org> wrote:
> :) em, close, I advocate direct and sole use of your platform's RNG.
> Rule #1:
> http://iang.org/ssl/hard_truths_hard_random_numbers.html
> 1. Use what your platform provides. Random numbers are hard, which is
> the first thing you have to remember, and always come back to. Random
> numbers are so hard, that you have to care a lot before you get
> involved. A hell of a lot. Which leads us to the following rules of
> thumb for RNG production.

Don't just use your platform RNG. There is a simple method which works
well, even if your platform RNG is backdoored.

Generate, independently of your platform's RNG, a secret
"personalization string" containing (say) 32 bytes of entropy. Then,
when you need a random number, do:

    personalization_secret = [roll dice or something]
    def randomkey():
      seed = urandom(32)
      return kdf(personalization_string, seed)

Even if your platform uses Dual-EC DRBG, an adversary still needs to
get the secret (and invert the kdf), to get any useful information.
This is better than broadcasting your platform RNG state out to the
internet. (Of course, this does absolutely nothing to help you if your
platform random always outputs 0 -- or very low-entropy randomness --
but nothing does.)

Reasonable choices for "kdf" here:
    kdf(k, s) = SHAKE256(k || s, 32)
    kdf(k, s) = Blake2b(mackey=k, s)[0:32]
An okay choice:
    kdf(k, s) = HMAC-SHA512(k=k, m=s)[0:32]

(The KDF should be indifferentiable from a random oracle; SHAKE256 and
Blake2b were designed to be.)

More information about the cryptography mailing list