Hacker News new | ask | show | jobs
by joeuser3932 3911 days ago
If you don't know what the PRNG (DRBG more appropriately) is for, you didn't watch the tech video. An asymmetric key generation algorithm can't work from a fixed length seed. You need to stretch the seed to an arbitrary length, because the asymmetric key generator requires a random stream.

Your 30-second look at the code needs more than 30 seconds. If a client connects to malicious server A, the private key it would use for that connection is different from the private key it would use on server B. So malicious server A cannot replay an authentication session on a different server.

3 comments

If you don't know what the PRNG (DRBG more appropriately) is for, you didn't watch the tech video.

Video is not suited for technical details.

It's not easy to quote / excerpt, to quickly refer back to previous (or later) parts, to take more time over parts that need it, etc; not the way text is.

My default reaction to "you'll understand if you just watch the video", is that someone is peddling bullshit and doesn't want me thinking too deeply.

It's also a really convenient way to deflect when, and this is just a hypothetical here, you were wrong and jumped to conclusions.
More typically you would use a KDF and simply request the number of bytes that you require directly from there.

Note, however, PBKDF2 has a bug where each additional block of output bytes is recomputed independently, which means the work factor (iteration count of the underlying hash algorithm) is applied separately for each block of output generated. So if you ask for, say, 1,000,000 iterations of PBKDF2-HMAC-SHA256 with 64 bytes of output, you are actually running two separate independent runs of 1,000,000 HMAC-SHA512 under the hood. This allows attackers to derive the output block-by-block instead of having to compute all or nothing, which can increase cracking speed in some cases (see 1Password writeup [1])

More simply, you can use a hash/KDF to produce a single block of seed with all your desired work factor imputed into that one value, and then stretch the seed simply as: for 1..n { hash(seed || n) } to get however many bytes you need to produce your privKey. In other words, 1,000,000 iterations of work for the seed, and a single iteration of work for each final block -- effectively all or nothing.

This will let you reduce the number of primitives to the single hash function you choose, which personally I think is much cleaner than introducing a whole PRNG into the mix.

[1] - http://blog.agilebits.com/wp-content/uploads/2013/07/playing...

> An asymmetric key generation algorithm can't work from a fixed length seed. You need to stretch the seed to an arbitrary length, because the asymmetric key generator requires a random stream.

That may or may not be true for traditional DH. For ECDH it's false. A Curve25519 ECDH private key, for example, is quite literally a handful of random bits. (Depending on how you look at it, it's a 256-bit number with some fixed bits or just 252-ish bits. I say "ish" because I don't remember the exact number of fixed bits off the top of my head.)

Edit: Fixed bogus EdDSA reference. Also, I just looked it up. A Curve25519 private key (http://cr.yp.to/ecdh.html) indeed requires exactly 252 random bits (or the 252-bit output of a secure KDF).