chacha20Poly1305Decrypt function
Verifies and decrypts ciphertextWithTag (ciphertext || 16-byte tag).
Returns the plaintext, or throws FormatException('invalid tag') if the
authentication tag does not match.
Implementation
Uint8List chacha20Poly1305Decrypt({
required Uint8List key32,
required Uint8List nonce12,
required Uint8List ciphertextWithTag,
Uint8List? aad,
}) {
if (ciphertextWithTag.length < 16) {
throw FormatException('invalid tag');
}
final ad = aad ?? Uint8List(0);
final ctLen = ciphertextWithTag.length - 16;
final ciphertext = Uint8List.sublistView(ciphertextWithTag, 0, ctLen);
final tag = Uint8List.sublistView(ciphertextWithTag, ctLen);
final otk = _poly1305KeyGen(key32, nonce12);
final macData = _aeadMacData(ad, ciphertext);
final expected = poly1305Mac(otk, macData);
// Constant-time comparison.
var diff = 0;
for (var i = 0; i < 16; i++) {
diff |= tag[i] ^ expected[i];
}
if (diff != 0) {
throw FormatException('invalid tag');
}
return _chacha20Xor(key32, nonce12, ciphertext, 1);
}