From b9bd51f7a61b1e1a8d5f9885e6a58ff44b12a787 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Fri, 17 Nov 2017 19:15:14 -0500 Subject: [PATCH] Remove variable block size for Threefish (GH #535) --- TestVectors/threefish.txt | 49 ++++---- bench1.cpp | 8 +- regtest2.cpp | 14 ++- threefish.cpp | 239 ++++++++++++++++---------------------- threefish.h | 211 ++++++++++++++++++++++----------- 5 files changed, 285 insertions(+), 236 deletions(-) diff --git a/TestVectors/threefish.txt b/TestVectors/threefish.txt index b4f175ba..95c09209 100644 --- a/TestVectors/threefish.txt +++ b/TestVectors/threefish.txt @@ -1,5 +1,21 @@ AlgorithmType: SymmetricCipher -Name: Threefish/ECB +Name: Threefish-256(256)/ECB +Comment: Test Vector 5, Threefish-256, null tweak +Source: skein_golden_kat_internals.txt +Tweak: word64 0000000000000000 0000000000000000 +Key: word64 0000000000000000 0000000000000000 0000000000000000 0000000000000000 +Plaintext: word64 0000000000000000 0000000000000000 0000000000000000 0000000000000000 +Ciphertext: word64 94EEEA8B1F2ADA84 ADF103313EAE6670 952419A1F4B16D53 D83F13E63C9F6B11 +Test: Encrypt +Name: Threefish-256(256)/ECB +Comment: Test Vector 6, Threefish-256, tweak +Source: skein_golden_kat_internals.txt +Tweak: word64 0706050403020100 0F0E0D0C0B0A0908 +Key: word64 1716151413121110 1F1E1D1C1B1A1918 2726252423222120 2F2E2D2C2B2A2928 +Plaintext: word64 F8F9FAFBFCFDFEFF F0F1F2F3F4F5F6F7 E8E9EAEBECEDEEEF E0E1E2E3E4E5E6E7 +Ciphertext: word64 DF8FEA0EFF91D0E0 D50AD82EE69281C9 76F48D58085D869D DF975E95B5567065 +Test: Encrypt +Name: Threefish-512(512)/ECB Comment: Test Vector 1 Source: Botan test vectors (threefish.vec) Key: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 \ @@ -9,7 +25,7 @@ Plaintext: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 Ciphertext: B1A2BBC6EF6025BC 40EB3822161F36E3 75D1BB0AEE3186FB D19E47C5D479947B \ 7BC2F8586E35F0CF F7E7F03084B0B7B1 F1AB3961A580A3E9 7EB41EA14A6D7BBE Test: Encrypt -Name: Threefish/ECB +Name: Threefish-512(512)/ECB Comment: Test Vector 2 Source: Botan test vectors (threefish.vec) Key: B1A2BBC6EF6025BC 40EB3822161F36E3 75D1BB0AEE3186FB D19E47C5D479947B \ @@ -19,7 +35,7 @@ Plaintext: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 Ciphertext: F13CA06760DD9BBE AB87B6C56F3BBBDB E9D08A77978B942A C02D471DC10268F2 \ 261C3D4330D6CA34 1F4BD4115DEE16A2 1DCDA2A34A0A76FB A976174E4CF1E306 Test: Encrypt -Name: Threefish/ECB +Name: Threefish-512(512)/ECB Comment: Test Vector 3 Source: Botan test vectors (threefish.vec) Key: F13CA06760DD9BBE AB87B6C56F3BBBDB E9D08A77978B942A C02D471DC10268F2 \ @@ -29,7 +45,7 @@ Plaintext: B1A2BBC6EF6025BC 40EB3822161F36E3 75D1BB0AEE3186FB D19E47C5D479947B \ Ciphertext: 1BEC82CBA1357566 B34E1CF1FBF123A1 41C8F4089F6E4CE3 209AEA10095AEC93 \ C900D068BDC7F7A2 DD58513C11DEC956 B93169B1C4F24CED E31A265DE83E36B4 Test: Encrypt -Name: Threefish/ECB +Name: Threefish-512(512)/ECB Comment: Test Vector 4 Source: Botan test vectors (threefish.vec) Key: F13CA06760DD9BBE AB87B6C56F3BBBDB E9D08A77978B942A C02D471DC10268F2 \ @@ -43,24 +59,7 @@ Ciphertext: 1BEC82CBA1357566 B34E1CF1FBF123A1 41C8F4089F6E4CE3 209AEA10095AEC93 073CB5F8FABFA17D B751477F294EB3DD 4ACD92B78397331F CC36A9C3D3055B81 \ D867CBDD56279037 373359CA1832669A F4B87A1F2FDAF8D3 6E2FB7A6D19F5D45 Test: Encrypt -################################################################################## -Name: Threefish/ECB -Comment: Test Vector 5, Threefish-256, null tweak -Source: skein_golden_kat_internals.txt -Tweak: word64 0000000000000000 0000000000000000 -Key: word64 0000000000000000 0000000000000000 0000000000000000 0000000000000000 -Plaintext: word64 0000000000000000 0000000000000000 0000000000000000 0000000000000000 -Ciphertext: word64 94EEEA8B1F2ADA84 ADF103313EAE6670 952419A1F4B16D53 D83F13E63C9F6B11 -Test: Encrypt -Name: Threefish/ECB -Comment: Test Vector 6, Threefish-256, tweak -Source: skein_golden_kat_internals.txt -Tweak: word64 0706050403020100 0F0E0D0C0B0A0908 -Key: word64 1716151413121110 1F1E1D1C1B1A1918 2726252423222120 2F2E2D2C2B2A2928 -Plaintext: word64 F8F9FAFBFCFDFEFF F0F1F2F3F4F5F6F7 E8E9EAEBECEDEEEF E0E1E2E3E4E5E6E7 -Ciphertext: word64 DF8FEA0EFF91D0E0 D50AD82EE69281C9 76F48D58085D869D DF975E95B5567065 -Test: Encrypt -Name: Threefish/ECB +Name: Threefish-512(512)/ECB Comment: Test Vector 7, Threefish-512, null tweak Source: skein_golden_kat_internals.txt Tweak: word64 0000000000000000 0000000000000000 @@ -71,7 +70,7 @@ Plaintext: word64 0000000000000000 0000000000000000 0000000000000000 00000000 Ciphertext: word64 BC2560EFC6BBA2B1 E3361F162238EB40 FB8631EE0ABBD175 7B9479D4C5479ED1 \ CFF0356E58F8C27B B1B7B08430F0E7F7 E9A380A56139ABF1 BE7B6D4AA11EB47E Test: Encrypt -Name: Threefish/ECB +Name: Threefish-512(512)/ECB Comment: Test Vector 8, Threefish-512, tweak Source: skein_golden_kat_internals.txt Tweak: word64 0706050403020100 0F0E0D0C0B0A0908 @@ -82,7 +81,7 @@ Plaintext: word64 F8F9FAFBFCFDFEFF F0F1F2F3F4F5F6F7 E8E9EAEBECEDEEEF E0E1E2E3 Ciphertext: word64 2C5AD426964304E3 9A2436D6D8CA01B4 DD456DB00E333863 794725970EB9368B \ 043546998D0A2A27 25A7C918EA204478 346201A1FEDF11AF 3DAF1C5C3D672789 Test: Encrypt -Name: Threefish/ECB +Name: Threefish-1024(1024)/ECB Comment: Test Vector 9, Threefish-1024, null tweak Source: skein_golden_kat_internals.txt Tweak: word64 0000000000000000 0000000000000000 @@ -99,7 +98,7 @@ Ciphertext: word64 04B3053D0A3D5CF0 0136E0D1C7DD85F7 067B212F6EA78A5C 0DA9C10 540306B460472E0B 71C18254BCEA820D C36B4068BEAF32C8 FA4329597A360095 \ C4A36C28434A5B9A D54331444B1046CF DF11834830B2A460 1E39E8DFE1F7EE4F Test: Encrypt -Name: Threefish/ECB +Name: Threefish-1024(1024)/ECB Comment: Test Vector 10, Threefish-1024, tweak Source: skein_golden_kat_internals.txt Tweak: word64 0706050403020100 0F0E0D0C0B0A0908 diff --git a/bench1.cpp b/bench1.cpp index 181b7db3..a3f9827b 100644 --- a/bench1.cpp +++ b/bench1.cpp @@ -6,6 +6,8 @@ #include "validate.h" #include "aes.h" +#include "kalyna.h" +#include "threefish.h" #include "blumshub.h" #include "files.h" #include "filters.h" @@ -575,9 +577,9 @@ void Benchmark2(double t, double hertz) BenchMarkByName("Camellia/CTR", 16); BenchMarkByName("Camellia/CTR", 32); BenchMarkByName("Twofish/CTR"); - BenchMarkByName("Threefish/CTR", 32, "Threefish/CTR (256-bit key)", MakeParameters(Name::BlockSize(), 32)); - BenchMarkByName("Threefish/CTR", 64, "Threefish/CTR (512-bit key)", MakeParameters(Name::BlockSize(), 64)); - BenchMarkByName("Threefish/CTR", 128, "Threefish/CTR (1024-bit key)", MakeParameters(Name::BlockSize(), 128)); + BenchMarkByName("Threefish-256(256)/CTR", 32); + BenchMarkByName("Threefish-512(512)/CTR", 64); + BenchMarkByName("Threefish-1024(1024)/CTR", 128); BenchMarkByName("Serpent/CTR"); BenchMarkByName("CAST-256/CTR"); BenchMarkByName("RC6/CTR"); diff --git a/regtest2.cpp b/regtest2.cpp index 12724b3e..e152c276 100644 --- a/regtest2.cpp +++ b/regtest2.cpp @@ -142,9 +142,17 @@ void RegisterFactories2() RegisterSymmetricCipherDefaultFactories >(); // Test Vectors RegisterSymmetricCipherDefaultFactories >(); // Test Vectors RegisterSymmetricCipherDefaultFactories >(); // Benchmarks - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + + RegisterSymmetricCipherDefaultFactories >("Threefish-256(256)/ECB"); // Test Vectors + RegisterSymmetricCipherDefaultFactories >("Threefish-256(256)/CBC"); // Test Vectors + RegisterSymmetricCipherDefaultFactories >("Threefish-512(512)/ECB"); // Test Vectors + RegisterSymmetricCipherDefaultFactories >("Threefish-512(512)/CBC"); // Test Vectors + RegisterSymmetricCipherDefaultFactories >("Threefish-1024(1024)/ECB"); // Test Vectors + RegisterSymmetricCipherDefaultFactories >("Threefish-1024(1024)/CBC"); // Test Vectors + + RegisterSymmetricCipherDefaultFactories >("Threefish-256(256)/CTR"); // Benchmarks + RegisterSymmetricCipherDefaultFactories >("Threefish-512(512)/CTR"); // Benchmarks + RegisterSymmetricCipherDefaultFactories >("Threefish-1024(1024)/CTR"); // Benchmarks RegisterDefaultFactoryFor >(); RegisterDefaultFactoryFor >(); diff --git a/threefish.cpp b/threefish.cpp index bb472851..8fff615b 100644 --- a/threefish.cpp +++ b/threefish.cpp @@ -7,7 +7,6 @@ #include "threefish.h" #include "misc.h" -#include "cpu.h" #include "algparam.h" #include "argnames.h" @@ -236,100 +235,85 @@ ANONYMOUS_NAMESPACE_END NAMESPACE_BEGIN(CryptoPP) -void Threefish::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms) +void Threefish256::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) { - switch (keylen) - { - case 32: // 256 - m_rkey.New(5); - m_wspace.New(4); - m_blocksize = 32; + // Blocksize is Keylength for Threefish + CRYPTOPP_ASSERT(keyLength == KEYLENGTH); - GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 4, key, 32); - m_rkey[4] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3]; - break; - case 64: // 512 - m_rkey.New(9); - m_wspace.New(8); - m_blocksize = 64; + m_rkey.New(5); + m_wspace.New(4); - GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 8, key, 64); - m_rkey[8] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3] ^ m_rkey[4] ^ - m_rkey[5] ^ m_rkey[6] ^ m_rkey[7]; - break; - case 128: // 128 - m_rkey.New(17); - m_wspace.New(16); - m_blocksize = 128; + GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 4, userKey, keyLength); + m_rkey[4] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3]; - GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 16, key, 128); - m_rkey[16] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3] ^ m_rkey[4] ^ - m_rkey[5] ^ m_rkey[6] ^ m_rkey[7] ^ m_rkey[8] ^ m_rkey[9] ^ m_rkey[10] ^ m_rkey[11] ^ m_rkey[12] ^ - m_rkey[13] ^ m_rkey[14] ^ m_rkey[15]; - break; - default: - CRYPTOPP_ASSERT(0); - } - - m_tweak.New(3); - ConstByteArrayParameter t; - if (params.GetValue(Name::Tweak(), t)) - { - CRYPTOPP_ASSERT(t.size() == 16); - GetUserKey(LITTLE_ENDIAN_ORDER, m_tweak.begin(), 2, t.begin(), 16); - m_tweak[2] = m_tweak[0] ^ m_tweak[1]; - } - else - { - ::memset(m_tweak.begin(), 0x00, 24); - } + SetTweak(params); } -void Threefish::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - switch(m_blocksize) - { - case 32: - ProcessAndXorBlock_256(inBlock, xorBlock, outBlock); - break; - case 64: - ProcessAndXorBlock_512(inBlock, xorBlock, outBlock); - break; - case 128: - ProcessAndXorBlock_1024(inBlock, xorBlock, outBlock); - break; - default: - CRYPTOPP_ASSERT(0); - } -} - -void Threefish::Enc::ProcessAndXorBlock_256(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +void Threefish256::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const { word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; - // Reverse bytes on BigEndian; Align pointer on LittleEndian + // Reverse bytes on BigEndian; align pointer on LittleEndian typedef GetBlock InBlock; InBlock iblk(inBlock); iblk(G0)(G1)(G2)(G3); - G0 += m_rkey[0]; G1 += m_rkey[1]; G2 += m_rkey[2]; G3 += m_rkey[3]; - G1 += m_tweak[0]; G2 += m_tweak[1]; + G0 += m_rkey[0]; G1 += m_rkey[1]; G2 += m_rkey[2]; + G3 += m_rkey[3]; G1 += m_tweak[0]; G2 += m_tweak[1]; G256x8(0); G256x8(2); G256x8(4); G256x8(6); G256x8(8); G256x8(10); G256x8(12); G256x8(14); G256x8(16); - // Reverse bytes on BigEndian; Align pointer on LittleEndian + // Reverse bytes on BigEndian; align pointer on LittleEndian typedef PutBlock OutBlock; OutBlock oblk(xorBlock, outBlock); oblk(G0)(G1)(G2)(G3); } -void Threefish::Enc::ProcessAndXorBlock_512(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +void Threefish256::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(G0)(G1)(G2)(G3); + + G0 -= m_rkey[3]; G1 -= m_rkey[4]; G2 -= m_rkey[0]; G3 -= m_rkey[1]; + G1 -= m_tweak[0]; G2 -= m_tweak[1]; G3 -= 18; + + IG256x8(16); IG256x8(14); IG256x8(12); IG256x8(10); + IG256x8(8); IG256x8(6); IG256x8(4); IG256x8(2); IG256x8(0); + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(G0)(G1)(G2)(G3); +} + +///////////////////////////////////////////////////////////////// + +void Threefish512::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + // Blocksize is Keylength for Threefish + CRYPTOPP_ASSERT(keyLength == KEYLENGTH); + + m_rkey.New(9); + m_wspace.New(8); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 8, userKey, keyLength); + m_rkey[8] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3] ^ m_rkey[4] ^ + m_rkey[5] ^ m_rkey[6] ^ m_rkey[7]; + + SetTweak(params); +} + +void Threefish512::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const { word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7]; - // Reverse bytes on BigEndian; Align pointer on LittleEndian + // Reverse bytes on BigEndian; align pointer on LittleEndian typedef GetBlock InBlock; InBlock iblk(inBlock); iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); @@ -342,20 +326,61 @@ void Threefish::Enc::ProcessAndXorBlock_512(const byte *inBlock, const byte *xor G512x8(0); G512x8(2); G512x8(4); G512x8(6); G512x8(8); G512x8(10); G512x8(12); G512x8(14); G512x8(16); - // Reverse bytes on BigEndian; Align pointer on LittleEndian + // Reverse bytes on BigEndian; align pointer on LittleEndian typedef PutBlock OutBlock; OutBlock oblk(xorBlock, outBlock); oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); } -void Threefish::Enc::ProcessAndXorBlock_1024(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +void Threefish512::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; + word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7]; + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef GetBlock InBlock; + InBlock iblk(inBlock); + iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); + + G0 -= m_rkey[0]; G1 -= m_rkey[1]; G2 -= m_rkey[2]; G3 -= m_rkey[3]; + G4 -= m_rkey[4]; G5 -= m_rkey[5]; G6 -= m_rkey[6]; G7 -= m_rkey[7]; + G5 -= m_tweak[0]; G6 -= m_tweak[1]; G7 -= 18; + + IG512x8(16); IG512x8(14); IG512x8(12); IG512x8(10); + IG512x8(8); IG512x8(6); IG512x8(4); IG512x8(2); IG512x8(0); + + // Reverse bytes on BigEndian; align pointer on LittleEndian + typedef PutBlock OutBlock; + OutBlock oblk(xorBlock, outBlock); + oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); +} + +///////////////////////////////////////////////////////////////// + +void Threefish1024::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + // Blocksize is Keylength for Threefish + CRYPTOPP_ASSERT(keyLength == KEYLENGTH); + + m_rkey.New(17); + m_wspace.New(16); + + GetUserKey(LITTLE_ENDIAN_ORDER, m_rkey.begin(), 16, userKey, keyLength); + m_rkey[16] = W64LIT(0x1BD11BDAA9FC1A22) ^ m_rkey[0] ^ m_rkey[1] ^ m_rkey[2] ^ m_rkey[3] ^ m_rkey[4] ^ + m_rkey[5] ^ m_rkey[6] ^ m_rkey[7] ^ m_rkey[8] ^ m_rkey[9] ^ m_rkey[10] ^ m_rkey[11] ^ m_rkey[12] ^ + m_rkey[13] ^ m_rkey[14] ^ m_rkey[15]; + + SetTweak(params); +} + +void Threefish1024::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const { word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7]; word64 &G8=m_wspace[8], &G9=m_wspace[9], &G10=m_wspace[10], &G11=m_wspace[11]; word64 &G12=m_wspace[12], &G13=m_wspace[13], &G14=m_wspace[14], &G15=m_wspace[15]; - // Reverse bytes on BigEndian; Align pointer on LittleEndian + // Reverse bytes on BigEndian; align pointer on LittleEndian typedef GetBlock InBlock; InBlock iblk(inBlock); iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15); @@ -369,82 +394,20 @@ void Threefish::Enc::ProcessAndXorBlock_1024(const byte *inBlock, const byte *xo G1024x8(0); G1024x8(2); G1024x8(4); G1024x8(6); G1024x8(8); G1024x8(10); G1024x8(12); G1024x8(14); G1024x8(16); G1024x8(18); - // Reverse bytes on BigEndian; Align pointer on LittleEndian + // Reverse bytes on BigEndian; align pointer on LittleEndian typedef PutBlock OutBlock; OutBlock oblk(xorBlock, outBlock); oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15); } -void Threefish::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - switch(m_blocksize) - { - case 32: - ProcessAndXorBlock_256(inBlock, xorBlock, outBlock); - break; - case 64: - ProcessAndXorBlock_512(inBlock, xorBlock, outBlock); - break; - case 128: - ProcessAndXorBlock_1024(inBlock, xorBlock, outBlock); - break; - default: - CRYPTOPP_ASSERT(0); - } -} - -void Threefish::Dec::ProcessAndXorBlock_256(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; - - // Reverse bytes on BigEndian; Align pointer on LittleEndian - typedef GetBlock InBlock; - InBlock iblk(inBlock); - iblk(G0)(G1)(G2)(G3); - - G0 -= m_rkey[3]; G1 -= m_rkey[4]; G2 -= m_rkey[0]; G3 -= m_rkey[1]; - G1 -= m_tweak[0]; G2 -= m_tweak[1]; G3 -= 18; - - IG256x8(16); IG256x8(14); IG256x8(12); IG256x8(10); - IG256x8(8); IG256x8(6); IG256x8(4); IG256x8(2); IG256x8(0); - - // Reverse bytes on BigEndian; Align pointer on LittleEndian - typedef PutBlock OutBlock; - OutBlock oblk(xorBlock, outBlock); - oblk(G0)(G1)(G2)(G3); -} - -void Threefish::Dec::ProcessAndXorBlock_512(const byte *inBlock, const byte *xorBlock, byte *outBlock) const -{ - word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; - word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7]; - - // Reverse bytes on BigEndian; Align pointer on LittleEndian - typedef GetBlock InBlock; - InBlock iblk(inBlock); - iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); - - G0 -= m_rkey[0]; G1 -= m_rkey[1]; G2 -= m_rkey[2]; G3 -= m_rkey[3]; - G4 -= m_rkey[4]; G5 -= m_rkey[5]; G6 -= m_rkey[6]; G7 -= m_rkey[7]; - G5 -= m_tweak[0]; G6 -= m_tweak[1]; G7 -= 18; - - IG512x8(16); IG512x8(14); IG512x8(12); IG512x8(10); - IG512x8(8); IG512x8(6); IG512x8(4); IG512x8(2); IG512x8(0); - - // Reverse bytes on BigEndian; Align pointer on LittleEndian - typedef PutBlock OutBlock; - OutBlock oblk(xorBlock, outBlock); - oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7); -} - -void Threefish::Dec::ProcessAndXorBlock_1024(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +void Threefish1024::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const { word64 &G0=m_wspace[0], &G1=m_wspace[1], &G2=m_wspace[2], &G3=m_wspace[3]; word64 &G4=m_wspace[4], &G5=m_wspace[5], &G6=m_wspace[6], &G7=m_wspace[7]; word64 &G8=m_wspace[8], &G9=m_wspace[9], &G10=m_wspace[10], &G11=m_wspace[11]; word64 &G12=m_wspace[12], &G13=m_wspace[13], &G14=m_wspace[14], &G15=m_wspace[15]; - // Reverse bytes on BigEndian; Align pointer on LittleEndian + // Reverse bytes on BigEndian; align pointer on LittleEndian typedef GetBlock InBlock; InBlock iblk(inBlock); iblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15); @@ -458,7 +421,7 @@ void Threefish::Dec::ProcessAndXorBlock_1024(const byte *inBlock, const byte *xo IG1024x8(18); IG1024x8(16); IG1024x8(14); IG1024x8(12); IG1024x8(10); IG1024x8(8); IG1024x8(6); IG1024x8(4); IG1024x8(2); IG1024x8(0); - // Reverse bytes on BigEndian; Align pointer on LittleEndian + // Reverse bytes on BigEndian; align pointer on LittleEndian typedef PutBlock OutBlock; OutBlock oblk(xorBlock, outBlock); oblk(G0)(G1)(G2)(G3)(G4)(G5)(G6)(G7)(G8)(G9)(G10)(G11)(G12)(G13)(G14)(G15); diff --git a/threefish.h b/threefish.h index fe8e7359..b06dd029 100644 --- a/threefish.h +++ b/threefish.h @@ -12,79 +12,75 @@ #include "config.h" #include "seckey.h" #include "secblock.h" +#include "algparam.h" +#include "argnames.h" +#include "stdcpp.h" NAMESPACE_BEGIN(CryptoPP) //! \class Threefish_Info //! \brief Threefish block cipher information -//! \note Crypto++ provides a byte oriented implementation +//! \tparam BS block size of the cipher, in bytes //! \since Crypto++ 6.0 -struct Threefish_Info : public VariableBlockSize<32, 32, 128> +template +struct Threefish_Info : public FixedBlockSize, FixedKeyLength { - CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "Threefish";} - - //! \brief The minimum key length used by the algorithm provided as a constant - //! \details MIN_KEYLENGTH is provided in bytes, not bits - CRYPTOPP_CONSTANT(MIN_KEYLENGTH=32) - //! \brief The maximum key length used by the algorithm provided as a constant - //! \details MIN_KEYLENGTH is provided in bytes, not bits - CRYPTOPP_CONSTANT(MAX_KEYLENGTH=128) - //! \brief The default key length used by the algorithm provided as a constant - //! \details MIN_KEYLENGTH is provided in bytes, not bits - CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=32) - //! \brief The default IV requirements for the algorithm provided as a constant - //! \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement - //! in cryptlib.h for allowed values. - CRYPTOPP_CONSTANT(IV_REQUIREMENT=SimpleKeyingInterface::UNIQUE_IV) - //! \brief The default initialization vector length for the algorithm provided as a constant - //! \details IV_LENGTH is provided in bytes, not bits. - CRYPTOPP_CONSTANT(IV_LENGTH=32) - //! \brief Provides a valid key length for the algorithm provided by a static function. - //! \param keylength the size of the key, in bytes - //! \details Threefish uses 256, 512 and 1024-bit keys. The block size follows key length. - CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) + static const std::string StaticAlgorithmName() { - // Valid key lengths are 256, 512 and 1024 bits - return (keylength >= 128) ? 128 : - (keylength >= 64) ? 64 : 32; - } - - CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidBlockSize(size_t keylength) - { - return (keylength >= 128) ? 128 : - (keylength >= 64) ? 64 : 32; + // Format is Cipher-Blocksize(Keylength) + return "Threefish-" + IntToString(BS) + "(" + IntToString(BS) + ")"; } }; -//! \class Threefish -//! \brief Threefish block cipher -//! \sa Threefish +//! \class Threefish_Base +//! \brief Threefish block cipher base class +//! \tparam BS block size of the cipher, in bytes +//! \details User code should use Threefish256, Threefish512, Threefish1024 +//! \sa Threefish256, Threefish512, Threefish1024, Threefish //! \since Crypto++ 6.0 -class Threefish : public Threefish_Info, public BlockCipherDocumentation +template +struct CRYPTOPP_NO_VTABLE Threefish_Base : public Threefish_Info +{ + + void SetTweak(const NameValuePairs ¶ms) + { + m_tweak.New(3); + ConstByteArrayParameter t; + if (params.GetValue(Name::Tweak(), t)) + { + // Tweak size is fixed at 16 for Threefish + CRYPTOPP_ASSERT(t.size() == 16); + GetUserKey(LITTLE_ENDIAN_ORDER, m_tweak.begin(), 2, t.begin(), 16); + m_tweak[2] = m_tweak[0] ^ m_tweak[1]; + } + else + { + std::memset(m_tweak.begin(), 0x00, 24); + } + } + + typedef SecBlock > AlignedSecBlock64; + mutable AlignedSecBlock64 m_wspace; // workspace + AlignedSecBlock64 m_rkey; // keys + AlignedSecBlock64 m_tweak; +}; + +//! \class Threefish256 +//! \brief Threefish 256-bit block cipher +//! \details Threefish256 provides 256-bit block size. The valid key size is 256-bit. +//! \note Crypto++ provides a byte oriented implementation +//! \sa Threefish256, Threefish512, Threefish1024, Threefish +//! \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE Threefish256 : public Threefish_Base<32>, public BlockCipherDocumentation { public: //! \brief Threefish block cipher data processing functions //! \details Provides implementation common to encryption and decryption //! \since Crypto++ 6.0 - class CRYPTOPP_NO_VTABLE Base : public VariableBlockCipherImpl + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl > { - public: - std::string AlgorithmName() const { - // Key length is the same as blocksize - return m_blocksize ? "Threefish-" + IntToString(m_blocksize*8) : StaticAlgorithmName(); - } - - unsigned int OptimalDataAlignment() const { - return GetAlignmentOf(); - } - protected: - void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); - - typedef SecBlock > AlignedSecBlock64; - mutable AlignedSecBlock64 m_wspace; // workspace - AlignedSecBlock64 m_rkey; // keys - AlignedSecBlock64 m_tweak; + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); }; //! \brief Provides implementation for encryption transformation @@ -95,33 +91,114 @@ public: { protected: void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - - void ProcessAndXorBlock_256(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - void ProcessAndXorBlock_512(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - void ProcessAndXorBlock_1024(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; }; - //! \brief Provides implementation for decryption transformation - //! \details Dec provides implementation for encryption transformation. All key and block + //! \brief Provides implementation for encryption transformation + //! \details Dec provides implementation for decryption transformation. All key and block //! sizes are supported. //! \since Crypto++ 6.0 class CRYPTOPP_NO_VTABLE Dec : public Base { protected: void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - - void ProcessAndXorBlock_256(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - void ProcessAndXorBlock_512(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; - void ProcessAndXorBlock_1024(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; }; -public: typedef BlockCipherFinal Encryption; typedef BlockCipherFinal Decryption; }; -typedef Threefish::Encryption ThreefishEncryption; -typedef Threefish::Decryption ThreefishDecryption; +typedef Threefish256::Encryption Threefish256Encryption; +typedef Threefish256::Decryption Threefish256Decryption; + +//! \class Threefish512 +//! \brief Threefish 512-bit block cipher +//! \details Threefish512 provides 512-bit block size. The valid key size is 512-bit. +//! \note Crypto++ provides a byte oriented implementation +//! \sa Threefish256, Threefish512, Threefish1024, Threefish +//! \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE Threefish512 : public Threefish_Base<64>, public BlockCipherDocumentation +{ +public: + //! \brief Threefish block cipher data processing functions + //! \details Provides implementation common to encryption and decryption + //! \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl > + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + }; + + //! \brief Provides implementation for encryption transformation + //! \details Enc provides implementation for encryption transformation. All key and block + //! sizes are supported. + //! \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + //! \brief Provides implementation for encryption transformation + //! \details Dec provides implementation for decryption transformation. All key and block + //! sizes are supported. + //! \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Threefish512::Encryption Threefish512Encryption; +typedef Threefish512::Decryption Threefish512Decryption; + +//! \class Threefish1024 +//! \brief Threefish 1024-bit block cipher +//! \details Threefish1024 provides 1024-bit block size. The valid key size is 1024-bit. +//! \note Crypto++ provides a byte oriented implementation +//! \sa Threefish256, Threefish512, Threefish1024, Threefish +//! \since Crypto++ 6.0 +class CRYPTOPP_NO_VTABLE Threefish1024 : public Threefish_Base<128>, public BlockCipherDocumentation +{ +public: + //! \brief Threefish block cipher data processing functions + //! \details Provides implementation common to encryption and decryption + //! \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl > + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + }; + + //! \brief Provides implementation for encryption transformation + //! \details Enc provides implementation for encryption transformation. All key and block + //! sizes are supported. + //! \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + //! \brief Provides implementation for encryption transformation + //! \details Dec provides implementation for decryption transformation. All key and block + //! sizes are supported. + //! \since Crypto++ 6.0 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + protected: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Threefish1024::Encryption Threefish1024Encryption; +typedef Threefish1024::Decryption Threefish1024Decryption; NAMESPACE_END