/// <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 UInt64 DecryptSingleBlock(UInt64 block64) { if (Context == null) { Context = new BlowfishContext(Key); } return(BlowfishEngine.Decrypt(block64, Context)); }
/// <summary> /// Constructor. /// </summary> /// <param name="Key"></param> /// <param name="IV"></param> internal BlowfishManagedTransform(BlowfishContext Context, CipherMode CipherMode, BlowfishManagedTransformMode Mode) { this.Context = Context; this.Mode = Mode; this.CipherMode = CipherMode; if (CipherMode != CipherMode.ECB) { throw new CryptographicException("Invalid cipher mode."); } }
/// <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 byte[] DecryptSingleBlock(byte[] block64, int Offset = 0) { UInt64 Block = ByteOperations.PackBytesIntoUInt64(block64, Offset); if (Context == null) { Context = new BlowfishContext(Key); } return(ByteOperations.UnpackUInt64IntoBytes(BlowfishEngine.Decrypt(Block, Context))); }
/// <summary> /// This performs Schneier's round function for Blowfish, which consists of swapping /// the left and right halves, and swapping bytes from the s-box. /// </summary> /// <param name="leftHalf"></param> /// <param name="rightHalf"></param> /// <param name="Key"></param> /// <returns></returns> private static UInt32 Round(UInt32 leftHalf, UInt32 rightHalf, UInt32 Key, BlowfishContext Context) { uint a = (0xFF000000 & rightHalf) >> 24; uint b = (0x00FF0000 & rightHalf) >> 16; uint c = (0x0000FF00 & rightHalf) >> 8; uint d = 0x000000FF & rightHalf; uint x1 = (Context.sbox[0, a] + Context.sbox[1, b]) ^ Context.sbox[2, c]; uint x2 = x1 + Context.sbox[3, d]; uint x3 = x2 ^ Key; return(x3 ^ leftHalf); }
public void EncryptDecryptBlock_NonCryptedKeys() { byte[] key = new byte[40]; var expectedLeft = 10U; var expectedRight = 235U; var blowFeistel = new BlowFeistel(); var context = new BlowfishContext(key); UInt32 left = expectedLeft; UInt32 right = expectedRight; blowFeistel.BlowfishEncrypt(context, ref left, ref right); blowFeistel.BlowfishDecrypt(context, ref left, ref right); Assert.AreEqual(left, expectedLeft); Assert.AreEqual(right, expectedRight); }
/// <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)); }
public void EncryptDecryptBlock_CryptedKeys() { byte[] key = new byte[56]; var expectedLeft = 10U; var expectedRight = 235U; var blowFeistel = new BlowFeistel(); Random rnd = new Random(); rnd.NextBytes(key); var context = new BlowfishContext(key); UInt32 left = expectedLeft; UInt32 right = expectedRight; blowFeistel.CryptPkeys(context); blowFeistel.BlowfishEncrypt(context, ref left, ref right); blowFeistel.BlowfishDecrypt(context, ref left, ref right); Assert.AreEqual(left, expectedLeft); Assert.AreEqual(right, expectedRight); }
/// <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)); }
/// <summary> /// Constructor via byte array for key. /// </summary> /// <param name="key"></param> public BlowfishManaged(byte[] key) : this() { Key = key; Context = new BlowfishContext(Key); }