/** * Process the last block in the buffer. * * @param out the array the block currently being held is copied into. * @param outOff the offset at which the copying starts. * @return the number of output bytes copied to out. * @exception DataLengthException if there is insufficient space in out for * the output, or the input is not block size aligned and should be. * @exception InvalidOperationException if the underlying cipher is not * initialised. * @exception InvalidCipherTextException if padding is expected and not found. * @exception DataLengthException if the input is not block size * aligned. */ public override int DoFinal( byte[] output, int outOff) { try { if (bufOff != 0) { Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned"); Check.OutputLength(output, outOff, bufOff, "output buffer too short for DoFinal()"); // NB: Can't copy directly, or we may write too much output cipher.ProcessBlock(buf, 0, buf, 0); Array.Copy(buf, 0, output, outOff, bufOff); } return(bufOff); } finally { Reset(); } }
/// <summary> /// Bitwise encryption /// </summary> /// <param name="input"></param> /// <param name="inOff"></param> /// <param name="length"></param> /// <param name="output"></param> /// <param name="outOff"></param> /// <param name="N">input length in bits to encrypt</param> public void ProcessBits( byte[] input, int inOff, int length, byte[] output, int outOff, int N) { //int bytesWritten = ProcessBytes(input, inOff, length, output, outOff); ////Console.WriteLine("input: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(input)); ////Console.WriteLine("output: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(output)); ////Console.WriteLine(bufOff); ////Console.WriteLine("buffer: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buf)); //int significantBits = N % 8; //Console.WriteLine(significantBits); ////DoFinal //try //{ // if (bufOff != 0) // { // Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned"); // Check.OutputLength(output, outOff, bufOff, "output buffer too short for DoFinal()"); // Console.WriteLine("buf: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buf)); // //Shifting last byte left on number of significant bits // buf[bufOff - 1] <<= 4; // Console.WriteLine("buf: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buf)); // cipher.ProcessBlock(buf, 0, buf, 0); // Console.WriteLine("buf: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buf)); // //Console.WriteLine("buf: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buf)); // //Console.WriteLine(significantBits); // //Console.WriteLine(maskLookUp[8 - significantBits]); // //Masking insignificant bits in last byte // //buf[bufOff - 1] &= maskLookUp[8 - significantBits]; // buf[bufOff - 1] &= 0xf0; // //Console.WriteLine("buf: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buf)); // //Shifting last byte back // buf[bufOff - 1] >>= 4; // //Console.WriteLine("buf: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buf)); // Array.Copy(buf, 0, output, bytesWritten, bufOff); // //Console.WriteLine("output: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(output)); // } //} //finally //{ // Reset(); //} int bytesWritten = ProcessBytes(input, inOff, length, output, outOff); //Console.WriteLine("output: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(output)); int N_ = N % (cipher.GetBlockSize() * 8); try { if (bufOff != 0) { Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned"); Check.OutputLength(output, outOff, bufOff, "output buffer too short for DoFinal()"); Array.Clear(temp, 0, temp.Length); cipher.ProcessBlock(temp, 0, temp, 0); //Console.WriteLine("gamma: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(temp)); BitArray bits = new BitArray(temp); bits.FixLength(N_); byte[] gamma = bits.GetBytes(); bits = new BitArray(buf); bits.FixLength(N_); byte[] lastBlockBytes = bits.GetBytes(); //Console.WriteLine("gamma: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(gamma)); //Console.WriteLine("lastBlockBytes: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(lastBlockBytes)); for (int i = 0; i < lastBlockBytes.Length; i++) { lastBlockBytes[i] ^= gamma[i]; } bits = new BitArray(lastBlockBytes); //Shifting non-significant bits bits = bits.ShiftLeft(8 - N % 8); //Console.WriteLine(bits.ToString()); lastBlockBytes = bits.GetBytes(); //Console.WriteLine("lastBlockBytes: " + Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(lastBlockBytes)); Array.Copy(lastBlockBytes, 0, output, bytesWritten, lastBlockBytes.Length); } } finally { Reset(); } }