public void Init(ICipherParameters parameters) { // setup AAD var aadParam = parameters as AADParameter; SecurityAssert.NotNull(aadParam); var a = aadParam.AAD; aSize = a.Length * 8; // setup IV var ivParam = aadParam.Parameters as IVParameter; SecurityAssert.NotNull(ivParam); var iv = ivParam.IV; ivSize = iv.Length * 8; // setup cipher Cipher.Init(ivParam.Parameters); // setup H subkey h = new byte[16]; Cipher.EncryptBlock(new byte[16], 0, h, 0); // setup tag hash tagHash = new GHash(h); tagHash.Update(a, 0, a.Length); var tagAADPaddingLength = 16 - a.Length % 16; tagHash.Update(new byte[tagAADPaddingLength], 0, tagAADPaddingLength); // setup pre-counter block if (iv.Length == 12) { // IV || 0^31 ||1 j0 = new byte[16]; Array.Copy(iv, j0, 12); j0[15] = 1; } else { // GHASH_H(IV || 0^(s+64) || [len(IV)]) var j0PaddingLength = 8 + (16 - iv.Length % 16) % 16; var j0Hash = new GHash(h); j0Hash.Update(iv, 0, iv.Length); j0Hash.Update(new byte[j0PaddingLength], 0, j0PaddingLength); j0Hash.Update(EndianBitConverter.Big.GetBytes(ivSize), 0, sizeof(long)); j0 = j0Hash.Digest(); } ctr = new CTRBlockCipher(Cipher); ctr.Init(new IVParameter(null, j0)); ctr.Inc(); cSize = 0; }