Remove Simon and Speck ciphers (GH #585)

We recently learned our Simon and Speck implementation was wrong. The removal will stop harm until we can loop back and fix the issue.
The issue is, the paper, the test vectors and the ref-impl do not align. Each produces slightly different result. We followed the test vectors but they turned out to be wrong for the ciphers.
We have one kernel test vector but we don't have a working implementation to observe it to fix our implementation. Ugh...
This commit is contained in:
Jeffrey Walton 2018-02-14 04:06:16 -05:00
parent 541caa3978
commit 15b14cc618
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
18 changed files with 3 additions and 5879 deletions

View File

@ -276,9 +276,6 @@ sharkbox.cpp
simple.cpp
simple.h
siphash.h
simon.cpp
simon-simd.cpp
simon.h
skipjack.cpp
skipjack.h
sm3.cpp
@ -290,9 +287,6 @@ socketft.cpp
socketft.h
sosemanuk.cpp
sosemanuk.h
speck.cpp
speck-simd.cpp
speck.h
square.cpp
square.h
squaretb.cpp
@ -472,12 +466,10 @@ TestVectors/sha3_256_fips_202.txt
TestVectors/sha3_384_fips_202.txt
TestVectors/sha3_512_fips_202.txt
TestVectors/shacal2.txt
TestVectors/simon.txt
TestVectors/siphash.txt
TestVectors/sm3.txt
TestVectors/sm4.txt
TestVectors/sosemanuk.txt
TestVectors/speck.txt
TestVectors/tea.txt
TestVectors/threefish.txt
TestVectors/ttmac.txt

View File

@ -250,15 +250,11 @@ ifeq ($(findstring -DCRYPTOPP_DISABLE_SSSE3,$(CXXFLAGS)),)
ifeq ($(HAVE_SSSE3),1)
ARIA_FLAG = -mssse3
SSSE3_FLAG = -mssse3
SIMON_FLAG = -mssse3
SPECK_FLAG = -mssse3
endif
ifeq ($(findstring -DCRYPTOPP_DISABLE_SSE4,$(CXXFLAGS)),)
HAVE_SSE4 = $(shell echo | $(CXX) -x c++ $(CXXFLAGS) -msse4.1 -dM -E - 2>/dev/null | $(GREP) -i -c __SSE4_1__)
ifeq ($(HAVE_SSE4),1)
BLAKE2_FLAG = -msse4.1
SIMON_FLAG = -msse4.1
SPECK_FLAG = -msse4.1
endif
HAVE_SSE4 = $(shell echo | $(CXX) -x c++ $(CXXFLAGS) -msse4.2 -dM -E - 2>/dev/null | $(GREP) -i -c __SSE4_2__)
ifeq ($(HAVE_SSE4),1)
@ -289,15 +285,11 @@ ifeq ($(SUN_COMPILER),1)
ifeq ($(COUNT),0)
SSSE3_FLAG = -xarch=ssse3 -D__SSSE3__=1
ARIA_FLAG = -xarch=ssse3 -D__SSSE3__=1
SIMON_FLAG = -xarch=ssse3 -D__SSSE3__=1
SPECK_FLAG = -xarch=ssse3 -D__SSSE3__=1
LDFLAGS += -xarch=ssse3
endif
COUNT := $(shell $(CXX) $(CXXFLAGS) -E -xarch=sse4_1 -xdumpmacros /dev/null 2>&1 | $(GREP) -i -c "illegal")
ifeq ($(COUNT),0)
BLAKE2_FLAG = -xarch=sse4_1 -D__SSE4_1__=1
SIMON_FLAG = -xarch=sse4_1 -D__SSE4_1__=1
SPECK_FLAG = -xarch=sse4_1 -D__SSE4_1__=1
LDFLAGS += -xarch=sse4_1
endif
COUNT := $(shell $(CXX) $(CXXFLAGS) -E -xarch=sse4_2 -xdumpmacros /dev/null 2>&1 | $(GREP) -i -c "illegal")
@ -374,8 +366,6 @@ ifeq ($(IS_NEON),1)
GCM_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
ARIA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
BLAKE2_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SIMON_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SPECK_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
endif
endif
@ -385,8 +375,6 @@ ifeq ($(IS_ARMV8),1)
ARIA_FLAG = -march=armv8-a
BLAKE2_FLAG = -march=armv8-a
NEON_FLAG = -march=armv8-a
SIMON_FLAG = -march=armv8-a
SPECK_FLAG = -march=armv8-a
endif
HAVE_CRC = $(shell echo | $(CXX) -x c++ $(CXXFLAGS) -march=armv8-a+crc -dM -E - 2>/dev/null | $(GREP) -i -c __ARM_FEATURE_CRC32)
ifeq ($(HAVE_CRC),1)
@ -409,8 +397,6 @@ ifneq ($(IS_PPC32)$(IS_PPC64)$(IS_AIX),000)
ALTIVEC_FLAG = -mcpu=power4 -maltivec
ARIA_FLAG = -mcpu=power4 -maltivec
BLAKE2_FLAG = -mcpu=power4 -maltivec
SIMON_FLAG = -mcpu=power4 -maltivec
SPECK_FLAG = -mcpu=power4 -maltivec
endif
# GCC and some compatibles
HAVE_CRYPTO = $(shell echo | $(CXX) -x c++ $(CXXFLAGS) -mcpu=power8 -maltivec -dM -E - 2>/dev/null | $(GREP) -i -c -E '_ARCH_PWR8|_ARCH_PWR9|__CRYPTO')
@ -419,8 +405,6 @@ ifneq ($(IS_PPC32)$(IS_PPC64)$(IS_AIX),000)
AES_FLAG = -mcpu=power8 -maltivec
GCM_FLAG = -mcpu=power8 -maltivec
SHA_FLAG = -mcpu=power8 -maltivec
SIMON_FLAG = -mcpu=power8 -maltivec
SPECK_FLAG = -mcpu=power8 -maltivec
endif
# IBM XL C/C++
HAVE_ALTIVEC = $(shell $(CXX) $(CXXFLAGS) -qshowmacros -qarch=pwr7 -qaltivec -E adhoc.cpp.proto 2>/dev/null | $(GREP) -i -c '__ALTIVEC__')
@ -428,8 +412,6 @@ ifneq ($(IS_PPC32)$(IS_PPC64)$(IS_AIX),000)
ALTIVEC_FLAG = -qarch=pwr7 -qaltivec
ARIA_FLAG = -qarch=pwr7 -qaltivec
BLAKE2_FLAG = -qarch=pwr7 -qaltivec
SIMON_FLAG = -qarch=pwr7 -qaltivec
SPECK_FLAG = -qarch=pwr7 -qaltivec
endif
# IBM XL C/C++
HAVE_CRYPTO = $(shell $(CXX) $(CXXFLAGS) -qshowmacros -qarch=pwr8 -qaltivec -E adhoc.cpp.proto 2>/dev/null | $(GREP) -i -c -E '_ARCH_PWR8|_ARCH_PWR9|__CRYPTO')
@ -440,8 +422,6 @@ ifneq ($(IS_PPC32)$(IS_PPC64)$(IS_AIX),000)
SHA_FLAG = -qarch=pwr8 -qaltivec
ARIA_FLAG = -qarch=pwr8 -qaltivec
BLAKE2_FLAG = -qarch=pwr8 -qaltivec
SIMON_FLAG = -qarch=pwr8 -qaltivec
SPECK_FLAG = -qarch=pwr8 -qaltivec
endif
endif
@ -1077,14 +1057,6 @@ sha-simd.o : sha-simd.cpp
shacal2-simd.o : shacal2-simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $<
# SSSE3 or NEON available
simon-simd.o : simon-simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SIMON_FLAG) -c) $<
# SSSE3 or NEON available
speck-simd.o : speck-simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SPECK_FLAG) -c) $<
# Don't build Rijndael with UBsan. Too much noise due to unaligned data accesses.
ifneq ($(findstring -fsanitize=undefined,$(CXXFLAGS)),)
rijndael.o : rijndael.cpp

