1. It's there to allow the user to call GetMac() after DoFinal().
2. The general contract of the cipher classes is that calling Reset() returns a cipher to the same state it was in after the most recent Init(). DoFinal() also must implicitly Reset() the cipher. It's a sort of oddity of the AEAD ciphers that AAD is included in the initialisation parameters, and so it must be processed again, although processing of AAD could conceivably be made lazy. Note that changes since 1.7 allow AAD to be streamed to an Snippet IAeadBlockCipher using the ProcessAadByte/s methods. AAD can even be interleaved with the plaintext/ciphertext processing, at the cost of a binary field exponentiation during DoFinal.
Regards, Pete Dettman On 13/03/2013 1:13 AM, Sid Shetye wrote:
Thanks Peter, it's been sometime since I read that paper - appreciate the insight. I'm also trying to understand some code that probably relates to a use case that's not obvious to me In GcmBlockCipher.DoFinal() we have, at the end, Reset(clearMac:false); Which in turn triggers: ... if (clearMac) { _macBlock = null; } if (_initialAssociatedText != null) { ProcessAadBytes(_initialAssociatedText, 0, _initialAssociatedText.Length); } ... Question: 1. Why do we care about preserving the _macBlock reference if we're done with even the final block? 2. Why is there the ProcessAadBytes() again in the Reset() section? I was under the impression we were done with the AAD at the beginning, inside Init() itself. I suspect the above two are related to a specific use case. Would appreciate your comments.