mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2025-02-14 18:21:13 +00:00
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:
parent
541caa3978
commit
15b14cc618
@ -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
|
||||
|
28
GNUmakefile
28
GNUmakefile
@ -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
|
||||
|
@ -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
12
bench1.cpp
12
bench1.cpp
@ -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;\">";
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
15
regtest2.cpp
15
regtest2.cpp
@ -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
|
||||
|
1227
simon-simd.cpp
1227
simon-simd.cpp
File diff suppressed because it is too large
Load Diff
BIN
simon-speck.zip
Normal file
BIN
simon-speck.zip
Normal file
Binary file not shown.
457
simon.cpp
457
simon.cpp
@ -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 ¶ms)
|
||||
{
|
||||
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 ¶ms)
|
||||
{
|
||||
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
179
simon.h
@ -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 ¶ms);
|
||||
};
|
||||
|
||||
/// \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 ¶ms);
|
||||
};
|
||||
|
||||
/// \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
|
1119
speck-simd.cpp
1119
speck-simd.cpp
File diff suppressed because it is too large
Load Diff
432
speck.cpp
432
speck.cpp
@ -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 ¶ms)
|
||||
{
|
||||
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 ¶ms)
|
||||
{
|
||||
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
179
speck.h
@ -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 ¶ms);
|
||||
};
|
||||
|
||||
/// \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 ¶ms);
|
||||
};
|
||||
|
||||
/// \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
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user