View File

@ -234,16 +234,12 @@ ifeq ($(IS_NEON),1)
GCM_FLAG += -mfpu=neon
ARIA_FLAG += -mfpu=neon
BLAKE2_FLAG += -mfpu=neon
SIMON_FLAG += -mfpu=neon
SPECK_FLAG += -mfpu=neon
ifeq ($(IS_ANDROID),1)
ifeq ($(findstring -mfloat-abi=softfp,$(CXXFLAGS)),)
NEON_FLAG += -mfloat-abi=softfp
GCM_FLAG += -mfloat-abi=softfp
ARIA_FLAG += -mfloat-abi=softfp
BLAKE2_FLAG += -mfloat-abi=softfp
SIMON_FLAG += -mfloat-abi=softfp
SPECK_FLAG += -mfloat-abi=softfp
endif
endif
endif
@ -256,8 +252,6 @@ ifneq ($(IS_ARMv8),0)
ARIA_FLAG = -march=armv8-a
BLAKE2_FLAG = -march=armv8-a
NEON_FLAG = -march=armv8-a
SIMON_FLAG = -march=armv8-a
SPECK_FLAG = -march=armv8-a
endif
HAVE_CRC := $(shell echo | $(CXX) -x c++ $(CXXFLAGS) -march=armv8-a+crc -dM -E - 2>/dev/null | $(EGREP) -i -c __ARM_FEATURE_CRC32)
ifeq ($(HAVE_CRC),1)
@ -277,13 +271,9 @@ ifneq ($(IS_i686)$(IS_x86_64),00)
ifeq ($(HAVE_SSSE3),1)
ARIA_FLAG = -mssse3
SSSE3_FLAG = -mssse3
SIMON_FLAG = -mssse3
SPECK_FLAG = -mssse3
endif
HAVE_SSE4 = $(shell echo | $(CXX) -x c++ $(CXXFLAGS) -msse4.1 -dM -E - 2>/dev/null | $(EGREP) -i -c __SSE4_1__)
ifeq ($(HAVE_SSE4),1)
SIMON_FLAG = -msse4.1
SPECK_FLAG = -msse4.1
endif
HAVE_SSE4 = $(shell echo | $(CXX) -x c++ $(CXXFLAGS) -msse4.2 -dM -E - 2>/dev/null | $(EGREP) -i -c __SSE4_2__)
ifeq ($(HAVE_SSE4),1)
@ -510,14 +500,6 @@ sha-simd.o : sha-simd.cpp
shacal2-simd.o : shacal2-simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $<
# SSSE3 or NEON available
simon-simd.o : simon-simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SIMON_FLAG) -c) $<
# SSSE3 or NEON available
speck-simd.o : speck-simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SPECK_FLAG) -c) $<
%.o : %.cpp
$(CXX) $(strip $(CXXFLAGS) -c) $<

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -614,18 +614,6 @@ void Benchmark2(double t, double hertz)
BenchMarkByName<SymmetricCipher>("Kalyna-256/CTR", 32, "Kalyna-256(256)/CTR (256-bit key)");
BenchMarkByName<SymmetricCipher>("Kalyna-256/CTR", 64, "Kalyna-256(512)/CTR (512-bit key)");
BenchMarkByName<SymmetricCipher>("Kalyna-512/CTR", 64, "Kalyna-512(512)/CTR (512-bit key)");
BenchMarkByName<SymmetricCipher>("SIMON-64/CTR", 12, "SIMON-64(96)/CTR (96-bit key)");
BenchMarkByName<SymmetricCipher>("SIMON-64/CTR", 16, "SIMON-64(128)/CTR (128-bit key)");
BenchMarkByName<SymmetricCipher>("SIMON-128/CTR", 16, "SIMON-128(128)/CTR (128-bit key)");
BenchMarkByName<SymmetricCipher>("SIMON-128/CTR", 24, "SIMON-128(192)/CTR (192-bit key)");
BenchMarkByName<SymmetricCipher>("SIMON-128/CTR", 32, "SIMON-128(256)/CTR (256-bit key)");
BenchMarkByName<SymmetricCipher>("SPECK-64/CTR", 12, "SPECK-64(96)/CTR (96-bit key)");
BenchMarkByName<SymmetricCipher>("SPECK-64/CTR", 16, "SPECK-64(128)/CTR (128-bit key)");
BenchMarkByName<SymmetricCipher>("SPECK-128/CTR", 16, "SPECK-128(128)/CTR (128-bit key)");
BenchMarkByName<SymmetricCipher>("SPECK-128/CTR", 24, "SPECK-128(192)/CTR (192-bit key)");
BenchMarkByName<SymmetricCipher>("SPECK-128/CTR", 32, "SPECK-128(256)/CTR (256-bit key)");
}
std::cout << "\n<TBODY style=\"background: yellow;\">";

View File

@ -14,8 +14,7 @@
\ref DES_EDE2 "2-key Triple-DES", \ref DES_EDE3 "3-key Triple-DES", \ref DES_XEX3 "DESX",
GOST, IDEA, \ref LR "Luby-Rackoff", Kalyna (128/256/512), MARS, RC2, RC5, RC6, \ref SAFER_K
"SAFER-K", \ref SAFER_SK "SAFER-SK", SEED, Serpent, \ref SHACAL2 "SHACAL-2", SHARK, SKIPJACK,
\ref SIMON128 "SIMON-64 and SIMON-128", \ref SPECK128 "SPECK-64 and SPECK-128", SM4, Square,
TEA, \ref ThreeWay "3-Way", \ref Threefish256 "Threefish (256/512/1024)", Twofish, XTEA
SM4, Square, TEA, \ref ThreeWay "3-Way", \ref Threefish256 "Threefish (256/512/1024)", Twofish, XTEA
<dt>Stream Ciphers<dd>
ChaCha (ChaCha-8/12/20), \ref Panama "Panama-LE", \ref Panama "Panama-BE", Salsa20,
\ref SEAL "SEAL-LE", \ref SEAL "SEAL-BE", WAKE, XSalsa20

