From ac036496d350a971a17fdb8765997dd36b2f9871 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sat, 30 Jun 2018 02:43:12 -0400 Subject: [PATCH] Add Simeck lightweight block cipher (GH #675) Add Simeck lightweight block cipher (GH #675) --- Filelist.txt | 3 + TestVectors/all.txt | 1 + TestVectors/simeck.txt | 147 +++++++++++++++++++++++++++++++++++++++ bench1.cpp | 3 + cryptlib.vcxproj | 2 + cryptlib.vcxproj.filters | 6 ++ regtest2.cpp | 8 ++- simeck.cpp | 145 ++++++++++++++++++++++++++++++++++++++ simeck.h | 141 +++++++++++++++++++++++++++++++++++++ 9 files changed, 455 insertions(+), 1 deletion(-) create mode 100644 TestVectors/simeck.txt create mode 100644 simeck.cpp create mode 100644 simeck.h diff --git a/Filelist.txt b/Filelist.txt index 0c83a64e..83acac8d 100644 --- a/Filelist.txt +++ b/Filelist.txt @@ -286,6 +286,8 @@ sharkbox.cpp simple.cpp simple.h siphash.h +simeck.cpp +simeck.h simon.cpp simon-simd.cpp simon.h @@ -485,6 +487,7 @@ TestVectors/sha3_256_fips_202.txt TestVectors/sha3_384_fips_202.txt TestVectors/sha3_512_fips_202.txt TestVectors/shacal2.txt +TestVectors/simeck.txt TestVectors/simon.txt TestVectors/siphash.txt TestVectors/sm3.txt diff --git a/TestVectors/all.txt b/TestVectors/all.txt index 9482e9d1..e973ae06 100644 --- a/TestVectors/all.txt +++ b/TestVectors/all.txt @@ -33,6 +33,7 @@ Test: TestVectors/sm4.txt Test: TestVectors/hight.txt Test: TestVectors/cham.txt Test: TestVectors/lea.txt +Test: TestVectors/simeck.txt Test: TestVectors/simon.txt Test: TestVectors/speck.txt Test: TestVectors/salsa.txt diff --git a/TestVectors/simeck.txt b/TestVectors/simeck.txt new file mode 100644 index 00000000..76bde400 --- /dev/null +++ b/TestVectors/simeck.txt @@ -0,0 +1,147 @@ +AlgorithmType: SymmetricCipher +Name: SIMECK-32/ECB +# +Source: SIMECK test vector +Comment: SIMECK-32/ECB, 64-bit key +Key: 1918 1110 0908 0100 +Plaintext: 6565 6877 +Ciphertext: 770d 2c76 +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-32/ECB, 64-bit key +Key: 3d6c 4ae1 6784 18be +Plaintext: 4823 0029 +Ciphertext: 6535 9de9 +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-32/ECB, 64-bit key +Key: 6df1 1649 5f90 6952 +Plaintext: 72ae 2cd6 +Ciphertext: 0ab0 73ca +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-32/ECB, 64-bit key +Key: 2ea6 0bb3 01eb 26e9 +Plaintext: 41bb 5af1 +Ciphertext: 6ed0 bc2e +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-32/ECB, 64-bit key +Key: 0099 0f3e 390c 7e87 +Plaintext: 153c 12db +Ciphertext: 7637 4119 +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-32/ECB, 64-bit key +Key: 4db7 4d06 491c 440d +Plaintext: 305e 0124 +Ciphertext: 8252 aa91 +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-32/ECB, 64-bit key +Key: 4dc8 074d 2d12 39b3 +Plaintext: 54de 1547 +Ciphertext: e288 e7ea +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-32/ECB, 64-bit key +Key: 5d03 701f 26a6 428b +Plaintext: 66bb 6443 +Ciphertext: b730 99ae +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-32/ECB, 64-bit key +Key: 1e1f 3b25 1238 4509 +Plaintext: 767d 7a5a +Ciphertext: 058a 62df +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-32/ECB, 64-bit key +Key: 7ff5 7f96 6bfc 63cb +Plaintext: 1ad4 6e5d +Ciphertext: 60c4 43f2 +Test: Encrypt + + + +AlgorithmType: SymmetricCipher +Name: SIMECK-64/ECB +# +Source: SIMECK test vector +Comment: SIMECK-64/ECB, 128-bit key +Key: 1b1a1918 13121110 0b0a0908 03020100 +Plaintext: 656b696c 20646e75 +Ciphertext: 45ce6902 5f7ab7ed +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-64/ECB, 128-bit key +Key: 0938251f 43bb8ba6 06b747de 870c3e99 +Plaintext: f1bbe9eb e16cd6ae +Ciphertext: 4d11c6b9 da2f7e28 +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-64/ECB, 128-bit key +Key: 323ba122 444066d0 9e7d49dc 407836fd +Plaintext: 1cdbae32 96f5453b +Ciphertext: 1e6a0792 f5a717c5 +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-64/ECB, 128-bit key +Key: 61ff698f 2ddc8e66 53bf67d6 99d5e980 +Plaintext: b9729d49 e18b1fda +Ciphertext: fca0fa81 94bda9c7 +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-64/ECB, 128-bit key +Key: cfd3902d 597e35cf 9e0cf4d5 2c53cbc9 +Plaintext: 844f4a77 9d9c1672 +Ciphertext: 562b1caa 75266241 +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-64/ECB, 128-bit key +Key: f8466a04 6454ceb1 3b33821f d4618dbe +Plaintext: 78818744 e6d91d2a +Ciphertext: d946fa49 41516d8e +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-64/ECB, 128-bit key +Key: 97278a59 28ce0bf5 2543e53c adae2488 +Plaintext: d0576876 162f6768 +Ciphertext: ca3e5050 126fa61b +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-64/ECB, 128-bit key +Key: a786c2b5 c19be1c0 978c2ff1 1128c18c +Plaintext: 08614014 c9cd68d4 +Ciphertext: a307ab5a a10f5c29 +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-64/ECB, 128-bit key +Key: 63b126df 89a98279 0c9bb447 9cfed971 +Plaintext: d96ca166 d923d155 +Ciphertext: 5e47b40d 9854418a +Test: Encrypt +# +Source: SIMECK reference implementation +Comment: SIMECK-64/ECB, 128-bit key +Key: 463608dc 1b2861c9 3f410784 28a11e20 +Plaintext: 3f895ef1 62e09612 +Ciphertext: c5fd5a6c 32056800 +Test: Encrypt diff --git a/bench1.cpp b/bench1.cpp index 9d41a91d..4cee1702 100644 --- a/bench1.cpp +++ b/bench1.cpp @@ -627,6 +627,9 @@ void Benchmark2(double t, double hertz) BenchMarkByName("LEA-128/CTR", 24, "LEA-128(192)/CTR (192-bit key)"); BenchMarkByName("LEA-128/CTR", 32, "LEA-128(256)/CTR (256-bit key)"); + BenchMarkByName("SIMECK-32/CTR", 8, "SIMECK-32(64)/CTR (64-bit key)"); + BenchMarkByName("SIMECK-64/CTR", 16, "SIMECK-64(128)/CTR (128-bit key)"); + BenchMarkByName("SIMON-64/CTR", 12, "SIMON-64(96)/CTR (96-bit key)"); BenchMarkByName("SIMON-64/CTR", 16, "SIMON-64(128)/CTR (128-bit key)"); BenchMarkByName("SIMON-128/CTR", 16, "SIMON-128(128)/CTR (128-bit key)"); diff --git a/cryptlib.vcxproj b/cryptlib.vcxproj index 181b5845..c217bbf8 100644 --- a/cryptlib.vcxproj +++ b/cryptlib.vcxproj @@ -295,6 +295,7 @@ + @@ -489,6 +490,7 @@ + diff --git a/cryptlib.vcxproj.filters b/cryptlib.vcxproj.filters index 273b3bb9..054aad47 100644 --- a/cryptlib.vcxproj.filters +++ b/cryptlib.vcxproj.filters @@ -377,6 +377,9 @@ Source Files + + Source Files + Source Files @@ -858,6 +861,9 @@ Header Files + + Header Files + Header Files diff --git a/regtest2.cpp b/regtest2.cpp index bd6ef0dc..4b1cc94e 100644 --- a/regtest2.cpp +++ b/regtest2.cpp @@ -35,6 +35,7 @@ #include "threefish.h" #include "cham.h" #include "lea.h" +#include "simeck.h" #include "simon.h" #include "speck.h" #include "sm4.h" @@ -177,12 +178,17 @@ void RegisterFactories2() RegisterSymmetricCipherDefaultFactories >(); // Test Vectors RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors RegisterSymmetricCipherDefaultFactories >(); // Test Vectors RegisterSymmetricCipherDefaultFactories >(); // Test Vectors RegisterSymmetricCipherDefaultFactories >(); // Test Vectors RegisterSymmetricCipherDefaultFactories >(); // Benchmarks - RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks RegisterSymmetricCipherDefaultFactories >(); // Test Vectors RegisterSymmetricCipherDefaultFactories >(); // Test Vectors diff --git a/simeck.cpp b/simeck.cpp new file mode 100644 index 00000000..6bd99e69 --- /dev/null +++ b/simeck.cpp @@ -0,0 +1,145 @@ +// simeck.cpp - written and placed in the public domain by Kim Sung Hee and Jeffrey Walton +// Based on "The Simeck Family of Lightweight Block Ciphers" by Gangqiang Yang, +// Bo Zhu, Valentin Suder, Mark D. Aagaard, and Guang Gong + +#include "pch.h" +#include "config.h" + +#include "simeck.h" +#include "misc.h" +#include "cpu.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::rotlConstant; +using CryptoPP::rotrConstant; + +/// \brief SIMECK encryption round +/// \tparam T word type +/// \param key the key for the round or iteration +/// \param left the first value +/// \param right the second value +/// \param temp a temporary workspace +/// \details SIMECK_Encryption serves as the key schedule, encryption and +/// decryption functions. +template +inline void SIMECK_Encryption(const T key, T& left, T& right, T& temp) +{ + temp = left; + left = (left & rotlConstant<5>(left)) ^ rotlConstant<1>(left) ^ right ^ key; + right = temp; +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void SIMECK32::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + CRYPTOPP_UNUSED(keyLength); + + GetBlock kblock(userKey); + kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]); + + word16 constant = 0xFFFC; + word32 sequence = 0x9A42BB1F; + for (unsigned int i = 0; i < ROUNDS; ++i) + { + m_rk[i] = m_t[0]; + + constant &= 0xFFFC; + constant |= sequence & 1; + sequence >>= 1; + + SIMECK_Encryption(static_cast(constant), m_t[1], m_t[0], m_t[4]); + + // rotate the LFSR of m_t + m_t[4] = m_t[1]; + m_t[1] = m_t[2]; + m_t[2] = m_t[3]; + m_t[3] = m_t[4]; + } +} + +void SIMECK32::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_t[1])(m_t[0]); + + for (int idx = 0; idx < ROUNDS; ++idx) + SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0], m_t[4]); + + PutBlock oblock(xorBlock, outBlock); + oblock(m_t[1])(m_t[0]); +} + +void SIMECK32::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_t[0])(m_t[1]); + + for (int idx = ROUNDS - 1; idx >= 0; --idx) + SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0], m_t[4]); + + PutBlock oblock(xorBlock, outBlock); + oblock(m_t[0])(m_t[1]); +} + +void SIMECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms) +{ + CRYPTOPP_UNUSED(params); + CRYPTOPP_UNUSED(keyLength); + + GetBlock kblock(userKey); + kblock(m_t[3])(m_t[2])(m_t[1])(m_t[0]); + + word64 constant = W64LIT(0xFFFFFFFC); + word64 sequence = W64LIT(0x938BCA3083F); + for (unsigned int i = 0; i < ROUNDS; ++i) + { + m_rk[i] = m_t[0]; + + constant &= W64LIT(0xFFFFFFFC); + constant |= sequence & 1; + sequence >>= 1; + + SIMECK_Encryption(static_cast(constant), m_t[1], m_t[0], m_t[4]); + + // rotate the LFSR of m_t + m_t[4] = m_t[1]; + m_t[1] = m_t[2]; + m_t[2] = m_t[3]; + m_t[3] = m_t[4]; + } +} + +void SIMECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_t[1])(m_t[0]); + + for (int idx = 0; idx < ROUNDS; ++idx) + SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0], m_t[4]); + + PutBlock oblock(xorBlock, outBlock); + oblock(m_t[1])(m_t[0]); +} + +void SIMECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + // Do not cast the buffer. It will SIGBUS on some ARM and SPARC. + GetBlock iblock(inBlock); + iblock(m_t[0])(m_t[1]); + + for (int idx = ROUNDS - 1; idx >= 0; --idx) + SIMECK_Encryption(m_rk[idx], m_t[1], m_t[0], m_t[4]); + + PutBlock oblock(xorBlock, outBlock); + oblock(m_t[0])(m_t[1]); +} + +NAMESPACE_END diff --git a/simeck.h b/simeck.h new file mode 100644 index 00000000..b3345f4d --- /dev/null +++ b/simeck.h @@ -0,0 +1,141 @@ +// simeck.h - written and placed in the public domain by Kim Sung Hee and Jeffrey Walton +// Based on "The Simeck Family of Lightweight Block Ciphers" by Gangqiang Yang, +// Bo Zhu, Valentin Suder, Mark D. Aagaard, and Guang Gong + +/// \file simeck.h +/// \brief Classes for the SIMECK block cipher +/// \since Crypto++ 7.1 + +#ifndef CRYPTOPP_SIMECK_H +#define CRYPTOPP_SIMECK_H + +#include "config.h" +#include "seckey.h" +#include "secblock.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// \brief SIMECK block cipher information +/// \since Crypto++ 7.1 +struct SIMECK32_Info : public FixedBlockSize<4>, public FixedKeyLength<8>, public FixedRounds<32> +{ + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize + return "SIMECK-32"; + } +}; + +/// \brief SIMECK block cipher information +/// \since Crypto++ 7.1 +struct SIMECK64_Info : public FixedBlockSize<8>, public FixedKeyLength<16>, public FixedRounds<44> +{ + static const std::string StaticAlgorithmName() + { + // Format is Cipher-Blocksize + return "SIMECK-64"; + } +}; + +/// \brief SIMECK 32-bit block cipher +/// \details SIMECK32 provides 32-bit block size. The valid key size is 64-bit. +/// \note Crypto++ provides a byte oriented implementation +/// \sa SIMECK64, SIMECK, The Simeck Family of Lightweight Block +/// Ciphers +/// \since Crypto++ 7.1 +class CRYPTOPP_NO_VTABLE SIMECK32 : public SIMECK32_Info, public BlockCipherDocumentation +{ +public: + /// \brief SIMECK block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 7.1 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + + FixedSizeSecBlock m_rk; + mutable FixedSizeSecBlock m_t; + }; + + /// \brief Provides implementation for encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 7.1 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + 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++ 7.1 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SIMECK32::Encryption SIMECK32Encryption; +typedef SIMECK32::Decryption SIMECK32Decryption; + +/// \brief SIMECK 64-bit block cipher +/// \details SIMECK64 provides 64-bit block size. The valid key size is 128-bit. +/// \note Crypto++ provides a byte oriented implementation +/// \sa SIMECK32, SIMECK, The Simeck Family of Lightweight Block +/// Ciphers +/// \since Crypto++ 7.1 +class CRYPTOPP_NO_VTABLE SIMECK64 : public SIMECK64_Info, public BlockCipherDocumentation +{ +public: + /// \brief SIMECK block cipher transformation functions + /// \details Provides implementation common to encryption and decryption + /// \since Crypto++ 7.1 + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + + FixedSizeSecBlock m_rk; + mutable FixedSizeSecBlock m_t; + }; + + /// \brief Provides implementation for encryption transformation + /// \details Enc provides implementation for encryption transformation. All key and block + /// sizes are supported. + /// \since Crypto++ 7.1 + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + 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++ 7.1 + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SIMECK64::Encryption SIMECK64Encryption; +typedef SIMECK64::Decryption SIMECK64Decryption; + +NAMESPACE_END + +#endif // CRYPTOPP_SIMECK_H