[noise] NoisePSK
Trevor Perrin
trevp at trevp.net
Thu Nov 12 11:24:50 PST 2015
On Thu, Nov 12, 2015 at 4:31 AM, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
> For example, for the DoS protection in a
> NoiseIK, before being able to discard the message upon attempted
> decryption/authentication of the first public ephemeral, this would
> result in:
>
> MixHash(handshake || prologue) - 1 hash
> MixHash(pubkey) - 1 hash
> HKDF(psk, none) - 6 hash
> MixKey(psk1) - 6 hash
> MixHash(psk2) - 1 hash
>
> 15 hashes in total. I don't have any numbers, but I imagine this is
> still computationally preferable to a single DH, but still, it's an
> awful lot.
Don't follow your counting - also, you should look at some real timing
data, hashing is fast.
To look at your case a little more, let's count the number of "blocks"
that are hashed, and consider padding (e.g. for SHA256 HASHLEN=32,
BLOCKLEN=64, but minimum 9 bytes padding):
# Processing handshake_name, prologue, psk
# Assuming handshake_name > HASHLEN, HASHLEN=32, BLOCKLEN=64
ck = h = HASH(handshake_name) # probably 1 block
h = HASH(h || prologue) # probably 1 block
ck, k = HKDF(ck, psk) # probably 12 blocks
h = HASH(h || k) # 2 blocks (using optimization I just posted)
# Process pre-message
h = HASH(h || server_static_pubkey) # 2 blocks
[EVERYTHING PREVIOUS CAN BE PRECALCULATED]
# Process client random
ck, k = HKDF(ck, random) # 12 blocks
So 30 blocks * 64 bytes/block * ~10 cycles/byte ~ 20K cycles. Your
server could precalculate everything but the client random HKDF, which
would eliminate 60% of the hashing. I think that's pretty efficient.
> For better DoS protection, you could add another aspect - a 32 byte
> MAC from Keyed-Blake2 over all the previous bytes of the handshake
> message, as the last field, that uses the psk as a key. This way
> invalid messages could be discarded after a single keyed-hash
> operation, instead of 15.
You could add that, but I don't think that's general enough to be
consider for Noise.
> Terrific. The way I'd probably go about using this is that for users
> who don't provide a PSK of their own, I'll automatically use
> "initiator.static_public || responder.static_public" as the PSK. This
> way, so long as the public keys stay secret or are forgotten about
> before the advent of a quantum computer / DH cryptographic advances,
> the messages automatically remain safe. What do you think of that
> idea? Is it as safe as I'm hoping?
You could do that, if you want to manage your public keys as secrets.
Trevor
More information about the Noise
mailing list