View File

@ -288,16 +288,12 @@
<ClCompile Include="shacal2-simd.cpp" />
<ClCompile Include="shark.cpp" />
<ClCompile Include="sharkbox.cpp" />
<ClCompile Include="simon-simd.cpp" />
<ClCompile Include="simon.cpp" />
<ClCompile Include="simple.cpp" />
<ClCompile Include="skipjack.cpp" />
<ClCompile Include="sm3.cpp" />
<ClCompile Include="sm4.cpp" />
<ClCompile Include="socketft.cpp" />
<ClCompile Include="sosemanuk.cpp" />
<ClCompile Include="speck.cpp" />
<ClCompile Include="speck-simd.cpp" />
<ClCompile Include="square.cpp" />
<ClCompile Include="squaretb.cpp" />
<ClCompile Include="sse-simd.cpp" />
@ -478,7 +474,6 @@
<ClInclude Include="shacal2.h" />
<ClInclude Include="shark.h" />
<ClInclude Include="simple.h" />
<ClInclude Include="simon.h" />
<ClInclude Include="siphash.h" />
<ClInclude Include="skipjack.h" />
<ClInclude Include="sm3.h" />
@ -486,7 +481,6 @@
<ClInclude Include="smartptr.h" />
<ClInclude Include="socketft.h" />
<ClInclude Include="sosemanuk.h" />
<ClInclude Include="speck.h" />
<ClInclude Include="square.h" />
<ClInclude Include="stdcpp.h" />
<ClInclude Include="strciphr.h" />
@ -515,4 +509,4 @@
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
</Project>

View File

@ -362,9 +362,6 @@
<ClCompile Include="simple.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="simon.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="skipjack.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -380,12 +377,6 @@
<ClCompile Include="sosemanuk.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="speck.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="speck-simd.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="square.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -455,9 +446,6 @@
<ClCompile Include="zlib.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="simon-simd.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Doxyfile">
@ -831,9 +819,6 @@
<ClInclude Include="simple.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="simon.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="siphash.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -855,9 +840,6 @@
<ClInclude Include="sosemanuk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="speck.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="square.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -939,4 +921,4 @@
<Filter>Miscellaneous</Filter>
</CustomBuild>
</ItemGroup>
</Project>
</Project>

View File

@ -32,8 +32,6 @@
#include "mars.h"
#include "kalyna.h"
#include "threefish.h"
#include "simon.h"
#include "speck.h"
#include "sm4.h"
#include "des.h"
#include "idea.h"
@ -163,19 +161,6 @@ void RegisterFactories2()
RegisterSymmetricCipherDefaultFactories<CTR_Mode<Threefish512> >(); // Benchmarks
RegisterSymmetricCipherDefaultFactories<CTR_Mode<Threefish1024> >(); // Benchmarks
RegisterSymmetricCipherDefaultFactories<ECB_Mode<SIMON64> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CBC_Mode<SIMON64> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<ECB_Mode<SIMON128> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CBC_Mode<SIMON128> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CTR_Mode<SIMON64> >(); // Benchmarks
RegisterSymmetricCipherDefaultFactories<CTR_Mode<SIMON128> >(); // Benchmarks
RegisterSymmetricCipherDefaultFactories<ECB_Mode<SPECK64> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CBC_Mode<SPECK64> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<ECB_Mode<SPECK128> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CBC_Mode<SPECK128> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CTR_Mode<SPECK64> >(); // Benchmarks
RegisterSymmetricCipherDefaultFactories<CTR_Mode<SPECK128> >(); // Benchmarks
RegisterSymmetricCipherDefaultFactories<ECB_Mode<SM4> >(); // Test Vectors
RegisterSymmetricCipherDefaultFactories<CBC_Mode<SM4> >(); // Test Vectors

File diff suppressed because it is too large Load Diff

BIN
simon-speck.zip Normal file

Binary file not shown.

457
simon.cpp
View File

