RFC 7539 (Section 2.8) specifies a ChaCha20/Poly1305 based AEAD cipher scheme; pseudocode:

     if (len(x) % 16)==0
        then return NULL
        else return copies(0, 16-(len(x)%16))

chacha20_aead_encrypt(aad, key, iv, constant, plaintext):
     nonce = constant | iv
     otk = poly1305_key_gen(key, nonce)
     ciphertext = chacha20_encrypt(key, 1, nonce, plaintext)
     mac_data = aad | pad16(aad)                // <- Here
     mac_data |= ciphertext | pad16(ciphertext) // <- Here
     mac_data |= num_to_4_le_bytes(aad.length)
     mac_data |= num_to_4_le_bytes(ciphertext.length)
     tag = poly1305_mac(mac_data, otk)
     return (ciphertext, tag)

Why do they require to pad the ciphertext/additional data during MAC-computation? Are there any cryptographical advantages over a similar algorithm without padding (as used by libsodium)?

  • 1
    $\begingroup$ What if you want to start computing the MAC over the ciphertext before knowing the length of the AAD? $\endgroup$ Apr 14 '18 at 3:59
  • $\begingroup$ @CodesInChaos, how would that work? You can only compute the Poly1305 MAC in order, can you not? $\endgroup$
    – otus
    Apr 14 '18 at 6:35
  • 2
    $\begingroup$ @otus You can compute the field-element associated with the concatenation of block-aligned messages knowing the field elements associated with the individual messages and their lengths. It's just a linear combination, where the multiplier depends only on the length. $\endgroup$ Apr 14 '18 at 9:42
  • $\begingroup$ @CodesInChaos, oh, right. For some reason I thought that would require a linear amount of extra work, but I guess it's simple to do some modular exponentiation to get the correct multiples. Thanks. $\endgroup$
    – otus
    Apr 14 '18 at 9:53