# Which AES mode when using Poly1305-AES

I am reading DJ Bernstein's paper on the Poly1305-AES mac (https://cr.yp.to/mac/poly1305-20050329.pdf). I understand that AES is needed to provide the array s. In its paper on page 5 we can read:

reads AESk(n) from s[0], s[1], . . . , s[15]

I understand that n is a nonce and k is the secret key. What I am not sure about is which AES mode is used (ECB, CTR, GCM...) ? Is the nonce the message being passed to AES or is it a real nonce and thus we need to pass another message to AES ?

I am quite surprised that I cannot find any details about the AES mode in its paper. Is it because there is a default plain AES mode ?

FYI, I am using the mbed_tls crypto library, but I don't find any relevant example in their documentation.

• You don't specifically need to use AES. Here is the spec for use with ChaCha. I suspect the AES mode is irrelevant as DJB in the paper you linked states "There is nothing special about AES here. One can replace AES with an arbitrary keyed function from an arbitrary set of nonces to 16-byte strings. This paper focuses on AES for concreteness." Dec 2 '20 at 20:20
• @ModalNest: do I understand that I could select any AES mode, as long as it uses a nonce ? Also, is the nonce the message to be ciphered through AES or is the nonce an IV (or nonce-counter) used as a parameter for AES ? Dec 2 '20 at 20:41
• I would take on board what @kelalaka says. I suspect the choice is largely down to efficiency. Personally I would use what nacl uses (well just nacl itself). Dec 2 '20 at 20:47
• When I look at Bernstein's reference implementation (poly1305aes-20050218) I see that he uses this custom function: aes_big(unsigned char out[16], const unsigned char k[16], const unsigned char n[16]). Then, out is being passed to poly1305 as the vector s. But again, I don't see a message being encrypted here, only a key and a nonce... Do he simply encrypt the nonce ? There is no comment in the code, it is not clear if he uses some "default" hardcoded message with k and n to generate s. Dec 2 '20 at 21:20
• Note that the Poly1305-AES cipher is a bit of a strange bird as you'd generally find that AES is best used with hardware acceleration which is usually not directly implemented for Poly1305. So if HW acceleration is present then AES-GCM may make more sense, as Intel did define instructions to help with GMAC. Dec 2 '20 at 22:05

Yes, AES is just used as a 128 bit / 16 byte block cipher in this scheme. The paper specifies:

Poly1305-AES feeds each nonce $$n$$ through $$AES_k$$ to obtain the 16-byte string $$AES_k(n)$$.

There is no mention of AES without this key $$k$$ or nonce $$n$$. So, as far as AES - the block cipher - is concerned, $$k$$ is the key and the nonce $$n$$ is the data / message.

The reason that no mode-of-operation such as ECB / CBC is mentioned is that the specification uses the block cipher itself, without any mode. If you only have access to AES-ECB then you should use ECB without padding (or, if padding is always performed, just taking the first 16 bytes after feeding the nonce). You can use CBC with an IV using 16 zero valued bytes in a similar manner. Or you could use CTR with the nonce $$n$$ and an all zero plaintext of 16 bytes - probably makes most sense as CTR mode won't pad.

FYI the reason that you don't find an example in a TLS library is possibly that they use ChaCha20/Poly1305 where the ChaCha20 cipher is used instead of AES

From RFC 7905 section 1:

The variant of ChaCha used in this document has 20 rounds, a 96-bit nonce, and a 256-bit key; it is referred to as "ChaCha20". This is the conservative variant (with respect to security) of the ChaCha family and is described in [RFC7539].

 otk = poly1305_key_gen(key, nonce)


...

 poly1305_key_gen(key,nonce):
counter = 0
block = chacha20_block(key,counter,nonce)
return block[0..31]
end


So here chacha20_block is used instead of AES - they did say it was nothing special right? Note that the encryption then helpfully starts with counter 1 instead of zero, so it is a simple continuation of ChaCha20...

• Thanks Maarten, this is exactly the information I was looking for! Dec 2 '20 at 21:46
• Well, I can always add more useful information :) Dec 2 '20 at 21:56
• Thanks. mbed_tls is not only a tls library. With that library, you can do auth, cipher, hash... it is similar to what you would find in libsodium or in monocypher. So they provide poly1305 implementation, but they don't provide a turn-key solution, so you have to generate the secret 's' yourself, using AES or ChaCha20. Which library are you using for your snippets in your answer ? Dec 2 '20 at 22:00
• None, that's the pseudo code in the specifications, i.e. the RFC's. Dec 2 '20 at 22:01

In Java, you would do something like ...

byte[] key = ... 16 byte AES key 'k'
byte[] nonce = .... 16 byte nonce 'n'