@ -1,457 +0,0 @@
// simon.h - written and placed in the public domain by Jeffrey Walton
#include "pch.h"
#include "config.h"
#include "simon.h"
#include "misc.h"
#include "cpu.h"
// Uncomment for benchmarking C++ against SSE or NEON.
// Do so in both simon.cpp and simon-simd.cpp.
// #undef CRYPTOPP_SSSE3_AVAILABLE
// #undef CRYPTOPP_SSE41_AVAILABLE
// #undef CRYPTOPP_ARM_NEON_AVAILABLE
ANONYMOUS_NAMESPACE_BEGIN
using CryptoPP::word32;
using CryptoPP::word64;
using CryptoPP::rotlConstant;
using CryptoPP::rotrConstant;
/// \brief Round transformation helper
/// \tparam W word type
/// \param v value
template <class W>
inline W f(const W v)
{
return (rotlConstant<1>(v) & rotlConstant<8>(v)) ^ rotlConstant<2>(v);
}
/// \brief Round transformation
/// \tparam W word type
/// \param x value
/// \param y value
/// \param k value
/// \param l value
template <class W>
inline void R2(W& x, W& y, const W k, const W l)
{
y ^= f(x); y ^= k;
x ^= f(y); x ^= l;
}
/// \brief Forward transformation
/// \tparam W word type
/// \tparam R number of rounds
/// \param c output array
/// \param p input array
/// \param k subkey array
template <class W, unsigned int R>
inline void SIMON_Encrypt(W c[2], const W p[2], const W k[R])
{
c[0]=p[0]; c[1]=p[1];
for (int i = 0; i < static_cast<int>(R-1); i += 2)
R2(c[0], c[1], k[i], k[i + 1]);
if (R & 1)
{
c[1] ^= f(c[0]); c[1] ^= k[R-1];
W t = c[0]; c[0] = c[1]; c[1] = t;
}
}
/// \brief Reverse transformation
/// \tparam W word type
/// \tparam R number of rounds
/// \param p output array
/// \param c input array
/// \param k subkey array
template <class W, unsigned int R>
inline void SIMON_Decrypt(W p[2], const W c[2], const W k[R])
{
p[0]=c[0]; p[1]=c[1];
unsigned int rounds = R;
if (R & 1)
{
const W t = p[1]; p[1] = p[0]; p[0] = t;
p[1] ^= k[rounds - 1]; p[1] ^= f(p[0]);
rounds--;
}
for (int i = static_cast<int>(rounds - 2); i >= 0; i -= 2)
R2(p[1], p[0], k[i + 1], k[i]);
}
/// \brief Subkey generation function
/// \details Used for SIMON-64 with 96-bit key and 42 rounds. A template was
/// not worthwhile because all instantiations would need specialization.
/// \param key empty subkey array
/// \param k user key array
inline void SIMON64_ExpandKey_42R3K(word32 key[42], const word32 k[3])
{
const word32 c = 0xfffffffc;
word64 z = W64LIT(0x7369f885192c0ef5);
key[0] = k[2]; key[1] = k[1]; key[2] = k[0];
for (size_t i = 3; i<42; ++i)
{
key[i] = c ^ (z & 1) ^ key[i - 3] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
z >>= 1;
}
}
/// \brief Subkey generation function
/// \details Used for SIMON-64 with 128-bit key and 44 rounds. A template was
/// not worthwhile because all instantiations would need specialization.
/// \param key empty subkey array
/// \param k user key array
inline void SIMON64_ExpandKey_44R4K(word32 key[44], const word32 k[4])
{
const word32 c = 0xfffffffc;
word64 z = W64LIT(0xfc2ce51207a635db);
key[0] = k[3]; key[1] = k[2]; key[2] = k[1]; key[3] = k[0];
for (size_t i = 4; i<44; ++i)
{
key[i] = c ^ (z & 1) ^ key[i - 4] ^ rotrConstant<3>(key[i - 1]) ^ key[i - 3] ^ rotrConstant<4>(key[i - 1]) ^ rotrConstant<1>(key[i - 3]);
z >>= 1;
}
}
/// \brief Subkey generation function
/// \details Used for SIMON-128 with 128-bit key and 68 rounds. A template was
/// not worthwhile because all instantiations would need specialization.
/// \param key empty subkey array
/// \param k user key array
inline void SIMON128_ExpandKey_68R2K(word64 key[68], const word64 k[2])
{
const word64 c = W64LIT(0xfffffffffffffffc);
word64 z = W64LIT(0x7369f885192c0ef5);
key[0] = k[1]; key[1] = k[0];
for (size_t i=2; i<66; ++i)
{
key[i] = c ^ (z & 1) ^ key[i - 2] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
z>>=1;
}
key[66] = c ^ 1 ^ key[64] ^ rotrConstant<3>(key[65]) ^ rotrConstant<4>(key[65]);
key[67] = c^key[65] ^ rotrConstant<3>(key[66]) ^ rotrConstant<4>(key[66]);
}
/// \brief Subkey generation function
/// \details Used for SIMON-128 with 192-bit key and 69 rounds. A template was
/// not worthwhile because all instantiations would need specialization.
/// \param key empty subkey array
/// \param k user key array
inline void SIMON128_ExpandKey_69R3K(word64 key[69], const word64 k[3])
{
const word64 c = W64LIT(0xfffffffffffffffc);
word64 z = W64LIT(0xfc2ce51207a635db);
key[0]=k[2]; key[1]=k[1]; key[2]=k[0];
for (size_t i=3; i<67; ++i)
{
key[i] = c ^ (z & 1) ^ key[i - 3] ^ rotrConstant<3>(key[i - 1]) ^ rotrConstant<4>(key[i - 1]);
z>>=1;
}
key[67] = c^key[64] ^ rotrConstant<3>(key[66]) ^ rotrConstant<4>(key[66]);
key[68] = c ^ 1 ^ key[65] ^ rotrConstant<3>(key[67]) ^ rotrConstant<4>(key[67]);
}
/// \brief Subkey generation function
/// \details Used for SIMON-128 with 256-bit key and 72 rounds. A template was
/// not worthwhile because all instantiations would need specialization.
/// \param key empty subkey array
/// \param k user key array
inline void SIMON128_ExpandKey_72R4K(word64 key[72], const word64 k[4])
{
const word64 c = W64LIT(0xfffffffffffffffc);
word64 z = W64LIT(0xfdc94c3a046d678b);
key[0]=k[3]; key[1]=k[2]; key[2]=k[1]; key[3]=k[0];
for (size_t i=4; i<68; ++i)
{
key[i] = c ^ (z & 1) ^ key[i - 4] ^ rotrConstant<3>(key[i - 1]) ^ key[i - 3] ^ rotrConstant<4>(key[i - 1]) ^ rotrConstant<1>(key[i - 3]);
z>>=1;
}
key[68] = c^key[64] ^ rotrConstant<3>(key[67]) ^ key[65] ^ rotrConstant<4>(key[67]) ^ rotrConstant<1>(key[65]);
key[69] = c ^ 1 ^ key[65] ^ rotrConstant<3>(key[68]) ^ key[66] ^ rotrConstant<4>(key[68]) ^ rotrConstant<1>(key[66]);
key[70] = c^key[66] ^ rotrConstant<3>(key[69]) ^ key[67] ^ rotrConstant<4>(key[69]) ^ rotrConstant<1>(key[67]);
key[71] = c^key[67] ^ rotrConstant<3>(key[70]) ^ key[68] ^ rotrConstant<4>(key[70]) ^ rotrConstant<1>(key[68]);
}
ANONYMOUS_NAMESPACE_END
///////////////////////////////////////////////////////////
NAMESPACE_BEGIN(CryptoPP)
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
extern size_t SIMON64_Enc_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SIMON64_Dec_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
#endif
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
extern size_t SIMON128_Enc_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SIMON128_Dec_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
#endif
#if defined(CRYPTOPP_SSE41_AVAILABLE)
extern size_t SIMON64_Enc_AdvancedProcessBlocks_SSE41(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SIMON64_Dec_AdvancedProcessBlocks_SSE41(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
#endif
#if defined(CRYPTOPP_SSSE3_AVAILABLE)
extern size_t SIMON128_Enc_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SIMON128_Dec_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
#endif
void SIMON64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
{
CRYPTOPP_ASSERT(keyLength == 12 || keyLength == 16);
CRYPTOPP_UNUSED(params);
// Building the key schedule table requires {3,4} words workspace.
// Encrypting and decrypting requires 4 words workspace.
m_kwords = keyLength/sizeof(word32);
m_wspace.New(STDMAX(m_kwords,4U));
GetUserKey(BIG_ENDIAN_ORDER, m_wspace.begin(), m_kwords, userKey, keyLength);
switch (m_kwords)
{
case 3:
m_rkeys.New(42);
m_rounds = 42;
SIMON64_ExpandKey_42R3K(m_rkeys, m_wspace);
break;
case 4:
m_rkeys.New(44);
m_rounds = 44;
SIMON64_ExpandKey_44R4K(m_rkeys, m_wspace);
break;
default:
CRYPTOPP_ASSERT(0);;
}
}
void SIMON64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef GetBlock<word32, BigEndian, false> InBlock;
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
switch (m_rounds)
{
case 42:
SIMON_Encrypt<word32, 42>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 44:
SIMON_Encrypt<word32, 44>(m_wspace+2, m_wspace+0, m_rkeys);
break;
default:
CRYPTOPP_ASSERT(0);;
}
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef PutBlock<word32, BigEndian, false> OutBlock;
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
}
void SIMON64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef GetBlock<word32, BigEndian, false> InBlock;
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
switch (m_rounds)
{
case 42:
SIMON_Decrypt<word32, 42>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 44:
SIMON_Decrypt<word32, 44>(m_wspace+2, m_wspace+0, m_rkeys);
break;
default:
CRYPTOPP_ASSERT(0);;
}
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef PutBlock<word32, BigEndian, false> OutBlock;
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
}
///////////////////////////////////////////////////////////
void SIMON128::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
{
CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32);
CRYPTOPP_UNUSED(params);
// Building the key schedule table requires {2,3,4} words workspace.
// Encrypting and decrypting requires 4 words workspace.
m_kwords = keyLength/sizeof(word64);
m_wspace.New(STDMAX(m_kwords,4U));
GetUserKey(BIG_ENDIAN_ORDER, m_wspace.begin(), m_kwords, userKey, keyLength);
switch (m_kwords)
{
case 2:
m_rkeys.New(68);
m_rounds = 68;
SIMON128_ExpandKey_68R2K(m_rkeys, m_wspace);
break;
case 3:
m_rkeys.New(69);
m_rounds = 69;
SIMON128_ExpandKey_69R3K(m_rkeys, m_wspace);
break;
case 4:
m_rkeys.New(72);
m_rounds = 72;
SIMON128_ExpandKey_72R4K(m_rkeys, m_wspace);
break;
default:
CRYPTOPP_ASSERT(0);;
}
}
void SIMON128::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef GetBlock<word64, BigEndian, false> InBlock;
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
switch (m_rounds)
{
case 68:
SIMON_Encrypt<word64, 68>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 69:
SIMON_Encrypt<word64, 69>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 72:
SIMON_Encrypt<word64, 72>(m_wspace+2, m_wspace+0, m_rkeys);
break;
default:
CRYPTOPP_ASSERT(0);;
}
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef PutBlock<word64, BigEndian, false> OutBlock;
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
}
void SIMON128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef GetBlock<word64, BigEndian, false> InBlock;
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
switch (m_rounds)
{
case 68:
SIMON_Decrypt<word64, 68>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 69:
SIMON_Decrypt<word64, 69>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 72:
SIMON_Decrypt<word64, 72>(m_wspace+2, m_wspace+0, m_rkeys);
break;
default:
CRYPTOPP_ASSERT(0);;
}
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef PutBlock<word64, BigEndian, false> OutBlock;
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
}
#if defined(CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS)
size_t SIMON64::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
#if defined(CRYPTOPP_SSE41_AVAILABLE)
if (HasSSE41())
return SIMON64_Enc_AdvancedProcessBlocks_SSE41(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
if (HasNEON())
return SIMON64_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
size_t SIMON64::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
#if defined(CRYPTOPP_SSE41_AVAILABLE)
if (HasSSE41())
return SIMON64_Dec_AdvancedProcessBlocks_SSE41(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
if (HasNEON())
return SIMON64_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
#endif // CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS
#if defined(CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS)
size_t SIMON128::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
#if defined(CRYPTOPP_SSSE3_AVAILABLE)
if (HasSSSE3())
return SIMON128_Enc_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
if (HasNEON())
return SIMON128_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
size_t SIMON128::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
#if defined(CRYPTOPP_SSSE3_AVAILABLE)
if (HasSSSE3())
return SIMON128_Dec_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
if (HasNEON())
return SIMON128_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
#endif // CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS
NAMESPACE_END

179
simon.h
View File

@ -1,179 +0,0 @@
// simon.h - written and placed in the public domain by Jeffrey Walton
/// \file simon.h
/// \brief Classes for the Simon block cipher
/// \details Simon is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith,
/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers.
/// \sa <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SPECK Families of
/// Lightweight Block Ciphers</A> and <A HREF="http://iadgov.github.io/simon-speck/">
/// The Simon and Speck GitHub</A>
/// \since Crypto++ 6.0
#ifndef CRYPTOPP_SIMON_H
#define CRYPTOPP_SIMON_H
#include "config.h"
#include "seckey.h"
#include "secblock.h"
#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64
# define CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS 1
#endif
#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64
# define CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS 1
#endif
NAMESPACE_BEGIN(CryptoPP)
/// \brief SIMON block cipher information
/// \tparam L block size of the cipher, in bytes
/// \tparam D default key length, in bytes
/// \tparam N minimum key length, in bytes
/// \tparam M maximum key length, in bytes
/// \since Crypto++ 6.0
template <unsigned int L, unsigned int D, unsigned int N, unsigned int M>
struct SIMON_Info : public FixedBlockSize<L>, VariableKeyLength<D, N, M>
{
static const std::string StaticAlgorithmName()
{
// Format is Cipher-Blocksize(Keylength)
return "SIMON-" + IntToString(L*8);
}
};
/// \brief SIMON block cipher base class
/// \tparam W the word type
/// \details User code should use SIMON64 or SIMON128
/// \sa SIMON64, SIMON128, <a href="http://www.cryptopp.com/wiki/SIMON">SIMON</a> on the Crypto++ wiki
/// \since Crypto++ 6.0
template <class W>
struct SIMON_Base
{
virtual ~SIMON_Base() {}
SIMON_Base() : m_kwords(0), m_rounds(0) {}
typedef SecBlock<W, AllocatorWithCleanup<W, true> > AlignedSecBlock;
mutable AlignedSecBlock m_wspace; // workspace
AlignedSecBlock m_rkeys; // round keys
unsigned int m_kwords; // number of key words
unsigned int m_rounds; // number of rounds
};
/// \brief SIMON 64-bit block cipher
/// \details Simon is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith,
/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers.
/// \details SIMON64 provides 64-bit block size. The valid key sizes are 96-bit and 128-bit.
/// \sa SIMON64, SIMON128, <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SIMON
/// Families of Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/">
/// The Simon and Speck GitHub</A>, <a href="http://www.cryptopp.com/wiki/SIMON">SIMON</a> on the
/// Crypto++ wiki
/// \since Crypto++ 6.0
class CRYPTOPP_NO_VTABLE SIMON64 : public SIMON_Info<8, 12, 12, 16>, public BlockCipherDocumentation
{
public:
/// \brief SIMON block cipher transformation functions
/// \details Provides implementation common to encryption and decryption
/// \since Crypto++ 6.0
class CRYPTOPP_NO_VTABLE Base : protected SIMON_Base<word32>, public BlockCipherImpl<SIMON_Info<8, 12, 12, 16> >
{
public:
std::string AlgorithmName() const {
return StaticAlgorithmName() + (m_kwords == 0 ? "" :
"(" + IntToString(m_kwords*sizeof(word32)*8) + ")");
}
protected:
void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params);
};
/// \brief Provides implementation for encryption transformation
/// \details Enc provides implementation for encryption transformation. All key
/// 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;
#if CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS
size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
#endif
};
/// \brief Provides implementation for encryption transformation
/// \details Dec provides implementation for decryption transformation. All key
/// 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;
#if CRYPTOPP_SIMON64_ADVANCED_PROCESS_BLOCKS
size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
#endif
};
typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
};
/// \brief SIMON 128-bit block cipher
/// \details Simon is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith,
/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers.
/// \details SIMON128 provides 128-bit block size. The valid key sizes are 128-bit, 192-bit and 256-bit.
/// \sa SIMON64, SIMON128, <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SIMON
/// Families of Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/">
/// The Simon and Speck GitHub</A>, <a href="http://www.cryptopp.com/wiki/SIMON">SIMON</a> on the
/// Crypto++ wiki
/// \since Crypto++ 6.0
class CRYPTOPP_NO_VTABLE SIMON128 : public SIMON_Info<16, 16, 16, 32>, public BlockCipherDocumentation
{
public:
/// \brief SIMON block cipher transformation functions
/// \details Provides implementation common to encryption and decryption
/// \since Crypto++ 6.0
class CRYPTOPP_NO_VTABLE Base : protected SIMON_Base<word64>, public BlockCipherImpl<SIMON_Info<16, 16, 16, 32> >
{
public:
std::string AlgorithmName() const {
return StaticAlgorithmName() + (m_kwords == 0 ? "" :
"(" + IntToString(m_kwords*sizeof(word64)*8) + ")");
}
protected:
void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params);
};
/// \brief Provides implementation for encryption transformation
/// \details Enc provides implementation for encryption transformation. All key
/// 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;
#if CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS
size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
#endif
};
/// \brief Provides implementation for encryption transformation
/// \details Dec provides implementation for decryption transformation. All key
/// 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;
#if CRYPTOPP_SIMON128_ADVANCED_PROCESS_BLOCKS
size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
#endif
};
typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
};
NAMESPACE_END
#endif // CRYPTOPP_SIMON_H

