internal ThreefishTransform(byte[] key, byte[] iv, int feedbackSize, ThreefishTransformMode transformMode, CipherMode cipherMode, PaddingMode paddingMode) { this.transformMode = transformMode; this.cipherMode = cipherMode; this.paddingMode = paddingMode; cipherBytes = key.Length; cipherWords = key.Length / 8; feedbackBytes = feedbackSize / 8; // Allocate working blocks now so that we don't have to allocate them // each time Transform(Final)Block is called block = new ulong[cipherWords]; tempBlock = new ulong[cipherWords]; streamBytes = new byte[cipherBytes]; depadBuffer = new byte[cipherBytes]; this.iv = new ulong[cipherWords]; GetBytes(iv, 0, this.iv, cipherBytes); switch (OutputBlockSize) { case 256 / 8: cipher = new Threefish256(); break; case 512 / 8: cipher = new Threefish512(); break; case 1024 / 8: cipher = new Threefish1024(); break; default: throw new CryptographicException("Unsupported key/block size."); } bool e = transformMode == ThreefishTransformMode.Encrypt; switch (cipherMode) { case CipherMode.ECB: transformFunc = e ? EcbEncrypt : new TransformFunc(EcbDecrypt); break; case CipherMode.CBC: transformFunc = e ? CbcEncrypt : new TransformFunc(CbcDecrypt); break; case CipherMode.OFB: transformFunc = OfbApplyStream; break; case CipherMode.CFB: transformFunc = e ? CfbEncrypt : new TransformFunc(CfbDecrypt); break; default: throw new CryptographicException("Unsupported cipher mode."); } var keyWords = new ulong[cipherWords]; GetBytes(key, 0, keyWords, cipherBytes); cipher.SetKey(keyWords); InitializeBlocks(); }
private void ProcessBlock(int bytes) { // Set the key to the current state cipher.SetKey(state); // Update tweak UbiParameters.BitsProcessed += (ulong)bytes; cipher.SetTweak(UbiParameters.Tweak); // Encrypt block cipher.Encrypt(cipherInput, state); // Feed-forward input with state for (int i = 0; i < cipherInput.Length; i++) { state[i] ^= cipherInput[i]; } }