/// <summary> /// Transforms the specified region of the specified byte array. /// </summary> /// <param name="inputBuffer">The input for which to compute the transform.</param> /// <param name="inputOffset">The offset into the byte array from which to begin using data.</param> /// <param name="inputCount">The number of bytes in the byte array to use as data.</param> /// <returns>The computed transform.</returns> public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { UInt64 block = ByteOperations.PackBytesIntoUInt64(inputBuffer, inputOffset); // Call a function from the blowfish engine function. if (Mode == BlowfishManagedTransformMode.Encrypt) { block = BlowfishEngine.Encrypt(block, Context); } if (Mode == BlowfishManagedTransformMode.Decrypt) { block = BlowfishEngine.Decrypt(block, Context); } return(ByteOperations.UnpackUInt64IntoBytes(block)); }
/// <summary> /// Transforms the specified region of the input byte array and copies the resulting transform to the specified /// region of the output byte array. /// </summary> /// <param name="inputBuffer">The input for which to compute the transform.</param> /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param> /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param> /// <param name="outputBuffer">The output to which to write the transform.</param> /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param> /// <returns>The number of bytes written.</returns> public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { UInt64 block = ByteOperations.PackBytesIntoUInt64(inputBuffer, inputOffset); // Call a function from the blowfish engine function. if (Mode == BlowfishManagedTransformMode.Encrypt) { block = BlowfishEngine.Encrypt(block, Context); } if (Mode == BlowfishManagedTransformMode.Decrypt) { block = BlowfishEngine.Decrypt(block, Context); } byte[] TransformedBytes = ByteOperations.UnpackUInt64IntoBytes(block); Array.Copy(TransformedBytes, 0, outputBuffer, outputOffset, TransformedBytes.Length); return(TransformedBytes.Length); }
/// <summary> /// Creates a symmetric decryptor object with the specified Key property and initialization vector (IV). /// </summary> /// <param name="rgbKey"></param> /// <param name="rgbIV"></param> /// <returns></returns> public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV) { BlowfishContext encryptionContext = null; if (ByteOperations.ArraysEqual(rgbKey, Key)) { if (Context == null) { Context = new BlowfishContext(Key); } encryptionContext = Context; } else { encryptionContext = new BlowfishContext(rgbKey); } return(new BlowfishManagedTransform(encryptionContext, Mode, BlowfishManagedTransformMode.Decrypt)); }
/// <summary> /// Decrypts a single block, running the 64 bits of data through all 16 /// rounds of the Blowfish algorithm. Returns the decrypted 64 bits. /// </summary> /// <param name="block64"></param> /// <param name="Schedule"></param> /// <returns></returns> public static UInt64 Decrypt(UInt64 block64, BlowfishContext Context) { UInt32 left32 = ByteOperations.Left(block64); UInt32 right32 = ByteOperations.Right(block64); // We unrolled the Feistel loop, so the very first key XOR happens // outside the loop here. left32 ^= Context.Schedule.Get(17); // 16 iterations of the Round function. for (int i = 15; i >= 0; i -= 2) { right32 = Round(right32, left32, Context.Schedule.Get(i + 1), Context); left32 = Round(left32, right32, Context.Schedule.Get(i), Context); } // Finalize the loop unrolling. right32 = right32 ^ Context.Schedule.Get(0); return(ByteOperations.Combine(right32, left32)); }