File diff suppressed because it is too large Load Diff

432
speck.cpp
View File

@ -1,432 +0,0 @@
// speck.cpp - written and placed in the public domain by Jeffrey Walton
#include "pch.h"
#include "config.h"
#include "speck.h"
#include "misc.h"
#include "cpu.h"
// Uncomment for benchmarking C++ against SSE or NEON.
// Do so in both speck.cpp and speck-simd.cpp.
// #undef CRYPTOPP_SSSE3_AVAILABLE
// #undef CRYPTOPP_SSE41_AVAILABLE
// #undef CRYPTOPP_ARM_NEON_AVAILABLE
ANONYMOUS_NAMESPACE_BEGIN
using CryptoPP::word32;
using CryptoPP::word64;
using CryptoPP::rotlConstant;
using CryptoPP::rotrConstant;
/// \brief Forward round transformation
/// \tparam W word type
/// \details TF83() is the forward round transformation using a=8 and b=3 rotations.
/// The initial test implementation provided template parameters, but they were
/// removed because SPECK32 using a=7 and b=2 was not on the road map. The
/// additional template parameters also made calling SPECK_Encrypt and SPECK_Decrypt
/// kind of messy.
template <class W>
inline void TF83(W& x, W& y, const W k)
{
x = rotrConstant<8>(x);
x += y; x ^= k;
y = rotlConstant<3>(y);
y ^= x;
}
/// \brief Reverse round transformation
/// \tparam W word type
/// \details TR83() is the reverse round transformation using a=8 and b=3 rotations.
/// The initial test implementation provided template parameters, but they were
/// removed because SPECK32 using a=7 and b=2 was not on the road map. The
/// additional template parameters also made calling SPECK_Encrypt and SPECK_Decrypt
/// kind of messy.
template <class W>
inline void TR83(W& x, W& y, const W k)
{
y ^= x;
y = rotrConstant<3>(y);
x ^= k; x -= y;
x = rotlConstant<8>(x);
}
/// \brief Forward transformation
/// \tparam W word type
/// \tparam R number of rounds
/// \param c output array
/// \param p input array
/// \param k subkey array
template <class W, unsigned int R>
inline void SPECK_Encrypt(W c[2], const W p[2], const W k[R])
{
c[0]=p[0]; c[1]=p[1];
// Don't unroll this loop. Things slow down.
for (int i = 0; i < static_cast<int>(R); ++i)
TF83(c[0], c[1], k[i]);
}
/// \brief Reverse transformation
/// \tparam W word type
/// \tparam R number of rounds
/// \param p output array
/// \param c input array
/// \param k subkey array
template <class W, unsigned int R>
inline void SPECK_Decrypt(W p[2], const W c[2], const W k[R])
{
p[0]=c[0]; p[1]=c[1];
// Don't unroll this loop. Things slow down.
for (int i = static_cast<int>(R-1); i >= 0; --i)
TR83(p[0], p[1], k[i]);
}
/// \brief Subkey generation function
/// \details Used when the user key consists of 2 words
/// \tparam W word type
/// \tparam R number of rounds
/// \param key empty subkey array
/// \param k user key array
template <class W, unsigned int R>
inline void SPECK_ExpandKey_2W(W key[R], const W k[2])
{
CRYPTOPP_ASSERT(R==32);
W i=0, B=k[0], A=k[1];
while (i<R-1)
{
key[i]=A; TF83(B, A, i);
i++;
}
key[R-1]=A;
}
/// \brief Subkey generation function
/// \details Used when the user key consists of 3 words
/// \tparam W word type
/// \tparam R number of rounds
/// \param key empty subkey array
/// \param k user key array
template <class W, unsigned int R>
inline void SPECK_ExpandKey_3W(W key[R], const W k[3])
{
CRYPTOPP_ASSERT(R==33 || R==26);
W i=0, C=k[0], B=k[1], A=k[2];
unsigned int blocks = R/2;
while (blocks--)
{
key[i+0]=A; TF83(B, A, i+0);
key[i+1]=A; TF83(C, A, i+1);
i+=2;
}
// The constexpr residue should allow the optimizer to remove unneeded statements
if(R%2 == 1)
{
key[R-1]=A;
}
}
/// \brief Subkey generation function
/// \details Used when the user key consists of 4 words
/// \tparam W word type
/// \tparam R number of rounds
/// \param key empty subkey array
/// \param k user key array
template <class W, unsigned int R>
inline void SPECK_ExpandKey_4W(W key[R], const W k[4])
{
CRYPTOPP_ASSERT(R==34 || R==27);
W i=0, D=k[0], C=k[1], B=k[2], A=k[3];
unsigned int blocks = R/3;
while (blocks--)
{
key[i+0]=A; TF83(B, A, i+0);
key[i+1]=A; TF83(C, A, i+1);
key[i+2]=A; TF83(D, A, i+2);
i+=3;
}
// The constexpr residue should allow the optimizer to remove unneeded statements
if(R%3 == 1)
{
key[R-1]=A;
}
else if(R%3 == 2)
{
key[R-2]=A; TF83(B, A, W(R-2));
key[R-1]=A;
}
}
ANONYMOUS_NAMESPACE_END
///////////////////////////////////////////////////////////
NAMESPACE_BEGIN(CryptoPP)
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
extern size_t SPECK64_Enc_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SPECK64_Dec_AdvancedProcessBlocks_NEON(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SPECK128_Enc_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SPECK128_Dec_AdvancedProcessBlocks_NEON(const word64* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
#endif
#if defined(CRYPTOPP_SSE41_AVAILABLE)
extern size_t SPECK64_Enc_AdvancedProcessBlocks_SSE41(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SPECK64_Dec_AdvancedProcessBlocks_SSE41(const word32* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
#endif
#if defined(CRYPTOPP_SSSE3_AVAILABLE)
extern size_t SPECK128_Enc_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
extern size_t SPECK128_Dec_AdvancedProcessBlocks_SSSE3(const word64* subKeys, size_t rounds,
const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags);
#endif
void SPECK64::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
{
CRYPTOPP_ASSERT(keyLength == 12 || keyLength == 16);
CRYPTOPP_UNUSED(params);
// Building the key schedule table requires {3,4} words workspace.
// Encrypting and decrypting requires 4 words workspace.
m_kwords = keyLength/sizeof(word32);
m_wspace.New(STDMAX(m_kwords,4U));
GetUserKey(BIG_ENDIAN_ORDER, m_wspace.begin(), m_kwords, userKey, keyLength);
switch (m_kwords)
{
case 3:
m_rkeys.New(26);
m_rounds = 26;
SPECK_ExpandKey_3W<word32, 26>(m_rkeys, m_wspace);
break;
case 4:
m_rkeys.New(27);
m_rounds = 27;
SPECK_ExpandKey_4W<word32, 27>(m_rkeys, m_wspace);
break;
default:
CRYPTOPP_ASSERT(0);;
}
}
void SPECK64::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef GetBlock<word32, BigEndian, false> InBlock;
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
switch (m_rounds)
{
case 26:
SPECK_Encrypt<word32, 26>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 27:
SPECK_Encrypt<word32, 27>(m_wspace+2, m_wspace+0, m_rkeys);
break;
default:
CRYPTOPP_ASSERT(0);;
}
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef PutBlock<word32, BigEndian, false> OutBlock;
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
}
void SPECK64::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef GetBlock<word32, BigEndian, false> InBlock;
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
switch (m_rounds)
{
case 26:
SPECK_Decrypt<word32, 26>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 27:
SPECK_Decrypt<word32, 27>(m_wspace+2, m_wspace+0, m_rkeys);
break;
default:
CRYPTOPP_ASSERT(0);;
}
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef PutBlock<word32, BigEndian, false> OutBlock;
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
}
///////////////////////////////////////////////////////////
void SPECK128::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params)
{
CRYPTOPP_ASSERT(keyLength == 16 || keyLength == 24 || keyLength == 32);
CRYPTOPP_UNUSED(params);
// Building the key schedule table requires {2,3,4} words workspace.
// Encrypting and decrypting requires 4 words workspace.
m_kwords = keyLength/sizeof(word64);
m_wspace.New(STDMAX(m_kwords,4U));
GetUserKey(BIG_ENDIAN_ORDER, m_wspace.begin(), m_kwords, userKey, keyLength);
switch (m_kwords)
{
case 2:
m_rkeys.New(32);
m_rounds = 32;
SPECK_ExpandKey_2W<word64, 32>(m_rkeys, m_wspace);
break;
case 3:
m_rkeys.New(33);
m_rounds = 33;
SPECK_ExpandKey_3W<word64, 33>(m_rkeys, m_wspace);
break;
case 4:
m_rkeys.New(34);
m_rounds = 34;
SPECK_ExpandKey_4W<word64, 34>(m_rkeys, m_wspace);
break;
default:
CRYPTOPP_ASSERT(0);;
}
}
void SPECK128::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef GetBlock<word64, BigEndian, false> InBlock;
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
switch (m_rounds)
{
case 32:
SPECK_Encrypt<word64, 32>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 33:
SPECK_Encrypt<word64, 33>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 34:
SPECK_Encrypt<word64, 34>(m_wspace+2, m_wspace+0, m_rkeys);
break;
default:
CRYPTOPP_ASSERT(0);;
}
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef PutBlock<word64, BigEndian, false> OutBlock;
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
}
void SPECK128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef GetBlock<word64, BigEndian, false> InBlock;
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]);
switch (m_rounds)
{
case 32:
SPECK_Decrypt<word64, 32>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 33:
SPECK_Decrypt<word64, 33>(m_wspace+2, m_wspace+0, m_rkeys);
break;
case 34:
SPECK_Decrypt<word64, 34>(m_wspace+2, m_wspace+0, m_rkeys);
break;
default:
CRYPTOPP_ASSERT(0);;
}
// Reverse bytes on LittleEndian; align pointer on BigEndian
typedef PutBlock<word64, BigEndian, false> OutBlock;
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[2])(m_wspace[3]);
}
#if defined(CRYPTOPP_SPECK64_ADVANCED_PROCESS_BLOCKS)
size_t SPECK64::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
#if defined(CRYPTOPP_SSE41_AVAILABLE)
if (HasSSE41())
return SPECK64_Enc_AdvancedProcessBlocks_SSE41(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
if (HasNEON())
return SPECK64_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
size_t SPECK64::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
#if defined(CRYPTOPP_SSE41_AVAILABLE)
if (HasSSE41())
return SPECK64_Dec_AdvancedProcessBlocks_SSE41(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
if (HasNEON())
return SPECK64_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
#endif // CRYPTOPP_SPECK64_ADVANCED_PROCESS_BLOCKS
#if defined(CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS)
size_t SPECK128::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
#if defined(CRYPTOPP_SSSE3_AVAILABLE)
if (HasSSSE3())
return SPECK128_Enc_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
if (HasNEON())
return SPECK128_Enc_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
size_t SPECK128::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks,
byte *outBlocks, size_t length, word32 flags) const
{
#if defined(CRYPTOPP_SSSE3_AVAILABLE)
if (HasSSSE3())
return SPECK128_Dec_AdvancedProcessBlocks_SSSE3(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
#if defined(CRYPTOPP_ARM_NEON_AVAILABLE)
if (HasNEON())
return SPECK128_Dec_AdvancedProcessBlocks_NEON(m_rkeys, (size_t)m_rounds,
inBlocks, xorBlocks, outBlocks, length, flags);
#endif
return BlockTransformation::AdvancedProcessBlocks(inBlocks, xorBlocks, outBlocks, length, flags);
}
#endif // CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS
NAMESPACE_END

179
speck.h
View File

@ -1,179 +0,0 @@
// speck.h - written and placed in the public domain by Jeffrey Walton
/// \file speck.h
/// \brief Classes for the Speck block cipher
/// \details Speck is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith,
/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers.
/// \sa <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SPECK Families of
/// Lightweight Block Ciphers</A> and <A HREF="http://iadgov.github.io/simon-speck/">
/// The Simon and Speck GitHub</A>
/// \since Crypto++ 6.0
#ifndef CRYPTOPP_SPECK_H
#define CRYPTOPP_SPECK_H
#include "config.h"
#include "seckey.h"
#include "secblock.h"
#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64
# define CRYPTOPP_SPECK64_ADVANCED_PROCESS_BLOCKS 1
#endif
#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64
# define CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS 1
#endif
NAMESPACE_BEGIN(CryptoPP)
/// \brief SPECK block cipher information
/// \tparam L block size of the cipher, in bytes
/// \tparam D default key length, in bytes
/// \tparam N minimum key length, in bytes
/// \tparam M maximum key length, in bytes
/// \since Crypto++ 6.0
template <unsigned int L, unsigned int D, unsigned int N, unsigned int M>
struct SPECK_Info : public FixedBlockSize<L>, VariableKeyLength<D, N, M>
{
static const std::string StaticAlgorithmName()
{
// Format is Cipher-Blocksize(Keylength)
return "SPECK-" + IntToString(L*8);
}
};
/// \brief SPECK block cipher base class
/// \tparam W the word type
/// \details User code should use SPECK64 or SPECK128
/// \sa SPECK64, SPECK128, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a>
/// \since Crypto++ 6.0
template <class W>
struct SPECK_Base
{
virtual ~SPECK_Base() {}
SPECK_Base() : m_kwords(0), m_rounds(0) {}
typedef SecBlock<W, AllocatorWithCleanup<W, true> > AlignedSecBlock;
mutable AlignedSecBlock m_wspace; // workspace
AlignedSecBlock m_rkeys; // round keys
unsigned int m_kwords; // number of key words
unsigned int m_rounds; // number of rounds
};
/// \brief SPECK 64-bit block cipher
/// \details Speck is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith,
/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers.
/// \details SPECK64 provides 64-bit block size. The valid key sizes are 96-bit and 128-bit.
/// \sa SPECK64, SPECK128, <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SPECK
/// Families of Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/">
/// The Simon and Speck GitHub</A>, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a> on the
/// Crypto++ wiki
/// \since Crypto++ 6.0
class CRYPTOPP_NO_VTABLE SPECK64 : public SPECK_Info<8, 12, 12, 16>, public BlockCipherDocumentation
{
public:
/// \brief SPECK block cipher transformation functions
/// \details Provides implementation common to encryption and decryption
/// \since Crypto++ 6.0
class CRYPTOPP_NO_VTABLE Base : protected SPECK_Base<word32>, public BlockCipherImpl<SPECK_Info<8, 12, 12, 16> >
{
public:
std::string AlgorithmName() const {
return StaticAlgorithmName() + (m_kwords == 0 ? "" :
"(" + IntToString(m_kwords*sizeof(word32)*8) + ")");
}
protected:
void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params);
};
/// \brief Provides implementation for encryption transformation
/// \details Enc provides implementation for encryption transformation. All key
/// 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;
#if CRYPTOPP_SPECK64_ADVANCED_PROCESS_BLOCKS
size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
#endif
};
/// \brief Provides implementation for encryption transformation
/// \details Dec provides implementation for decryption transformation. All key
/// 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;
#if CRYPTOPP_SPECK64_ADVANCED_PROCESS_BLOCKS
size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
#endif
};
typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
};
/// \brief SPECK 128-bit block cipher
/// \details Speck is a block cipher designed by Ray Beaulieu, Douglas Shors, Jason Smith,
/// Stefan Treatman-Clark, Bryan Weeks and Louis Wingers.
/// \details SPECK128 provides 128-bit block size. The valid key sizes are 128-bit, 192-bit and 256-bit.
/// \sa SPECK64, SPECK128, <A HREF="http://eprint.iacr.org/2013/404">The SIMON and SPECK
/// Families of Lightweight Block Ciphers</A>, <A HREF="http://iadgov.github.io/simon-speck/">
/// The Simon and Speck GitHub</A>, <a href="http://www.cryptopp.com/wiki/SPECK">SPECK</a> on the
/// Crypto++ wiki
/// \since Crypto++ 6.0
class CRYPTOPP_NO_VTABLE SPECK128 : public SPECK_Info<16, 16, 16, 32>, public BlockCipherDocumentation
{
public:
/// \brief SPECK block cipher transformation functions
/// \details Provides implementation common to encryption and decryption
/// \since Crypto++ 6.0
class CRYPTOPP_NO_VTABLE Base : protected SPECK_Base<word64>, public BlockCipherImpl<SPECK_Info<16, 16, 16, 32> >
{
public:
std::string AlgorithmName() const {
return StaticAlgorithmName() + (m_kwords == 0 ? "" :
"(" + IntToString(m_kwords*sizeof(word64)*8) + ")");
}
protected:
void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params);
};
/// \brief Provides implementation for encryption transformation
/// \details Enc provides implementation for encryption transformation. All key
/// 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;
#if CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS
size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
#endif
};
/// \brief Provides implementation for encryption transformation
/// \details Dec provides implementation for decryption transformation. All key
/// 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;
#if CRYPTOPP_SPECK128_ADVANCED_PROCESS_BLOCKS
size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const;
#endif
};
typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
};
NAMESPACE_END
#endif // CRYPTOPP_SPECK_H

View File

@ -175,8 +175,6 @@ bool ValidateAll(bool thorough)
pass=RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/seed.txt") && pass;
pass=RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/threefish.txt") && pass;
pass=RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/kalyna.txt") && pass;
pass=RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/simon.txt") && pass;
pass=RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/speck.txt") && pass;
pass=RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/sm4.txt") && pass;
pass=ValidateVMAC() && pass;
pass=ValidateCCM() && pass;