/// <summary> /// Encrypt a block of bytes using offset parameters. /// <para>Encrypts one block of bytes at the designated offsets. /// Initialize(bool, KeyParams) must be called before this method can be used.</para> /// </summary> /// /// <param name="Input">The input array of plain text bytes</param> /// <param name="InOffset">Starting offset within the input array</param> /// <param name="Output">The output array of encrypted bytes</param> /// <param name="OutOffset">Starting offset within the output array</param> public void EncryptBlock(byte[] Input, int InOffset, byte[] Output, int OutOffset) { // xor iv and input IntUtils.XORBLK(Input, InOffset, m_cbcIv, 0, m_cbcIv.Length); // encrypt iv m_blockCipher.EncryptBlock(m_cbcIv, 0, Output, OutOffset); // copy output to iv Buffer.BlockCopy(Output, OutOffset, m_cbcIv, 0, m_blockSize); }
/// <summary> /// Decrypt a block of bytes with offset parameters. /// <para>Decrypts one block of bytes at the designated offsets. /// Initialize(bool, KeyParams) must be called before this method can be used.</para> /// </summary> /// /// <param name="Input">The input array of encrypted bytes</param> /// <param name="InOffset">Starting offset within the Input array</param> /// <param name="Output">The output array of decrypted bytes</param> /// <param name="OutOffset">Starting offset within the Output array</param> public void DecryptBlock(byte[] Input, int InOffset, byte[] Output, int OutOffset) { // copy input to temp iv Buffer.BlockCopy(Input, InOffset, m_cbcNextIv, 0, m_blockSize); // decrypt input m_blockCipher.DecryptBlock(Input, InOffset, Output, OutOffset); // xor output and iv IntUtils.XORBLK(m_cbcIv, 0, Output, OutOffset, m_cbcIv.Length); // copy forward iv Buffer.BlockCopy(m_cbcNextIv, 0, m_cbcIv, 0, m_cbcIv.Length); }
private void ProcessDecrypt(byte[] Input, int InOffset, byte[] Output, int OutOffset, byte[] Vector) { byte[] nextIv = new byte[Vector.Length]; // copy input to temp iv Buffer.BlockCopy(Input, InOffset, nextIv, 0, m_blockSize); // decrypt input m_blockCipher.DecryptBlock(Input, InOffset, Output, OutOffset); // xor output and iv IntUtils.XORBLK(Vector, 0, Output, OutOffset, Vector.Length); // copy forward iv Buffer.BlockCopy(nextIv, 0, Vector, 0, m_blockSize); }
private void TransformParallel(byte[] Input, int InOffset, byte[] Output, int OutOffset, int Length) { int outSize = Length; // parallel CTR processing // int cnkSize = m_parallelBlockSize / m_processorCount; int rndSize = cnkSize * m_processorCount; int subSize = cnkSize / m_blockSize; byte[] tmpCtr = new byte[m_ctrVector.Length]; // create random, and xor to output in parallel System.Threading.Tasks.Parallel.For(0, m_processorCount, ParallelOption, i => { // thread level counter byte[] thdCtr = new byte[m_ctrVector.Length]; // offset counter by chunk size / block size thdCtr = Increase(m_ctrVector, subSize * i); // create random at offset position Generate(Output, OutOffset + (i * cnkSize), cnkSize, thdCtr); // xor with input at offset IntUtils.XORBLK(Input, InOffset + (i * cnkSize), Output, OutOffset + (i * cnkSize), cnkSize); // store last counter if (i == m_processorCount - 1) { Buffer.BlockCopy(thdCtr, 0, tmpCtr, 0, tmpCtr.Length); } }); // copy the last counter position to class variable Buffer.BlockCopy(tmpCtr, 0, m_ctrVector, 0, m_ctrVector.Length); // last block processing int alnSze = cnkSize * m_processorCount; if (alnSze < outSize) { int fnlSize = outSize % alnSze; Generate(Output, alnSze, fnlSize, m_ctrVector); for (int i = alnSze; i < outSize; i++) { Output[i] ^= Input[i]; } } }
private void Process(byte[] Input, int InOffset, byte[] Output, int OutOffset, int Length) { int prcSze = (Length >= Input.Length - InOffset) && Length >= Output.Length - OutOffset ? IntUtils.Min(Input.Length - InOffset, Output.Length - OutOffset) : Length; if (!m_isParallel || prcSze < m_parallelBlockSize) { // generate random Generate(prcSze, m_ctrVector, Output, OutOffset); // output is input xor with random int sze = prcSze - (prcSze % BLOCK_SIZE); if (sze != 0) { IntUtils.XORBLK(Input, InOffset, Output, OutOffset, sze); } // get the remaining bytes if (sze != prcSze) { for (int i = sze; i < prcSze; i++) { Output[i + OutOffset] ^= Input[i + InOffset]; } } } else { // parallel CTR processing // int cnkSize = (prcSze / BLOCK_SIZE / m_processorCount) * BLOCK_SIZE; int rndSize = cnkSize * m_processorCount; int subSize = (cnkSize / BLOCK_SIZE); uint[] tmpCtr = new uint[m_ctrVector.Length]; // create random, and xor to output in parallel System.Threading.Tasks.Parallel.For(0, m_processorCount, i => { // thread level counter uint[] thdCtr = new uint[m_ctrVector.Length]; // offset counter by chunk size / block size thdCtr = Increase(m_ctrVector, subSize * i); // create random at offset position this.Generate(cnkSize, thdCtr, Output, OutOffset + (i * cnkSize)); // xor with input at offset IntUtils.XORBLK(Input, InOffset + (i * cnkSize), Output, OutOffset + (i * cnkSize), cnkSize); // store last counter if (i == m_processorCount - 1) { Array.Copy(thdCtr, 0, tmpCtr, 0, thdCtr.Length); } }); // last block processing if (rndSize < prcSze) { int fnlSize = prcSze % rndSize; Generate(fnlSize, tmpCtr, Output, rndSize); for (int i = 0; i < fnlSize; ++i) { Output[i + OutOffset + rndSize] ^= (byte)(Input[i + InOffset + rndSize]); } } // copy the last counter position to class variable Array.Copy(tmpCtr, 0, m_ctrVector, 0, m_ctrVector.Length); } }