Subject: [quicwg/base-drafts] ChaCha inputs (#2171)

From: ekr <[email-masked]>
Date: Thu, 13 Dec 2018 16:15:45 -0800

Here's what 5.4.4 says

```The first 4 bytes of the sampled ciphertext are interpreted as a 32-bit number
in little-endian order and are used as the block count.  The remaining 12 bytes
are interpreted as three concatenated 32-bit numbers in little-endian order and
used as the nonce.```

However, RFC 8439 says:

```
   o  A 96-bit nonce, treated as a concatenation of three 32-bit little-
      endian integers.

   o  A 32-bit block count parameter, treated as a 32-bit little-endian
      integer.
```
 
This is a little confusing, but I think the correct way to read this is that the ChaCha function takes the nonce as a 96-bit opaque quantity, and the fact that it's little-endian is an internal detail irrelevant to our purposes, so we should just replace the second sentence with "The remaining 12 bytes are used as the 96-bit ChaCha nonce". This is reinforced by the fact that the test vectors have the nonce as a byte block.

The situation with the counter is more complicated because we are told it is both a counter and 32-bits (which might make you think it's an integer parameter), but it is also treated as a little-endian integer, which makes one think it's a bitstring. And then the test vectors treat it as a value, rather than as a bitstring. If you look at code it typically thinks of this as an integer:

See, for instance:
https://searchfox.org/nss/source/lib/freebl/verified/Hacl_Chacha20.c#147

So, I think the right answer here is to think of ChaCha as having the following API:

```
ChaCha20(k [32]byte{}, nonce [12]byte{}, nonce uint32, []byte{})
```

Note that because the value on the wire is in big-endian format, this would invert the nonce, but I think it's the right answer anyway. Otherwise, you're having to pass in the counter in the wrong format on big-endian platforms.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2171

---

From: MikkelFJ <[email-masked]>
Date: Thu, 13 Dec 2018 16:25:13 -0800

As a completely general note, I don't think it is right to change endianness of crypto wire formats. AES-GCM has a completely backwards neither little nor big endian encoding (byte and bit swapped so no platform wins) this remains so on the wire. Especially for HW processing this is significant. But little endian is also more performant on nearly all relevant platforms today so there is no need to go over board forcing big endian if it can be avoided without insulting RFC's.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2171#issuecomment-447170020

---

From: Martin Thomson <[email-masked]>
Date: Thu, 13 Dec 2018 17:01:06 -0800

Yeah, this should simplify that text some.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2171#issuecomment-447176468

---

From: David Schinazi <[email-masked]>
Date: Thu, 13 Dec 2018 17:35:49 -0800

I like the proposed change, the text had somewhat confused me when implementing this in a previous life.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2171#issuecomment-447182753