Threefish supports block sizes of 256 bits, 512 bits and 1,024 bits, and where the encryption key is the same size as the block size. is a large, tweakable block cipher. It is defined for three different block sizes: 256 bits, 512 bits, and 1024 bits. The key is the same size as the block, and the tweak value is 128 bits for all block sizes. Overall, it was used by the Skein hash function, and which was a finalist in the SHA-3 competition.
Threefish with Bouncy Castle and C# |
Coding
First we create a folder named "bc_skipjack", and then go into that folder.We can create a Dotnet console project for .NET 8.0 with:
dotnet new console --framework net8.0
This produces a Csproject file of:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> </Project>
We then add the latest Bouncy Castle library:
dotnet add package BouncyCastle.Cryptography --version 2.2.1
The following is the coding:
namespace Serpent { using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Paddings; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; class Program { static void Main(string[] args) { var msg="Hello"; var iv="00112233445566778899AABBCCDDEEFF00"; var size=128; var mode="CBC"; if (args.Length >0) msg=args[0]; if (args.Length >1) iv=args[1]; if (args.Length >2) size=Convert.ToInt32(args[2]); if (args.Length >3) mode=args[3]; try { var plainTextData=System.Text.Encoding.UTF8.GetBytes(msg); var cipher = new ThreefishEngine(size); byte[] nonce = new byte[16]; Array.Copy(Convert.FromHexString(iv), nonce, 16); PaddedBufferedBlockCipher cipherMode = new PaddedBufferedBlockCipher(new CbcBlockCipher(cipher), new Pkcs7Padding()); if (mode=="ECB") cipherMode = new PaddedBufferedBlockCipher(new EcbBlockCipher(cipher), new Pkcs7Padding()); else if (mode=="CFB") cipherMode = new PaddedBufferedBlockCipher(new CfbBlockCipher (cipher,128 ), new Pkcs7Padding()); CipherKeyGenerator keyGen = new CipherKeyGenerator(); keyGen.Init(new KeyGenerationParameters(new SecureRandom(), size)); KeyParameter keyParam = keyGen.GenerateKeyParameter(); ICipherParameters keyParamIV = new ParametersWithIV(keyParam,nonce); if (mode=="ECB") { cipherMode.Init(true,keyParam); } else { cipherMode.Init(true,keyParamIV); } int outputSize = cipherMode.GetOutputSize(plainTextData.Length); byte[] cipherTextData = new byte[outputSize]; int result = cipherMode.ProcessBytes(plainTextData, 0, plainTextData.Length, cipherTextData, 0); cipherMode.DoFinal(cipherTextData, result); var rtn = cipherTextData; // Decrypt cipherMode.Init(false,keyParam); outputSize = cipherMode.GetOutputSize(cipherTextData.Length); plainTextData = new byte[outputSize]; result = cipherMode.ProcessBytes(cipherTextData, 0, cipherTextData.Length,plainTextData, 0); cipherMode.DoFinal(plainTextData, result); var pln=plainTextData; Console.WriteLine("=== {0} ==",cipher.AlgorithmName); Console.WriteLine("Message:\t\t{0}",msg); Console.WriteLine("Block size:\t\t{0} bits",cipher.GetBlockSize()*8); Console.WriteLine("Mode:\t\t\t{0}",mode); Console.WriteLine("IV:\t\t\t{0}",iv); Console.WriteLine("Key size:\t\t{0} bits",size); Console.WriteLine("Key:\t\t\t{0} [{1}]",Convert.ToHexString(keyParam.GetKey()),Convert.ToBase64String(keyParam.GetKey())); Console.WriteLine("\nCipher (hex):\t\t{0}",Convert.ToHexString(rtn)); Console.WriteLine("Cipher (Base64):\t{0}",Convert.ToBase64String(rtn)); Console.WriteLine("\nPlain:\t\t\t{0}",System.Text.Encoding.ASCII.GetString(pln).TrimEnd('\0')); } catch (Exception e) { Console.WriteLine("Error: {0}",e.Message); } } } }
For a block and key size of 256 bits:
=== Threefish-256 == Message: Hello 123 Block size: 256 bits Mode: ECB IV: 00112233445566778899AABBCCDDEEFF00 Key size: 256 bits Key: 1A8DE242F1AD85C13706E994BC1BE6599A41477269A6F3773EEFE2223AFB6DE8 [Go3iQvGthcE3BumUvBvmWZpBR3JppvN3Pu/iIjr7beg=] Cipher (hex): DFA5463B1E0C7CCD8F617B57BC3CF701823710013F3CC9DDF660A600A796D026 Cipher (Base64): 36VGOx4MfM2PYXtXvDz3AYI3EAE/PMnd9mCmAKeW0CY= Plain: Hello 123
For a block and key size of 1,024 bits:
=== Threefish-1024 == Message: Hello 123 Block size: 1024 bits Mode: ECB IV: 00112233445566778899AABBCCDDEEFF00 Key size: 1024 bits Key: 302A39A655E5C24425924D35F7AC21D26018F4FFB3B2B97A3CDF17784AA628F7F15E7D40F6A9A469800ECEEE9D2411003BD21B58310B9C2E477701ED11B35381AC57B1581F762CC6A3C2FBE47E19DD6EB1F6D2FA254663F69BA08CAF90ECB2482545B82165A79EED1ADD892F49C79A56528F6D4211AEA1DB1FD1281AB520C93E [MCo5plXlwkQlkk0196wh0mAY9P+zsrl6PN8XeEqmKPfxXn1A9qmkaYAOzu6dJBEAO9IbWDELnC5HdwHtEbNTgaxXsVgfdizGo8L75H4Z3W6x9tL6JUZj9pugjK+Q7LJIJUW4IWWnnu0a3YkvSceaVlKPbUIRrqHbH9EoGrUgyT4=] Cipher (hex): BA82AEB1644115202D7CDAFC2EA6F3C597C060D50666FECCF7D0D746FA46ABB5D13B21C73DB4F1353251E9F9D804F07BACFCE07DD861F27B0B7DEE3046E8514E15DC621888AE204D8AF393529EEEF26E35C83D19D1C3CFF6C97B9A1353FD65570B38E573CCEB6EE03F5906757713DAA602E991C9738C40CAF9A40963FECEF090 Cipher (Base64): uoKusWRBFSAtfNr8LqbzxZfAYNUGZv7M99DXRvpGq7XROyHHPbTxNTJR6fnYBPB7rPzgfdhh8nsLfe4wRuhRThXcYhiIriBNivOTUp7u8m41yD0Z0cPP9sl7mhNT/WVXCzjlc8zrbuA/WQZ1dxPapgLpkclzjEDK+aQJY/7O8JA= Plain: Hello 123