public void Init(ICipherParameters parameters) { // setup AAD var aadParam = parameters as AADParameter; SecurityAssert.NotNull(aadParam); var a = aadParam !.AAD; var aSize = a.Length * 8; // setup IV var ivParam = aadParam !.Parameters as IVParameter; SecurityAssert.NotNull(ivParam); var iv = ivParam !.IV; var ivSize = iv.Length * 8; // setup cipher _cipher.Init(ivParam !.Parameters); // setup H subkey var h = new byte[16]; _cipher.EncryptBlock(new byte[16], 0, h, 0); // setup tag hash var tagHash = new GHash(h); tagHash.Update(a); var tagAADPaddingLength = 16 - a.Length % 16; tagHash.Update(new byte[tagAADPaddingLength]); // setup pre-counter block byte[] j0; 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); j0Hash.Update(new byte[j0PaddingLength]); j0Hash.Update(EndianBitConverter.Big.GetBytes((long)ivSize)); j0 = j0Hash.DigestBuffer(); } var ctr = new CTRBlockCipher(_cipher); ctr.Init(new IVParameter(j0)); ctr.Inc(); _state = new State(aSize, BlockLength, TagLength, j0, tagHash, ctr, _cipher); }