[noise] Noise replacements for crypto_box and crypto_secretbox
Trevor Perrin
trevp at trevp.net
Sun Oct 2 01:24:23 PDT 2016
On Sat, Oct 1, 2016 at 9:35 PM, Brian Smith <brian at briansmith.org> wrote:
>
> A lot of people think the NaCl crypto_box and crypto_secretbox are great and
> want to use them. Totally reasonable. However, those things use Salsa20,
> which isn't supported by crypto libraries as ubiquitously as ChaCha20. Thus,
> I suggested we (the crypto community) should make things that are just like
> the NaCl stuff, except swapping ChaCha20 for Salsa20, and encourage people
> to use it.
>
> Trevor brought up the good point that Noise tries to do something like this,
> and it might be good to define that things as an instance of a Noise
> protocol. However, it isn't obvious that Noise covers all the same use cases
> as crypto_box and crypto_secretbox. Also, Noise has a lot of options, and it
> isn't clear exactly which combinations of Noise options are most directly
> replacements for crypto_box and crypto_secretbox.
Good topic - Noise was inspired by NaCl, so I'd like to see it work
for those cases:
crypto_secretbox is just "authenticated encryption" (AE):
https://nacl.cr.yp.to/secretbox.html
So you could implement it with any AEAD scheme that Noise supports
(e.g. ChaCha20/Poly1305, or AES-GCM) just by setting the "associated
data" (the "AD" in AEAD) to zero-length.
crypto_secretbox_xsalsa20poly1305 is interesting because it supports a
24 byte nonce, which is large enough to be randomly generated without
fear of collisions. To support that, it uses a hash function derived
from Salsa20 to hash the key and the nonce into a new key.
Noise tries to make minimal assumptions on its underlying crypto
functions. So a large-nonce AE in the style of Noise could just use
HKDF, e.g. with Noise's "HKDF" function:
crypto_secretbox(key, nonce, plaintext)
k = HKDF(key, nonce)
ENCRYPT(k, n=0, ad=zerolen, plaintext)
crypto_secretbox_open(key, nonce, ciphertext)
k = HKDF(key, nonce)
DECRYPT(k, n=0, ad=zerolen, ciphertext)
You could adapt the Noise naming convention, e.g.
NoiseSecretBox_ChaChaPoly_BLAKE2s
NoiseSecretBox_AESGCM_SHA512
etc.
I don't know enough about the use cases, though:
* Is re-using the same key with random nonces common enough to make
this worthwhile?
* If the use cases are low-end devices, then you might prefer a more
integrated design like XSalsa20. But then you have to customize it
for every cipher.
---
If you're using multiple crypto_boxes to build a protocol (like
CurveCP) then you'd want to understand Noise patterns.
But if your protocol is a single box, it should be easy to convert -
you'd just use Noise_N, Noise_K, or Noise_X, depending on the sender's
static public key:
(N)one
(K)nown to recipient
(X)mitted to recipient
If you were using a crypto_box for case N, with an ephemeral key, this
is similar, though perhaps with small improvements (e.g. the Noise
ciphertext is broken into <= 64k chunks, for streaming decryption).
If you were using a crypto_box for cases K or X with a static sender
key, Noise adds an ephemeral key, giving better forward-secrecy and
authentication in case the sender's key is compromised, and
identity-hiding (in case X).
If you wanted to do static-static DH with caching of the shared
secrets for efficiency (like DNSCurve) you're out of luck. Noise
insists you use ephemeral public keys for a handshake, since that's
usually the safest choice.
We could think about being more friendly to reuse of static-static DH,
but that's a less-conservative protocol pattern, so I'm not eager to
encourage it.
Alternatively, we've thought about generalizing Noise Pipes to support
PSK-based resumption, which can give similar performance, so that
might be a better option for cases that need extreme speed.
Trevor
More information about the Noise
mailing list