// Token: 0x060001DB RID: 475 RVA: 0x0000C99C File Offset: 0x0000AB9C
        public int DoFinal(byte[] output, int outOff)
        {
            int num = this.bufOff;

            if (!this.forEncryption)
            {
                if (num < this.macSize)
                {
                    throw new InvalidCipherTextException("data too short");
                }
                num -= this.macSize;
            }
            if (num > 0)
            {
                byte[] array = new byte[16];
                Array.Copy(this.bufBlock, 0, array, 0, num);
                this.gCTRBlock(array, num, output, outOff);
            }
            byte[] array2 = new byte[16];
            GcmBlockCipher.packLength((ulong)((long)this.A.Length * 8L), array2, 0);
            GcmBlockCipher.packLength(this.totalLength * 8UL, array2, 8);
            GcmUtilities.Xor(this.S, array2);
            this.multiplier.MultiplyH(this.S);
            byte[] array3 = new byte[16];
            this.cipher.ProcessBlock(this.J0, 0, array3, 0);
            GcmUtilities.Xor(array3, this.S);
            int num2 = num;

            this.macBlock = new byte[this.macSize];
            Array.Copy(array3, 0, this.macBlock, 0, this.macSize);
            if (this.forEncryption)
            {
                Array.Copy(this.macBlock, 0, output, outOff + this.bufOff, this.macSize);
                num2 += this.macSize;
            }
            else
            {
                byte[] array4 = new byte[this.macSize];
                Array.Copy(this.bufBlock, num, array4, 0, this.macSize);
                if (!Arrays.ConstantTimeAreEqual(this.macBlock, array4))
                {
                    throw new InvalidCipherTextException("mac check in GCM failed");
                }
            }
            this.Reset(false);
            return(num2);
        }
        // Token: 0x060001D4 RID: 468 RVA: 0x0000C5F8 File Offset: 0x0000A7F8
        public virtual void Init(bool forEncryption, ICipherParameters parameters)
        {
            this.forEncryption = forEncryption;
            this.macBlock      = null;
            if (parameters is AeadParameters)
            {
                AeadParameters aeadParameters = (AeadParameters)parameters;
                this.nonce = aeadParameters.GetNonce();
                this.A     = aeadParameters.GetAssociatedText();
                int num = aeadParameters.MacSize;
                if (num < 96 || num > 128 || num % 8 != 0)
                {
                    throw new ArgumentException("Invalid value for MAC size: " + num.ToString());
                }
                this.macSize  = num / 8;
                this.keyParam = aeadParameters.Key;
            }
            else
            {
                if (!(parameters is ParametersWithIV))
                {
                    throw new ArgumentException("invalid parameters passed to GCM");
                }
                ParametersWithIV parametersWithIV = (ParametersWithIV)parameters;
                this.nonce    = parametersWithIV.GetIV();
                this.A        = null;
                this.macSize  = 16;
                this.keyParam = (KeyParameter)parametersWithIV.Parameters;
            }
            int num2 = forEncryption ? 16 : (16 + this.macSize);

            this.bufBlock = new byte[num2];
            if (this.nonce == null || this.nonce.Length < 1)
            {
                throw new ArgumentException("IV must be at least 1 byte");
            }
            if (this.A == null)
            {
                this.A = new byte[0];
            }
            this.cipher.Init(true, this.keyParam);
            this.H = new byte[16];
            this.cipher.ProcessBlock(this.H, 0, this.H, 0);
            this.multiplier.Init(this.H);
            this.initS = this.gHASH(this.A);
            if (this.nonce.Length == 12)
            {
                this.J0 = new byte[16];
                Array.Copy(this.nonce, 0, this.J0, 0, this.nonce.Length);
                this.J0[15] = 1;
            }
            else
            {
                this.J0 = this.gHASH(this.nonce);
                byte[] array = new byte[16];
                GcmBlockCipher.packLength((ulong)((long)this.nonce.Length * 8L), array, 8);
                GcmUtilities.Xor(this.J0, array);
                this.multiplier.MultiplyH(this.J0);
            }
            this.S           = Arrays.Clone(this.initS);
            this.counter     = Arrays.Clone(this.J0);
            this.bufOff      = 0;
            this.totalLength = 0UL;
        }