From 15b14cc6189084e4b4ef1930087a56bddd5a8aee Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Wed, 14 Feb 2018 04:06:16 -0500 Subject: [PATCH] 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... --- Filelist.txt | 8 - GNUmakefile | 28 - GNUmakefile-cross | 18 - TestVectors/simon.txt | 1119 ---------------------------------- TestVectors/speck.txt | 1056 -------------------------------- bench1.cpp | 12 - cryptlib.h | 3 +- cryptlib.vcxproj | 8 +- cryptlib.vcxproj.filters | 20 +- regtest2.cpp | 15 - simon-simd.cpp | 1227 -------------------------------------- simon-speck.zip | Bin 0 -> 87474 bytes simon.cpp | 457 -------------- simon.h | 179 ------ speck-simd.cpp | 1119 ---------------------------------- speck.cpp | 432 -------------- speck.h | 179 ------ validat1.cpp | 2 - 18 files changed, 3 insertions(+), 5879 deletions(-) delete mode 100644 TestVectors/simon.txt delete mode 100644 TestVectors/speck.txt delete mode 100644 simon-simd.cpp create mode 100644 simon-speck.zip delete mode 100644 simon.cpp delete mode 100644 simon.h delete mode 100644 speck-simd.cpp delete mode 100644 speck.cpp delete mode 100644 speck.h diff --git a/Filelist.txt b/Filelist.txt index b679a6cf..24842d31 100644 --- a/Filelist.txt +++ b/Filelist.txt @@ -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 diff --git a/GNUmakefile b/GNUmakefile index 7de31b00..6fadc15f 100755 --- a/GNUmakefile +++ b/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 diff --git a/GNUmakefile-cross b/GNUmakefile-cross index 79cdf31f..ff5d4bc3 100755 --- a/GNUmakefile-cross +++ b/GNUmakefile-cross @@ -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) $< diff --git a/TestVectors/simon.txt b/TestVectors/simon.txt deleted file mode 100644 index 60b8889f..00000000 --- a/TestVectors/simon.txt +++ /dev/null @@ -1,1119 +0,0 @@ -AlgorithmType: SymmetricCipher -Name: SIMON-64/ECB -# -Source: Simon and Speck paper, Appendix B -Comment: Simon64/96 -Key: 13121110 0b0a0908 03020100 -Plaintext: 6f722067 6e696c63 -Ciphertext: 5ca2e27f 111a8fc8 -Test: Encrypt -# -Source: modified simon6496 reference implementation -Comment: Simon-64/96 -Key: 90513b78 3b7ba1cb dea9437c -Plaintext: d1a412f4 b60a4829 -Ciphertext: 53af42aa b72a839a -Test: Encrypt -# -Source: modified simon6496 reference implementation -Comment: Simon-64/96 -Key: 082125ec 0be12c1e 767cd5d0 -Plaintext: 1da0a37f cc5518c2 -Ciphertext: f5fd38d4 a5d219be -Test: Encrypt -# -Source: modified simon6496 reference implementation -Comment: Simon-64/96 -Key: 10d4bc3b b6af23d6 bf8487c5 -Plaintext: 2ff6f40a 5ca648db -Ciphertext: 95a8cc1d f3bd8d81 -Test: Encrypt -# -Source: modified simon6496 reference implementation -Comment: Simon-64/96 -Key: 1876dd58 cb8931d6 f55197e8 -Plaintext: 49c501a9 8b487592 -Ciphertext: a954dad2 41e3ef9b -Test: Encrypt -# -Source: modified simon6496 reference implementation -Comment: Simon-64/96 -Key: 9a579b05 4ececac6 04e977fa -Plaintext: 8055fda2 6dea789a -Ciphertext: cf0cf7d2 b93ca3cd -Test: Encrypt -# -Source: modified simon6496 reference implementation -Comment: Simon-64/96 -Key: 67e0569f ee58c1ff 94ddb4c0 -Plaintext: 3d51ddb6 00a43b66 -Ciphertext: 0a1d4917 33cb1243 -Test: Encrypt -# -Source: modified simon6496 reference implementation -Comment: Simon-64/96 -Key: def6039e 384d4692 a6918a2b -Plaintext: b6b703f8 8f75fce9 -Ciphertext: 9fe84833 828b34ae -Test: Encrypt -# -Source: modified simon6496 reference implementation -Comment: Simon-64/96 -Key: aff47180 6812f080 9ae3da26 -Plaintext: 3c1e1fcf 77a97b9f -Ciphertext: 1a643883 889bf476 -Test: Encrypt -# -Source: modified simon6496 reference implementation -Comment: Simon-64/96 -Key: cf65cc64 1db4b705 4daff4dc -Plaintext: 50d1dcd5 650d7d0b -Ciphertext: 819c04c6 8dc9c233 -Test: Encrypt -# -Source: Simon and Speck paper, Appendix B -Comment: Simon64/128 -Key: 1b1a1918 13121110 0b0a0908 03020100 -Plaintext: 656b696c 20646e75 -Ciphertext: 44c8fc20 b9dfa07a -Test: Encrypt -# -Source: modified simon64128 reference implementation -Comment: Simon-64/128 -Key: 02a425ec 5a6f4914 5b26185d f7bbeb55 -Plaintext: 3c479af9 2303d687 -Ciphertext: fc64ce56 024df169 -Test: Encrypt -# -Source: modified simon64128 reference implementation -Comment: Simon-64/128 -Key: 0e1b0903 0b4521d7 e8b93449 f799c50d -Plaintext: 5ec951de 9abf674d -Ciphertext: 7d9278d4 4d68c819 -Test: Encrypt -# -Source: modified simon64128 reference implementation -Comment: Simon-64/128 -Key: 351cea05 ed5b233f 10246760 8c875579 -Plaintext: fa16ab43 16964f84 -Ciphertext: aba8dc98 cbd69287 -Test: Encrypt -# -Source: modified simon64128 reference implementation -Comment: Simon-64/128 -Key: 94dad669 1b9cc3c1 82c6753d 88ea3c84 -Plaintext: 5d02136b 008cd49b -Ciphertext: 5607fd18 278d8530 -Test: Encrypt -# -Source: modified simon64128 reference implementation -Comment: Simon-64/128 -Key: c932e799 ecd82264 da2ece5f 99363049 -Plaintext: aafb6300 6cdfdf40 -Ciphertext: dfe3ba1a e0f533a2 -Test: Encrypt -# -Source: modified simon64128 reference implementation -Comment: Simon-64/128 -Key: a426cca3 2c32cd4d 674aa682 94414069 -Plaintext: e12a1d79 b5b1f005 -Ciphertext: 8e30d819 3f0bbddd -Test: Encrypt -# -Source: modified simon64128 reference implementation -Comment: Simon-64/128 -Key: 5a398e91 3bf92d14 62ff83cb 2f1c543f -Plaintext: dbc2ecd5 ecf3f38f -Ciphertext: b449fa76 83a62e49 -Test: Encrypt -# -Source: modified simon64128 reference implementation -Comment: Simon-64/128 -Key: 2ff5a053 27a2c09f 41ce44b0 d8a16ccc -Plaintext: 5bccce0f 810d1bd3 -Ciphertext: aca4007d d8c45af8 -Test: Encrypt -# -Source: modified simon64128 reference implementation -Comment: Simon-64/128 -Key: 3e67ae45 855d1db0 bf82fa0a 6857ac2a -Plaintext: 3ad0c436 c861ab47 -Ciphertext: 970ee248 5aee1c5b -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SIMON-64/CBC -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 13121110 0b0a0908 03020100 -IV: 33323130 2b2a2928 -Plaintext: 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 \ - 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 \ - 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 \ - 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 -Ciphertext: 30ECC72B 76BF8E68 FA9F97F1 D5029672 7AA7A036 C9500D1B 8FDC2027 7B1CBFE0 \ - 5B2EE0AA 62086FC4 88A5C8B3 8A945935 205A0F1D AAC74C7E 59B32DAC 908F2216 \ - DA6579D1 8CA56234 2EB12E1A 9AAD489B 1D47385E FB9C684E 9E8D61D8 54E7AB84 \ - 76FFDA5A FE455A8E A25EBF40 D7E69E86 3D3F5CFD 5D230078 8E66F68B 76D3AE2D -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: c2a156b1 2afbf940 59404a4f -IV: 1886db05 a1128b60 -Plaintext: fdd6d311 d1c9c2a9 a59dba69 76ebbf4b a807f543 cfd1a764 0d82db77 a442f850 \ - 0bfcb900 b842dc6c d18dee7d 90bf599d e2a9c786 0bc0a292 8e2a8a18 881d4744 \ - 28ed4bf8 7c7027f2 2ca7fc86 28ab39e0 37cd6e39 134709ab 71526606 3050fc0f \ - e30ca80b abb29956 30f56d90 78e7e0d2 0d33c817 aa3a3902 805d5479 cc2311ee -Ciphertext: 7d176e86 94f95ab1 5636dc93 72ea01cc 2ea1a9fa 61730a32 1e746f6e 925b3170 \ - 988610d2 194f4369 56addb47 69c0ba18 e602574f dfcb0eab b9eb6b6e e257ca48 \ - 5e812225 b78a6f9c 072e65d4 c36b9385 ec599b61 ce613b86 a6e5a80a 7ec2fcdc \ - 0d919094 58b41ca3 2faf3fdf c3130c7d f241d94d 94060b78 6a242480 c33bce3b -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: dec44069 ccdf2596 fb6c566f -IV: 69254631 90e64c6e -Plaintext: 4a1b433d 947e7469 2fe2cb67 8c17ad8e 12b00815 dd80c296 ef93b4ca 78072872 \ - 42d6b92c 5999b692 0ec44610 f4d0caab ee7a5ddb 1861b77a 18530b8d 6b45d4fa \ - 042a72e2 52eef789 c24808b7 7908d35e aa14aa34 35212bc8 745eb15d 3746e19a \ - 93613033 f952e4aa 96b21ada 12928513 49527b63 0e326195 29068370 15454311 -Ciphertext: 39a7dbca 7a9093ff fe7775d7 9515f38e 42ba4f86 5b520280 92184f36 e9ae743b \ - 25f26a54 346459f9 644a5a27 2736d2eb 270da41e dc082fdd 9f54f5ca 57899783 \ - 48db1a5a 266d62d5 788b69bb 6581f3d3 cecd4265 0e99a5e7 709af46b dfba3eb4 \ - 2fcd2602 16bddcf0 59007137 d95b1ad4 b84b579b d9884f65 cf48bdb6 3a2fd84f -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/128, large block -Key: 1b1a1918 13121110 0b0a0908 03020100 -IV: 33323130 2b2a2928 -Plaintext: 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 \ - 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 \ - 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 \ - 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 6f722067 6e696c63 -Ciphertext: E53FE324 78573A58 635176CE B3CF68A8 DAAA10AB A41D4826 026C535A 86F0D277 \ - B6E1598F F295C8C4 3D48EBEC 19157DE4 DC166534 D4BE1754 C57394A1 A2435E32 \ - DA441E87 1B1548CD 16444167 D0A92B4C B17F3D91 F7A7C708 4BE7D31D 436DD8DC \ - 0F47BA6A BD9EE20D 7DB9F200 6D75D542 D3428E3E B99A5AF1 0F7362BD 1AFA4C01 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/128, large block -Key: ee6f4add 2fbabef2 39ae11f7 9803f6eb -IV: ccf3c166 bcea2421 -Plaintext: e3af3bc7 4aff4930 c09b0be6 6ad0585c 3b52f983 de1378d8 2cb05472 8c78e4b2 \ - 88516870 58d59f94 f02f54db 7929fbd6 f886ab8e 683c25a4 b80e453b 982c3559 \ - 5cd34697 670332b4 2b99982c aac2780b 70927e4f b7fd85c6 6d035eca f26a345b \ - 71b14716 06d22936 b150c858 7a04200c 80613750 e7226aea 28944827 261e6a80 -Ciphertext: e03056ae b02e778f 34c29058 d1e281f3 82668d25 a9c9b297 c8bee90c 18cfc49c \ - 8a292a1e c67cdfe3 0c499c8c cefd1526 34f397fb a4016cd0 00e2d93d 1db9b167 \ - d04847d2 e7f5e1b1 678fa35d 3eb59100 15641db2 baa9af0e 6ac34975 e290653a \ - 5b71a66c 7c1d0072 2d46f06d ef88f153 d240ba32 96f09d9f 47d7186a d6c3eb57 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/128, large block -Key: 4627ada6 4a3decb1 d9c5f3ee 9f9b1f3c -IV: 3c554459 ab24d2f4 -Plaintext: ff5d2ff9 d230eee4 5594000a 89518790 3d41f8e9 2ee9090a 016a4f56 52ba5d81 \ - 1a3cf525 42e715e7 c2ba1c0c 3a697dcc 09aa28f4 808edfb8 0ebb7025 125cf8f5 \ - 30f0dbda b0f72fa9 eab525c7 7c313a3d 72b10150 39fe507e f9d56208 cffc5268 \ - 70ba61b5 9b0d2404 ae3d2d7b 10055d13 48233a1f 6487375d 05a3ac8e c6f9a635 -Ciphertext: 3dc606b9 14a34c06 d9f25320 92d06278 fa6f4a70 13065734 15d9143f be0ef523 \ - fc4b45d9 1b331c1c 1d69e436 02cd5898 18e21cb2 9961e4fe 6742d3b0 9023cb85 \ - 7c04d0c6 e392e2be ce233fd5 3530fba2 d057a393 90fcdbd5 2bac6f43 26c45ed1 \ - 3a51d3b3 b2b5610b 217c9a57 e7c50e8a 3c87af48 fc6abca2 70a9c7c0 25a6798d -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SIMON-64/CTR -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 066053e8 76ece34e 9126f0c7 -IV: 1ac29087 424ae16e -Plaintext: 836f08de d972ce87 14047c34 47f942c7 613a3fb6 ce2bed34 66c56254 6043dd17 \ - 62ac0f67 05558b01 b06bfefb ef1a6c9c 0ad1fa80 ed858c92 5af47c95 08e0c5f2 \ - 86ecc321 fcd3d2dd d1925b3c c9319772 005114d6 c0c625c2 e101d7fc 3a6f27fe \ - a643f5d0 b751a1d3 1d6b5347 d1b5f8e5 fffe7477 d50d31e2 6aa83ee7 6e55b69b -Ciphertext: 89b64cb8 4760d216 77ff5f63 c9fb1244 96da7989 79480b69 efb9eaa2 80fbed07 \ - 306d9945 51e6dd75 c9e1d294 ce99bbe6 0181fd49 aaf50168 c74ca188 c9b90ed0 \ - 82003084 9442a282 ca2c0269 54015cb0 71f8f510 1c195120 4e7ede94 b54f5d3b \ - d0681548 73339cec 5368e3f6 1d3bcedf 38495bde cfcdb35f 1326fc04 89275180 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: bb980229 ebd3ba64 44215cae -IV: af8bbc11 54b28bcd -Plaintext: 6467ab0d b7623968 dac5e270 7c87e009 5676773f 07671013 2abdeaed 28acd5f2 \ - 00a49802 bdc516e5 ebd0b880 76253f8c 82a474c1 26da4fc2 54d3c176 702bb711 \ - 7c4a5d89 bbf7aa12 854e42c6 3585a1da d6f019b1 d46bfaee d457a4f0 63ba71b5 \ - c165f1e8 046d1dda 1786d6b0 1a24d33a 5e590a1c 3a5b70f9 cd666607 80ded5ff -Ciphertext: 97b4db28 944579f2 e8899698 dd60fcc0 86dd327b 91a13bee 5a5789ea 7b6ea3ce \ - 16b43ac5 f9608c22 b61cefd0 cc7ce18d bc8cc34c f93990c5 357a4c1c f168d637 \ - aa0df39c ced8f87a 7a33661b 10431fa6 29cf947e b808bf26 8170f1a2 a9dc5f3a \ - 159c0481 f4e911a0 68063f72 377438b8 ebc06c68 52c8743d 7444c622 95f24426 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: a1398395 3d759cd0 4dec3172 -IV: c221c6c6 51d3d677 -Plaintext: 64f51624 3d85dda1 0fad6dd7 7b2cb092 99670609 bb994060 41e72571 cd5fd412 \ - 18558e1b 6b19064f 2ea6ecd0 0d9efda5 be06f844 d191e1d0 6178be85 8cfda8c0 \ - 35620ed0 8c3023a1 bd775278 e735c94a 73043354 d38f3652 a69db1cd 3697d649 \ - 16788962 c68f3b31 effe0542 51d12c66 4a1dd81b 2ae23513 45ba247b eecedca7 -Ciphertext: b64ca306 8074ba6d 12233afa a0d8b398 7a5c77ae ab14ef33 65057733 788a8d9b \ - ae799565 8ba948ba 8d0b4a44 9f81b022 b9a07d9c 2f0d31b6 3a8cc339 0aa58299 \ - 82ce8cdc 6f5f07be 601fe84e 79fab70a fa82483c a9678094 fe38fe60 d22d74c3 \ - 83cef44c d8c95eaf 9d391ca5 eb8f3752 6b2048c8 9b88eaa2 4ef8d0a5 60b7f8a2 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 5210201b 6e1e95ed fe77dc45 -IV: 6c135049 5e4ce9d4 -Plaintext: 3b15ac81 91147797 495ae33d 3e25c0a3 27c20cf4 2dbe3443 f7e2035e 08118103 \ - 42c8fe01 e149bd0b 62d9f1a1 577175bd 529af04e 59dc353d cbf5b2e3 bc7d2401 \ - 727ff707 bb58ac74 f31c50ec b101b9b6 fb0d5a32 53fab5cd a1694a1a 3c0684d4 \ - 9a825c1b 6d7c0ece 6d9600ed 03eeebf7 3c907717 8ee0fea7 66da8ab1 f607f39e -Ciphertext: e181dd0e 91c4e950 2afd3c6c 3107bac2 e3962dc3 435009cc 574f3d7c f8928e4e \ - 575c5df2 bcf16bf5 21bf7e06 8714cba0 6967b061 8ba0aafe fb6d3f5d cab617fd \ - 8d5f7a20 4125cd88 119f9255 f7907546 f3f82282 2dc46719 5956c238 8075fb7b \ - 98ac525d 078d5168 ecb8638b 35003fe7 3d33ddbf 79b3e781 547f6c30 f644661b -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 9ac69443 6639b7fb 4b465ab6 -IV: 50aa2f90 b8201b8a -Plaintext: 5d7e580b 84b8b085 a73ae4ed a6191cea 367a80c3 22f0c968 3e32dbb5 686d9c83 \ - 0fd1f42a a2c78682 5ad71041 30127766 47b8691f 8e48a7f7 fadd7ae4 dd3596e3 \ - b5adbd47 4a2a0efd defef79f a1cc1c45 b41eb822 30aa5522 714190c9 8c2c20da \ - b072d557 13b0eb82 ce48ce95 f948fb18 c34a9d54 7c04b874 89105230 1ba3675b -Ciphertext: b0463ba2 8e4a2f88 99fbe7d2 8af60ddd 3ad4b9c5 fa0a6273 abf37c36 ec1de5a7 \ - 31937793 aa85679d c47724b2 5953006e ffbe7fd2 77012eec 8618b4a7 b590178d \ - b9304902 88688d0b d9d1b816 aec6a091 022dc7d6 3409e0f6 b47fa888 5d3eb85f \ - b58d8005 3537b60b 9ba4035e df4c0f98 a531ae11 a8d9a458 309cbdc3 d71eb25c -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 479fae05 f039e1f5 1a44be21 -IV: 7c695d29 867c571f -Plaintext: b631e16f dfeecb7e bda6d104 45d26d9f b57f0050 c9fa2703 913297e5 eb0d99b7 \ - ea0ec44d 6b4173be 1d9a6be1 5214d3b9 5bc2b06d 559d3ab7 79dea3fc 6a04a63c \ - fa161ad6 82b3d0f5 51edd5c4 cfe4bf0b 05d7fb25 0662fb06 98e6cbaf fb76c45b \ - f9d39424 4a712447 98d1766c 4cacdda6 67b962a4 91af5881 a2e623d6 c608ad0d -Ciphertext: fb3c288e 18670e61 9d3a8c19 ac6ba944 001d0844 431133aa 1404e8e8 532e2419 \ - 100e3c21 308d59e5 15d02d56 03fd0eed 0a92d46f 257bf8e2 da960b3c 8243c164 \ - 4ee3b130 a7865ab1 2c5cefc0 7e6dd216 c46e3b95 d9125193 41776f37 1b44a407 \ - 45912230 89b3cc5b 3a1346f8 6f4c2c7e 7ad77936 05372501 f65174c2 a408f87d -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 8eee7a0c f9bd1bae 030dc61a -IV: 0c08b22b f50ff2cb -Plaintext: 6fb9feb5 61de0669 a891c47e 7bb433cf 898f5f31 b038eed4 aee59faf 268d6951 \ - e21d1819 029bef0a b892e07a 3ad3c7e2 3066ad96 8cd5d55b c6ad4811 44d0a911 \ - 91213e55 bf03b865 d14bc9e0 851bd2c2 f349b701 2aa09237 c6bf3ab7 2179cd64 \ - a508bf48 1b1a2fa2 7ffbb4e8 7defd6e2 376d6ba3 7dfaf9b3 adac2a0f 1319a89c -Ciphertext: 96d35f2c 013de612 62d6f90f 6419db39 c8519f08 2d0e45b4 c4d4f2ff b17e5ae5 \ - 4b65c08a 28cb13bc 1a03345d c4fa1642 ce3f6561 5bc0625c 28e0428b e5bb27e4 \ - aa74d1f1 d15f1697 5af6f8c3 31c2e43f 1ce29408 9c634dbb 536724fd b1a0502c \ - e45903a1 12f9a091 2e2b9587 f8b3d2d9 8c1d12b7 c4cb2a7e f0f49570 4b41ea11 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 199d5a5f ae4a47ac c7f38e7c -IV: 71a3b3f8 d14c9ad5 -Plaintext: 6aaa81df a3d70ca6 72e389ad c7963160 715a80ed 2a217701 14dfa2a6 a76c4abb \ - f151e82d 179f3672 b8359eb5 c36fddd0 e83fbd41 c64d04ae 1283c29c ccb8d986 \ - 67663e9e 726f2dc1 1916c527 5225cd91 0659a728 24928c4a e0d89509 dd4429c5 \ - b94e493e e0f7cb67 6e04abb8 2414e72b f0c6eae2 d88c5cb1 44164db1 90fb0553 -Ciphertext: a2bca3c5 5890fb69 b4f3c5c7 9d130b83 e247627a 1b016413 744f1dac 634cc873 \ - 72546884 d64d89f5 79755713 20ceee41 0d08d17d 0f7f18e8 7797e0a0 e8dcc06f \ - de713a42 082ece33 75368e42 f4c334e3 513fbe19 b61705c4 e8d308d8 4c79916a \ - d2329ead 392f440f eeaee3aa 381efbce db388b50 a422f143 06df4f7e d294697a -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: eb66ab66 1d030578 0e7b8401 -IV: e139b60f bd709b20 -Plaintext: e6a6a6b0 9964cd3b 5c24e926 caec475a 08afb665 1aa32939 f646287f 23b2696c \ - 150836ef 89028fb7 f82547be 129b1e57 d7b71af3 2a515565 1f4d4fc2 b0fe41c1 \ - ba8c88d9 14417b21 28497724 c85aa7ed fae8895e 95997d33 30b65ff1 c303b85f \ - 642da96e 695c369a 9aed3b97 a6ce31f7 4bd81b92 b9c62733 75c162de ab7cc1ac -Ciphertext: c39c76cf 12e76748 ff5b2326 e0355f7c 6e97efa9 89716fa4 a1b58f55 4e620d5c \ - d0eba98f 7fba3eae 39316df0 296db0fd 10902b82 aa5c2de8 30bfa82f 815a1944 \ - f9011c1b 9568d452 fe9d0b90 dbf8ca8b dc41c864 3e9452f4 255facf2 78921a6a \ - 45cc31dc 3d4cc1e9 c5132945 c72550c9 c79b0555 9e15231f 1271107f 60758b4a -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 0d8cabd5 4d64fa95 33cd3f2d -IV: 076dd257 c5cac3d7 -Plaintext: fa27b35a a6bd2400 19463ef0 620049fe 6a7abe7d 9eefcbb9 2aec0249 71d564f8 \ - 454b8f2d 0bfd4f49 089989b7 a78ba949 1c9f56e6 abbab89f 202207ec 1db32d2a \ - 24c5d092 6bd0e94c 7a18927d 537f0448 6e4d0359 d7790914 5c047eda cc51caed \ - 9d5d03ed 03f25528 68a64c68 f7de41b9 270a01eb 42315df3 4273c183 6c73286c -Ciphertext: 250469e6 2fc5ace2 70d79eea eb92d153 6c542486 bfd995b5 81cd7f42 9248477e \ - 7b563d32 58b230e0 bae72c5f ec87a795 f7da89eb fc323746 35998d8f 0f959c0c \ - 94320a3b 33d88efe f0dcfaae dfd15d3c 883aaa7d f1c3a1c5 bae29fac 8ce22111 \ - b6150408 26591464 8c184bc6 c7fa7aed f160b898 8d6e9ebe aaaa7048 c16e72f6 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 0d793258 a9f8b9ba 6e85c2b8 -IV: d5b53735 8c3d4457 -Plaintext: 89ab20e5 3d84be39 6b6c05be 00f018d1 0729af4d e5b7721e d77b3b57 7b6e09cc \ - cfee4678 ab6c7d06 9837104c 88fa304d fe58a11a 3e2f28af 9948456f dc11255b \ - 020ade7d a191079e 49619975 29176830 0905204f 78322dad 3d9243a6 25fbda9a \ - 1208b3ee 209f29cf 27d89855 dc714ba2 1b5809de 7befcbb0 7fa20e5e 079ada39 -Ciphertext: e1cd0451 182bb03f 1e07b888 32d5c952 96a77ab3 36e7543d c87c16f0 a83516ef \ - ae09dac9 1cfd5124 82eb553b 1192bf1e dba38450 1c5b9700 1ce69a37 1b3e7c37 \ - cc29a9aa ce892a0d 0bbabb58 4670a77b 4b93d600 ae2a9700 89aa783d 582d1a9a \ - c4f03c24 de2a8857 46f2ba12 28860f93 e7d652da 8363a505 091668a4 8749f5f3 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 648e534c 14243d1c 822d3cb1 -IV: d36912fd ffc68939 -Plaintext: f3ab2562 8902613e 684f0328 e1fdbcea 5f2596e8 8c740ac5 9c6a9841 16dc2cbb \ - 44766fe6 4d7bf929 46ec3842 d8d99585 a79c5061 c6c20d95 142a5d1a c77aa589 \ - b2a6ffd9 b302b6df 37f21298 d79dbd84 c651f7ff 90d7124b 19282242 99878986 \ - 9212612c de78fcd6 a1a1f2a3 0327cb3d 4dc1af8b 61111810 ad763365 d9a7e6ee -Ciphertext: c561f35f a8106045 6f20664f b7771bb9 2c4d84a0 9c0a982c 1b7c73b6 7a783933 \ - 7bb4819a 642fe356 813643a4 01d3e305 f177eb20 e4d06729 c7cd34bc 0f7956cb \ - 133d61c6 96e0d2a0 a5049f72 8dc50617 9f5b6564 331e7856 5166a916 d5ab59ca \ - be702058 debfa8db 90efc752 4b39fa74 ca7cede8 9abdfdf1 596c8d25 fe473e52 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 35c0c64f dff6e5ae 126f2a25 -IV: 40979dbf 6a9fbd27 -Plaintext: 88225afc 2be9d843 1fded79a 243435d5 a2344037 2149fda2 8c5e8155 06afdc40 \ - c3714a19 dd06b9d9 a89a3ca4 57f38fdb e793f9e8 bfeed811 e14da329 07fec042 \ - d9982dc9 5bca6475 fc6d7c3f f1c9144b 6fa1146c 11fb1519 070de89e a062bbc4 \ - 47eaae9a c9adeaff e97fe964 9f632215 e9affc75 8b6cd2be 2a9177c1 010f45ce -Ciphertext: aae08fd2 a96f0efe 2b6a4bc4 516b19de 38ae394a 60ba12f3 2ca9b6aa f237969d \ - 12741a44 2acbef2d 12bb04d3 a221f02e 7eb1135a 9df4ee15 fb815c9a d2ca4a97 \ - fa862ccc ce20d794 7d1de839 b46c2c95 c4b26658 fee99057 03b002f9 f39f088c \ - d555a3e9 5afcd689 b1df45af 904a8fac d9766625 52b7cc1b 6f83cbed f2972ef7 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: ef266791 7fd55f40 a6fcbc3b -IV: 7a772d34 e84fc898 -Plaintext: d88371f3 a7fd407b 3d01b5d7 2c3322d0 e23caef1 8375f0b5 c9054a18 b3d29c7a \ - ed455c2d 8c199f10 928a3870 2f6a7b4b 6e5d8446 ad570186 112bbc5b d593bf1f \ - f068a1f4 88b7f109 406cae24 bb38fafb ec6fe60c 1a503d4a d95584df e91a9ae1 \ - c0b827eb e175ddd4 d5b5002f 4a0e3a22 ab223b6a 817e4ce3 fcde1b59 85d525c4 -Ciphertext: 4ff2ff28 22d27364 7c9e8dae 47b55985 ca4d1e67 3e8a589c 76c1fa1e 053766e7 \ - 739cf3cd 4b0df05f 3c00d175 f18369d3 1ecabb92 36f907ad 029abf1f 6f34a1ca \ - e6a5b75e a6a5b69c c347280a 763e0476 c6daa02c e3fe9c60 c326157f 134f92b3 \ - ed12d1f6 1db1d511 dc43992c 8e05b2b3 a7656f9d 1b48e2fa d38b9585 caf818ba -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 6c92ee88 9a13613d ffe4dda8 -IV: 5e0284a4 14a601a7 -Plaintext: be02203d 9f13be03 19d071e6 f8700bb7 94636267 26c06bab d267826f b232f062 \ - 692bad33 6423f21a 7413b38b eaedfb07 ad8f1ec1 09da01ed 6222ed7a e480795a \ - 351ce397 5da27286 7b5bfcae 1e24c4d2 9a695051 c7435a53 e7399d66 ed163177 \ - 6507ee6a f26579de be1c0513 61c9ddb3 ea6848d3 a2735040 47178fa8 3842204f -Ciphertext: c45996b2 829ae403 8a4ed800 3307f879 cc56e1ba 4ef906fc 4668c863 893e7e42 \ - 4c6b7d36 9bc72de0 6b3ad2a9 84ef7fbf 354c1591 de060bd7 c6c7eec3 b0814424 \ - 0a7ec6a3 3f8e4035 3c7263c2 bc89cfc2 3a8170da 43720248 a7eee249 7ff2e491 \ - 095e3ee1 32a2346b 6c305e1b 795ca874 5ff8a3e1 0d2c63d2 fc3c5ee8 9b30c0ad -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon64/96, large block -Key: 125b5184 fa11bdc2 ba1c4afb -IV: de2443df df5ab452 -Plaintext: 3495ff2f d5316b50 c73d25ba f574c955 9b657e3a 3afd48aa dd27a691 ab59bf55 \ - 6b0683d5 a574f5e4 588e7223 4f694549 72acf0c6 f059c19c 86a50b0e 80f02465 \ - ab1da7d1 e49c0b21 3ffe6101 8cef9fc3 1076d0bd 5d52c703 5bb79726 867ac725 \ - c2cf7f8f 54142fe3 0a8ecf4f 27591023 0079f5f0 926b5899 95f6f5b0 41c439b4 -Ciphertext: 8f478528 ca718589 e0e0e2fc 2481a6e6 a99a4bd0 556f9d24 b39fa9ca 67faf9a8 \ - 4bb90edc 4b7fe771 faeb5b6a 8aa65b37 87459d31 9af7b200 e09523d0 9a0db5dc \ - 126a2d8b a2668f51 b8e99a58 6dc27a8d 8fdc0f42 be341c5d 844dfa08 e28ad7d5 \ - d3a991b7 167598a1 c252cfb2 1e0b6b20 76c0e6e6 22adb00c 4c160f45 8ed860c4 -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SIMON-128/ECB -# -Source: Simon and Speck paper, Appendix B -Comment: Simon128/128 -Key: 0f0e0d0c0b0a0908 0706050403020100 -Plaintext: 6373656420737265 6c6c657661727420 -Ciphertext: 49681b1e1e54fe3f 65aa832af84e0bbc -Test: Encrypt -# -Source: modified simon128128 reference implementation -Comment: Simon-128/128 -Key: a588c5576b291d08 9eeb50958db3cb87 -Plaintext: 534078adaa1c7f48 2bdefbf930d4531b -Ciphertext: e25d454fd15730df eb5d67539e3933e4 -Test: Encrypt -# -Source: modified simon128128 reference implementation -Comment: Simon-128/128 -Key: b9768f1a15a7948b 9b98c5e7980b9aaa -Plaintext: d188430452e29d10 322331fe3fa11981 -Ciphertext: 221c8cf1196ebff4 ab88a376ee74793a -Test: Encrypt -# -Source: modified simon128128 reference implementation -Comment: Simon-128/128 -Key: d09b9a496c5128e0 e6259eef29f2a0dc -Plaintext: 751bee61dbed3614 4d40d77b70138564 -Ciphertext: c8509b4c5fed1dd2 eb642e7d0aec0e14 -Test: Encrypt -# -Source: modified simon128128 reference implementation -Comment: Simon-128/128 -Key: 7acf10d1124345b2 a6e0106de8547324 -Plaintext: 4af07574f5922678 fce78ad85aa16c71 -Ciphertext: 07ebfcb42ea50b1e 4612ec22c253f56b -Test: Encrypt -# -Source: modified simon128128 reference implementation -Comment: Simon-128/128 -Key: d41f76fc5dc02f7b da73b914f8a14489 -Plaintext: 013a394227470237 b4003cdfdee1b835 -Ciphertext: 47fc1eb8c2de95cc 543f8260170e5596 -Test: Encrypt -# -Source: modified simon128128 reference implementation -Comment: Simon-128/128 -Key: 080d9d309e524aef 68c11506ae876925 -Plaintext: 7d6f925730aea1a9 a7d590ffe7e288f4 -Ciphertext: a25ad610acf7470f 09c758380d0ca69e -Test: Encrypt -# -Source: modified simon128128 reference implementation -Comment: Simon-128/128 -Key: 9fc3989d016e07a7 a2f79c71d1601b18 -Plaintext: fdbc4c3f819e5c96 4349459bc5bfbe9c -Ciphertext: b1b8bc4caab1d088 1ca93680fc224652 -Test: Encrypt -# -Source: modified simon128128 reference implementation -Comment: Simon-128/128 -Key: 701b0424b0cdc04d bdbd4ea47cbeaac3 -Plaintext: 1b533dbf31b513e0 cf2cbb8eccd8beab -Ciphertext: a08e42212e6eafcd 9d270bba12aa4b9b -Test: Encrypt -# -Source: modified simon128128 reference implementation -Comment: Simon-128/128 -Key: dbcb8b5f99df4490 322ea4e2be1617f9 -Plaintext: d0a0625fc395d7dd fa431b8b55743dd1 -Ciphertext: 44e782dc7f5d15bf f8467e9c99487b6e -Test: Encrypt -# -Source: Simon and Speck paper, Appendix B -Comment: Simon128/192 -Key: 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -Plaintext: 206572656874206e 6568772065626972 -Ciphertext: c4ac61effcdc0d4f 6c9c8d6e2597b85b -Test: Encrypt -# -Source: modified simon128192 reference implementation -Comment: Simon-128/192 -Key: b6c5e0ef90ac4fc6 2abf3bc9581df237 7207f81c5f3f2225 -Plaintext: 36875f5e99ea6c92 e496a8e62574928a -Ciphertext: aa748c76e520b3ba 670f719639e9efe0 -Test: Encrypt -# -Source: modified simon128192 reference implementation -Comment: Simon-128/192 -Key: 05c8ba8d2fc9b3ac f64749a74e1bd9db cb41708b53463fff -Plaintext: d560b0577faa49da 02ac1332891bf7ca -Ciphertext: 45ace31582ff3d27 8eda206c2b59ae70 -Test: Encrypt -# -Source: modified simon128192 reference implementation -Comment: Simon-128/192 -Key: af9eb827709bfe4d 5077bed361cba7b5 9a7848166b5dd456 -Plaintext: 3db14a51c0436dc3 16e48de36334482a -Ciphertext: 259ef34079017b4c 51c5d30862a3d6fe -Test: Encrypt -# -Source: modified simon128192 reference implementation -Comment: Simon-128/192 -Key: b5ff241d499498dd 608cb297cfe6923e 2c9231847c069f16 -Plaintext: 48e15eff212b39eb 7318e0761658a75e -Ciphertext: 662c14e095882a29 e1828b5127799071 -Test: Encrypt -# -Source: modified simon128192 reference implementation -Comment: Simon-128/192 -Key: 337cce71fd742ab1 fffd9362d6955881 b5d9e236a6a46968 -Plaintext: 9c153daf08ae0792 a74de78e56f146a1 -Ciphertext: 4f890eba4abd9cca ef754fa75e112521 -Test: Encrypt -# -Source: modified simon128192 reference implementation -Comment: Simon-128/192 -Key: 4b65d913f93b3a60 9f9a3af8bda9afc1 56efcfc3e5a931f3 -Plaintext: d480bcc9c07c299c 4701ad7bac169990 -Ciphertext: 00bb2e25fd4a1ffe e1376667b31e137b -Test: Encrypt -# -Source: modified simon128192 reference implementation -Comment: Simon-128/192 -Key: d40765380ace5f02 1843df49b1c866f8 9262794b3f0d892f -Plaintext: 15cf6b0cb8fcb0ab 79f73b6f5f66821a -Ciphertext: 5f4fa8813f0da53e ac98a5db78f48f9e -Test: Encrypt -# -Source: modified simon128192 reference implementation -Comment: Simon-128/192 -Key: 47a69b20748c8574 4447e83c35a6b121 68e1926c89059a33 -Plaintext: 70e8ff0af54c660b 357ea7645dcf199a -Ciphertext: 8e3a750d8104d9f6 01337ee1f2be9ae3 -Test: Encrypt -# -Source: modified simon128192 reference implementation -Comment: Simon-128/192 -Key: 77428aef2064e177 bdefe37b6d26b00a 54b4e93e70b31ca5 -Plaintext: 4de7a00b9b4f6060 6c5c87fd9037ef52 -Ciphertext: 5207cd6603ccc1a5 e10eeecfbf318c63 -Test: Encrypt -# -Source: Simon and Speck paper, Appendix B -Comment: Simon128/256 -Key: 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -Plaintext: 74206e69206d6f6f 6d69732061207369 -Ciphertext: 8d2b5579afc8a3a0 3bf72a87efe7b868 -Test: Encrypt -# -Source: modified simon128256 reference implementation -Comment: Simon-128/256 -Key: dafe9c969e7cbe87 31682732cd5a6d71 164938f37d1a4d42 0a82dabf0a268b99 -Plaintext: dab4b7e6e1e540bb 0fdaff6a1764a197 -Ciphertext: c704945d970ef15f f9299cc3a40c91e4 -Test: Encrypt -# -Source: modified simon128256 reference implementation -Comment: Simon-128/256 -Key: ee0df1aaef2ae18d be67750f805b54ef 13e8ec35b84c8275 015f216eb9472b83 -Plaintext: 9d56cd9309beb4ed 142859f7161c48b8 -Ciphertext: 9cae6ea59ef60fce e1efde29642ae185 -Test: Encrypt -# -Source: modified simon128256 reference implementation -Comment: Simon-128/256 -Key: 2c289416a1f793ff 1d9028aa25e2e8c1 269e77274290714b e8ca6dbfa38926d3 -Plaintext: 6b537313d0b75dd6 e38f9d377299d9a8 -Ciphertext: fa3805cadc7073ad 0e39ec997e6f3eb0 -Test: Encrypt -# -Source: modified simon128256 reference implementation -Comment: Simon-128/256 -Key: b614675dbf46d143 62e130ba70e98c09 04501d0f2a4b2183 81f112f8b3c7313f -Plaintext: db7762147c459d6f 1b03970a1af640d3 -Ciphertext: a9fda9a29394d134 4f9b379ae9fcf328 -Test: Encrypt -# -Source: modified simon128256 reference implementation -Comment: Simon-128/256 -Key: a39c2c3240ca9fc5 f34dbac32042acd6 111dfe7755f06786 a0424bbb0768ed23 -Plaintext: f5b0ca1a69293d06 3d8bb832b8338a6e -Ciphertext: 7dd7ab9d138c4088 846a0c9e42248541 -Test: Encrypt -# -Source: modified simon128256 reference implementation -Comment: Simon-128/256 -Key: 4e52525d47faf66e 48406f3fc99165f8 657bcd374dce0b50 f0fcb36d0d9057fb -Plaintext: a06a80a59ba1e17e dc2dd9110c1eddbc -Ciphertext: ad5060576b57192b b8a01dd660814e0b -Test: Encrypt -# -Source: modified simon128256 reference implementation -Comment: Simon-128/256 -Key: 85d15462a2429f63 5d466309d9e443d4 e24702a0286e9c94 d8d9f2f9dad323ca -Plaintext: dc2ee11f0bb24950 9f38af23546b95cf -Ciphertext: 2e20d4a9ba27ef98 f61a39c7322f6015 -Test: Encrypt -# -Source: modified simon128256 reference implementation -Comment: Simon-128/256 -Key: bdd1f4fdc42a3615 0ecc30d3a26c104e 7a8464bf7dd03869 d29252a87d9d863a -Plaintext: f466eec478d2090f 53fb350c516ab1d0 -Ciphertext: 2ffa8e263eeb463b 03a0160fed2e01d2 -Test: Encrypt -# -Source: modified simon128256 reference implementation -Comment: Simon-128/256 -Key: 2a961d8c82821dd2 46c773cbdb3993ee c4a9bcd05a20b620 64e295107fadbbd8 -Plaintext: a789f976c69298e4 46f1410221141876 -Ciphertext: 64514d1256a05d9b ca261545f94af135 -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SIMON-128/CBC -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128, large block -Key: 0f0e0d0c0b0a0908 0706050403020100 -IV: 2f2e2d2c2b2a2928 2726252423222120 -Plaintext: 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 -Ciphertext: C7D52B8F3FFB4897 8452F49A94E85D93 39A969245D226982 0B3D2B653C7F4185 \ - A1B51DA44C2046DC C009A863548AF65E F44ECA6E96AFFAB4 BA206FF65C493C0A \ - 35899B8010A270A4 A8B1D7084EB76794 84D38FDA07E35564 517961B8F4ABDED8 \ - 5B740E2C616C22D3 94D23A002CCD9021 B63DD493B86407E9 7C30572B028C4DEB \ - 293E847DA1C93025 AB636CEBC25AE234 B467C6D22370BED4 4148445C0E08838E \ - EC9FFCC168471FD2 B4BB0A7956F453FA 271BCCE16FB837D4 BFB7F6D751B7FD78 \ - C166B5CBD81BC0F6 93675F7B066FD6DB 49F3925626634088 1BA502A1CBA53854 \ - 883DD63E5E0397BC A3D74D4C3442CEB2 7A59C1BC8CB7EC6C 7B07287AC370627B -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128, large block -Key: c189b2fa063ce9f3 5d6cae920e406e96 -IV: aef30b53900f88d9 00db126e681eac63 -Plaintext: 61f12f42e0298085 cc4d75511aea8d30 780678d10f024e75 ef7eb039b46fd0ee \ - 714cc2c06884aadc 9c051dea8635826e 10f66968ae7273f5 6ea6baa739da6707 \ - e0dbc3701c7765ee 08ca50d38af986eb 61f639eca5ee0843 f0ff2e1543eba53e \ - 97e85182532fe826 ad6c205de20a704f d82a7665f48d4e47 660111509d8cd98f \ - 52a2188efdc70e95 7e9d715f913fa450 28534c3d02caf388 c7b63b0a04c57c8b \ - d4c264059f239947 e159dd09f00c9f09 123fb45c93f9f3a6 cfadb8121358e3e7 \ - 822d0b81815049d5 0bac25283ca01c8c b34009f57e6a49a0 7ee8dc10e5c3c0d0 \ - 121230b7bc4bbaeb c0821717ade1e7a5 cf18fe58af5ef6f4 6d8419e7a11a8368 -Ciphertext: 977bf2289bb5bd3c 16bf095ec29cc139 ee10b392fc3e2a51 522bd8ddc71b5328 \ - 4e6c06d5d37a592a fad34b984e248958 dc31e4c3bcf0a570 85ea42544f5a7ee1 \ - 2e35d459d510dff9 231c5692d989d966 9f54165fc642447d 336de67fe56bf3a8 \ - ea657fd82f55e2f2 ddd59a4c648cba36 56e71e5c48e2513e fa66ff9416a6ebcd \ - d2868add16e00043 e6f5792ab4b97890 e10cf203318f7802 e8cdc3f9aff62887 \ - 2044f0f61c2db1a0 6e6fe0f727b34492 d6b0d1c99d537cf7 9ec2d6d0e15fcaf1 \ - 8575fb68db2002c2 1ee9a2f2f0b26b28 3ac5404e115d2881 e61bb1b1b2970e23 \ - e3f446b391ad72b3 ae719554951ee104 6204b67085a03737 b206244bdd5203f9 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128, large block -Key: 685b59ca4b6f2018 a54a1bcd45c8be1e -IV: a4cd3c506cfb5181 cc8cd9edfc62ff23 -Plaintext: ddc60e60e34ace46 e691a08a6125a7a9 34df6d7d0776fa86 33d22ee9cbaa0b54 \ - 26213dd44a970a3d 65cc324970d925b9 d97bd4bdeb545e2b 7cd4519eaba8bded \ - 0b3570f71cfd6dba 160b0435d4801741 05ec041079e5b392 19a6e065d1aa8517 \ - 7a6b51b78724f010 5f18e1a947225fc7 27e2c45a79da503a 906d3e5ed2435529 \ - b29734f9eaeed504 c6b39bbaa179f1a3 88bfd32e4e919598 1abb4fd5a0d67b75 \ - 28c58d94475b64a1 a6297cb419064ec9 a753840d03fd2f58 23c47853b0c2f27f \ - cc793a6cc2e578ea d67bbea587aa1e4a bd1da15765fa2e74 66a49d2c496e49e2 \ - 644f4f2b8421cf39 0ac33f04113c24ad 00d32dd8ed9efc3f bcf4d17e7bdaf795 -Ciphertext: 43447f8d09d4e847 cd206c58462db355 81df0d9a0336878b ebe8616608ef378b \ - 77b1467a3b80eae6 b6688febbd58907f 8589506717a34f67 4194101153b587d2 \ - abad0f903b253fc6 419ceef625b7f14e b736dc8dc4f43d3d fe396791eb163bf1 \ - 75ecced8d4f4ddfb 17ec153c9806b356 525546856678ce4d b837f571aa2d0038 \ - 92c62148c07c0a38 775c0d801be35359 f0c358e9ce316e74 eedd52b19ab0714f \ - 80b6f637693648ab 3e979111272e1a55 38ed77ae8b66bbfa 28f8a24299151302 \ - 71ee36e7762d92c8 babc442798630a0a b94f6db967b9288d d95ffe3e27fd3113 \ - 3ecbe567bc7af7b6 3ba6f88143a4f786 cdc34439840532db 53b7875852ced6d0 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192, large block -Key: 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -IV: 2f2e2d2c2b2a2928 2726252423222120 -Plaintext: 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 -Ciphertext: C4E8A46ECAA39BF2 BA84C13A840F1CD4 0310A1AA41C82FE9 0E7919B8AC503264 \ - 905697BF3D991CE7 C7EF61C66363ED71 E10FCFF811444269 AAE1DCB6B587AA2D \ - 7E6AA057DEAF4107 54EA82B799EC6A6F 330AD442B502174D ABF3A1FBFA718F45 \ - 0A0839AA0F43C011 1611992D80866E70 4DAE45FDED8AB37C 2D06F958ECD05AE3 \ - 7F92AE098669A6F5 888FF4AA3A7AD48A CED8DA7469C563BD EBF5003520062916 \ - 857840F31100556D 7ED5C6224F314BE7 6C73ECF11F096407 37BF24C1480B95EF \ - F8A22F1F1BF02736 C7949FB6B8931F65 826E4D9AA2028F4A 62CF64A372957D26 \ - 201AC3B724EE28EF E9096A01DA17B46D 219B77BC38B08EF5 E9C471E20D2F06FB -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192, large block -Key: 43dfd3c613b2cd2d be7dc5b34db2244a 95ec19612817f282 -IV: 9dd5ee928356e1f5 12901b352bc29730 -Plaintext: 391c9c9b08c47070 20f33343e374ee7f 841b2079153ebe09 8cb53e2c3f211385 \ - 034849e2f494727c eae01254ecc06609 cc6b0b673298d56b dd1e56bcf872bb46 \ - 900b0a7263673d7b 168981ae8b1a7e57 7a68565e0f1e61c3 b8dcfc2cf91a8eb7 \ - 4b225e6ff0414f65 7de524c89816fab1 328e54296d17fa45 133059001cf9c705 \ - b9f3d6840e37bbdc eb2b49bd649ba384 f51416f37a5a3777 c367465786e1e0c1 \ - e059bcf6a7255a67 82b40f35047b2fe6 ad4bfcf1c86ae4f8 950b6f7a508565e1 \ - 975f1c9f34c481b5 5315a73e343061de ce1ce203c4f29989 bad0f046e0ed44d5 \ - c6550ffa8b981f47 d119f918cc28d83f 8ee00b3945593478 38200dfc8ee32c89 -Ciphertext: 1db624b4245f9fae f46536295be525c2 52ef00a151ef5c01 8326184b620c3a61 \ - b4f8c8797751ea87 190ea8d87500d34b 30771747da169b63 9a5183a628d8b372 \ - a4b1fd2a39a85cc6 0749cc61cb6be431 47b47e1b2cf65902 32109bd3170d3b33 \ - 704f2d9d72e66259 8fb88d4109ad0f7d 3256b9dd4629039e 42eb1a1b49e898f2 \ - 47a3f515e42db1c6 dd08d24fccc0b193 10a359b1573d4ca0 9b7a4aed0785a221 \ - dcb3320b1a4c4461 746297543b53d19a 7b0ca4b097066b68 4356cf5d6e935aa5 \ - e90976db19944867 f9b9ce98d57e1ca1 be2cbca9818aff9d ee39813c2869bf04 \ - 007e4f5a6b88cea0 6fb5a009722a48ad 537dd73877b20bf9 72bbeed5f4d4b431 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192, large block -Key: 65a270cadf2a0b7c 83bee3097dced9a0 5375ddc7ce52440a -IV: baedfb32824a91b9 032364a387b3960b -Plaintext: 9b6c5c928dfd822a 8b77905b57514117 8d1acb3c287c5d45 bf07d27069cace3e \ - 0a0f7933f329e1a3 0c05e3ae192d8d68 8f2c607ae2085013 fc9c426cb03355d8 \ - 7bd2309da401adaf f30910af462609b1 c88d3ae5e66ef5c5 2ebb7e9b897debd0 \ - e75d2f4795d6c1e2 9b57e2e028107cf5 74b7bcd641d49fe4 c7b3e021a6e40957 \ - 9ae1f941fbff47db 8f25579ba06709b8 fd4da1292e546981 37c8d0968154805a \ - 2092699811512949 9a06bf36ad57e4d7 d1aa37e6441d38b9 2cf484620ed3930a \ - 49ff96694ce68c60 12db21607f11bdb5 ec3038482e91da69 66ead4b13a45e739 \ - 74b36f6db488616a 72ebee47a2e6f2b6 276aa2f8ca9212e0 a8456b4d0ac0de6b -Ciphertext: f252ddd466b536a2 13e6b7d213f46cf8 086bbf4d0085fab5 fd595fc2184b7ff4 \ - c831db666f68c767 c9d3b4f72185c0bd 0a247e5564fa789b 65c727649a08654a \ - a44d00dab149acdc 33d2114194fe24e7 a94915350cf55330 4f2127ca6fd5beed \ - f570a41ee9eb0a15 43ae19c5cf4fd977 b27bcb8eecd0a812 d0d734111aa1fd60 \ - f5792d2eacfdc4a4 9873ff7317b1fe2f f2dfd2046b87df48 1b6d5f02dff3a034 \ - a352017a0b2aaffe 9b67f75d95244ad2 219af8f0b3d380af e1cdd7e3d7df8c2d \ - ec6be293611a9aeb f4e1f0a9020b2808 4e3b4387790f002e e8766e2ce6297714 \ - e812ceb42493db4d 4c209f6e1375d7e4 35ed39d2543ebfa8 fe593e41c0add162 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256, large block -Key: 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -IV: 2f2e2d2c2b2a2928 2726252423222120 -Plaintext: 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 -Ciphertext: A644E82271C97948 32DB00733519C10F 14F72D9627F8F420 31C62154A29A6071 \ - BC330B973A086F41 D628A43982402FAF B7C72D2CCBE22C4B E47FF196FF55D004 \ - 66CB5E996C195FBC A3164EB0CE3675BE 55371385A1FFEB39 6CAC581D5F18CB25 \ - 6A8A038E75C4E2B7 B8C6DD03C2534D29 4D1B77A41706D65D F2B3CBDEDF905245 \ - EDD4D3149F45A5B9 3EBC3FBA7196DBD5 73381E27974464DE 1279322D0C216C74 \ - 1405717ED0416FF1 11E02294D09733E1 DDD5264F0CEC7B5A 0EBD7D1CD2EFE950 \ - 6513A4C9E4811E48 3F32EB8B907C1589 255F223D362E0C43 F637274666FDF73D \ - A734250B84267C31 F45470CA6CB2BB34 9B41301B4228A92A F08994353148EACD -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256, large block -Key: c4c2910c714dc8cf 70421443bbaacb1a b30acf3efc9daa69 06b5a5c83aab3f4b -IV: 76214a0dfcba0600 3e110bfb5417e0f3 -Plaintext: ad8bcf312a572059 88ba56a47e89e50d ed8222c9192ee1e0 e2645d929af6bfc4 \ - a905cbf1a64367e7 f2039003376b3423 d777d90b49a0010b b0b614006de88f5d \ - 0d56b65343cc227a 80dc045eed6808bc e71b2db424665869 9c18814e995340c0 \ - 92a43399bfabeb30 9aa02be5807c3b2e 347291d04c4de409 4f51008edee0f059 \ - e3afc15d73a88f93 5f14dc7b2c2d75af de99ef702516c924 9d2d857bcafa61ce \ - 738f8a2f39a97664 d62121c5517b3bbd ca25988fbb5ca3c6 b45a7f6d8b920df4 \ - e73c1f519118e45a 6dc9082f0ecc0e8a ce92b54fa1ddd9f8 653a40c5f0753f96 \ - b473e2d213bd1cae c33e380bcd849af1 62738f016b2253a0 6192d8267dbcc5da -Ciphertext: ab6f8ead4b6e2372 af14cafdcb415dfe 9e88bdce36cbc58b c3d9285d697861b8 \ - 96302b38651f0999 e9c050aad33636d0 231caeed0e156bd9 5534935b2c3740bd \ - 736bb21a9f03e77e 9b948c3d25ff933b 2ca69c7afe3b90ca 27d161ad07b532f7 \ - 6bb13440be34dc9b a46daff43ec359fd 9f82280c956ac778 fdeb536c2b120772 \ - c32c17e4a1ed8f03 84b45b3c3eb965dd c7c839ee02c7c817 346eb22e3bac01ba \ - f83772ac21a1de2d f1e1218b7bd95961 7333e7d751a51e48 cfcad515adf442e3 \ - 7a02102534d5aecd baa540f21cc8b600 3a26a91f96170313 d63aaf89ecad709e \ - 3dfeaf3d3d0b7a0a ec532241562baa64 985b3a9689b63a12 b39e135f24a1c942 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256, large block -Key: 2b75d368498bffc4 bd60ddb4c36b55d8 bf60643ddce821a9 298fc84ed0ee75ae -IV: 8b9542fb8c47013a e0265501d6f9f69b -Plaintext: 324cab03f3c24481 85d2f9b8acdf191a 41511406baef94d2 a4997028211977ab \ - e78d6d5664b90ccd 17009f37032c1267 9b4d21d775b61454 157d3105cfaf25e7 \ - 3de17baceedf65fa 1e4bbc387ce3fc66 9df3e42f68d882da 06b6942a49698908 \ - 9bbe3af42e4fe72e cd29dab22ab435f8 8d90ee3aa6f19c3f 9a9c72d23aba61e7 \ - 48bb1f04bac475b4 fd490a18dd92cb04 41c815eaa23967d2 f9403f24dd240440 \ - ec69098b65149ab6 49e0bbd3c35dc626 645c88a866fa26c7 2c79f8b3bad2f6e9 \ - 83048a993e80319d 19867758a0948034 17bd065653fb7fef 1072245900abf7cb \ - d7f04e967e2e8328 146b04e8104e0c0b c9c5b0b7b134b2d6 f78626f7d6114088 -Ciphertext: 6b2ddf7a40dd08fe b0e4bf94975812e4 ce0c83c311385417 a02b50bf609e53e9 \ - 9bb5c3bac14d6dc8 f780282d1aca7347 845c4efc47c58e6c f107c20b14ef998c \ - 3a7507bd0ff0323a dd6edf3e225c01d1 22b60d02a7cec640 51b583162863fc0f \ - bd886aa1ebc56a0f a1f17f4ff91da53c 380d40deb4020c91 701f9156489e34a3 \ - 0411d9b55bdc4ed6 29e49b486b391da0 722cb93b310f0831 ceec16d2905e56dd \ - bcacbc297edc6097 339c84ef532478bf e177f1e1ac922abf 215dd3b5ecdfe66a \ - 96da0939798c3933 9573fc7892631684 bc22c68205a20d9f 1ad0876848c67b9e \ - 9d22155a33af83c4 7205a00161c4d2d6 dea99b558629f5ae 1de0ca82db2fdeb2 -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SIMON-128/CTR -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128 -Key: E7A412500EC37BE4 DBE7C53C3E0A2DCE -IV: 53E88FAC9B54808F 2E81504700BDE9F1 -Plaintext: 8F3406C9862EFF1A 409A3D4D24AE272C -Ciphertext: D22D7CDE94A52F3A 8DC7C354147311D2 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128 -Key: 6531AB27F9F63594 39F8F25C81AD7301 -IV: 1223FBD84BB2F571 B4228359FD64661B -Plaintext: 504BE960AEEE0832 B0868D70B9D31FA8 -Ciphertext: 3F19B4D289A267A5 9162717AD36D0AB1 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128 -Key: 6468818A85E8BFCA 173E11CBE04C56B8 -IV: DCD8BDB47BD6EE28 C63C07A4851F97E2 -Plaintext: 0A7A856C19AFC7B3 4AEBC55D614A2A1E -Ciphertext: 0E64E3D3CE28C2B2 0D915950D476335A -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128 -Key: 53CCD23133D8105A 9442AF089079811F -IV: 102A8739CC8789F4 06A81108EEF049CA -Plaintext: 6322FA1E89D6ACC9 41E170E98FEB7BB5 -Ciphertext: AF125ADFEA8E3C7C 58337249CC67C2D3 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128 -Key: 35B111DF6E824776 F3013125807F502E -IV: 4F5DA65425861CDA 5607121FD7438B7D -Plaintext: 0FE6E02DFD8D4633 1AE627F668FA68CB -Ciphertext: C5C137E446203642 27389DA9847D74F8 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192 -Key: 2A501E5294D1D4F5 375C2418EF66EBB1 CE429A0412694A2D -IV: 43BE92B1FAF86975 2FCCC75E27549111 -Plaintext: A6C744E5A65396C0 807B00DC34A75620 -Ciphertext: 122082D6C123735C CD7CDEC976E966AB -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192 -Key: B2072CA7DA78752F F9263A95DEF9BACB 31C1529BDE22BDA1 -IV: ADCFB61D1E9819CA 4B29A5305217DF3A -Plaintext: 4DD2762EE998EBFB 67A28B5486F3B01F -Ciphertext: E7FBFA2067B3A806 79BFAEC77AF6038E -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192 -Key: B0C07E845690D767 13AFFAC084A6E6D3 9E96C714D74BD651 -IV: 32B1F1B0DD27A433 0220A5D6357942AB -Plaintext: 0160B01D9B07568E F64CD9ACFC7E11AC -Ciphertext: 5DCAAA507BA4B46F 17B2606449ABC65D -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192 -Key: 33A2FF0A60100265 32FF77D02A4A2B63 561CA2302A29FE6F -IV: B6873737154D6C10 3F08AABBC81A57FE -Plaintext: 37DEFB05C97BED07 EAD9EF1FA40AA024 -Ciphertext: AEB9D19FA84375A0 FB94F1A4371276B0 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192 -Key: E765183A7827A19B BC1A7A24479E4E65 28FD13A6C56FAE2C -IV: CB846572BFE4F87F 319ADD350F1D9F98 -Plaintext: BE7F6B5E4A21B80C 1C3D45234D2CA1C3 -Ciphertext: 3A6DB21E6C0E9197 F0D711F80B1EDF75 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256 -Key: 4287A874E088ECCF 66D85A1ECCED816A 0238B039A8A23403 0B112C3128299ED5 -IV: 171BAD8AB05B2273 AB15B0A7B87154D4 -Plaintext: 0CB01D1D65A4007B 744A32F412273217 -Ciphertext: 186EC8002B5487D1 DC40B1D7DDC0F927 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256 -Key: 92DAB58B873CFEAA DDDCB488D63B8952 0CC16466798974A1 2D7AEF11C1920A47 -IV: D929D6744A0118AA 4256C2668D56162D -Plaintext: 3862CB191E0D2E3A 87687383AEAEBC08 -Ciphertext: FBF976486E46BF28 AEFF1DCACF70CB66 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256 -Key: E4824E89DC6818C9 F935A9F5E1CD41A9 956159DCDD3D81C0 93B9E38A6AAC023D -IV: 81109AA0FD5B7919 3001B18264C3530C -Plaintext: F3EEBD6D75CBA20B E337041F7E62B9E1 -Ciphertext: 5AF69F75E238F779 89CFDA76B5F3911C -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256 -Key: 077E020448EB29CA 243049BCC66F8F89 93E68625F7B67CB7 A58AC57BAF6EB3AE -IV: F73701F6205452E6 B570E2D69B7AC5C9 -Plaintext: FD4676E1A1F4552F EAD6B764E567FDE1 -Ciphertext: 48AEC095DA0120C1 9043C85D5458108C -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256 -Key: 2E3E72DE26C58DBC 8EF733203D8F8F32 D49383E4E925C2EB F8FF944E50A95F67 -IV: 0DF27DA06C390CE7 5A02CF8F31485116 -Plaintext: D510E30B32D985D5 50FE591BF7F9C785 -Ciphertext: 6C17A07CA7FE192B 502EA0663D9706F8 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128, large block -Key: 91E59E3EF4513F7A F17478897FE65729 -IV: 9C65F4E7F96197FF 119C1FC0B83D0465 -Plaintext: 7AED5FBB85E500DA 00A46ABA78524C28 C261FA366087E62A C266A6A069625D0C \ - 89225C34F783EB72 B0788F9113BCCB78 DF25B25B7DDFB24E DAE6A29F8EE90915 \ - DF36A44A15DB36DF B05AAC2FDEE2447C F54D23EBC04A5391 A4EB7299439438AF \ - 31367EB540BF54B6 C6EF78698F7524FE 7A8DDC225F28A087 C6F7006CD84C24E3 -Ciphertext: 85E115E1B558819E 9AEDAF2B47EF3D0F F09006D6A894B52C F5C27D61D22C80B2 \ - ECFA084BEE20EED6 6505AA29DDCDE119 2F164AA0195DE222 6C78FEF5C41CF0FA \ - 8F820061742AE4F0 57EA7DC40127733A 4047D6AE7FB6D155 924F4A06AB03917B \ - 687E3D097F7CAFAC 8C21B16BC00DF7FB F6A44F18A8B50969 1740E70DA6E02D50 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128, large block -Key: DDE75F3FC2E64576 4218099C58C16932 -IV: 4A469C9D66477421 D2B58F850BB21800 -Plaintext: FABFFDDC2DDFB6EE 7D9D5D2778D0141D 8E7A24259A3503B4 4E8416B7B6FCB842 \ - E1BBD8A4F7B244F7 0130E3E6A76D76E9 21068CC11524F367 F6EF064A738A53BD \ - 91D38A0929E62844 E1165287DB4118A8 2D35E0CC3E60C690 4A622C405197F82A \ - 3589CB44644B4606 5285641AF8978292 90CEBFF074DA40BB 2351EDABBF57579C -Ciphertext: 70A3EAE9ED0DA9E1 0C67D094B24BE5BD 5278FC8C3AC7D88E AF856D3A6B56B88D \ - 181784F00B3DDC7D 726143B2D19EF0B0 F1B2E044BC31610D 83C5C8EA094D9CCB \ - AA95F8860DEE5E8A 82C1F208CC4B7552 7836251DDEB4728E 03F9196736E78C74 \ - E7494AEED9B36805 347FF48993384365 785156F746D7A6CA E562150B5F0D87CA -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/128, large block -Key: EBF200B19ECACF5D 258D10FD19F2AE84 -IV: 950810F42AF6C3CB 360D0BA36D895F27 -Plaintext: E356916400F64328 C681AB9329897E56 C7733EC4CC54C5A1 2F03EDBF90E24B4C \ - 9520310DF45B7FAB F4EA7A238D6DE8B2 B291153E880B9886 805783F39FFD9C2D \ - 44B956EE8DBDEBDA D2AC5D7D34A1639D F9D71A870FDCC048 5873AA9A236C332A \ - A79C9457C1B34A4B 7AEF097C453D38E1 A8A9D96E5645C6BA 71BD057840C298C1 -Ciphertext: 5B6DD83315995147 2CD056F384F90D22 A40335259464DA3A 1A18788A3537CE45 \ - B69DC56AC2695EE1 9F87EE9502D95676 D4C7B8A273C78E90 BB443B47FB9D6F79 \ - A08C6044E4F6C0BF 99B28903B03F75FD 6EB64C0CA5FE217E 6B4E2C0A141F6867 \ - 16D3BE6933A4BBC5 9EF254F49D03BA21 DF796252C0C6478A 366D5AF4B86B36B5 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192, large block -Key: CAD219480954F4E2 5F9ED320BCE6F8BC E3335197E7F71E4E -IV: E61042F2A4B1F7DC 27D8B60F7A0CE26E -Plaintext: 13745C1B187E9EB9 5731892D470FA563 2CF19D96333ABE02 D360EBAEB2633A59 \ - E57A9D851A84D842 EDF03DFAE60353CE FA07B80AEBE5AE54 42F0FD0F25C8A16C \ - 9EE6B5206F7E5C8B 20CE81DAAC95C24C 4B9B6CDB4F302B92 65AD32A7FAD311C5 \ - 8B8BCD1A3CBEA64C DF1BB73298C97483 5F086DC4D9630AE1 F9EE11874E93A96D -Ciphertext: CEA4D070D0CF8244 BD698563B61A1CFD 9AFD2E51BFED87C1 36AFD1315A56E31E \ - 7DD9F7729D248F97 F08D7EAC27BD221F 2F70EE7C4B455E5B FC2B289EBE2C349F \ - 656AE044B445EAD7 EC9562AA8B6D2C5A 49B397EBBDC32D3F 9BBA2CCCA2C84C90 \ - 38AB7163736AEF83 EC8EE54071C9E2A5 9711343C49B00429 842DFFCBB6273F74 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192, large block -Key: 92E516F9E17BCF04 718D3E0667D3DDF6 A53B15F7138B88E8 -IV: A0CD571229D4F3E8 D16FFB0760380510 -Plaintext: EE37EADCF3F5BC99 EF4FB202734B4180 C9273A027DE41CDB 399085C61F700817 \ - B9488D6778F9E08A 0FC5466BD94C273D 5CA76818BEE40621 36B11A376311AF4D \ - 0FFB5F14D3FC8194 C441235765FFF1C2 BE34C805D8D9B253 7F2869488C69813A \ - 96BDE9E3F7DF52F6 BBE1AA5A989228C9 BABACED65D8BAB69 3E7381A36E3C36EA -Ciphertext: 9A292703AD1BFDC2 C72B07A8E9EB0861 25809E2463C6AD9D 79B03DC3C0AC3D24 \ - 6B58E660A09AB846 2AB75BE337409550 08C78E38D1B4BF51 DBABCE1532DD202A \ - 2E45BF057668DBDA 5D3684EDBB40EED3 06B336489E2CD2D5 9253A2F4612283F9 \ - 4FFBAD5B0DD2245D D60E1D00FD1A23F5 783FCA276FB3F1F5 29064F7C6B644A51 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/192, large block -Key: E09A547ED471C8D0 0B94DE127654F9C6 DE5B9FC44C02C060 -IV: D685687464113399 655536B6F3B498E0 -Plaintext: 99A5BF6398DC4089 5E3C0A030360A3FA 4FE8382A90F33F65 F7F707F571282DD6 \ - 0DC55CFFC5BFB1A6 46887E3FE487967B 1C32FBB44ECE0A6D 4F9C5F7579EC3BEC \ - 75A6DAB383DB33A0 E37FE70FB7B15FE1 7BA5EC6672D2D743 92045385873F12BC \ - 3750FE9A7BA1744D 5B724C9AFA2142FE A72899511F587686 EF11436A9A8C8CB7 -Ciphertext: 070A343DF05B03DE 2A9F5F7FF6295C66 896E479A01F68386 497D2D357705D698 \ - 2E1DB3F91E16C426 A613806E6260ED17 72BF0D9364E33261 7D1A8972A594C1CC \ - B100D26683B02A82 1242D5C6C356DDF5 151B9CFFB1C1A09D 244EFF4013CC7BA4 \ - D8E71D2EC019D09E E08BEB53454F972F 0CE9C7578D7BB0B6 CF9FEA389081B2C2 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256, large block -Key: 9AC1BECD06D48538 9781F7780A9FFE36 8C4F448DA3BFB8B7 1C99B56E2A8A6F54 -IV: D514C21176D74560 227960277AFC8FF1 -Plaintext: 552237BEFFD3D8A5 1620E68804A16986 3FD6A9FC7A1EBFC5 51DB3E02C33CD96E \ - D7A26AC819ED968B 57E162277AA05856 6C5AA609BB4E631E 76100DD404180637 \ - 18D38154F1EF1B2B DD5C625C1A80A478 13027EEB841E44D5 99AE343C44207147 \ - 1B21512EDC1CCD2C D492040FB98045FE C56FDCCE194348CD 03E5308E9B2BA26D -Ciphertext: DBBA513FFCCEC5DC 8C6EF4DAEA907E91 06711024AB72C0D3 457F33A25D1DD48C \ - EAE70C1C6F6A531D A78F895980524BCC BD34138DDC5EA817 C9FA2D568613322F \ - F9175E03DE339CDE CFD3C5B75E69DAF1 CB8D0B4BD43044B4 4ABF8B8C18EADCB0 \ - CEC5A1E5F705E22C 3862A9A8E7061173 BC73B71F9227E739 1605FF9B2126341C -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256, large block -Key: 95BB432F5961DE40 0589F909B5F8C897 DFB11E6049596F4A 8083C1EDEDF998FF -IV: BE359A28DA2EE94E 21DE0AA669029F11 -Plaintext: 5E5ABC5F3AB359CF 9EDD54E6F30245BE 8BBB9914022A2B30 5656D3A82E2B0776 \ - 26DE512454C0FF67 5AE2D447FAE08195 DCE898F6B123B425 BD50100EA5836130 \ - AFB9A02A5D43DD25 4404D69D26F7B69C 8A4D81795F4B27CE 60348728677F4BD3 \ - 19A66110BCD6F078 89CEBEA8D107A558 602631C32E3F1DB8 A4037869604CE912 -Ciphertext: 4490E32229A46A2B 5CAB4B5BF49A7263 3CAD91E13838F1DE D0B09DE21E4EF6FC \ - 2D2F75072C5FF38C 640747C602F9855B 5B18FC5045ECC2CC E73D6BE7E5270D66 \ - 9C842F81FA69FBC4 82621D96DB333468 757B0F283E833EA1 D8C56DBEFF74A521 \ - 0B91CCBA8EA61D6F BE5AB7C494BC68A7 B4999B3E1DDE1821 E912C73CAAB2CCC8 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Simon128/256, large block -Key: 8D885B06D19A734F FAA5FF8D9509A3B7 77AA45A0A34142D2 A2CD3CB830A6DD37 -IV: 52F22C95B16AFBA6 00B248DE3212ABFD -Plaintext: 8FD8A368969A39CA BA27DD5095CE2DFD A8C2790B4C5BAB1F C8F53DF8C6F38C93 \ - 6D09E65A2DE4A197 CC9EAF1E846CB6C0 25597124BA10BBC6 6485A421AEE6ECF3 \ - 67CFF24870238196 AD614FC2BEEA68BB E23367B8D50C9F37 F48849181F901657 \ - 42629443F956C241 B9A7E1A1C5818BA6 9EC2AE166C2F4460 43864CB7FDCC5603 -Ciphertext: B66499FCE9B9F4CA AE7717D825A0CEC6 CDC5877AE81EE267 53B6D1D12C559973 \ - F766C08322385EAF 44C56B4CDAC2F48B E49D49373B227A5E 4361291C054FDEAD \ - 2B3A41A0EC74CC77 16BC903487D74DDF 634CC8C239698E45 EDDD33A31F82BBB7 \ - 3215245F5292CD23 45590A19B2D22105 D804815E587BFC7E E9133362199B0C0C -Test: Encrypt diff --git a/TestVectors/speck.txt b/TestVectors/speck.txt deleted file mode 100644 index 5404f4a4..00000000 --- a/TestVectors/speck.txt +++ /dev/null @@ -1,1056 +0,0 @@ -AlgorithmType: SymmetricCipher -Name: SPECK-64/ECB -# -Source: Simon and Speck paper, Appendix C -Comment: Speck64/96 -Key: 13121110 0b0a0908 03020100 -Plaintext: 74614620 736e6165 -Ciphertext: 9f7952ec 4175946c -Test: Encrypt -# -Source: modified speck6496 reference implementation -Comment: Speck64/96 -Key: c40f8507 5934046a 8ceded44 -Plaintext: 2203b9de 8bf9ca31 -Ciphertext: d3af2346 682922a8 -Test: Encrypt -# -Source: modified speck6496 reference implementation -Comment: Speck64/96 -Key: 6c65a9ba 5a0712a5 e04a04bf -Plaintext: e05349aa 204c1230 -Ciphertext: 3317e849 b8bfa9f9 -Test: Encrypt -# -Source: modified speck6496 reference implementation -Comment: Speck64/96 -Key: 19677d80 03d0c4d7 74b97dbb -Plaintext: 108597f1 5b756713 -Ciphertext: 4d74883f 0207db30 -Test: Encrypt -# -Source: modified speck6496 reference implementation -Comment: Speck64/96 -Key: cc8d5345 45d15977 a460923b -Plaintext: 2753e7f2 d2636081 -Ciphertext: d17e471a c5d62705 -Test: Encrypt -# -Source: Simon and Speck paper, Appendix C -Comment: Speck64/128 -Key: 1b1a1918 13121110 0b0a0908 03020100 -Plaintext: 3b726574 7475432d -Ciphertext: 8c6fa548 454e028b -Test: Encrypt -# -Source: modified speck64128 reference implementation -Comment: Speck64/128 -Key: 10391892 0ae2144b bc09f540 a51490cb -Plaintext: 7394225f 75c5209f -Ciphertext: 28c7efd1 a6d4c651 -Test: Encrypt -# -Source: modified speck64128 reference implementation -Comment: Speck64/128 -Key: 5858ebac 10095f36 f2ad734f 30b16f25 -Plaintext: 63d7a40a 30587bf1 -Ciphertext: 5ebb96a6 151a3250 -Test: Encrypt -# -Source: modified speck64128 reference implementation -Comment: Speck64/128 -Key: 0aeff1fc d8b6a72c 6c4db6f2 4a41e8f0 -Plaintext: 59700d77 9596725d -Ciphertext: 035319e7 9614f714 -Test: Encrypt -# -Source: modified speck64128 reference implementation -Comment: Speck64/128 -Key: acde017d b9640593 98e7b248 19bf6e30 -Plaintext: 06f8d302 73fbf7ee -Ciphertext: 88979af0 1d21a12a -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SPECK-64/CBC -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 13121110 0b0a0908 03020100 -IV: 2b2a2928 23222120 -Plaintext: 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 -Ciphertext: F6E89A18 C3D86773 EDCDC20E 75373B74 C5675E97 AC656A1C \ - 875E6571 500D5BE1 C8F3C462 48F411AD 2FD29D4C 4CEEF139 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 13121110 0b0a0908 03020100 -IV: 23222120 2b2a2928 -Plaintext: 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 -Ciphertext: 3E17D0CB E94D04B9 A0BBC9B5 80D4DCEA 9F8C92F0 F1FF5113 \ - C00F23E6 9714BC5D 5F77BE4A C2044265 7EF62C75 15D86982 \ - 7D56F2F0 AD865A39 4EDB489D B4762C82 B4A6A65F EB2959F9 \ - E6C77CC4 29AF09F4 75D4B0EA 18FB6CDF EE9E260E 67B64BE3 \ - 40DA7F52 31BD3AFD A64BF702 106F11ED C5FAC0AC 67C90A40 \ - DBD0FBAD 07DC9981 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: fd897804 791bbcad 27d3cc23 -IV: 2e6f8e62 497d6894 -Plaintext: 5736c8ae 98f248bd dfd0616e b729d4ec ee64e9da 72c2545b \ - d3cd6db8 4a1de8ac 20ac79e6 b3829998 233e3f14 78984598 \ - 0d00e01b c15b44ac a58095a5 8abd1868 c893bf8d c8c541a2 \ - 41ec3cf9 67c4330d 7fe6e4bc 95d007c3 30ce55b4 d07f32eb \ - dce43e5f e15e6653 52d674a1 af13dc74 4da5714d 5adc8fd3 \ - 4a5c0ea7 1c297e8a -Ciphertext: f8fcaa28 d5e1348d 49ca3223 2bc50e27 1f924778 4a234f24 \ - 6dc8b0f0 93f39ce6 8fc09efc 9adba077 145a179b 11e70655 \ - ca09214f 15f3aca5 979b507b 351a1ae4 151f7d27 7cd336b2 \ - 79b94bd3 7852909a 73a14c6f 60361be2 5b33b8aa 18797b7b \ - 63e7cb64 797905cf cab285dd 8e54de45 95585ccc f18ccba2 \ - 1b1bc333 cc0e42cc -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 7a5d83ec 3b01a66a c7df3f0a -IV: 3612f5e1 bb8078ba -Plaintext: e2c92de9 d7a8246d 07068dff d20d75e2 75185316 fcb73f11 \ - 8876a878 8a777535 6207b78f 153b3cab 7e09cfcc 6f359874 \ - 07ce2d0d 38d386b8 df8f12f8 ba2e3bcd a4a04366 c26de05a \ - 25a3d976 658b39ba 43700e20 b3cf8e08 5bb0c885 8d4c01e9 \ - 4d418dfa 795676b5 f38654d9 a14fbec5 df731bdb 67138f13 \ - ff34c5d2 0beb130a -Ciphertext: 2e568bba 9aaed9d9 0871f89d 3a859c1c 89b7f071 8810b4a3 \ - 4ecef490 c085de09 fafebe94 901a64ea aa9b8872 e3e34621 \ - f834e88e 9f1441dd 8e902dd4 8a17b181 27d32ddf a63144e2 \ - d8b102eb 1c07efe0 d1e25e64 01328fc8 d7604d32 1d04ed40 \ - 9b7bb0df e6917b82 05f4b9ca a84b4df2 e7002d8a c014a682 \ - 4a527f87 84c63208 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/128, large block -Key: 1b1a1918 13121110 0b0a0908 03020100 -IV: 2b2a2928 23222120 -Plaintext: 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 -Ciphertext: 6E1CA864 6D5F7BFF BB5ACC0D 58D1FDEA 90046600 1DF7145A \ - 76EA33F6 8BAA55E0 853AE5D8 6E3952EE B16FDFA2 83746490 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 1b1a1918 13121110 0b0a0908 03020100 -IV: 23222120 2b2a2928 -Plaintext: 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 74614620 736e6165 74614620 736e6165 \ - 74614620 736e6165 -Ciphertext: E8F71A10 591B516E B725F046 DA3E228D 8A849DE0 E4AEF499 \ - 6417186E 3366C952 3E823053 AE6B318C 8A411D94 1D601564 \ - C2B319E0 4655C7C5 5B87CA1B F86ADCE8 AD40BAE7 58F2B2EA \ - 0FCE4E4D D6F67E11 E884B794 4238F124 A12D9C61 17E6AFE4 \ - 32097CA1 7A854927 C11E5763 DC3942DB 4E9F911C 20A89B53 \ - 929C6A46 03F38DAE -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/128, large block -Key: 97dd3868 4209085a 7605a048 0bf89c4d -IV: 9763f9b9 74ee65a3 -Plaintext: 8294c446 ac74fa32 c1ec0f8e f536625a 6a7ba0b3 551d6527 \ - 3ce763e2 8146fd81 6b7fa5f1 4a9b4e2d c9ad86da eab61e7e \ - 6682f61e 69764c66 8724712f 3b3252ed 1cefd25b b9587102 \ - 7e0043f1 65f37ab9 6d831be9 e496ed2d 7303c632 daab19e7 \ - b57020d6 ca46da54 498e8826 87ec1429 e4480eb1 de612108 \ - 0642f023 59e1447e -Ciphertext: d59cfe00 ffecd29e 143e1991 0bebdd8c f0f89fc9 a9c442f5 \ - 4d7f22b7 4802b84f e17797c8 ec48acb5 ec96fb5e 0402a895 \ - 51e81b1b 20d01841 b8de802e c7780497 7f4f3dee 35d65602 \ - 2d728fb6 ceebf231 43768184 5b33d8ee f20fd5cd ff4d3442 \ - c9d83592 6279d4db a5aa12a9 8dbeaeb6 0a036855 8a9049b5 \ - b8836f22 1ede81b7 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/128, large block -Key: e8b67fe9 5fdee2ba fa26551f e2bd9ed4 -IV: f93b7f5d bd25a41d -Plaintext: 5a1dbb9f 0f7091cf 9cb69d78 d3370a5b 9e5d776b c5325bc5 \ - af3cc38c adb851e8 3f9387bc 8b26cadf 7da8cb26 7cc4a056 \ - 10e56b42 dcfebc60 9f7fa773 165cb653 9eed8bd4 1e68bcd5 \ - d6f17fe7 5a9e4963 c79218d9 892c0c33 2965c774 23c56e87 \ - 93e06950 4f56a689 98f43fdc 61f36722 398a9a13 1386b761 \ - cb77c4e9 dd8e27b6 -Ciphertext: 6488fe92 2f575648 f99a1fad 3fcb1419 65178da6 79c58f4a \ - a987812b 60b2c02a 340a81f7 d1a077f7 967f3c82 386d563b \ - 865798d9 f63fb1ec 88d1892d d3c6f85a dee8fa9e 9ed1e7eb \ - ec7780c9 386237f6 3000447b f57c5928 77faaf6a ecf57747 \ - 10a2bd70 ec126e15 c3d0df43 5682772b 9c515f50 be7328c1 \ - d195732f 4dd297eb -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SPECK-64/CTR -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 01e008df d878622a 2b7ebf81 -IV: aedda5ac 2793f82c -Plaintext: 37557546 ee59d585 114df2a7 a2db66dc 9aea6a40 f9e5656d 90432431 \ - d059e328 57402739 fbaf9f1f 589949ad 377f3744 57c69fd4 69d0b709 \ - d31fb7f6 d8a14035 cf2ee371 340d01c7 8b220556 49d05bdc 77e1dd77 \ - f643e3dd 65654b5f 5eb44529 5d0f9c05 7a9a21ad 14ec629d 6e90840b \ - 23cba457 409dcad8 88bb5336 6ba834d5 -Ciphertext: 453b3433 d64cccdb 8d091482 d8efa357 85ebd223 c9632635 9587eb0c \ - 9a5ca163 ef92dc46 f576fa30 5b092c89 c247888b fe950047 6642716e \ - 88d1374f 1eb7df21 c27f8d32 b810afa0 84122caa 5fd1e11c d2efd8a0 \ - 6823de24 5ee8db41 773cc65d 417ccfce b9b1b542 37ddf27a 5708ea54 \ - 9269d575 aee55f6d 4e4d43ee 2de13dc7 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: d3047e0e c3b589a3 46429a15 -IV: f12bf8dd dd176834 -Plaintext: fe51d579 48335bc5 bd68a329 c4e79399 81ca3195 fa20f4f4 f2127fe7 \ - d7891cbc b3ed1ee4 c078d3aa db015f88 5ae333c1 846216ef 50880c20 \ - 9b317ad1 e9dcaacf 003765ec 889c9a82 ee9af56b 20883209 42f54beb \ - 44c9676c 9b2bacde d270201b 6a77f7b4 4fdc2e64 3db5baaa 50dc3569 \ - 50a9fc7a edd10aca 7f19a377 61c8b94f -Ciphertext: 6d6f6471 64cb6110 22dfdf1e 1c301a77 0bae9055 44e68917 c5bd5560 \ - 8d8830eb f8befcfb 961e599f 8011b446 6999434d 69275342 c57245c1 \ - 20bfad26 6ec3ce36 7620c2b6 30dd8be4 bf0a000c 199b2237 8043d2c6 \ - ec345a78 996a40fa 8bc5362c 5ec206ed 9d64faeb e1f654be 6002fb4c \ - 6f7e5fe7 340c0b4b d88667f6 e38bf799 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 2085eca3 ab4e99fc e3117fc8 -IV: b0f3d376 a6b7277e -Plaintext: 216a27d2 55a7d72a c9c69d3d 1b2e7faf 9bba051d b1e089af b2b1b6c8 \ - 1bb4f80b 62e9b2f6 8547fde1 7191efc9 13109cb8 7fa786d4 09216c4c \ - 2762feab adb732a7 71edb5c8 1b35ffc1 889811f6 ec93f481 2611d240 \ - 99f40c9d c2abcec9 fc54dbde 81ab45dc 75c9c3e3 aea85daf 454df9e0 \ - 22555a05 80fa986f 5a0ecc16 c760ba07 -Ciphertext: 5b88b8ce b8f07d4d d59a9fc0 015075e7 9857f147 31446905 b40fdc61 \ - 8880112f 6209596c 874045b2 eca82144 c04203db 3af9d8a4 76eb95a9 \ - df4894fe 80333bc9 1cbe41cb 8ef443ac 6674723e bf01bcab 8c3b7dcb \ - 94514fc6 0c437e6e 78f3caa9 61fe01d3 687968d0 874f7999 ac9398ba \ - 769e01dd 068be060 0fd37fa2 2f7fcafd -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: b22afa39 7ce72944 959bd673 -IV: cdbcecb3 89f37933 -Plaintext: 4b02a986 f82e7864 32b391ab e3701c69 213cccc3 61a5e608 235f4f60 \ - d8aa85ce 952e23d1 e35f7560 57889c40 173ef00f 909e5ac3 5f9a5dc2 \ - aa9f8538 b811c390 ee1f2ced 5a5a4af8 93754c6c 8b53c204 eb322a23 \ - cddff753 ddaecba8 87537738 e29d8671 44da56e0 6ed99444 cd313774 \ - 9284148b 19160e53 0ff014d6 ca5abd9f -Ciphertext: 831befab 18a6cfb7 abd6a14e 24040841 f755d816 ffc25ad5 0579770f \ - adeea740 f8c8aef5 78a2df24 1a958d1f 25c23b7d 63b2630c 7fbadd4e \ - 269f70f0 7a096b5c 3beb93a4 11fe97ba 70131481 2567fcb2 a5ddf18a \ - 06b46ed7 139b07b5 69fef670 9ddd68f9 341e8eb5 98a10e3e 70617139 \ - 85020a5a 9386c52d 285a7e70 efd16e63 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: fc0a760e 0a669927 f412f9d4 -IV: efc35119 917a0d49 -Plaintext: 32a6b81b ce4760e8 7e7e231f 04632181 8611c15a a3330428 33c9de6b \ - 9d0124e4 b935e263 bc6623f2 86efd0a8 3adf163e 761fd9b1 4da8b7e2 \ - d75be1ff 4b6a9556 92c128bc 09d920e1 18162b3c 6b33fc47 2abf9536 \ - c3960169 2a2f9d37 7da57551 c5956cbc 1d5dfe22 c2dd9382 a1fced5f \ - e120b363 e96f7f27 9f7845c8 bbc7d1cc -Ciphertext: caf22960 e1feca77 7ccfd442 240f86d2 d7a7e6b1 fedc728c 09b3f8da \ - cf281ed9 b3b50bc3 a9b5b12a 3c5f63b6 d85f0eee 3481f14d c32dbaa7 \ - 0b8b9a5f 4ce9cf13 31bcfe76 7c29ed15 db9f2502 aa8607cd ed4623cf \ - 43e70d11 ab95bc50 2a854ba6 7c8c40c5 a1c05734 f7239b3e c5415e9d \ - 3563f2db 438cfc19 ff95c95e 5e889545 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: e8e42ab9 9ba57bcf 9908b8d8 -IV: cd3c8239 098b4bea -Plaintext: 1e0f5543 f182286b cb004da6 c6efd2b5 3696ee0a 37c25d60 e49384ed \ - ffb0c6ff 93a77bbd e24b3680 97c28652 3caaad7c d951153e c8752a54 \ - 15c2443e 32cf399e d7cc2020 e9b55eb8 721a31f1 fc0002a3 19fb36b5 \ - 6d945527 90574184 85260546 87dbec81 a4f2614c 43914a84 0534bb25 \ - 529c7921 48091ce3 19cb1374 9dafc9d0 -Ciphertext: 08e586d8 30f05dab ee37131b 35320dce b2fae52e add4eba4 59e39772 \ - 23be9aff fbd223ad e7ae55bd f707f1ef 4b2bdb3a c0c0b0c1 cf5e4ecc \ - 728314de 02675e70 0c9015cd cceab730 bb93eca8 049dd88a c0aa53c4 \ - 097b4cd7 83c1f8e7 d3a067e8 1ae1e50b 7579ef00 3aa679f9 76e12b5d \ - e0d3abb8 732743df 5f5f49b7 3b9956fb -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 5d5e6aa3 5b340fa0 5860c3c0 -IV: 1bec9d59 6917cfff -Plaintext: 1873586c ab219460 84a0b7e5 b4dc93ff 40dd6958 4bf4204a f702dcb7 \ - b40e8b6e 31af4054 ebc68771 850343cd 11e43518 3864b1a4 2f914510 \ - f0d4b04f 9e262071 f26a2cca b8b6b898 8b228f5a 5305ff83 4ddbd4b7 \ - 320e2aa3 121fc1c0 54fd453e aeb650a1 26d0ac0d ec468493 e83fece6 \ - 043c14e2 c9a73c33 45c5ca9e c1a94c83 -Ciphertext: 0e2b32d3 177d9abd 8aa9d004 e0512aa0 7a018f20 eb7cc785 1554fc4f \ - 62ab417e 39fb437c 7983c3a1 793c34a9 80cc7eb7 177979f8 24f684e1 \ - c9319d62 1813dd5f 1f41cf62 f885d311 3b5c7d53 1c716b88 cdc006cc \ - ecd65f93 9eb84950 206bf943 c9c41ca3 5bcb729a be8210b7 05f31b32 \ - 29fdf417 c3316c4c 4f543ffb 62e746d4 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 0ce93bcd cba42490 395b9bce -IV: 71775410 ab930944 -Plaintext: e454e403 bc308714 73383da9 cb20db6d 459bb508 d184fef4 4ca2405a \ - 362b24f7 86dd8441 a88322cc d68d83f7 a88e0a5b ede3fdfe c4161dd6 \ - f045297e 95cae7d1 2c5adfe2 cad70223 151f0ebb 8115dc85 dab7af50 \ - 53c189df 70248981 90c5e23b a1c7b4a3 a3794d18 ea2a3dd9 9575779c \ - 3eb3cfc6 651bae48 a2e6aee4 760111ed -Ciphertext: 2a6985d3 8b1f71b0 d5811d9a 9ab9e8d1 ccb501f3 bca8c4c5 baca4ac2 \ - 4654942b 23ad480d eee295f5 47e46962 80ee81e5 f13c6d2d 9ff12f47 \ - d7bc790d d9b8e2b2 8d8d0456 952a91b4 71c57980 c5aaee34 c59ac158 \ - 72348f27 a6e37e67 bcb9e87d dc307efc 2a636b54 e4625c02 07333afb \ - 16a29228 595552a3 1dd6b149 5d6961a9 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: b06fee47 f5a46b7a 7d99ba6e -IV: ebf68a00 4ebf7dc1 -Plaintext: 0bdafc03 73421a71 8c9acdfe 0b1fefb5 bf5d6bf6 14b84792 ac19a5c0 \ - e811f618 f9303851 2deeab4b 58a1dea6 26d62566 30807dff f0d65f0a \ - 587102b7 062b765e f88d4cc4 d89c3058 1fc12d03 f950654b 4a59e017 \ - e1cb63c3 6675c8f5 38d8e0e3 04a0bb68 4bc74d95 fed8cfa1 da97ecaf \ - 99363695 46df48c4 20338b4f fe708a67 -Ciphertext: e1b0d5b1 0471540e de4096fd 09f26ed8 b08da4a0 f7cca45e 6070f5d2 \ - c6f501d4 83de255a 273d46fc eb0dc310 c86a903f 25db7ae9 7fc746f1 \ - 0c2a2f68 f30bb277 84c5f005 e08ee2b4 2fedbd99 16740bcd 11eb3b8c \ - e255536b adda87d9 488cff9c abb87da5 d632f8b2 37820790 dff6b9c8 \ - 0f693c09 e6f8dcaa 42d1e954 2feb9013 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 7f88b273 be78dd9f 4e90ba0f -IV: 2232a422 457db6e1 -Plaintext: 0571d828 ce3e3216 c35142a8 b46beb08 a065fe93 51e4c938 e0e7ebc0 \ - a0ce51dc afa8ab7f bb00a59a 28641877 52b58bad ad083ec4 ccc09f61 \ - 0c5dde5d 6f74babf d653373b 3ec00272 52a3d012 5665e800 9ca19633 \ - 7bc050cd 8c9b81ef 321f2db7 abce7aad a642a63e 30529a39 8a8e1a83 \ - e6969441 2bd89d27 bed78e0e 5b17f86a -Ciphertext: 593342ad 20c9204b 3bfa74f0 2f179a66 325182bf cfc3efcb 79438b89 \ - 86c63168 f82e7984 67031d27 4a53fa65 992faa34 16d5c9d4 f7b8d0fc \ - 769907c3 a653cde4 a350302e 27bdfdbf 80cc813a 4e7fd197 41ba2d59 \ - 72e04e68 238e9d72 6a31b73d a5111abc 4ab734c8 c18f8ac4 ed1a175a \ - 0a0e2fe6 0ff4d59e 5de2470d 5a8c3831 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 62870ce0 de3a04ad bfb2b65b -IV: b90b19b8 678e5053 -Plaintext: a2a85535 2ea29f6e fb992bee ad4c85bf c62c2531 de968998 5a14836d \ - 5f619122 7e92c345 b6654e44 d7d0fb29 098b66e2 4cacbb46 23f0443b \ - 0f1ffb4b d62875cb cea2f9ed 2334d6fd 1cc93ca1 6e3bd141 f4945659 \ - 50b87673 95b02f2e ae3bc64b ccb92a46 a014ac9c e268258c a925fd52 \ - 655368d0 da4d0650 2bc3433e 102f0938 -Ciphertext: fc31426f aa0ff9a7 06ad20db 0960882d 5f6f0ed8 f4be9256 2f888315 \ - 6c81ad5d 98974f68 f866f876 fb34b6b5 822c4d7f 46bc5bfa f423c8a3 \ - b57b65dc a4a57aef 6c1aad6b d518163a 1a621bdb a79e7c57 5d76ca87 \ - 3d354404 8d639b9b a5a18afa 66d38d2e 8738d8d5 75efac78 6e5ee98a \ - 9f7807c2 6c4d57f7 05b4b5cb 9be96a6d -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 5e365c7b 0e733eb0 3a58615e -IV: f465f87e 5944a033 -Plaintext: 4353b29e 6429d228 7efbe6c7 20606a3b 1e319cfc 2a9a9fdd c8d2c79a \ - 4be099fd 06d56a93 9e6b01e2 a0a679a2 2a2dc685 52b3da6d c6071f3c \ - c87177ff bf5acfb9 0bc23b1c 5bdb8db7 2ae1c594 b12e174c 7cb2c4da \ - f71bbeeb 759e52a1 3b77a663 ded3ecce 2bce4b38 59a9700b 1dd9857c \ - b31ddb69 a27190c2 e066910c c2bc34cf -Ciphertext: 04e2c9bf e2c59b24 d588c114 9a267e79 34929db2 660f3404 03f25e99 \ - 7deb02ca d86feea5 7fc0f3f5 3721c004 83029ff4 16d745ce e0f8378c \ - ceb73231 3d5bc304 ce972ffb 5c75250b eb645277 77fcb157 5e06004f \ - f7979608 e1175868 bcd3cee8 d36ccef9 d84c01b4 eb52cadd f8c0029b \ - 5b5282bc 800eec5a d2a19298 db8a106b -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 209de4ef 26529a61 23033dcb -IV: b22ae6dc d402339d -Plaintext: 5c95c517 22e1710c 26fda5ef 01e14da4 e9261e56 db41855c afd19050 \ - c31b5bd9 82e48ab3 581942d0 28cbf808 054a4f47 f7b85798 b5d22c40 \ - 9f19e964 5b848977 7bc580b4 42b9935f 086a088f 394be1b3 d01eaa41 \ - c8869357 ef57c378 60f3dfe9 e78ad415 86f5c374 29b1c779 33d9e03c \ - 7750bd0c 250d1afc cbc0fcb5 8f74011e -Ciphertext: 63c5a3c9 48e32107 4a04e8a1 8ff46a6e cacd7a3b 7b1ca1d9 3e2205c2 \ - 2a4e09df 016e1957 4a0b4dff 8b5e31bb ec1cef77 aa3be551 f03ed1a1 \ - bbfa31aa 26362aa4 6923dfdf bb771391 cf9869fb 7caf09e3 0387b5fa \ - 8fce70fc 37aa9952 7a991d4d 78f34fde 94476407 e9d01521 e164eb49 \ - 8a074732 8f024f85 41a04e47 35bd9a6a -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 3ed22886 e8150a1d 469f6e04 -IV: de9cca25 3053575a -Plaintext: e87bd4dc 79884ae0 3404fb42 9a455fda 326b191f a6de4ae7 aa588002 \ - 521673ae 34c50523 e1d611b5 6226c495 48c8ec7a 0bc819de cf277f8b \ - 241c0b3c cc6d47c9 9a717d31 32b24a15 87b1fc96 53953d47 560b96b2 \ - b4351510 8dbde188 746e9480 392dc7da c54c958f 5c2c8d4c da9fbcbb \ - 6966cc89 55de6d66 c286a00c b4eaed70 -Ciphertext: 4af556d3 c58a8f86 06e26425 a396f14f 89c31875 c445b2db 233dcc40 \ - 1e037e97 7fa4b8ce 58c3c6f6 d2d34bdc c5c78840 76009e41 34f4ca5c \ - a8d5cdfc 2aa117b9 ac207e35 6f432eb6 3c4f0d1f 70d4bd42 8e24a70b \ - 584895a2 3b5757da c926f3bd c85ddaaf f85f6c59 c4d1821d dc67c6e7 \ - 87f5cf94 300be608 cf4df1a6 db22558f -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 97dee01d 51690264 1d5520ef -IV: 8c927532 68cca698 -Plaintext: 07e3d507 da0473e4 9d89e09a d4cb7b84 b90a8a05 b65c4aaa 13eec172 \ - fe4aed22 46b6fe54 14a8f116 1e1091ba 1b23b7d0 45352dc5 31f22a81 \ - 22c6ab0f f9451211 9697b923 5b9631a4 2634373e bfafc1d9 3858664b \ - 16d2e84f 36aa02ba 51c9f68d f3ba884d 27449501 15c0234d 51fb2dfa \ - 37da1d60 90fc93ae a97df2c8 f59dfe7e -Ciphertext: 90692e92 1400503d 1d715068 bcd6f18b 587cdda5 f89785f3 2f681f4b \ - 97b822b8 1f096f3b 66498424 08961999 838fd1da a56947c0 e22a8f2f \ - a75c9643 9f499002 ef3d5f1a 0c220ca4 f483a58c a64dd03a f6afe844 \ - ba3609dc 764a737b 040df5e3 4c0d94f5 0ea34a61 03e3de8a 1c2e219d \ - 5aebda89 a6714428 70a33a38 8b286200 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck64/96, large block -Key: 9c64b298 4f9b16c9 7fa390c1 -IV: 3b413ced ab042ed2 -Plaintext: 77ad5297 006cc0cf 79b3010e 03de19c0 201f592f 8835273a 76ff003f \ - e88187b2 5ddea59f 7bb3a136 7df8a454 f40555ab ba68740c b98a8fd9 \ - 00f83ded c10cf152 6f52174a 83eace2f ff4a6261 84c46822 ff61cd0a \ - 82bd32aa 485230cc 9c8e4e1d 64f1d463 eb5424ad a51f1321 68cde408 \ - c8f6598e 2f163c2d bff7d40a e5dc0018 -Ciphertext: 92710755 4aff00b2 4743bad9 cc130ff0 5cd676f2 b0f384be 416dc875 \ - 13d05f5c e6b5a150 99705d7e 62a42486 8a8b442e 46b9b753 1bd62d21 \ - bd4e4955 ae463a6b ed5378b4 635cbe38 ea444a6e e7547276 93fdceee \ - c949b57f 053bd621 f48251b1 9d6dd934 7211a58a f7afa8e3 02e412ce \ - bc803aef 1b56ab2b 5d94e224 245eee3a -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SPECK-128/ECB -# -Source: Simon and Speck paper, Appendix C -Comment: Speck128/128 -Key: 0f0e0d0c0b0a0908 0706050403020100 -Plaintext: 6c61766975716520 7469206564616d20 -Ciphertext: a65d985179783265 7860fedf5c570d18 -Test: Encrypt -# -Source: modified speck128128 reference implementation -Comment: Speck128/128 -Key: dcc7317a143f0809 8cf934ffa0fa0166 -Plaintext: e95bb3a86bff9904 3ac90a0dff04508d -Ciphertext: 46c9f2cde92e495c b4b043184a79358c -Test: Encrypt -# -Source: modified speck128128 reference implementation -Comment: Speck128/128 -Key: d8971bdb1ac43023 b1f0bababfd49fa2 -Plaintext: 4d24d7db47ce1d7f 2171288c8d56b7d1 -Ciphertext: 6ac918924cbb2982 5a5b9b2c55241b74 -Test: Encrypt -# -Source: modified speck128128 reference implementation -Comment: Speck128/128 -Key: 227ae0a52a953bc8 0d9941492af92b16 -Plaintext: 9dd7705e6735b82c 20b15d7e09d18ece -Ciphertext: 305c4dce6a2a6d6a 4ce40ceabab19e66 -Test: Encrypt -# -Source: modified speck128128 reference implementation -Comment: Speck128/128 -Key: 2711e1202873f5a9 7d7595d07d0d46d5 -Plaintext: 21fbbe7ee7ea5c36 c57deaefa43d02cf -Ciphertext: e0f82c7541bc7c48 e7a6b5c1407f6a1c -Test: Encrypt -# -Source: Simon and Speck paper, Appendix C -Comment: Speck128/192 -Key: 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -Plaintext: 7261482066656968 43206f7420746e65 -Ciphertext: 1be4cf3a13135566 f9bc185de03c1886 -Test: Encrypt -# -Source: modified speck128192 reference implementation -Comment: Speck128/192 -Key: 325505cd609fb51f 9b9d45f94fc4b1bf ae97dcd50230c96d -Plaintext: 5305aebab8ec1199 2b8a179d18f5f4cf -Ciphertext: 70b726dff52b7cd6 feee6a1dbd281b6b -Test: Encrypt -# -Source: modified speck128192 reference implementation -Comment: Speck128/192 -Key: b70e94221848d8c9 b5b6f8321c7ae332 08b23336e6bfc606 -Plaintext: e599ffcf3d9a3604 d28c41bced252e0e -Ciphertext: 3e183b8e42aaf312 5534867c8362f45e -Test: Encrypt -# -Source: modified speck128192 reference implementation -Comment: Speck128/192 -Key: f6065032e84c44e7 eeb8cb9784de9165 17d70b3effe14dd2 -Plaintext: 73d1d920a04d5424 2c1e8e165f5400f7 -Ciphertext: 8cddc774cd54de94 640508f5bf28b4ed -Test: Encrypt -# -Source: modified speck128192 reference implementation -Comment: Speck128/192 -Key: d668611ccb157f86 af2d16f2a180704a e47ebbbce0fc518c -Plaintext: f7e882b59610cabf 387c11cd327306a5 -Ciphertext: 35d04e14af2e323d dc2ed1c342158cf2 -Test: Encrypt -# -Source: Simon and Speck paper, Appendix C -Comment: Speck128/256 -Key: 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -Plaintext: 65736f6874206e49 202e72656e6f6f70 -Ciphertext: 4109010405c0f53e 4eeeb48d9c188f43 -Test: Encrypt -# -Source: modified speck128256 reference implementation -Comment: Speck128/256 -Key: 009de74aff060640 4f8a3a01b82c2709 89f4f20e50cf78d5 6b30510fbde1ad1f -Plaintext: 36b0e93a0c985b1d 95157bb5eace3396 -Ciphertext: 7fabf615c7f6f27d 59638cdfc00b94f5 -Test: Encrypt -# -Source: modified speck128256 reference implementation -Comment: Speck128/256 -Key: 56e98e97e4c8395a 5837ff90f4af0262 8443eb9ac42894f0 0323e1b753aa9eea -Plaintext: 01949b6adb670104 09cdaf021832b51a -Ciphertext: 4ca628164586adea 4328cf80a1c46ea9 -Test: Encrypt -# -Source: modified speck128256 reference implementation -Comment: Speck128/256 -Key: 52182ebb79e4c18f af0a488c2fbc6d29 887909a5acb91a45 958ecffea2d9cf3e -Plaintext: eeb40213bf670ff2 150c5e2ef8adc425 -Ciphertext: bda5a149daca2515 64e0e37e27747ca5 -Test: Encrypt -# -Source: modified speck128256 reference implementation -Comment: Speck128/256 -Key: 50dffe5dea70cdc3 2b61f347dc6b90ea 0d722fa9c533f6cc 60b386852a63b0b4 -Plaintext: b024db26b66484aa 974ae6a8cea034b6 -Ciphertext: 04c43c06d14d75d8 905c3e0487f2be30 -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SPECK-128/CBC -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128, large block -Key: 0f0e0d0c0b0a0908 0706050403020100 -IV: 1f1e1d1c1b1a1918 1716151413121110 -Plaintext: 6c61766975716520 7469206564616d20 6c61766975716520 7469206564616d20 \ - 6c61766975716520 7469206564616d20 6c61766975716520 7469206564616d20 \ - 6c61766975716520 7469206564616d20 6c61766975716520 7469206564616d20 -Ciphertext: C5A2FD31AC3E6503 637F10A940ABB06E 7B9F2F82298E112F 5CB2CCA6CE515281 \ - 6DA76987AD55E001 8D9688474643B9F8 1FA074A01E49DA70 B5E60E17B133F1A4 \ - 6A523B35EAAEA8D4 E62F529FF7762802 2ED85AAD0593A762 9FE414308A2D4073 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128, large block -Key: 0f0e0d0c0b0a0908 0706050403020100 -IV: 2f2e2d2c2b2a2928 2726252423222120 -Plaintext: 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 -Ciphertext: 326CAB63D41F6AF8 6C690C17E291E889 8BC9926083CC09A3 8287EC3866163A9D \ - FB28FB7FBB482231 F5EDC321BC62FC3A 4C8916ED98796D0F E27BAE58CB20F26E \ - CFB9068555B17E2F 488DCBA452B7D947 8525AAB49241B022 6002989890F79606 \ - 17F8ABA35CBCECBD 60A3D47A7250A7B3 DDD46C9A778880F3 79AB461BBCA47057 \ - 44FA679481F8BDE9 CBC07AC26FDC3207 66D39279FA8E2169 1E7F4FCAB991659C \ - 6D7EB45A003344B5 593FFABACCA6CB46 2D716071D06E4273 159F0E4E0388FDBD \ - 12809864CBC5D597 0EEA0EAA8C1513F2 9240BAABE82A477D B2398A8DA616981F \ - ECF3D6F3BA981251 41ED126C1C86C17D 9367F94D2778C12B 2AE8958818EAD21E -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128, large block -Key: c68d29664b2766a2 bdfe20230619b8ce -IV: a0de35c7b9fd10cd 051528b16a09a6d4 -Plaintext: 3823348a2b6185cd c6672a829cf0db60 076edc8c0f7efb3c 733735ca75768f6e \ - fa168311dc335bef 811749d9f0fda742 0106bcac21e32d75 f3e3e410db98321d \ - c363579419d696f7 502a2d655ef39f63 5959c25bbe8608aa f36f65915177ddeb \ - 21af1d863ab1e9e2 473d2b4fd4c677c8 07646825e8690650 f5d3ac8851625814 \ - a80b84b2d98da474 db006f922e20d4f4 1ede2c22d6d28ef0 eea8b37d49c53b97 \ - cd1ac8e450698767 e47a5fd775c61e0f 733bccf42fc6a8f8 068b9cb640875128 \ - 579da221416ab150 38151cbf49452934 e7553040448d1646 7f49aa7f7c48c005 \ - 7bb674e8c6aca324 9ab41ca5246f2dd2 c3e366d3401372d5 e1716889d11a4bff -Ciphertext: 620efc4fc69f13ca 59825dafcb789392 6fa35bb85756607f f45e4eee64ce16d0 \ - 8050baf34977712f 71d25952286a25c4 d5e33d658cc7132a 23d569775a69aa4e \ - bd331a966e935e8d e133f3e299528dc1 e8b88a4e23414a83 a3407aa7e5111bb7 \ - d83fc447dcb49c55 548434cfb054798a 6b1942bbf8455a55 8ad014f560c9d6d3 \ - 85c52722d5053b7f c3f096c4e453947a 28b7989b11126299 feaba0c036d139b8 \ - f60e607354532cfc a9ffa8216418bb85 3654f0487061d68f cbc481564448e9fa \ - 2ba5da8e54c222ff 458a4015ebd9a230 596e29d71bd7e998 5e75132ca3347c4c \ - 6a5429c56866e0c1 18d175de90d33979 ffc6c5296916ad9f 0776a70f8908bd32 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128, large block -Key: 9039e8b1530076b4 6b3cf7287ec85e70 -IV: 65a9b1991f814387 bb059eba320db1a8 -Plaintext: b477749b15778e93 31bf8752abf913b6 181ceaa94903e6cc 66d962d0f7bd8a2f \ - 96b8ff71cef39487 657e67831ea69fdb 8ff0a5df910f3418 0992010b8d23d554 \ - 7f4972d9c2a1efcd 02e6b8950059faba 17fbab1b7f0ebe2a 1da06d43e7767541 \ - 80e9cda53b0e2fdf 269318d62c095015 10640f3aca1dd4cb 378aa5d8cd923aac \ - 25be5a0e55fcd161 f877c4b078caf27d d410d7eced28cf77 3d0258a25b6c2014 \ - e3ff18addcdb1173 5498cf13defc90f9 85264d9da179d372 3097221bb978db9d \ - 8b95c76ac888aa4e 8b7bc907ca2f6b4e 5a23fb36d1954a39 982cfd8c28aadc18 \ - 2431167ebd648d05 cd44f76bd965c9a1 05b96640c59bb8b0 52672ffb3b639a27 -Ciphertext: 4feebefeb9310741 a1384dc25ab69501 e2e8f77cd971c91d a9f0b023eef42aa1 \ - 7059924961bd32f0 0f4398a57193355a dc3436ec130ba116 bf186f86e476887b \ - 2332f0fe17a8b908 94819b252d7c8065 17efae225743f88c 5239a4309b0ebd2e \ - 18df51ad08b0cf70 6f2aca28f222057c 5d76a888db649f6e 74f393e04ebc64ff \ - 9210da6676269cc4 d06d61c82f4d86aa 234aabc6856571ec c02540caef21188b \ - 1127b2ccb89e5b85 e7fbf93ac3f83c42 e0a558c01de04fd5 398f09b2da9a8677 \ - 8fdde8d7595febef 7d22f233db29cbda c17853f90ea2e985 59f399bab7ef74d1 \ - cb4867773db210f0 dd28e18d24623cb2 ef6cc49f650e4223 252bac29113041dd -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/192, large block -Key: 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -IV: 1f1e1d1c1b1a1918 1716151413121110 -Plaintext: 6c61766975716520 7469206564616d20 6c61766975716520 7469206564616d20 \ - 6c61766975716520 7469206564616d20 6c61766975716520 7469206564616d20 \ - 6c61766975716520 7469206564616d20 6c61766975716520 7469206564616d20 -Ciphertext: F68676ABC19DB568 9491BF84472D6E56 A3FA518DE28333FD C89800B89444EF4E \ - 574D601B4895B0F1 031E32FB0C2E52B0 86992049789C2BCB 15783CD487C27CC4 \ - EAE30A4A344823CA 2AA8500A0BB19A44 E8667B5B225869C3 94E893D7DD0EDC9E -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/192, large block -Key: 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -IV: 2f2e2d2c2b2a2928 2726252423222120 -Plaintext: 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 -Ciphertext: 7F27FD5047066D9A 1B75FC13ECCE25F5 524E35B87055CCE8 80D1EDF503CCF5E0 \ - 013BEA759EFD4626 1551D39FA4622952 603FF6750602CAE0 2B0994AD1E6414F1 \ - F2804AAF2B955C23 FB1D54FB37B03A10 C47BD1E774EF29EF 87DA840C652A51D0 \ - D2DDD6CF235C99BD 7F8C89188ECDD971 DDC79BBC271CCD0E D156B262EA1A549A \ - FFE911FEFD5EBC14 BBD1772CF5B54D18 CB33AD85CC5033A5 DBD24257EF9567E4 \ - 0F42175584BECDB9 C204ED3E2BE4F62D EE38DE07DBEBD74B 1B6C064769753134 \ - A3FC6D5C1E156C9B CFDE7B08713F373A 089AA3954F5BD2D9 D37A6FC4630AD003 \ - FEB0DC05E233C770 85A5D92904290DD2 CC1415C62F0D6330 FFDC78AEBD5851D5 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/192, large block -Key: a0f764c6654c2016 1d993b738cb6c482 1220a547a0244512 -IV: 60a0c78d6b45e9de dceb2690f6420711 -Plaintext: b9eaf424ffb1c2f1 8892206fae5eac4b 614ef86491a242b3 d81b14b78775ac53 \ - 336dba9409fa5a88 cd99cb4a993a163a f4332235a48672be eb87255c216bd238 \ - 2d47d2114a6210d1 b2d472aaf26e221c 9db4667a45d38e3c 46a8f2d1a3069388 \ - f920452237d96be7 b4f2497dbd754913 1024eee878709466 ea2a1f16e967a8c0 \ - b2ca9a95fe866156 b7175a5f18802e45 2f7a3ef80cf663b5 9c2641dbe56502da \ - 9baa9f95cf1885bb 7d1330cefc78cedf 78f874fbe78f198b c95a97b469cea3dc \ - 793521b9727174b6 3623f3fd9e7eda75 a2f969e97295250b 27bdf35b0a9884c4 \ - bba5f3da0c48baac 57434d66e3d87dd4 8c380ebb063d4d60 3717764ca679a923 -Ciphertext: e68016c68dc908ef adff4f143b45a066 1f14cfbe7411cf2c 1e5be465e05748e2 \ - 19d6a139f61e828c 2ebe248abd14ad9b 283d39b3dd579919 619a930c6bf6d22f \ - e73d6ee83710bc58 e87d45b98d736673 1cc2c6c6aafec5a6 b1838b29fcc09a69 \ - f663419455354df9 fb7e147fb6efa7f8 a31610d181646d8c e163a111825acfc5 \ - bb8cbc67f17ecbac 67ecd1e8c24d490f 0d07b563362b471a e3b61bb72c98a9d9 \ - 0c9a208035792642 52435f4b4251f442 a10f0cd2a7a60453 5b5b75e067399e4b \ - 1ae5d6cb0b8e99f3 c4cdf2ee19483b4c 821f70e37edb6e0e 8db1c7e076b32eca \ - 6ae910100c5cc245 4009771172309fde fbdac55236e39f67 4e4dc07ba200a577 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/192, large block -Key: e5cc0ece213aeccb fa51ecb1ff08d83f fb7b25d1968b01c3 -IV: 39a1a296dfa6680b 3434b5dbdd67ad25 -Plaintext: a25d7ee67db1ba92 b7cdf71b8f4570fe 653ed014e6dc6d72 edf4beb4c8a54c77 \ - 22ab00d1752a99ad 2461eba1e4e9076f 29756a8639f14597 4fb4a68738fa5a2b \ - ccede25ffff9def2 1640668bfddf9d8f c473ad020dafd547 f30d9af47b3a57e8 \ - c883e1d690772227 f7a3dfaec3e224f2 8d652df0a6b20b63 3f12c67cd199280d \ - 00973a3381d4ccab b16d579b3abb5c2a be3dd1d8c954b4ac 5cafe99746861296 \ - 44a79e14dd648745 73f3c23e578db592 acb25b19145a0cf3 35b33f1fb224c766 \ - a78e3194509bf86e 317cb1b77f519e5f fa155fac07ddf854 41fa67c8f4fa45e9 \ - 5f6cd447abe4d712 31ffbd14bb4e7735 d37c8df6d3caff03 dcebe51170a12a26 -Ciphertext: 244c80c64a83002c 2b5ac8c556326fc1 c3093b9e45168cb6 5d88fdc80255ea06 \ - 9add97e8e61593d8 9bcde835afae1cbb ede24f17af963c91 a28ebdb35889280a \ - d62f80eb7f283c55 a45ed2ef617a2b48 170c7ce0613fad9c 2f5e5b4cd1f9b283 \ - 4f8ac3e92930f591 6c467e8aabb69a46 07b0f4fb2eefc2fb 58c9e823a55d43e3 \ - d44fad428d9d2e46 d9dd847c0fb29134 94b87d332101008a f18ed7d5ac5321a9 \ - 6b9d04fa194957b5 6076f96cdc702cce aacf218623e1ccd6 f61993d674a43897 \ - 7572d8dfdcaf40b1 297b84cd5845e8a6 35d32eb666244278 5edb1a27f127b71f \ - c45b1b2d069f3f25 c82f1f157649f254 f7b8f2b7875b7078 dd2db73cab744053 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256, large block -Key: 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -IV: 1f1e1d1c1b1a1918 1716151413121110 -Plaintext: 6c61766975716520 7469206564616d20 6c61766975716520 7469206564616d20 \ - 6c61766975716520 7469206564616d20 6c61766975716520 7469206564616d20 \ - 6c61766975716520 7469206564616d20 6c61766975716520 7469206564616d20 -Ciphertext: 4DE90B93CE9A3ED3 482C3F03C0E1A020 DB6E66073231E19F DA9F831411CCF97D \ - 4B1AC081024BBE96 0CC0D279D8A47F24 8F91492DF4AB6035 228E551DE6A7811B \ - CCDFD166983B3555 120B98B22646A5EE 3B8ED54D34CACCAB 28BC79222CF04749 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256, large block -Key: 1f1e1d1c1b1a1918 1716151413121110 0f0e0d0c0b0a0908 0706050403020100 -IV: 2f2e2d2c2b2a2928 2726252423222120 -Plaintext: 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 \ - 6373656420737265 6c6c657661727420 6373656420737265 6c6c657661727420 -Ciphertext: B17D08C5D2F46C09 246509E786C2273E C88FC41243F9C75A A27CFCD11240AF92 \ - 2DD8DE5003543B44 DB9C94244047E053 F359AD3277FB5204 91494FD5289C563F \ - E077FCF6725B04FE D71532F0602996B2 AEFE28D5CFD4CFCD 7EFD03C28D67AFC5 \ - E055CCA6F5913B13 7E1B3C1807591EBB 0870A51D2A1286B8 2E29E280C2D2519B \ - 3E4F0365388EB1CA F1725396927353C8 7A619704472EBF3C 38300A47AE31C537 \ - FF38F7EEB72E3597 4849185FEAD04C35 6374B958F7D6705D 2AC74DFD729EADB2 \ - 16FC22F637531027 F4A9DFDBFE189E5C 4DAC2CE9A5E31E93 ABA0B09384652F61 \ - 0F82D8CAB45FBD36 50EEB60523D4AA57 9D2DA9F6F3A70400 8C311EFB1718A48C -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256, large block -Key: a46f8d24f853e092 efa6b9f3794bd306 875ddc329696b265 6cdf8ea4c37ea72e -IV: 06f588f36c6b277a b1e5e63b1d4a11b5 -Plaintext: 7811a75fc0366a64 da0a1f65b1a02482 435610691a0f46cc 56188cf05d6f681d \ - 732f23f8b29b871b 297280cfdf722b4d bdd9fdbbbc404ff8 8fd4789a560188b7 \ - de8330c107445cfc 1d2af1d804cfe1d8 da12bbdb71c9d21e 4ed966724b96d604 \ - 8437648813ab601f 1cb2ee111f516462 f55ec55b9ed10e57 163720ad62b629d6 \ - a3331ab726426f10 b30460e5f63db742 72e77e2dacb5564f 634678df907803d4 \ - 4ce73346dd2dd16e 77d03d175fe4f877 3c2fe1988f94d626 1845de1c078127f7 \ - 46641b983c0de061 05b4cff210ac59ee b486b3cbcd554607 14d30c8090e3cc7b \ - de268f71032c805c 96af7a8cdd73c47c 776441f11a33a1e9 09dbef3ac1f17f2c -Ciphertext: 1b06c9002db58e65 7007df575c830cfc e691cb94a5f0abf5 75f4cd2bafa8d2a6 \ - 728ee446add2f836 6a7ef404082c0993 6900a84329400b67 a0319f4d968843bd \ - f3e6f4ae320e68e0 ada60073cc91fc23 f11ee5f8bf90601d 76c5b30ae3f70ade \ - 69623b402b3c5a63 afe41cd19960d0b2 8032b8511eb1c3c0 8171abb2d8f3abe9 \ - d689b8aa3f230399 04d5537311a784c4 9cfd243f5d0f687d 38909dbec1add2ad \ - 713189f49375c1f7 2193792745268047 16cd917c78d32b67 2af93ab54cb2e3ae \ - f9c589a841506bb4 7303a13bc3e227f8 d84b9be5d5717a13 f9df78466cfbfa7a \ - f37da8941740c350 6fcb199102e9f6d5 ef17673527f8b7cf 998f80a8904b2d68 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256, large block -Key: c1fe73fbaddd6ad8 292c5984c7cf35a2 057102d7e185bcdc 339fe92b2d28a4d7 -IV: 07d2ffa50d44c485 0c594cdf5f0c1466 -Plaintext: 07e22c9c8dcd5383 fd1267177933622f 8d7cc3895af9d678 4d47d068d075f70d \ - f21d7b47990c0dff 848ff77d5f4a96dd aa31d71fc380f73a adc2c1a5cdd03ceb \ - afb70bcb2d3ad743 8e57a1406c8ed951 6e8075137685a085 ce899e6552dfad1c \ - 840de5218051a151 96dadc59cac768de 70a9eed1ed45b20c 7e2847ea963425ad \ - d39f088471655a56 da660f559e65b10d f84244a178e3f3d1 7bdd46b36ab32484 \ - aabc64f6a8cb442e 7a4596a0b123f785 8bb670dcf9e7491f f8d0442befa14840 \ - e52d979c0bb3be00 2555aec34c8640e8 4e3c23c80287e570 28f143328753c4ba \ - 841b238acec7aecf cd7136369f2cd9f7 a56d22c0b87736f0 b7eea024a9b05502 -Ciphertext: eb73d06ebc67a3d5 4fada0fb8f6c8739 c38224ea6d08d9c8 d4aaa4624d4453c4 \ - ee3d5e2bad7da8cd 8cc29627ab8233aa 5c1ee0fbd14e3bdb ab1ed79be1b7b6b3 \ - 538b3d1b62463b8d cda650acfca85324 f00a1bf7cca1578a e9fdc5027372c82f \ - dbd1e0a38f56b074 fcd7392f9c1a96ea 993658d95c0448c9 110993f8cd222a79 \ - 6d01d0a41b02dfde baf57cb1e1222a0f eedfff11e2e89e52 bcaf42f0daec225f \ - d60ed9645feddf1d 98cbe39963ab7cb0 b84fe78c3c29c197 2106648df7d6d7d4 \ - 0de719d367093e85 a4d3587ab3044c54 8c8428e7346da3e7 7f71abbbf964ff3f \ - ca2d81334a83438c 801eb8957c660e30 048f7ebc83c08d57 c55501ca9ce98cb4 -Test: Encrypt - -AlgorithmType: SymmetricCipher -Name: SPECK-128/CTR -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128 -Key: 9E045FE3CD3A6432 9BC697030F831DE7 -IV: BD54F56F18591EB5 C3FAE0A4D5192C71 -Plaintext: 2A8E5F44EA97A25B 4BF57FEED71501FF -Ciphertext: 63393A9691CE1DE2 9073C70938023B03 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128 -Key: 57070B0749F3EE3C CF3072A37FBCC6DE -IV: DD98A136CE46C2FA E8F27E697F4825F7 -Plaintext: 8F74B3993701C80B 79A801D5E56AF92D -Ciphertext: C0ECDCBDD47E8BD4 F40F1B3FBF48C046 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128 -Key: 1BFAD7EC9F580B5B 4B6B67E807AFFA98 -IV: 1E2FFA060ACD51C3 338D390FFB24E49E -Plaintext: 7E7D6C5790179D02 1A759973530E3800 -Ciphertext: 6E41207EDEBE11A0 A805D0830F04D40E -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128 -Key: E5114CD3CEE1AA30 9079403CD8425DAF -IV: 15E1F2D923444CB3 0FD0F5E891844502 -Plaintext: AF77E4F42A12D52B 97B1F0E6B00F666A -Ciphertext: 17CDFFA20E5167D2 1E7F346A9F0499B2 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128 -Key: 08A06AC30866DB7F 8AED2DA6F8D209C6 -IV: EAAA9773428897AC A0EF60FE1E1E4330 -Plaintext: CDD5765A1C3E2E0A 11BD52ADD6630872 -Ciphertext: 8C2BE022406B048B CFC8301582C00104 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: 1129A35E6890BADD D26C8E96F91111BA 53E183209704BCC7 -IV: 7C452C259BDA234E EEBEA0078F1EE0B3 -Plaintext: EF564F75A45BDF3F 0230CB43C65CBD4A -Ciphertext: E716AE1543A39156 BB5F55F3702912F3 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: 140DCC8D0B620E33 DE10DFB3D986D0E4 8CFD5684837D9270 -IV: 16AD22CD66B20BE3 FA20FD4BEDAD2E30 -Plaintext: 79269BB4C6261E76 598BF5742AEEF92B -Ciphertext: 949B0CBB036F47E6 FC153421953F635C -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: 0EBD1351587B7C9E 4219A1D1DE936538 71FFFA49586D468B -IV: 1D3B286F1EB01382 523F531ED10682A9 -Plaintext: 6C905925CE0E9698 93812659DE773573 -Ciphertext: 6F98EF5759CD7682 67EF2685CE6F07EE -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: 7EE407CA26483C7D F7EF68BE77320EC6 DECA710D8E817D1E -IV: 13B80A81C3FB8C9E 35FA7AA445FF4E97 -Plaintext: 7EA97D29756C6F99 137ED7C4FAA27EB4 -Ciphertext: DC2EEDB8A3DF4673 A7A92AD4E6F0ED45 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: E947B700E271E96B 2049C6FED0DA40FE 3D0B474CB68856F6 -IV: BA92C9283D9D268C 06675D9E86EDEF27 -Plaintext: 772D5D21E32EA640 F3272E1EFAB2F08C -Ciphertext: C5A7371465C5C288 A0AD7503CAA8DF2D -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: A2606EF6303D2BAB 050F5C834EB81318 253F5B0C1E326691 898170D0EE5D76C2 -IV: E7AED3794C1F32B3 8C9BC347C5ED6AB0 -Plaintext: 9BAC53B9E47E209C 49F467201A01F81A -Ciphertext: A7AFC55F92CB36A9 13E12F03BD96A6EE -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: EFB01A20CDEF7DE8 2F9B652003FB4115 6815D6F84652A0A5 A703E76C7FFD1E30 -IV: 60A680B83EEB78D7 3834F1B2A486897F -Plaintext: FFDD90C6CEDA1C72 009814912E06A9B1 -Ciphertext: DEC3D47D4F403F03 6B498576CC807293 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: EC6D77F3F7C03A77 EE71A95EED13E902 BEDE09F1A557B0CF EDBE0B37B3A41B64 -IV: D4E52F202FBA9B61 FDEB371D9052D77B -Plaintext: 435D967970B2FE45 15CEC513046FF403 -Ciphertext: 9EA2C996334EB495 64DE5CA918D6AC9D -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: D803E472A9FE63A4 C61A91974FE55301 9F51D682BEC9FCC3 C8551D2162EFA0CD -IV: EB1426FDF74C0E4B 3D2C95556C3A989D -Plaintext: 060BECADB7DC6950 9687E0040544787C -Ciphertext: CE2DA5E2AC60864E 13CBA1768491912C -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256 -Key: AD443936D4D45250 5B54AA48151D1BFC D595C82B34C22DD7 72AE97681D97F48D -IV: 5FFD13216D191F3F B254B5B1EE7C377F -Plaintext: B8272A438AA32C26 D273D4AFABF8556B -Ciphertext: 9E3F2B39AA558028 3B700D9480062270 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128, large block -Key: 2710D19CF12B4AD6 C888C66F75FF36FF -IV: 1182E822C3C66588 CD78FE4761483418 -Plaintext: 1593246B3DC3748D CBBB36BC2BBDAA21 9AFCF2BEE1525C92 50104FEA10DBE20A \ - F1E73340FCBB3007 9E21F3728FC96C08 59A812FBFEC13655 EFB51E2563453A6A \ - 9DA1CD0CB3255A46 DB983A99D875A227 5F7A9304B9CE0880 5E95E2070CF87239 \ - 507E97DF9C971E22 2B05677DD0C7107F 512D0709FFBB0BB3 D5D2FF6ECD6127F4 -Ciphertext: 6281046414D51AA2 7315FEA219DFB5A2 92D18F56196A7D36 1F0F58C5C686A7C5 \ - 3CE57A09CEB108FE 1F09F0E8AD2C9B79 89A3ABEF920CD91B BB998EEC9C32BA3F \ - 5574992F074266D4 403EC4FB755761A3 17EBF7E2CBEA3D88 DB41E06E9A0AA0DB \ - 53FE40FFBDB9C4B4 14A9F2C8CAAB0E33 174E16B131780BC6 1CEF7A0BD37CDADC -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128, large block -Key: 1A7605ADF68AAD3C E752FDF072D2730D -IV: 638F767A73E5A89B 69098E472A0F6096 -Plaintext: 0939F98ABD6E0B13 399D942EA3300B87 1109E426398DB9A8 7AD0CA9FB545DFF5 \ - 3A5256C6F70FA824 7AD1800FA11B0181 49D4F306A5C49915 A7A3F1CBE3277398 \ - 8DE747A6B2432D56 CC0FC9B78CB2D83A B0BE9D9E2DCBD3FF 493056ADC01E68CC \ - 9192C400BCCB6E7D 2961C07311250BBD D90FA76806BCB851 189A55B21B743932 -Ciphertext: 4C501ADDAC037FAE 037CDCFA8FA87B37 2AC1183D9344C992 46B3328C68D0AA30 \ - 709BF80FA612A1A6 3E49F2EB5D8118A4 95C4F0CF0B3D19EA 93601E063C9A50AB \ - A8DE1722CDF147AB D7B3E6C3BC88F86C 85EB77777D2E3CFA EAFB3DF3C363D26D \ - C068BCBFEBD1629D E8550B30A14EAF0A F9BC5374F37D06B7 05E848F6F24B04F1 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/128, large block -Key: A756807259892B04 4BAAB33B8CCBE9A5 -IV: A84EB9BD9FB92D15 B52529FF5A6A3BF6 -Plaintext: D40A91F6564922F2 C323684F0B877734 53048A0B17DF9420 AAE5A4EC90A25E10 \ - 191A46AA1E7884FA F59FE759BAEF7374 2BD1FCDB03012E1C F82C296C668E91FD \ - B1BDF3C00495910B 163F423B8F7E843A 6B6CCABD61E34C59 6E5EF203E280D4F9 \ - DC827FFAB18C1BAE CB1FA0FD312A24D9 064E157211F76B3A 29090EF1F7A01A6C -Ciphertext: 5B7DA9DF20D1F00D 04724A2364AF72C3 244E416AC2EC3CD8 FD1AC505D7D18D88 \ - 3F60167943B6399C B3D13C9DE6336AEC 6E9FEA0DA0C189D9 4701F56E84AC3B47 \ - 41207A450099EAF0 F86AEC007895B684 459962155F8E0397 EF843A8ED088C87D \ - 2F91E88A75388238 A222BF0C163E08FB 3C2163A50EE1AD63 1C76F4DC956DB173 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/192, large block -Key: BE7FFAF81D9E10E1 B1642CABA2E91E88 244EA8D1736AD721 -IV: EABC9F42A98257EF D17219E2F93EB8A6 -Plaintext: 125E9B0921FB30F6 2E4A382F4465AC18 578943E3B19D5295 3105D09EF935026C \ - 0453687E99FC3C73 2EB274BC1942EDE0 F247C6D6DCBEA3FA 1A96CDDEE0215605 \ - 746BA699720F658C 54ABD2C9EA2155FF FC39F550A3D2909E D63EE3ADE9798D8E \ - A914AB031D3282B7 FD1D166E29EF6B61 ACBB45562181525F C08B47523F2FB458 -Ciphertext: 24042268B5769F06 8869A5E77AC7FF09 DF984AE5A2ABD2DE F478563C8245F32B \ - C991D5D8988382A0 0F33406B52726C6D E91569809D55E259 CEDA48A4434F76D9 \ - 0772C35FA3BDE58C B8304A1FB6C46962 B80F9823B5EC6975 CD7678A223D89A46 \ - 2F6F970BD7369C79 B27E67911D2B51E4 516FA6C6DA180EF9 D10ABA42AE9A9A82 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/192, large block -Key: 5D337EA0D37DC7DF 7AB7255DB899C4D4 D7EE32FCF34B4E0A -IV: 707ACEBC023BD676 25C166A194FB34A2 -Plaintext: CAC6B53C123D198F 88930B19201D7B0B 12586EA017DCC0D0 B88A4BC3D904FA1E \ - 55FBB0F2ACEEA4FC 4FE49DFB7371CDD2 45AC4A6C2889EBAC 9CAF4A80F2EB94F9 \ - 6C7BDDD28DE40E75 39EDD856E161D834 E8BDFB612F5232D1 90E22B8DFE4992C0 \ - FF4AAFE880CA09BB D375B99CEC62F86A F5673FE8D45C68CB B234B45BCFC675EC -Ciphertext: 1A48FAC0D9AC301C C681A0BE769FD912 548191EB159E0718 44F204F7F4A390A8 \ - 99031539DA9E8A47 8874DD88A7E55B14 C987F907CF69B8C4 88EE9A03807C24CC \ - 010E5BAC4B93558B 6AF7559D46C61F77 74EF0244F362554E 10861F789CDBDA32 \ - 38D9DD28C99FE163 4CC43EB9DBFF6ADF 486DDC7BE93CCF04 77B9996E2A7D8F88 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/192, large block -Key: 40EF8FD8DC9FF6F8 673014A4DDF384F0 9ED4CAC7EF5BDE48 -IV: 8B030D1DA443570D 8CCDF095F2F3D7F9 -Plaintext: DABF0C63FEDA185D 0F047B88E8756F3D 0011F0B5D6C3EA44 07E2226EEC701C30 \ - DEDB2D1738F5808A 957A4F202AA547BB DDDB7CA23FDED05D 783F81F32366520D \ - 06B84AA2DA51B652 AF5110639BDD9203 E1F6B860AA6085DA 913A22A0ADA5059F \ - 4011C7370D3D5D08 BF5617BA38D4A605 84D18F39B414D931 BE97A9263CC27974 -Ciphertext: C9A6BEF2F065FA37 8A1B5ECAC7B73716 EF0309B4E7422428 BD08168D328DD8F0 \ - D5B0653203A6D188 4035FF98BF70E50F CC3AEF8578C33A4A 09F50260A7F1ABC9 \ - E202F7D0D285F443 8BB909ABAFDF37EB D605516B8AFE137F 265A448B8B975317 \ - 7A6C4655A5EA0264 C8E6805C09026A96 93F752E90467A6C5 090EC995F19580CE -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256, large block -Key: 5C04A62C610F0344 02462643D2380CCC 16C0194032C6A419 AC631C79386AA391 -IV: 65E10DB0B3246035 83CDDE1BD1C5A5F8 -Plaintext: 1D0AB752B55C7EC7 A0324BBA40F1D445 BF15089332D65FAC E3200520DC7799E7 \ - BE96AEF2859419EE AA50375BF9EE6B09 7A3ADB00AE40B903 F61F59C70AC39947 \ - 9F7C18CA9ED2E27B 72B05778C9E29737 0FAA292CDA11B8E3 CD9251525136924F \ - 01CAE3DE692841FD D8C7EBD70E7FC669 E183A2D98472960E D2BA16FB1B9DD66A -Ciphertext: F42A59B2C836F898 B3097F7D8366FCF1 3ACD891A579165B1 E63B9D56FFFA6914 \ - D4B121B764355CB4 FEB34CAB43231E9C FE4174F474676CD3 0A3BAF1861B543E8 \ - 8A3476191F496A64 86575A9079B74729 4C35FCCBC84B0A3C 9B76BC9A31ACF038 \ - 35A0E330766AD8BD 6D88A595C5B0F522 6825E6868D78BE5C 8136FA5352207415 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256, large block -Key: A8329F5C071FEBDC 34367D38604B34BA 2F491F450FD9B711 895BE93C09F34A10 -IV: D16EB618B420CB1A 1E1ECFA57CA77774 -Plaintext: C4389834DE057992 7BF15318274C3580 DDE3DA065E5ACE53 68FA16FA7913B0AB \ - 8FFD85EBA391EC47 B300D369BF81E298 9F442DA254B8C453 C64F9B4F4C6CFD67 \ - 4AB47A78FAE5A4B2 B83A3A509F7ED3C9 80A5DBC28460BCAD 7D12B5CC8997FA4E \ - 5D823AE7041602BB 2E1EAD462A0F74AC 72374A2C976BB0ED D692E45CCEFB3F07 -Ciphertext: AB7D40C4263ADCD3 7E04C6EFA2DB1AE5 C1C13B64793BCF9A 5F4AD42B45FEAB96 \ - 3F559520799AAD06 E356C73D532EC1CD CABDFE598FC84F8A 6920064F3B4F9F4A \ - 5BEB8A58D624114F 22E2455C88C3F4FA 03C96881C33D497D E679AE3AEA08C0C0 \ - C32EDE201CEDC27E 4CA903B54E80084F D9C24E1BA1A20E44 0C28E02B42B2DA28 -Test: Encrypt -# -Source: Crypto++ 5.6.5 generated -Comment: Speck128/256, large block -Key: 92E480850032DCB6 E6EB042252FA2BDA 2EECF5EE9E361871 C0B4067D64D5D3F6 -IV: 64714524A417CE09 EA48210A4343E40B -Plaintext: 9BA2C02C498A099B C8F02FD4B3214662 95EDA139D8A8AB78 0F6B83F1D57D31D5 \ - 284D83CC72D2BBFA 53203765BB529D43 A66B83103E3E52FD 61D7C2C6571CAD6E \ - C597E3013448099D 7FA5520B882D239F D7D85F6B3B2DB80B 2948EB07EF976DB7 \ - 3C7F7EACDF6F6E02 6ABC54CCD83269EA A11A2EA5351DDB1D 170AFCF34D5AB528 -Ciphertext: 34DCBA24D03FC93A 05699B14BD3483B8 D37D76AFEE2B5D6E 9DB3456F225C8F04 \ - DA8C19F63C3D58EB B3F8E0EB64977DB5 F2B53E87316F3F8D 53AEC942197FDD4E \ - 434C40EDCE29ADCD B4B0E8850C12C8FF AD6E3C85A374E794 9DCC11F532D034CF \ - B799F393BEFE3C41 FA043D0D8A61A22E F5A78474EAC95E02 CB77D9A8AE702DBC -Test: Encrypt diff --git a/bench1.cpp b/bench1.cpp index 153428ff..06580086 100644 --- a/bench1.cpp +++ b/bench1.cpp @@ -614,18 +614,6 @@ void Benchmark2(double t, double hertz) BenchMarkByName("Kalyna-256/CTR", 32, "Kalyna-256(256)/CTR (256-bit key)"); BenchMarkByName("Kalyna-256/CTR", 64, "Kalyna-256(512)/CTR (512-bit key)"); BenchMarkByName("Kalyna-512/CTR", 64, "Kalyna-512(512)/CTR (512-bit key)"); - - BenchMarkByName("SIMON-64/CTR", 12, "SIMON-64(96)/CTR (96-bit key)"); - BenchMarkByName("SIMON-64/CTR", 16, "SIMON-64(128)/CTR (128-bit key)"); - BenchMarkByName("SIMON-128/CTR", 16, "SIMON-128(128)/CTR (128-bit key)"); - BenchMarkByName("SIMON-128/CTR", 24, "SIMON-128(192)/CTR (192-bit key)"); - BenchMarkByName("SIMON-128/CTR", 32, "SIMON-128(256)/CTR (256-bit key)"); - - BenchMarkByName("SPECK-64/CTR", 12, "SPECK-64(96)/CTR (96-bit key)"); - BenchMarkByName("SPECK-64/CTR", 16, "SPECK-64(128)/CTR (128-bit key)"); - BenchMarkByName("SPECK-128/CTR", 16, "SPECK-128(128)/CTR (128-bit key)"); - BenchMarkByName("SPECK-128/CTR", 24, "SPECK-128(192)/CTR (192-bit key)"); - BenchMarkByName("SPECK-128/CTR", 32, "SPECK-128(256)/CTR (256-bit key)"); } std::cout << "\n"; diff --git a/cryptlib.h b/cryptlib.h index cbff1fe2..95315177 100644 --- a/cryptlib.h +++ b/cryptlib.h @@ -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
Stream Ciphers
ChaCha (ChaCha-8/12/20), \ref Panama "Panama-LE", \ref Panama "Panama-BE", Salsa20, \ref SEAL "SEAL-LE", \ref SEAL "SEAL-BE", WAKE, XSalsa20 diff --git a/cryptlib.vcxproj b/cryptlib.vcxproj index fff3f475..9bc4a9a3 100644 --- a/cryptlib.vcxproj +++ b/cryptlib.vcxproj @@ -288,16 +288,12 @@ - - - - @@ -478,7 +474,6 @@ - @@ -486,7 +481,6 @@ - @@ -515,4 +509,4 @@ - \ No newline at end of file + diff --git a/cryptlib.vcxproj.filters b/cryptlib.vcxproj.filters index c1fd8c01..c43131e7 100644 --- a/cryptlib.vcxproj.filters +++ b/cryptlib.vcxproj.filters @@ -362,9 +362,6 @@ Source Files - - Source Files - Source Files @@ -380,12 +377,6 @@ Source Files - - Source Files - - - Source Files - Source Files @@ -455,9 +446,6 @@ Source Files - - Source Files - @@ -831,9 +819,6 @@ Header Files - - Header Files - Header Files @@ -855,9 +840,6 @@ Header Files - - Header Files - Header Files @@ -939,4 +921,4 @@ Miscellaneous - \ No newline at end of file + diff --git a/regtest2.cpp b/regtest2.cpp index b5bf18b0..4b3732e9 100644 --- a/regtest2.cpp +++ b/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 >(); // Benchmarks RegisterSymmetricCipherDefaultFactories >(); // Benchmarks - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Benchmarks - RegisterSymmetricCipherDefaultFactories >(); // Benchmarks - - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Test Vectors - RegisterSymmetricCipherDefaultFactories >(); // Benchmarks - RegisterSymmetricCipherDefaultFactories >(); // Benchmarks RegisterSymmetricCipherDefaultFactories >(); // Test Vectors RegisterSymmetricCipherDefaultFactories >(); // Test Vectors diff --git a/simon-simd.cpp b/simon-simd.cpp deleted file mode 100644 index 81a73204..00000000 --- a/simon-simd.cpp +++ /dev/null @@ -1,1227 +0,0 @@ -// simon-simd.cpp - written and placed in the public domain by Jeffrey Walton -// -// This source file uses intrinsics and built-ins to gain access to -// SSSE3, ARM NEON and ARMv8a, and Power7 Altivec instructions. A separate -// source file is needed because additional CXXFLAGS are required to enable -// the appropriate instructions sets in some build configurations. - -#include "pch.h" -#include "config.h" - -#include "simon.h" -#include "misc.h" -#include "adv-simd.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 - -#if (CRYPTOPP_SSSE3_AVAILABLE) -# include -# include -#endif - -#if (CRYPTOPP_SSE41_AVAILABLE) -# include -#endif - -#if defined(__AVX512F__) && defined(__AVX512VL__) -# define CRYPTOPP_AVX512_ROTATE 1 -# include -#endif - -#if (CRYPTOPP_ARM_NEON_AVAILABLE) -# include -#endif - -// Can't use CRYPTOPP_ARM_XXX_AVAILABLE because too many -// compilers don't follow ACLE conventions for the include. -#if defined(CRYPTOPP_ARM_ACLE_AVAILABLE) -# include -# include -#endif - -// https://www.spinics.net/lists/gcchelp/msg47735.html and -// https://www.spinics.net/lists/gcchelp/msg47749.html -#if (CRYPTOPP_GCC_VERSION >= 40900) -# define GCC_NO_UBSAN __attribute__ ((no_sanitize_undefined)) -#else -# define GCC_NO_UBSAN -#endif - -ANONYMOUS_NAMESPACE_BEGIN - -using CryptoPP::byte; -using CryptoPP::word32; -using CryptoPP::word64; -using CryptoPP::rotlFixed; -using CryptoPP::rotrFixed; -using CryptoPP::vec_swap; // SunCC - -// *************************** ARM NEON ************************** // - -#if defined(CRYPTOPP_ARM_NEON_AVAILABLE) - -template -inline uint32x4_t RotateLeft32(const uint32x4_t& val) -{ - const uint32x4_t a(vshlq_n_u32(val, R)); - const uint32x4_t b(vshrq_n_u32(val, 32 - R)); - return vorrq_u32(a, b); -} - -template -inline uint32x4_t RotateRight32(const uint32x4_t& val) -{ - const uint32x4_t a(vshlq_n_u32(val, 32 - R)); - const uint32x4_t b(vshrq_n_u32(val, R)); - return vorrq_u32(a, b); -} - -#if defined(__aarch32__) || defined(__aarch64__) -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline uint32x4_t RotateLeft32<8>(const uint32x4_t& val) -{ -#if defined(CRYPTOPP_BIG_ENDIAN) - const uint8_t maskb[16] = { 14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3 }; - const uint8x16_t mask = vld1q_u8(maskb); -#else - const uint8_t maskb[16] = { 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 }; - const uint8x16_t mask = vld1q_u8(maskb); -#endif - - return vreinterpretq_u32_u8( - vqtbl1q_u8(vreinterpretq_u8_u32(val), mask)); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline uint32x4_t RotateRight32<8>(const uint32x4_t& val) -{ -#if defined(CRYPTOPP_BIG_ENDIAN) - const uint8_t maskb[16] = { 12,15,14,13, 8,11,10,9, 4,7,6,5, 0,3,2,1 }; - const uint8x16_t mask = vld1q_u8(maskb); -#else - const uint8_t maskb[16] = { 1,2,3,0, 5,6,7,4, 9,10,11,8, 13,14,14,12 }; - const uint8x16_t mask = vld1q_u8(maskb); -#endif - - return vreinterpretq_u32_u8( - vqtbl1q_u8(vreinterpretq_u8_u32(val), mask)); -} -#endif - -inline uint32x4_t Shuffle32(const uint32x4_t& val) -{ -#if defined(CRYPTOPP_LITTLE_ENDIAN) - return vreinterpretq_u32_u8( - vrev32q_u8(vreinterpretq_u8_u32(val))); -#else - return val; -#endif -} - -inline uint32x4_t SIMON64_f(const uint32x4_t& val) -{ - return veorq_u32(RotateLeft32<2>(val), - vandq_u32(RotateLeft32<1>(val), RotateLeft32<8>(val))); -} - -inline void SIMON64_Enc_Block(uint32x4_t &block1, uint32x4_t &block0, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. If only a single block is available then - // a Zero block is provided to promote vectorizations. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - uint32x4_t x1 = vuzpq_u32(block0, block1).val[0]; - uint32x4_t y1 = vuzpq_u32(block0, block1).val[1]; - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - - for (int i = 0; i < static_cast(rounds & ~1)-1; i += 2) - { - const uint32x4_t rk1 = vld1q_dup_u32(subkeys+i); - y1 = veorq_u32(veorq_u32(y1, SIMON64_f(x1)), rk1); - - const uint32x4_t rk2 = vld1q_dup_u32(subkeys+i+1); - x1 = veorq_u32(veorq_u32(x1, SIMON64_f(y1)), rk2); - } - - if (rounds & 1) - { - const uint32x4_t rk = vld1q_dup_u32(subkeys+rounds-1); - - y1 = veorq_u32(veorq_u32(y1, SIMON64_f(x1)), rk); - std::swap(x1, y1); - } - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = vzipq_u32(x1, y1).val[0]; - block1 = vzipq_u32(x1, y1).val[1]; -} - -inline void SIMON64_Dec_Block(uint32x4_t &block0, uint32x4_t &block1, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. If only a single block is available then - // a Zero block is provided to promote vectorizations. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - uint32x4_t x1 = vuzpq_u32(block0, block1).val[0]; - uint32x4_t y1 = vuzpq_u32(block0, block1).val[1]; - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - - if (rounds & 1) - { - std::swap(x1, y1); - const uint32x4_t rk = vld1q_dup_u32(subkeys + rounds - 1); - - y1 = veorq_u32(veorq_u32(y1, rk), SIMON64_f(x1)); - rounds--; - } - - for (int i = static_cast(rounds-2); i >= 0; i -= 2) - { - const uint32x4_t rk1 = vld1q_dup_u32(subkeys+i+1); - x1 = veorq_u32(veorq_u32(x1, SIMON64_f(y1)), rk1); - - const uint32x4_t rk2 = vld1q_dup_u32(subkeys+i); - y1 = veorq_u32(veorq_u32(y1, SIMON64_f(x1)), rk2); - } - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = vzipq_u32(x1, y1).val[0]; - block1 = vzipq_u32(x1, y1).val[1]; -} - -inline void SIMON64_Enc_6_Blocks(uint32x4_t &block0, uint32x4_t &block1, - uint32x4_t &block2, uint32x4_t &block3, uint32x4_t &block4, uint32x4_t &block5, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. If only a single block is available then - // a Zero block is provided to promote vectorizations. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - uint32x4_t x1 = vuzpq_u32(block0, block1).val[0]; - uint32x4_t y1 = vuzpq_u32(block0, block1).val[1]; - uint32x4_t x2 = vuzpq_u32(block2, block3).val[0]; - uint32x4_t y2 = vuzpq_u32(block2, block3).val[1]; - uint32x4_t x3 = vuzpq_u32(block4, block5).val[0]; - uint32x4_t y3 = vuzpq_u32(block4, block5).val[1]; - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - x2 = Shuffle32(x2); y2 = Shuffle32(y2); - x3 = Shuffle32(x3); y3 = Shuffle32(y3); - - for (int i = 0; i < static_cast(rounds & ~1) - 1; i += 2) - { - const uint32x4_t rk1 = vld1q_dup_u32(subkeys+i); - y1 = veorq_u32(veorq_u32(y1, SIMON64_f(x1)), rk1); - y2 = veorq_u32(veorq_u32(y2, SIMON64_f(x2)), rk1); - y3 = veorq_u32(veorq_u32(y3, SIMON64_f(x3)), rk1); - - const uint32x4_t rk2 = vld1q_dup_u32(subkeys+i+1); - x1 = veorq_u32(veorq_u32(x1, SIMON64_f(y1)), rk2); - x2 = veorq_u32(veorq_u32(x2, SIMON64_f(y2)), rk2); - x3 = veorq_u32(veorq_u32(x3, SIMON64_f(y3)), rk2); - } - - if (rounds & 1) - { - const uint32x4_t rk = vld1q_dup_u32(subkeys + rounds - 1); - - y1 = veorq_u32(veorq_u32(y1, SIMON64_f(x1)), rk); - y2 = veorq_u32(veorq_u32(y2, SIMON64_f(x2)), rk); - y3 = veorq_u32(veorq_u32(y3, SIMON64_f(x3)), rk); - std::swap(x1, y1); std::swap(x2, y2); std::swap(x3, y3); - } - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - x2 = Shuffle32(x2); y2 = Shuffle32(y2); - x3 = Shuffle32(x3); y3 = Shuffle32(y3); - - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = vzipq_u32(x1, y1).val[0]; - block1 = vzipq_u32(x1, y1).val[1]; - block2 = vzipq_u32(x2, y2).val[0]; - block3 = vzipq_u32(x2, y2).val[1]; - block4 = vzipq_u32(x3, y3).val[0]; - block5 = vzipq_u32(x3, y3).val[1]; -} - -inline void SIMON64_Dec_6_Blocks(uint32x4_t &block0, uint32x4_t &block1, - uint32x4_t &block2, uint32x4_t &block3, uint32x4_t &block4, uint32x4_t &block5, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. If only a single block is available then - // a Zero block is provided to promote vectorizations. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - uint32x4_t x1 = vuzpq_u32(block0, block1).val[0]; - uint32x4_t y1 = vuzpq_u32(block0, block1).val[1]; - uint32x4_t x2 = vuzpq_u32(block2, block3).val[0]; - uint32x4_t y2 = vuzpq_u32(block2, block3).val[1]; - uint32x4_t x3 = vuzpq_u32(block4, block5).val[0]; - uint32x4_t y3 = vuzpq_u32(block4, block5).val[1]; - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - x2 = Shuffle32(x2); y2 = Shuffle32(y2); - x3 = Shuffle32(x3); y3 = Shuffle32(y3); - - if (rounds & 1) - { - std::swap(x1, y1); std::swap(x2, y2); std::swap(x3, y3); - const uint32x4_t rk = vld1q_dup_u32(subkeys + rounds - 1); - - y1 = veorq_u32(veorq_u32(y1, rk), SIMON64_f(x1)); - y2 = veorq_u32(veorq_u32(y2, rk), SIMON64_f(x2)); - y3 = veorq_u32(veorq_u32(y3, rk), SIMON64_f(x3)); - rounds--; - } - - for (int i = static_cast(rounds-2); i >= 0; i -= 2) - { - const uint32x4_t rk1 = vld1q_dup_u32(subkeys + i + 1); - x1 = veorq_u32(veorq_u32(x1, SIMON64_f(y1)), rk1); - x2 = veorq_u32(veorq_u32(x2, SIMON64_f(y2)), rk1); - x3 = veorq_u32(veorq_u32(x3, SIMON64_f(y3)), rk1); - - const uint32x4_t rk2 = vld1q_dup_u32(subkeys + i); - y1 = veorq_u32(veorq_u32(y1, SIMON64_f(x1)), rk2); - y2 = veorq_u32(veorq_u32(y2, SIMON64_f(x2)), rk2); - y3 = veorq_u32(veorq_u32(y3, SIMON64_f(x3)), rk2); - } - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - x2 = Shuffle32(x2); y2 = Shuffle32(y2); - x3 = Shuffle32(x3); y3 = Shuffle32(y3); - - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = vzipq_u32(x1, y1).val[0]; - block1 = vzipq_u32(x1, y1).val[1]; - block2 = vzipq_u32(x2, y2).val[0]; - block3 = vzipq_u32(x2, y2).val[1]; - block4 = vzipq_u32(x3, y3).val[0]; - block5 = vzipq_u32(x3, y3).val[1]; -} - -#endif // CRYPTOPP_ARM_NEON_AVAILABLE - -#if defined(CRYPTOPP_ARM_NEON_AVAILABLE) - -template -inline T UnpackHigh64(const T& a, const T& b) -{ - const uint64x1_t x(vget_high_u64((uint64x2_t)a)); - const uint64x1_t y(vget_high_u64((uint64x2_t)b)); - return (T)vcombine_u64(x, y); -} - -template -inline T UnpackLow64(const T& a, const T& b) -{ - const uint64x1_t x(vget_low_u64((uint64x2_t)a)); - const uint64x1_t y(vget_low_u64((uint64x2_t)b)); - return (T)vcombine_u64(x, y); -} - -template -inline uint64x2_t RotateLeft64(const uint64x2_t& val) -{ - const uint64x2_t a(vshlq_n_u64(val, R)); - const uint64x2_t b(vshrq_n_u64(val, 64 - R)); - return vorrq_u64(a, b); -} - -template -inline uint64x2_t RotateRight64(const uint64x2_t& val) -{ - const uint64x2_t a(vshlq_n_u64(val, 64 - R)); - const uint64x2_t b(vshrq_n_u64(val, R)); - return vorrq_u64(a, b); -} - -#if defined(__aarch32__) || defined(__aarch64__) -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline uint64x2_t RotateLeft64<8>(const uint64x2_t& val) -{ -#if defined(CRYPTOPP_BIG_ENDIAN) - const uint8_t maskb[16] = { 14,13,12,11, 10,9,8,15, 6,5,4,3, 2,1,0,7 }; - const uint8x16_t mask = vld1q_u8(maskb); -#else - const uint8_t maskb[16] = { 7,0,1,2, 3,4,5,6, 15,8,9,10, 11,12,13,14 }; - const uint8x16_t mask = vld1q_u8(maskb); -#endif - - return vreinterpretq_u64_u8( - vqtbl1q_u8(vreinterpretq_u8_u64(val), mask)); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline uint64x2_t RotateRight64<8>(const uint64x2_t& val) -{ -#if defined(CRYPTOPP_BIG_ENDIAN) - const uint8_t maskb[16] = { 8,15,14,13, 12,11,10,9, 0,7,6,5, 4,3,2,1 }; - const uint8x16_t mask = vld1q_u8(maskb); -#else - const uint8_t maskb[16] = { 1,2,3,4, 5,6,7,0, 9,10,11,12, 13,14,15,8 }; - const uint8x16_t mask = vld1q_u8(maskb); -#endif - - return vreinterpretq_u64_u8( - vqtbl1q_u8(vreinterpretq_u8_u64(val), mask)); -} -#endif - -inline uint64x2_t Shuffle64(const uint64x2_t& val) -{ -#if defined(CRYPTOPP_LITTLE_ENDIAN) - return vreinterpretq_u64_u8( - vrev64q_u8(vreinterpretq_u8_u64(val))); -#else - return val; -#endif -} - -inline uint64x2_t SIMON128_f(const uint64x2_t& val) -{ - return veorq_u64(RotateLeft64<2>(val), - vandq_u64(RotateLeft64<1>(val), RotateLeft64<8>(val))); -} - -inline void SIMON128_Enc_Block(uint64x2_t &block0, uint64x2_t &block1, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - uint64x2_t x1 = UnpackLow64(block0, block1); - uint64x2_t y1 = UnpackHigh64(block0, block1); - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - - for (int i = 0; i < static_cast(rounds & ~1)-1; i += 2) - { - const uint64x2_t rk1 = vld1q_dup_u64(subkeys+i); - y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk1); - - const uint64x2_t rk2 = vld1q_dup_u64(subkeys+i+1); - x1 = veorq_u64(veorq_u64(x1, SIMON128_f(y1)), rk2); - } - - if (rounds & 1) - { - const uint64x2_t rk = vld1q_dup_u64(subkeys+rounds-1); - - y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk); - std::swap(x1, y1); - } - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - - block0 = UnpackLow64(x1, y1); - block1 = UnpackHigh64(x1, y1); -} - -inline void SIMON128_Enc_6_Blocks(uint64x2_t &block0, uint64x2_t &block1, - uint64x2_t &block2, uint64x2_t &block3, uint64x2_t &block4, uint64x2_t &block5, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - uint64x2_t x1 = UnpackLow64(block0, block1); - uint64x2_t y1 = UnpackHigh64(block0, block1); - uint64x2_t x2 = UnpackLow64(block2, block3); - uint64x2_t y2 = UnpackHigh64(block2, block3); - uint64x2_t x3 = UnpackLow64(block4, block5); - uint64x2_t y3 = UnpackHigh64(block4, block5); - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - x2 = Shuffle64(x2); y2 = Shuffle64(y2); - x3 = Shuffle64(x3); y3 = Shuffle64(y3); - - for (int i = 0; i < static_cast(rounds & ~1) - 1; i += 2) - { - const uint64x2_t rk1 = vld1q_dup_u64(subkeys+i); - y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk1); - y2 = veorq_u64(veorq_u64(y2, SIMON128_f(x2)), rk1); - y3 = veorq_u64(veorq_u64(y3, SIMON128_f(x3)), rk1); - - const uint64x2_t rk2 = vld1q_dup_u64(subkeys+i+1); - x1 = veorq_u64(veorq_u64(x1, SIMON128_f(y1)), rk2); - x2 = veorq_u64(veorq_u64(x2, SIMON128_f(y2)), rk2); - x3 = veorq_u64(veorq_u64(x3, SIMON128_f(y3)), rk2); - } - - if (rounds & 1) - { - const uint64x2_t rk = vld1q_dup_u64(subkeys + rounds - 1); - - y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk); - y2 = veorq_u64(veorq_u64(y2, SIMON128_f(x2)), rk); - y3 = veorq_u64(veorq_u64(y3, SIMON128_f(x3)), rk); - std::swap(x1, y1); std::swap(x2, y2); std::swap(x3, y3); - } - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - x2 = Shuffle64(x2); y2 = Shuffle64(y2); - x3 = Shuffle64(x3); y3 = Shuffle64(y3); - - block0 = UnpackLow64(x1, y1); - block1 = UnpackHigh64(x1, y1); - block2 = UnpackLow64(x2, y2); - block3 = UnpackHigh64(x2, y2); - block4 = UnpackLow64(x3, y3); - block5 = UnpackHigh64(x3, y3); -} - -inline void SIMON128_Dec_Block(uint64x2_t &block0, uint64x2_t &block1, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - uint64x2_t x1 = UnpackLow64(block0, block1); - uint64x2_t y1 = UnpackHigh64(block0, block1); - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - - if (rounds & 1) - { - std::swap(x1, y1); - const uint64x2_t rk = vld1q_dup_u64(subkeys + rounds - 1); - - y1 = veorq_u64(veorq_u64(y1, rk), SIMON128_f(x1)); - rounds--; - } - - for (int i = static_cast(rounds-2); i >= 0; i -= 2) - { - const uint64x2_t rk1 = vld1q_dup_u64(subkeys+i+1); - x1 = veorq_u64(veorq_u64(x1, SIMON128_f(y1)), rk1); - - const uint64x2_t rk2 = vld1q_dup_u64(subkeys+i); - y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk2); - } - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - - block0 = UnpackLow64(x1, y1); - block1 = UnpackHigh64(x1, y1); -} - -inline void SIMON128_Dec_6_Blocks(uint64x2_t &block0, uint64x2_t &block1, - uint64x2_t &block2, uint64x2_t &block3, uint64x2_t &block4, uint64x2_t &block5, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - uint64x2_t x1 = UnpackLow64(block0, block1); - uint64x2_t y1 = UnpackHigh64(block0, block1); - uint64x2_t x2 = UnpackLow64(block2, block3); - uint64x2_t y2 = UnpackHigh64(block2, block3); - uint64x2_t x3 = UnpackLow64(block4, block5); - uint64x2_t y3 = UnpackHigh64(block4, block5); - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - x2 = Shuffle64(x2); y2 = Shuffle64(y2); - x3 = Shuffle64(x3); y3 = Shuffle64(y3); - - if (rounds & 1) - { - std::swap(x1, y1); std::swap(x2, y2); std::swap(x3, y3); - const uint64x2_t rk = vld1q_dup_u64(subkeys + rounds - 1); - - y1 = veorq_u64(veorq_u64(y1, rk), SIMON128_f(x1)); - y2 = veorq_u64(veorq_u64(y2, rk), SIMON128_f(x2)); - y3 = veorq_u64(veorq_u64(y3, rk), SIMON128_f(x3)); - rounds--; - } - - for (int i = static_cast(rounds-2); i >= 0; i -= 2) - { - const uint64x2_t rk1 = vld1q_dup_u64(subkeys + i + 1); - x1 = veorq_u64(veorq_u64(x1, SIMON128_f(y1)), rk1); - x2 = veorq_u64(veorq_u64(x2, SIMON128_f(y2)), rk1); - x3 = veorq_u64(veorq_u64(x3, SIMON128_f(y3)), rk1); - - const uint64x2_t rk2 = vld1q_dup_u64(subkeys + i); - y1 = veorq_u64(veorq_u64(y1, SIMON128_f(x1)), rk2); - y2 = veorq_u64(veorq_u64(y2, SIMON128_f(x2)), rk2); - y3 = veorq_u64(veorq_u64(y3, SIMON128_f(x3)), rk2); - } - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - x2 = Shuffle64(x2); y2 = Shuffle64(y2); - x3 = Shuffle64(x3); y3 = Shuffle64(y3); - - block0 = UnpackLow64(x1, y1); - block1 = UnpackHigh64(x1, y1); - block2 = UnpackLow64(x2, y2); - block3 = UnpackHigh64(x2, y2); - block4 = UnpackLow64(x3, y3); - block5 = UnpackHigh64(x3, y3); -} - -#endif // CRYPTOPP_ARM_NEON_AVAILABLE - -// ***************************** IA-32 ***************************** // - -#if defined(CRYPTOPP_SSSE3_AVAILABLE) - -// Clang __m128i casts, http://bugs.llvm.org/show_bug.cgi?id=20670 -#ifndef M128_CAST -# define M128_CAST(x) ((__m128i *)(void *)(x)) -#endif -#ifndef CONST_M128_CAST -# define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x)) -#endif - -// GCC double casts, https://www.spinics.net/lists/gcchelp/msg47735.html -#ifndef DOUBLE_CAST -# define DOUBLE_CAST(x) ((double *)(void *)(x)) -#endif -#ifndef CONST_DOUBLE_CAST -# define CONST_DOUBLE_CAST(x) ((const double *)(const void *)(x)) -#endif - -inline void Swap128(__m128i& a,__m128i& b) -{ -#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5120) - // __m128i is an unsigned long long[2], and support for swapping it was not added until C++11. - // SunCC 12.1 - 12.3 fail to consume the swap; while SunCC 12.4 consumes it without -std=c++11. - vec_swap(a, b); -#else - std::swap(a, b); -#endif -} - -#if defined(CRYPTOPP_AVX512_ROTATE) -template -inline __m128i RotateLeft64(const __m128i& val) -{ - return _mm_rol_epi64(val, R); -} - -template -inline __m128i RotateRight64(const __m128i& val) -{ - return _mm_ror_epi64(val, R); -} -#else -template -inline __m128i RotateLeft64(const __m128i& val) -{ - return _mm_or_si128( - _mm_slli_epi64(val, R), _mm_srli_epi64(val, 64-R)); -} - -template -inline __m128i RotateRight64(const __m128i& val) -{ - return _mm_or_si128( - _mm_slli_epi64(val, 64-R), _mm_srli_epi64(val, R)); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline __m128i RotateLeft64<8>(const __m128i& val) -{ - const __m128i mask = _mm_set_epi8(14,13,12,11, 10,9,8,15, 6,5,4,3, 2,1,0,7); - return _mm_shuffle_epi8(val, mask); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline __m128i RotateRight64<8>(const __m128i& val) -{ - const __m128i mask = _mm_set_epi8(8,15,14,13, 12,11,10,9, 0,7,6,5, 4,3,2,1); - return _mm_shuffle_epi8(val, mask); -} -#endif // CRYPTOPP_AVX512_ROTATE - -inline __m128i SIMON128_f(const __m128i& v) -{ - return _mm_xor_si128(RotateLeft64<2>(v), - _mm_and_si128(RotateLeft64<1>(v), RotateLeft64<8>(v))); -} - -inline void GCC_NO_UBSAN SIMON128_Enc_Block(__m128i &block0, __m128i &block1, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - __m128i x1 = _mm_unpacklo_epi64(block0, block1); - __m128i y1 = _mm_unpackhi_epi64(block0, block1); - - const __m128i mask = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - for (int i = 0; i < static_cast(rounds & ~1)-1; i += 2) - { - const __m128i rk1 = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i))); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk1); - - const __m128i rk2 = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i+1))); - x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON128_f(y1)), rk2); - } - - if (rounds & 1) - { - const __m128i rk = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+rounds-1))); - - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk); - Swap128(x1, y1); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - block0 = _mm_unpacklo_epi64(x1, y1); - block1 = _mm_unpackhi_epi64(x1, y1); -} - -inline void GCC_NO_UBSAN SIMON128_Enc_6_Blocks(__m128i &block0, __m128i &block1, - __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - __m128i x1 = _mm_unpacklo_epi64(block0, block1); - __m128i y1 = _mm_unpackhi_epi64(block0, block1); - __m128i x2 = _mm_unpacklo_epi64(block2, block3); - __m128i y2 = _mm_unpackhi_epi64(block2, block3); - __m128i x3 = _mm_unpacklo_epi64(block4, block5); - __m128i y3 = _mm_unpackhi_epi64(block4, block5); - - const __m128i mask = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - for (int i = 0; i < static_cast(rounds & ~1) - 1; i += 2) - { - const __m128i rk1 = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + i))); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk1); - y2 = _mm_xor_si128(_mm_xor_si128(y2, SIMON128_f(x2)), rk1); - y3 = _mm_xor_si128(_mm_xor_si128(y3, SIMON128_f(x3)), rk1); - - const __m128i rk2 = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + i + 1))); - x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON128_f(y1)), rk2); - x2 = _mm_xor_si128(_mm_xor_si128(x2, SIMON128_f(y2)), rk2); - x3 = _mm_xor_si128(_mm_xor_si128(x3, SIMON128_f(y3)), rk2); - } - - if (rounds & 1) - { - const __m128i rk = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + rounds - 1))); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk); - y2 = _mm_xor_si128(_mm_xor_si128(y2, SIMON128_f(x2)), rk); - y3 = _mm_xor_si128(_mm_xor_si128(y3, SIMON128_f(x3)), rk); - Swap128(x1, y1); Swap128(x2, y2); Swap128(x3, y3); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = _mm_unpacklo_epi64(x1, y1); - block1 = _mm_unpackhi_epi64(x1, y1); - block2 = _mm_unpacklo_epi64(x2, y2); - block3 = _mm_unpackhi_epi64(x2, y2); - block4 = _mm_unpacklo_epi64(x3, y3); - block5 = _mm_unpackhi_epi64(x3, y3); -} - -inline void GCC_NO_UBSAN SIMON128_Dec_Block(__m128i &block0, __m128i &block1, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - __m128i x1 = _mm_unpacklo_epi64(block0, block1); - __m128i y1 = _mm_unpackhi_epi64(block0, block1); - - const __m128i mask = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - if (rounds & 1) - { - const __m128i rk = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + rounds - 1))); - - Swap128(x1, y1); - y1 = _mm_xor_si128(_mm_xor_si128(y1, rk), SIMON128_f(x1)); - rounds--; - } - - for (int i = static_cast(rounds-2); i >= 0; i -= 2) - { - const __m128i rk1 = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i+1))); - x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON128_f(y1)), rk1); - - const __m128i rk2 = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i))); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk2); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - block0 = _mm_unpacklo_epi64(x1, y1); - block1 = _mm_unpackhi_epi64(x1, y1); -} - -inline void GCC_NO_UBSAN SIMON128_Dec_6_Blocks(__m128i &block0, __m128i &block1, - __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - __m128i x1 = _mm_unpacklo_epi64(block0, block1); - __m128i y1 = _mm_unpackhi_epi64(block0, block1); - __m128i x2 = _mm_unpacklo_epi64(block2, block3); - __m128i y2 = _mm_unpackhi_epi64(block2, block3); - __m128i x3 = _mm_unpacklo_epi64(block4, block5); - __m128i y3 = _mm_unpackhi_epi64(block4, block5); - - const __m128i mask = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - if (rounds & 1) - { - const __m128i rk = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + rounds - 1))); - - Swap128(x1, y1); Swap128(x2, y2); Swap128(x3, y3); - y1 = _mm_xor_si128(_mm_xor_si128(y1, rk), SIMON128_f(x1)); - y2 = _mm_xor_si128(_mm_xor_si128(y2, rk), SIMON128_f(x2)); - y3 = _mm_xor_si128(_mm_xor_si128(y3, rk), SIMON128_f(x3)); - rounds--; - } - - for (int i = static_cast(rounds-2); i >= 0; i -= 2) - { - const __m128i rk1 = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + i + 1))); - x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON128_f(y1)), rk1); - x2 = _mm_xor_si128(_mm_xor_si128(x2, SIMON128_f(y2)), rk1); - x3 = _mm_xor_si128(_mm_xor_si128(x3, SIMON128_f(y3)), rk1); - - const __m128i rk2 = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys + i))); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON128_f(x1)), rk2); - y2 = _mm_xor_si128(_mm_xor_si128(y2, SIMON128_f(x2)), rk2); - y3 = _mm_xor_si128(_mm_xor_si128(y3, SIMON128_f(x3)), rk2); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = _mm_unpacklo_epi64(x1, y1); - block1 = _mm_unpackhi_epi64(x1, y1); - block2 = _mm_unpacklo_epi64(x2, y2); - block3 = _mm_unpackhi_epi64(x2, y2); - block4 = _mm_unpacklo_epi64(x3, y3); - block5 = _mm_unpackhi_epi64(x3, y3); -} - -#endif // CRYPTOPP_SSSE3_AVAILABLE - -#if defined(CRYPTOPP_SSE41_AVAILABLE) - -template -inline __m128i RotateLeft32(const __m128i& val) -{ - return _mm_or_si128( - _mm_slli_epi32(val, R), _mm_srli_epi32(val, 32-R)); -} - -template -inline __m128i RotateRight32(const __m128i& val) -{ - return _mm_or_si128( - _mm_slli_epi32(val, 32-R), _mm_srli_epi32(val, R)); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline __m128i RotateLeft32<8>(const __m128i& val) -{ - const __m128i mask = _mm_set_epi8(14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3); - return _mm_shuffle_epi8(val, mask); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline __m128i RotateRight32<8>(const __m128i& val) -{ - const __m128i mask = _mm_set_epi8(12,15,14,13, 8,11,10,9, 4,7,6,5, 0,3,2,1); - return _mm_shuffle_epi8(val, mask); -} - -inline __m128i SIMON64_f(const __m128i& v) -{ - return _mm_xor_si128(RotateLeft32<2>(v), - _mm_and_si128(RotateLeft32<1>(v), RotateLeft32<8>(v))); -} - -inline void GCC_NO_UBSAN SIMON64_Enc_Block(__m128i &block0, __m128i &block1, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. Thanks to Peter Cordes for help with the - // SSE permutes below. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - const __m128 t0 = _mm_castsi128_ps(block0); - const __m128 t1 = _mm_castsi128_ps(block1); - __m128i x1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(2,0,2,0))); - __m128i y1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(3,1,3,1))); - - const __m128i mask = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - for (int i = 0; i < static_cast(rounds & ~1)-1; i += 2) - { - const __m128i rk1 = _mm_set1_epi32(subkeys[i]); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON64_f(x1)), rk1); - - const __m128i rk2 = _mm_set1_epi32(subkeys[i+1]); - x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON64_f(y1)), rk2); - } - - if (rounds & 1) - { - const __m128i rk = _mm_set1_epi32(subkeys[rounds-1]); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON64_f(x1)), rk); - Swap128(x1, y1); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - // The is roughly the SSE equivalent to ARM vzp32 - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = _mm_unpacklo_epi32(x1, y1); - block1 = _mm_unpackhi_epi32(x1, y1); -} - -inline void GCC_NO_UBSAN SIMON64_Dec_Block(__m128i &block0, __m128i &block1, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. Thanks to Peter Cordes for help with the - // SSE permutes below. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - const __m128 t0 = _mm_castsi128_ps(block0); - const __m128 t1 = _mm_castsi128_ps(block1); - __m128i x1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(2,0,2,0))); - __m128i y1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(3,1,3,1))); - - const __m128i mask = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - if (rounds & 1) - { - Swap128(x1, y1); - const __m128i rk = _mm_set1_epi32(subkeys[rounds-1]); - y1 = _mm_xor_si128(_mm_xor_si128(y1, rk), SIMON64_f(x1)); - rounds--; - } - - for (int i = static_cast(rounds-2); i >= 0; i -= 2) - { - const __m128i rk1 = _mm_set1_epi32(subkeys[i+1]); - x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON64_f(y1)), rk1); - - const __m128i rk2 = _mm_set1_epi32(subkeys[i]); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON64_f(x1)), rk2); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - // The is roughly the SSE equivalent to ARM vzp32 - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = _mm_unpacklo_epi32(x1, y1); - block1 = _mm_unpackhi_epi32(x1, y1); -} - -inline void GCC_NO_UBSAN SIMON64_Enc_6_Blocks(__m128i &block0, __m128i &block1, - __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. Thanks to Peter Cordes for help with the - // SSE permutes below. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - const __m128 t0 = _mm_castsi128_ps(block0); - const __m128 t1 = _mm_castsi128_ps(block1); - __m128i x1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(2,0,2,0))); - __m128i y1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(3,1,3,1))); - - const __m128 t2 = _mm_castsi128_ps(block2); - const __m128 t3 = _mm_castsi128_ps(block3); - __m128i x2 = _mm_castps_si128(_mm_shuffle_ps(t2, t3, _MM_SHUFFLE(2,0,2,0))); - __m128i y2 = _mm_castps_si128(_mm_shuffle_ps(t2, t3, _MM_SHUFFLE(3,1,3,1))); - - const __m128 t4 = _mm_castsi128_ps(block4); - const __m128 t5 = _mm_castsi128_ps(block5); - __m128i x3 = _mm_castps_si128(_mm_shuffle_ps(t4, t5, _MM_SHUFFLE(2,0,2,0))); - __m128i y3 = _mm_castps_si128(_mm_shuffle_ps(t4, t5, _MM_SHUFFLE(3,1,3,1))); - - const __m128i mask = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - for (int i = 0; i < static_cast(rounds & ~1)-1; i += 2) - { - const __m128i rk1 = _mm_set1_epi32(subkeys[i]); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON64_f(x1)), rk1); - y2 = _mm_xor_si128(_mm_xor_si128(y2, SIMON64_f(x2)), rk1); - y3 = _mm_xor_si128(_mm_xor_si128(y3, SIMON64_f(x3)), rk1); - - const __m128i rk2 = _mm_set1_epi32(subkeys[i+1]); - x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON64_f(y1)), rk2); - x2 = _mm_xor_si128(_mm_xor_si128(x2, SIMON64_f(y2)), rk2); - x3 = _mm_xor_si128(_mm_xor_si128(x3, SIMON64_f(y3)), rk2); - } - - if (rounds & 1) - { - const __m128i rk = _mm_set1_epi32(subkeys[rounds-1]); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON64_f(x1)), rk); - y2 = _mm_xor_si128(_mm_xor_si128(y2, SIMON64_f(x2)), rk); - y3 = _mm_xor_si128(_mm_xor_si128(y3, SIMON64_f(x3)), rk); - Swap128(x1, y1); Swap128(x2, y2); Swap128(x3, y3); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - // The is roughly the SSE equivalent to ARM vzp32 - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = _mm_unpacklo_epi32(x1, y1); - block1 = _mm_unpackhi_epi32(x1, y1); - block2 = _mm_unpacklo_epi32(x2, y2); - block3 = _mm_unpackhi_epi32(x2, y2); - block4 = _mm_unpacklo_epi32(x3, y3); - block5 = _mm_unpackhi_epi32(x3, y3); -} - -inline void GCC_NO_UBSAN SIMON64_Dec_6_Blocks(__m128i &block0, __m128i &block1, - __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. Thanks to Peter Cordes for help with the - // SSE permutes below. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - const __m128 t0 = _mm_castsi128_ps(block0); - const __m128 t1 = _mm_castsi128_ps(block1); - __m128i x1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(2,0,2,0))); - __m128i y1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(3,1,3,1))); - - const __m128 t2 = _mm_castsi128_ps(block2); - const __m128 t3 = _mm_castsi128_ps(block3); - __m128i x2 = _mm_castps_si128(_mm_shuffle_ps(t2, t3, _MM_SHUFFLE(2,0,2,0))); - __m128i y2 = _mm_castps_si128(_mm_shuffle_ps(t2, t3, _MM_SHUFFLE(3,1,3,1))); - - const __m128 t4 = _mm_castsi128_ps(block4); - const __m128 t5 = _mm_castsi128_ps(block5); - __m128i x3 = _mm_castps_si128(_mm_shuffle_ps(t4, t5, _MM_SHUFFLE(2,0,2,0))); - __m128i y3 = _mm_castps_si128(_mm_shuffle_ps(t4, t5, _MM_SHUFFLE(3,1,3,1))); - - const __m128i mask = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - if (rounds & 1) - { - Swap128(x1, y1); Swap128(x2, y2); Swap128(x3, y3); - const __m128i rk = _mm_set1_epi32(subkeys[rounds-1]); - y1 = _mm_xor_si128(_mm_xor_si128(y1, rk), SIMON64_f(x1)); - y2 = _mm_xor_si128(_mm_xor_si128(y2, rk), SIMON64_f(x2)); - y3 = _mm_xor_si128(_mm_xor_si128(y3, rk), SIMON64_f(x3)); - rounds--; - } - - for (int i = static_cast(rounds-2); i >= 0; i -= 2) - { - const __m128i rk1 = _mm_set1_epi32(subkeys[i+1]); - x1 = _mm_xor_si128(_mm_xor_si128(x1, SIMON64_f(y1)), rk1); - x2 = _mm_xor_si128(_mm_xor_si128(x2, SIMON64_f(y2)), rk1); - x3 = _mm_xor_si128(_mm_xor_si128(x3, SIMON64_f(y3)), rk1); - - const __m128i rk2 = _mm_set1_epi32(subkeys[i]); - y1 = _mm_xor_si128(_mm_xor_si128(y1, SIMON64_f(x1)), rk2); - y2 = _mm_xor_si128(_mm_xor_si128(y2, SIMON64_f(x2)), rk2); - y3 = _mm_xor_si128(_mm_xor_si128(y3, SIMON64_f(x3)), rk2); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - // The is roughly the SSE equivalent to ARM vzp32 - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = _mm_unpacklo_epi32(x1, y1); - block1 = _mm_unpackhi_epi32(x1, y1); - block2 = _mm_unpacklo_epi32(x2, y2); - block3 = _mm_unpackhi_epi32(x2, y2); - block4 = _mm_unpacklo_epi32(x3, y3); - block5 = _mm_unpackhi_epi32(x3, y3); -} - -#endif // CRYPTOPP_SSE41_AVAILABLE - -ANONYMOUS_NAMESPACE_END - -/////////////////////////////////////////////////////////////////////// - -NAMESPACE_BEGIN(CryptoPP) - -// *************************** ARM NEON **************************** // - -#if (CRYPTOPP_ARM_NEON_AVAILABLE) -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) -{ - return AdvancedProcessBlocks64_6x2_NEON(SIMON64_Enc_Block, SIMON64_Enc_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} - -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) -{ - return AdvancedProcessBlocks64_6x2_NEON(SIMON64_Dec_Block, SIMON64_Dec_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} -#endif // CRYPTOPP_ARM_NEON_AVAILABLE - -#if (CRYPTOPP_ARM_NEON_AVAILABLE) -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) -{ - return AdvancedProcessBlocks128_6x2_NEON(SIMON128_Enc_Block, SIMON128_Enc_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} - -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) -{ - return AdvancedProcessBlocks128_6x2_NEON(SIMON128_Dec_Block, SIMON128_Dec_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} -#endif // CRYPTOPP_ARM_NEON_AVAILABLE - -// ***************************** IA-32 ***************************** // - -#if defined(CRYPTOPP_SSE41_AVAILABLE) -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) -{ - return AdvancedProcessBlocks64_6x2_SSE(SIMON64_Enc_Block, SIMON64_Enc_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} - -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) -{ - return AdvancedProcessBlocks64_6x2_SSE(SIMON64_Dec_Block, SIMON64_Dec_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} -#endif - -#if defined(CRYPTOPP_SSSE3_AVAILABLE) -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) -{ - return AdvancedProcessBlocks128_6x2_SSE(SIMON128_Enc_Block, SIMON128_Enc_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} - -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) -{ - return AdvancedProcessBlocks128_6x2_SSE(SIMON128_Dec_Block, SIMON128_Dec_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} -#endif // CRYPTOPP_SSSE3_AVAILABLE - -NAMESPACE_END diff --git a/simon-speck.zip b/simon-speck.zip new file mode 100644 index 0000000000000000000000000000000000000000..65a981c4e2f2a45b1b4bdae82145bd8350608dda GIT binary patch literal 87474 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 z zVR2SMyrd)PxD7_ZpuutsWW6qe7o8C{cal0FQYy|v4fzX6EMwB<^g0*YVX_rEVeterDGtIhuMLr3_>pbtA zFQt2alrl7M^2>REREMOYidHgAU&}G-j-8J|`+`l~c&{y3#5Qe*zV!~F4G|Qsw_Amz zsTfdpLH9(=7j+;kAfV170ui;slPKF{X%+(bR{fHi_*3M<1|cR&6>xIOLC|o4_y_jx zVj_J0L>T%^>(Vyj#v8kuKS07^_P9v&BD!~Tc!j9AAx3Z5KDaO z>Cul=8~M-CAaJ2{rpDR5r!Mk1z*O>buZz1z112X=_j3-O!{@LKVl15HhhT{LP$Q*9 zXxVj`F~v%|E&Mq7R+QvWDPmAw$*ECPh=!#A6{xU8<3!>{Wm*D++yrQZ>h6IgFnm#eJBoDKc6gbdMaq zQnYH&9`KvqN(z&wb;NuS9oYcJ+_`*S72GT1@)kNd{?y<3(H@s8CRFA-h&~moI@Q@- z$O=cb+P1l@vX;_Z%!_#JODj-b7lAO8hUEn7hV^*IGVlxkB%vumHh+)whzdb&A!3=% z%${RX*2HcOJtKZ~zAsac>e4!+E@WE9bXfwsCS*jfY}>S2jVNtSjpNAyB=zcSYVbFE z&^C7NSNGX83#KC5Jfy57#n5gp9+}p##=D<{;RZJH<1_JZ=YDjRDwfXpt|Oiz^KlX1 zzrZKk#H`U?Tl_+-aRbl>{sYvyhu-D$*s5hT;p}`4Mq$-S#KqDntxE+~MKb&W%qJF1 zN5_!nV^>xaBqE2hJhAF%dzDZdL%T0Ld{i)J_Y3R%*#jyg7bs21AB72on%gU5-G3&T zkMv&TMX(>FMCOvnB9M>7Awa@0!IfWeD>6|OiQ(%qOq9rr0OlswDBOoB zB$V#uF+rJyyTu0n7VUF4LH|K0*!O0OwDA*bz+9D4B=f{m9mf2GPjdKL?HuPY3UFnL z0o|NnNi`=IwkY$F9&>$5afm`Gv7mDt(XOE=q5c~TrPQnaWE3ZD^mRx} zG^+4@(=$hvdeR!c55g)eYViiYX9=rUgf-|7yL06;%hYR_7FShU`PL++tR~4Ln==UU z_!mt>-D8@+#5cc>9TK7G^L(k+s#=y@i#&8|S~PDa!=5g`&=RegEON6$oSN!4eG)4< zoo|zLW<;NG@936UDb0UdGo-H29s6V>A>xRCXW6kTPUn;3LL3-QONqy%$@8X&&P+LS zH)TfOZ{N~7EGD{2z-Odhy&ok{v=eRU$$Ych!e!p@c_S=W(Np!Dub9->Q zRR(K2w{?{Vdu`9AT2ChMnK4m9|*B1_zT_VuNFtF~Tq5DEY= zFIgn;Yg&}7_%7Jq&EbG;| zDh}*aC?stc`x6x=j6Ju2UwNB3I)%>7eGDI%H`Q=TFqXaP6CL_*7_~eAH}7CGW8d5> zT=7<#d21^S>?q4Z#IoXx&wae+FW0tZGX-R+n_VdPRV~~#K;Hzcn*YnkUf0kQm)Ti0 zV~-DJukE$z#=2y0SssC7UD0}Z=&$W9#vllM1X#Z|&g{8^N->4%mfHF9abh= zz0LC&@=EVwG@@mXZ;VPKcr0|(uGoDxjeE@NmpKq}a7yk)EN?`?ppdJ73O@XAT?J#m z@N(z-)A!@`w{}5SIg6hiULH%F+$LtatB$sRK#ux&^&!LH1A=PfXyu?23e5z!71M)p zJ=;$|kNpPt`ai0JXJZ;mV?!PWVqbviuArFzw8pFWSxlk&e5qRb_YK)ypxhJQFneii za%98gsWC>xRKI3^d&z1{POpVLGGK-TaXlo}@_UOEJbfp;POnd_d64-ylPt4*H2W3A zqG`W;1MVC~$jJP%(<3I6_8g#*7g(~GJVb(+Q|iaq^16_*D6uz#dmm1pFi}eyL-~tK zj+xC>XUe0i$;rn@$BAYJphtzdzN^S8_UbzN^DpCSO-=-J<=x$sS4#u;Lc}=zPTNoD ztL*LgnVR%RkIw=xSkLPLZ{=O@#!ieKpT{nzaxacc7H%;`CA8OeR;PxdLWyB|WD!<= zt*?GaE>fe4>LTtH+-yG5S>Fcd)whS|Ye|)JX4%cHN7IU0>}FmZ_wm7U0oOpTR;`Ec z&#R5y?ctE~Q;P+>G3Ak9k?(okliI6%@rDz_aP@Jxh*YIsul)mv3_8WJn=%7CanL3M zx{g1Hd8k~f2~^+IqO4AU+7jqFB%Y8k=r9tC{_`_xW(C*$_tyz@;eAqEf@TJ%(O>!z zh0=NKdZ5m7HF)NE-oRGOW}1MRn9lX}oK3LI47Pp<2pF9>p6?DKJ@ifUZn9A%W!ga< z#Ze8?ib_{M8fg*9pC|do9>p>)q~pt^%l340IMnYXD`c0k&G{E?XmidctNqaOQB)Ut zxoJv_Z+-!p2ri;{VlTLIeuiG6P!7$F5T?i5ec@e8$CKyt_ol^LZysCM%83zffJfw& zj!Pe8?7aoAXLh8kKnmzWl5j5|B)1Uu!2p6tAWH}@A)R$}1Rg|JP|UwFH^T!l>-QIc z6&ZX81`Y63$$WpT^|)y=17MCt1(D|YVA{!9^s$I!4r2hC1R1EA*wYPsN-#mNDCkhx zLTlGs_uZ&)i=)B__?!B+b8ibSuv{mU>;qXUIr`o+O_=)*4b?H zoI<>Ft*2^O-FumUw!W*9MKS!g|R{``CL6MGt&dK8WY$TJf124FJJ=Z@h?nxs+fmX!FDzcoi zpfo!3V1;kp^=NK%jt4r+`{$vtA4RDlZAh7=$H=BIwv{JaDYw5O4mS4}42n*bS{OFoxU znP-9NJpeH&P7akC!4_r_pH#)9Y z^0-YamojV4wpNgP%GvD%~rMra2(sWm*Jo{=4j4X)oNmqPb>aB@3F#K5?Aba!?cWdi_0 zvWI6f27t=8w(cyEB#nR+pfMUj-QkTC55&-f_Nn0UAfFS53=BZ`b}@JapnsaVxUcOt z<2pqZ?jZ@<*#t>gZgzyx#mb*-@eCZt;!4x4~WLLB<|lj1m``JcMgRsmqiK%+216f_mz>;5uTM z{nF1P^~*mib@l+*F8uV)A5axQP`^7zq#M{T*a;MGlh(mHCNMiGlnCYTb0i}*mDwU) zdp5aCHEGlB>U34i_iUaFdQiOqDMu(M#*eOsx_g1F_6%zK(Q8(!qmNXiJd2Dq2##31 zGc?Kf++$Fr`EI75;c>Am5+LVdyk$Tj0@N!04Bm=Y^?3htsj;;J1rrln2lBUMUR47i z7D2`L(GB$BtN4!_fR5{`021xGfI?V1Jb?6(Tf(aX4su($(Gh?*03pcB zbVJ4O#M1V^b3>P+ZJB<2HJicuXn9p@6gHvR;1RY!@yI zC&MAN;PKT><3cZ`%3THi_=Q^N?6sNNlE;c%#(mW&zTeOjz!Dw)C?7f=FsvBiz1;Uq zIHx)L3vK5b`vcjysZ1Wouf)dE1~02{_!RixcCf$XnoifAZ74&i3p&j!K5BApc#n}4j$v%p2D@c}Hnnq4%i0~b$;+Y}P(l8iF)tjBmg>|U3*Z&faYE?mZak^M>&ks| zrL|>jV*uv#dcgO*8cO0d1Z-mjTtO0StT*y3W6L&Bbflx1cgO(0u;&a;@!KNma<~AGi&F_SeNi_IE?o6#y;|;b>%A%@L4Nz#UK)I;y-(la)An5uM5Ug-r zIn$%!4Gbg4RhKau4flZEA|#*9)u3UeD=Tqf7`acN+lnmxb$4au0{vAain=okPM#2HkkuJTMI$|oT0^KGY6JxV z9c}SA`n0I(I>8KeW$_<=v@G6OaEZxD+Hcvi_A2W2QS7O6q2f^IBL8uwzh&K+*-E2W zm@!LJ#qu3ZYYfyGoDeKAuMjSb3|_pKDHIQ*gP6JFTTd)b{H>~$T)6&uv>IehcBn~? zcFIUYa6p;>#5QQ3VoOHXoC+x!xKspBx;{(xi2Kr$33m1O7Icp{~xL48=OxKo9dZVrL*)h@{o;;fe7 z58tVN+oXB)-3c~h9(}^%)(QT#&y~)JKi!8;@W;PpaQg&*{?{xXOM-tbYf|t74$H4e ze*D9{?|08esIISnkDEUW_CzNL2<0*_!=xOdC=7bX>s8UE2pPQ_t!6|u3W6M$mtpUeCjQhI9j#e1P#KIdtkO@PZ$5pWa?1{c%xb=4vV#${5_nR+Se~|h8 zgomj=plZb-YH2jq=k$D&GfKYW2r83&01*y1`SjTAhb2qve%)HqJ4>x{rWeT|i|O-Q zT+EmHywvBVK7Y7;L;8K?~~=v)@eqV0DRi{27?Sf{n!JN85gHI7o#K;{BK~yr-)sd5`apTSxcxl{7 z-mFtKM*=s)Aw+sB?IbLgm+JNal--tfg8@QdvV!UTrDBw z!7CREZA7EK*&9KaVRwRgEsnr{%f#IZdhnl{p6~)EWj*=-x$Z{TH{-p6$x7?O284Ef zd`b?c{Rj-m6Ik2_H6R6Epjq6A(7umQ$%VVI=|<#9Ebt~65zc?GNrXTD2T)4`1QY-Q z00;o!MNLffqC*-FSpWbr)&Kw%02}~RWpi{^Wn*-2a&s?pX>D(AE_8TwRa6N815@mR zT3YOaT6K5}009K(0{{R7=mP)%?Y-HqExVPbcP~Ki5P&bMG5euY5x? z7+FH48mMHT^6mZoQ(Ku@a|-EH>g;V4tZbxn_Fikw2y%?SAqNN7zyG^m|MnNZ`>((J z+kg1Y{140D{KGGQIe+)tUyS`1zxl88w?F^ce`>$fAOFYy{r~t+|1O39_1w3g|LlMH z`Op65*Z=o#hyLOhzx?&DmiDWA`J3O&@!yu;wBO9%{@Z2!&2Q$f?qB?mg`eJk%}4&~ zci(=N'=Kl|V2Km3Qqdh4vUW-;9~Q%zZnH_ljNe*Uxn{P*n_zxv($AN*c=vU4Wo zCCyaRNS@DpJ>BpBI*#V1%g@3`wepPe^Pm0g{O|n5`K$5UfB4PszC7005sz+)vo6lTs88#Lol8!6-0}W8>h^A? zd4_e27;PEu>!UyMxqZ3A(&FuG?ej-Gx;1y`!*_%tToT_<v@efdOe7|nTN0^|i-P%&AALM#Jef!D z)sN=K{UaVdYa!+rNKzQ(%0qvelzF|yS6l)gT?Y4#4)=EeKbtqcA~ zJo-JKWPF{AFX0ZUx}~LROLP6pqxaOa@lRRGljAey8^Y9Qk|5qM#g*@%Jv=T>vC&(}w{pMi<_%$rt-}NorQD+q=l|J&`PWdWb>$DZ(rvTE#lM(LW9nkj z1x5{N=J@r=Ll{t~Gi2%gG?V`f*eC21eQ{)I4e0htf+0=UQ z3*(#ueEddPy(tSsd^aejsrnIbQN@!fRT89*0n~tiBjxCC@MOY2dd@$di`zKsQ-=b| z0PWv0Iwq5!n>5pml<3Wmd5clKn}p6X$6cHQmq1ZiI6`FACvU>nxoGX_{3*yg?&n4W zeSM4jnI5&;mT8{oeRDtNEy(RO;QYl6?-<-0UJk9L;+UpjgGpcC0$B><=DPIQ?PJUv zMwRIes;w^mF}>gS{bSxDHebuE7RmoqcY{$0p;?dw2u?d<@XuH6-v?6#N6hi~$Co#H z>%hX(G92Msax?s(?Bh>-U@aYNG{X z^35-g5ZhCJ5Jt_E+YE6jF~Y<=JVwAlSPjh)a~tlfHudc`Blxt8k}P2L#uqi4IbA5s z@tjQMr>y?@&(=TBDDT_;<=uCE&aeN?zggnHPyaqHe>Z)4%fdC8mIx9c=-kGjOoou^q> z5XO{r?E%hO<6btz@LEHxKBC{^YA$;$>$>N#=W~g5^X^#ph2XfHv+4a~k2OKw2UNJP zF*zR=cW&05c3tYa9--82u}8?h#B;f}x~CG(rJm(T_8>XJnb)m^_m9o#x{fuj%XNkr z*K#hai|2L)vmE(M{C-;e;jg$~#}W@Do5}cpP4c+0_(;fdDa{R^F10YzGuU#Ar z`BWY)@*kmv=l9uTOG&ppZnL0FPhUmzbKmLq)-Jb|p2wcISnrM@M%TYdmO{;G8xrCEF)cbXn?B66?m2=~8uNHRE@G~cnIoq3Eql=QF(hw^ z+lli^^Xr;cv)BW#r_Y)@T-!6<=%8vDHn+RX#k!90wsE=dVg|su%%}Pu1_MW8VH@1r zz>zWxy2CP74LO-%^pwo}f?X$CnNxD9MP{D#PL@n;`~%v(7ZfNK?GD7%TTTYom{qq# zH|LWJudHD%9k2#gZyzV&ZBehFr^n>EK1j6?XSbMD&+AQF-#-18K6e|_~%)knRAZVPF!U~ zaZU!Q19605>=DM%N{q85Jh0KMjmhx+Jsw?rTxyZG3kjydW2X>WY|xd|E|)kX<)Z3-mpahlz|?&E=ha7cIkDK4t-C?&Ofgxq!2^_a((*AAf_K$YrcTWC&_) zaWdwB(-UxI_tTr7{eydyQjT24eBuPgBV31Gtk26`aSx5`1YWyVF!__hyYur=zwn9q_Iy8#PjKZyLmAMtvJS*zQ^zHByM{=lhTdChw! z%=q|xc*G)fcpT-}KUnArd0W%EY)3s$XO1NwTfLl?5{?{?7~FFB;L7P4mRgZ}Xk2rF z2yWvU)@u#BvEMh3=1fn3$;tZO`b64*fz#Rt#4E<53HtBzXyCX9L%TqYB1-#pdBMZ4 zePoE~c|s-K@WI{mnV{9%#1aP{Kf0#^WA_A0%3V-V$in~)74+B){e5N%D4q&v9m_4) z49jC2s0jPy>gvmX8n=O{Kx09<5Ahx3GlEl;m4t82#FEa|UpBoft%s{)r zSsBqf$)40E$X#k6_ThnKXF}9`&7%pHA+(q>;~=8)z#uR=g^(bNy4Me=;(qY-031fcp|xZU%0$@F<5e}+J~v2=4zB&Lxhu<~ZIUKw=n2CNgP=aE4IU7fW-@*s z0*vI6_jXt^?oM@TQOvk;$5PQJm`ghd_*zNv@Jub#y4!cY+BiRYi67>F7^!Xa zq_61a&Rb1w8X)jIQX8OlnxBum*^->0#9sMj?Il#CD za?Uz{VB~Kr5lx^8!Q<~Bw>K|UJU?1)ly}W;Oz8l^jt~xj2&Cf(=%jGQplK%hgg=%f zvxY@mk_rCCb-(K>*RcG6Br%H(HI_6<{h1)@e896Iv)gX_0Q$>>W6Hp9MFyWaL9Ul+ zz>g0`#ZM{%HW6gP3I#OT9nI|_AAq|R@J$*pM%j+HEd?B8AiNpGL?*+G zIRkGG>Ty8b)`b9C-;J26&^eBf&tPnNogfh~^f1uogJej~yVekw2w~ngyfNyuw?iBZ zEKZl?FcxOKL)G3*1RMdIjP13Bf2bWpeSa))6bRaz6101QPbh8~TFZA@>3{$uN(G7+ z3Su=#b-)<#2s6)n^3`2d?f!IrU`vsvTrxhS4(-PJR3^G=Q7#UUR>cU|D&lV_lYM+Z zAfgu#U<@5IQp|TQBFAnq=x?{7Qv{-3%7Y|{S2V|h;tQ<=&6=|4>Tb0$HSRk z$Q8aO`Uj~}TnkLA1@Lgr4{?q%M5AUR%{aKrzC&OhLG)O8MhMwn*MHq5Lp=WC3#K z3A0+;RQ+O-M{O)V=im$IGCOoW2)pPAw;;`dcLVrfT;hsQPTw_q7^6^(7p#Nk&myUyGHhRLd@A zyC`)~gYVg63zUNZUsAVdYHW;~4d#%DzbmudqBKo<3K$H5SOC;$H5lW79Kki*t&De! z^wMpD&N4j8g=g(|&QaQFW*uYQ|eNjN5#?SK(0vro5KXTDj{7nm5%A#KZ{o24QtXIiM7pnC#*CjPj{A zlhOVdYVqW2K}`AND|FvtakYMO52{1U*a>lyyy?1|25v5rWccJh$-Yr*wKzpzCzXbsC-Wlr) zlVTUV3@6IRXyrc-X9m8;-5qI&K7R6a^73dbi%>BBV-_T|h z3|I5qGOtWf1iHK`U`BspcUb8@vV6-2_n^C;4Bq!1;k?WQVi{1~W06I|QELal+)*wT zg2PIYG|eW`%1W4{B*Oi^SX&8;I5d7Y8l7C=A3%1}bTMeN3D5DX)#$mGGN*ZFL$E=Z zMSDY!N^pFA+e3l{$TuSuJpf+Zn`;luiUs$U_-vAtP`%^Tm%#j(ih=Z+UN>0~W4-yjW%t1k)8 zS@g!9I0du`wYxv0Y4NF;E|CHLHze!v!~+tszN#?U%M7-@S`a*P`}Tf$Pl`x zYBy9#R@z&6R-RFdT_to33c%m8Z%iCvmmr0Kj_`=PVwh$JoDHcvKRua*2ujG0IzDzK z%!8*vLNCZ?WKfZ(xen@Q#&8h@1XTX z*D&L^YI!H~`;a07X@Vi>&>}C2HW1K8{(-21|3-ze94K(V3yf~EyCeP=^S>&E7-L*M{1@bNgx2Ut0wIZ^&JYr> zhUa12;`8ybvD^hCss#(QC?8vU3oq2YpMWujfLrudOU;Y8wuMM+0VG|ZLcq*UHhA+sd9yaz%_KgO~?u>v<~@#{}D?-EIcDOV{2A4FVl;a$`vd z%^tH#?Tid>!x4E9)w`Nsb_OLz&c4?KwAYU7YcJJiG(9%4w$!H;RpKRjRr#3fTK$ZW zk8iJSRLqpe-!osKCI7zQt8!9{tVC&af1BrJp6@#jJo7U{f0!Qw96XG<7E>HVlt93l z0Obb=&RSA>hsZ~ABA{J~FS&W`7^wOHnm~PxTdSd)%G96A9F4fu!+Dn@sA6uniPBaKm(15yEwS^lI z)rEG>TAk3U2ZX~90V#KdpvYo~3KS&W0g!-r{9NM*u}ZHRt)cia7--)D~*xIE|j@ z8Y!)?H6l=<34IV|{BRSTxBh|W7FH+@uM9D2kjWmzn6eaM@}OJHGK+uEVV3YFSwd5l zk@j7+^n*OUYk9AbOb~*fmArQ8K}T3^)hDDiv+X3$h2W#ZB?9u++p zf|F8uQ*JfPQ2kWZeSVcaC4!B2(q~}jvw+8pG@D?&6i~S008r{!nxPFXG?8kYJP;GIw)#k0!-rX~<)+7ymJ9JYM#&#OJgbna6tpd0UMlR1 zQ$=-Z8Pp7I@-YGs8r%s9J^8U>GTGT_nuh!yWYmYmx+kB|$UIYYd_l_=ueD|V1dbp( z5z)~yT@yf*bu!|6K1~!@py*tgh>tb5+o4bsm;LNGe#2kwexeX;ZDcua7ll#Z_9 z>)m59Ajpv?;N=!A#FNSGyJpYqU^xGeIMN1r)?Ou+BA9Q=ZCdP5;?XzEc{)?$ zf3^QsQy5ybkHg_}9bAp(4LLT(RHr_YBq4sh0-G4R^mG0Nlb;p?pJKnjcBYlwN+PFkDbOekmLAyLb zI1Yen#iVIz7-d~!tr<%S#{t+6z={*~e?p#v*OE39yB$gG+H{yu+A`z(2qjg2gsv60 zss*hfhobO80=ZiYW*N)X-neJ@Isg_R+s&M^_7Jrq;u+S7@W-T+B9oxjPI0Lj?TjvL z7OU_?9fVCdv^YL@P$sIc;IUujY9NlU0NnkU#Z}c8!vxka=CW`2zQGg9Np!84>4-&a zwtiIfqFRi#S~#f@EfFF~Gb{E7vy7oHqrqGEU`7he4Sw+xT0`PB+IZkR>|u3%^sk2H0>A%0Ex+n zI)i(A!18_su{z9(D;#aJ)(RKn@KHgQStYE9otJQ1IX;FXx^S z8=_~)=FW^CT-bFqD(W|*3Y2w1AMY69d#v0$Tv!oXMKiuszqa*Wi>+@vkPjjvL4%Ou$oI>; zd#$-?7M|u!(7JjosM@BL@y8YI22^4uY6W9hoau+ZH%#%ZELNedAr_ZV6T&sCj2fR` zFsJ};bS8k##XCp^*>Dq!Ui*C!rPw~|wyneWs4U8v`e;v(TtO8T@bDfPV}%nECzyK6 z3%>9JH4E%8Y>ZMy! zx#6@PaC+$;ZIV>ykspT?#M5P*IQh?qMWmKGXn-n&7h#3}aZZ3<3mW6YO`$q?aXc@H zS)Or2hPK(qH6*xqI3eOAkk6{wSP~Gc4X&l#IeD*z3vAX*?`MVvw*67v38vB{@@OG$ zOiHiv*PQK(zz5zXU`L>X_NtY&sKD$y-cw;&{ipBgJro_>KyE(MM{W4~1U7`l*xOI9 zrB|%!1Q8dpFqTv5NaeYG$O&nW=3`^V!a2!83CyyA^Np5L2wjyC->*r^Iy!*@mU8o! zfl_58QQio3@VRw3?IU~8D*&DfYp0~+-F5Kh8QLTb-RoE}^VRa0l9!;k&Vt*8P#dq} zThx2@Gk)LQQXf^)^*Uko=nRys1yj}Bx82fUszM7L*;E|u-nfUzitQPT>qy76%4oPvG4I(>_%HbIpDz!m_CvdXajNu|6mab zM52AVjav3YGXbec0+Zl@@vi!jbx0K6S4%3hk$CtKbbr$ReS*Mj)ES;f)4mkA^j7gD z_)C;x&5Sh<0{<<0_(W5*>C#ktEGRkBwT0U=NzOjTL65UrD=l7e-xD{nJe|4X?eO8u0L1a(ds<0u z3{~nlNtvJ%gAAJ2Vh7l!+QSiWxQSF?wkial!Io}}dvL*CONZstrQv6AXH_eBppr_g zEYB1rGfZejs_(AgY$8{pdl^X0ppN=W)VZ47eDe2QHF$WdTrFaP$9;%o5PGQh)weY_ zh}WsKb3!Tu@cr6)ph!|NbB$jQhzpdCL8#nWEf^$z05M10Phf!`jgQg78N(NJI8y75 z_~UojnOIL*Rteo&AFF!gf}qH_+XunY73VXOt;q6r$BaZw1iYdf!FI>$Q6cZb2Oyp;Z{;eUd(rSKG5BckRy3>yze`_ zw65Y}ff%MIELGI*;Dn~yE>&!J6{=2#3Cj<@xH#TgnS@6x&szG!zh&rQ$pfUg!M1>T zi3merH{5onjC3txT5Mbz_R#?bZGI&5+z0pgs`Dz4VK?_<;5I*uxvhW%6Gpy)eiIw4 z6%MZz@{D#hPF-VESN?cr?UN*CQu&_FE9xJTRy}>l?sXOw4~%crzSiBEmZhf$T1L`& zQaC%Ro1PEoi~hls^R`I3S4}8s6Llzh1YdO$vrNo^ex+py?Exn&tcrwhDzWM>aWY_g zi%I^z%579Pr*^ZO)zM2yG)Nok_^sAp8izm#DzQ(-wy)gNr>wfpt3Ik!G>m?|O=eb? zhhRtlLfRquRT1uql^UK}w7X8Nug4HcI@-DHxc zAk&53NO>&zy(H%xw1=?{1v?SjN1YoA-fK4k{$p~JTy%ei=#~^h2qDi}s;FnH!eRh8 zN?9{ucS@Sf^ciA(Wla_sIx|;=wzA)l~WB-V~+aJJ_?kAXtq@qCGbTzQw93!VfFs04Fqdw z3bIR$0kq`~P$X-tmVKVexGz>qj7DX2P{L4ML<9hk07vYX=~QWG9KEH%qpOSLK&k{s|tV>~_1GooWZ;LG4H2klVM8>(a z*IHw(XgRn&zR*_;Dl;Ghk+L>rTlw5AeH}3%&miB4f6@v)2qIQ&Eya$!CMH$9VF8jS zcO40xgt0?X@F(U*R*X+Un3}tRwx$Dr57^Vo>r8i9Kum{H#e#MkLSWwMJ-hQlRf-A;seL%Oa^#}>ZGFWh`6vBCGOr1 zW`>%I?RMH31JQ_Lh&m19VB)~2_33wvtUs!` z^#WPsG!H@r_w*=oG^*vM5*MPQFI~US1VM1fb-i5bD zCy&W5eyUDt5Z<1OU~PU{1jpN4qOsHgh!+z}VGu&HZVu;$4h_ZBf7o0G`((rxK#oDe zEkcUER~yhFh@Mth4{`C1?velVi{X&y)GOAu5t@?zzB5ILW?uX?iuVPT`-HclYke9BC>)Apc zeYQ6I*H-2|dVlu^&cMQeRYNs?D3USID6_pW2?_+C;mE}_wL-KYrLuNCtZV42`s4Dl zLyA2XfQye16BeVzJ!@AL~csaE=lP$nh` zHIOn>uB|rh-TkCJi(fCMZsxyt7@6mfHvCgRoIgwdIGuS%_oO1RqtX!lW7Z$z$!m7+ z#|u0*qI|zqXS&Eb=d78`zmhR;Pb5a zu2db#8E>y0RFU9qEbe*mojOT$H$r1LoMoH&hrKp_OUE>_s=BoLv_ym8dFh|gTUOVI zmJ8l3;Q(*6>sxp9yW7yB1>V#XPwkawDEIWqd$nO{?=>0BsT8x0P9U9@C`;u{Nv?Ug zZ2qtym-`QDm|sIJz>v=Fs@2QDSy$)h;)q>u3s`MZeeBoQ4rSU%uBx+|SD{DdM`5yL zQ!FjVw+)Sy+^|7@v=p_>(s?jPAnEW=)ddF} z?>e1VL0?E%vM;Y)hmHP5KbFSJs@Z=I+BTgyc^guD2k)m;)tZGy0uB8Ad@|lgEj z_rqRW)z){lUd{S^OGXW3n%9o5$|+EOOHA__kkX7u1^awu=3AW<25@ZhaJAyqVRo#4 zC&N=^0^bxfER0XmIpSuKVk(~0K27dA-{SKRLvn4Zq=>p}>cy@0b44p+p>`GF>Fh&w z$zlJxe^edpzCxOf<4I_jUetY3?KkVA?P+zKNX6N=+>TGs2_~!0YLN_Tqm~x$p3$M@ zsXr{YgVyLe9HnEpkPadufOW7-qLNIGZbW1ec2 zit%`CeZMiJOiw_o)i(;SK5CUgmSHj;Z3?&Pf7EMdQkuL}odJ}UaXdQEr?XV3Z6z7+&XzZ*m2?R(sZjr&8r=R7aFK=XfMw z%d36ePb|z_{Ks2r9v!b&t?3^+7XD>Q?f3c&*vB%bCn3FnLwvKr>6+}*TWJ&;L26aN zQ9u!+R_nSMiBVF`bSi(=jPqK5-i-g#IDo`b!uU2Bijo&^$;+(n^+fueRi6{8+6H7@ z@pP-Qy`iSjbEdgedVSO8O}B~6^jd=h#B}nsJrB4}^fS_LEdfS0vSGLSl0P=0&8yIH z_!i8l_Rn0)`U}QkGS`o7iv9Ncej77oa`GuA_86wN2`4_v$6mr*wYe0)gqSm3le0)cZ83lk*m_UYH`_1?=Hs>jmHE`BGY;Xl z>UpJuX5huFXbkUu7(O&#hc2@q9eF05jn;Xu#-FHxuu9zk%Uc^N5qXf*z`MQHD|$yb z;7Hupc+ker;H5#z>Qxi#@6t&gC6F&IeKgL#bL%?iQ%2A_4A#AY3|h7bB?kMW#vx!X z)p$ThtdTAg`5p`*iPNjX)QOKXM>0r$7{sCGw@PbQtRYFw9I8qp{6EOG_?M~y?#8cM)wIr3j!!x)m3yt+G1 z?UjbtSuBhzppnEZ;Z?5rIFi2IUZpr+^J2KE#-`G{K}{{{Ll`{H^Ci8a9^cHL>Z3wq z)Erb<3l7^VL?J8(a@rq;ll@jh1(n|6IuQ=)$vr%I3@Hw)9wfODs{vZSZ{tf+^TrjKPp|{}uf5>p+Y;xWJg)Hn zt}Ru6;2z>#Cz-!B$zEK>Y(-L!aCg@InVY5mf}eP+MfmF{{`C|8<)8R9HTQf(x0TCZ z*A`06PsU=beN^>&v>D9f&BD4J=ka-c#+HLQ-JWdPojd$e!{PjDjNA7EF>RME z`QzYuwu1D_XI=8H1G8>}H1}|v+eh>N>dzALvDzI=;o`FL5otfS-Np6P{WcqFbx#bW z&t^LhaMPktLfp-XZ1UxN|HyN%*R}7sy^!s7I6h(9%&O}CD@1>-fQ{Yu{j}-YiqCxH zc5V4mlXS~}ANk|O)#H7O`*sw5(OgNlLF9Pl&7^c4>DZP~FJE<51j+D{b9P&!al97) z?a^}|ZKMh#mHZh`spV~7R)6Ghgx!bWcz<0w6zk6Sm3_W(=8h7&PXJex1XYd z?4N=1VN310kSqCtIF}$&QEzo-A`oZ&*7ONuiF=5?8Z4!b4jXfK>(Wfc&h}dC_+u!? zO1LLL<&dCyK#dV@6t=Z(Hk}pMT_K3=+rG-ZruuY0dCF2C2VR|1J{qBifsi*k^4_pl zIx(Uf8Jn`F@Ei*tm9$!`lZe?rr1xy8x0XH1E#;4XC=gg5jIo99Q=DqtHk!K7BHt?7 zPbXa-ZNc!TxNDtkc+_)bLeDt4*Ye)mF`7I}v_&1DpQ)<{+O2av5g%-HmheGJx(43F zCzLx(U2}ux)7CbM3b$R}ORl5ZEa)ht{G=L4tlT)xT?Y}gTO zSYsk|cZtoqfM!}<6vHFg@;Z9>#Hkykmvon4@%1{3SbTb4oyfUA&JpN6cAX+sqc|0K zs>Q^xzAk8Z)76_`_^D&`>LQ^lr*(LcsCS>`cvI!Xcf>GZf}C0@>VQ!#LD$n&o%k8v zPNt@h2cMMH)@ADM)DWJi>eG*kQ#ZW|qZmSK?&o!7svQx6xm6}mQ+nOqBC|Fiu@LgT zc~h52|&G9c=z0r$kH1DeZy-?6s92b7^cV_NjjmU&S1x3=8XusreQT0$WQ z#{JpJp^#&^hct~bB*je3EF;i)d&IBND(HBe@t!%#>bCo8LrFAg9nF>UQC1Hb22v|o zEM$N6W92i|fP9zuF*ZIA-6Fx%-B?qi_aX2<#3r3;$E$Xpk*hJ{`mDl7w@jMQ zL7EbqL2KlNFHcMqUMn&lPyNnNo=SWjLgOJAf2&?-y3uJ6RJy#u{-N`-+EeIA+jvwx zYyoG1&%B8%otk*t_)(Ml$^ZG##teyZVgyWS3D?qctBVi!lXSPT`cE}oA?I(WTLg%( z24{TSdzOF_bzsp6RJHThMa~}goXxGS<5g#R`pvLSewn!KOV&G(-@2lfKfXWiXY=v3 zWj-E)qPIn-xsA@A1(Z=%CzPo3V6XGWQF*@Dssgd3vz86eeviovbwt~9QBxqq)e_Y| z#WpRKs&YeDEKR42G&AfHaj#1S4*ZN5SiU&A&y$-q>!60(p4=d%S~{^>%TGHli53laLbEpyuQ4#=H|J*f)wOL2^)nJR z%~0pZSqd^cJWluKF*&bpwZr>|sjxa!tOZgS*WGuSY9XwXc;F?DI8Q>L>9FS8eky>F z)l0TQph&-E+$tG}B_yXd=jvW?KLnCmNu`o?Xrs@9mQ4m8_4$Jl7sx?trOoS#mp0SV z6Ds4Gczd<%VU$$GO}>bMn8K71rvN0(%}6pf_s3BO;`BC8HNLAra3uZ0m{1krogW*> zTiwt#U_o7cckA4XdY|TMXSYeGuRflV2v#3#^|83`r!NeVwxS0Di%5E1(-GAYC?gQ%*?dP+C`$6JE+%oImNq^mt}k4U!9^-20>MU+M=OT&)%YG9P0JJxv|1 z&+3=!Mp=487zCFQY2N4}*yIlP+w=xgRF3=VzOQtGe|xU}UO16SP>$bp=Lt&ALE%U3Na} zSar+i9+TgW<=if{phl{qTI=Vf#As?w1c0g=lhVOR9C1(11^!I;)-7qz{@gEXFH^NL zw0MTzF@?ymt;X|u|H!MX&RzDh+huf4m+7gYUJQPz-d^g7@6s6##zvQ7^8ASG{Yqga zo+@+T(x;iQ>+Uyn+j+XeSDuxJS&cnbo43GYI|3%>ZTDp}{6OR<_K>aa(sLK1x_xJC zSN)Oto?Fxb>P1`i`5wqpUCn`AKuW^(wkFlWt)rJ}EbJ;&&4l$K zarqV7)stUWx0!4M#6Ax2fzoQQi`!!0 zp4W{{YJYDF-k{vYKd-j`S~3YSR*$Jb*Z~}PNdCej)7}b(?A@`#JveP`J#A{kFnVw% zcI`}$*FCX zYHSEW7iZ9V2~T;e&nHH8kceHqpe=HqAkzW6I}G*L>A8ibo3Bb#qmPeOox!6!ez}F$ z)yzxQ)2N{pkZ`NrPFCGR=mwXLa8E^7G^FuF^-J@ywGUF$ErJ?O{*3oa2j#?rW#Q^C(}(Fj$|-y4h+&|TMzVtU>Y5x z9pn9R<6_rkll9g`pY2w^cm9pIB<~$u0TQbPDc=BGCuMwGoUVqPwHHQ97jwPiX4Wm1 zAy@5C=&HEN`%djK6lB;?2i%}V<2${I+MgM;81DId9l8z%z3_3*2|S9Ee{?`Izuh$b6W4 zrnh5Q44PBt79Ee^O`S>&)#|}n&ul~f3o;h3&+ijEx`T#sjd=8-E6#h?>Dc$KbH$4> z63?lVF>q=HUGe7p2ISDySKk4|+R%JdbD_)02dX4#gQ27t+9$T_`)}RLRGaQa(lVur zGHQ6H_MjH^14Rr)Lo7v9!4h=1A&-`LT%pKE+oPC`ZdX^wNHG_fsEi>uRa#S3f9$f3 zhE3g))r!>(o4^w(N)*5}$^40rB;(v{L$x`&;-F;zJQ;q0nh;-%Hd(Lz<6iRp`&RGi zR%!eFJiZ~)K3-gs-e&N~wWeBp;3GdIQxyWW+es0(r##U4txEal)%ozw6HRtMIuH7R z?FhZ8>xk{Er%%^aYW6V=LgZVD?y;UsmvFcuGt^Z|M>i9IKgBEAemv!5bjFl~okNfy z(2_;Vwr$(CZQHhO+qS!G+qP}n?3$ig&EiM=)!XJGUqs^OxdIh=^WEtT%TtUO%>lP5 zkkRpz30pm_d&@n?nG*0X>}+*E5O2zc+&m)-|J{)E&j-DfGBp`+GNexLzGy-GdtVhe*^nv!Q`nf;ZG_CxUtP zn%+)>?H0YMG+(>*?~5gJQcY98;?_V6WJ&yC5vxS{tQQG7Vocb@CC zr%L3c3yB8}y0#BpRTJA@j7`0BdUk|wheggdC zsxNT8D`UcZvl{{Um$0U`*BtBvoSDPC_*z<*?5Q(uZubBOa(x=p6qew2^u&(p`>^RBXXkW!-BV}vdGO7+4 z<*}ZUC9t|iblaq=cH);Vs7l1p#EvIUi7)?V(_vkM$4ldHm9EcC!m>g=GY|5+uFoQ} zmkA#ibF^2TodNyy^vvqZyt87GQ26Fc&8j%{X{j+@l3ZY6FF5?G;<#NBmZmm4Updyzb@;xc*WiICS^1jvWhdpTLKdCBJc&u|*OkezZMefH*pOaN6 zLg-59v<}O)Q&ac`g|snS6fHB(}P;$N2k zHkcs51fX`W%^{V4t=neh_lP@6g0Y3)ILn{UhhsKh%yf4IDw)D9dy$nM$WqFXNkdB% zhgP&)1ey#`gcGgJGwfeP7X~uF&-=?JOd?y!vO3LuRGcm=6DO|Db&9D_Y$bHj(Jr6k zc+QzFBXnI;1TcMa&{EmjpO3jID<`#6Npc+ap)CU=zVEU z@HSZ$aIXeSLsVOZ9xPSh$pz*Pmpu-OY%cS5mRkwD^C!0VPgFM)_d6Ac7r;^iAf2ni ztWiK%p5jmz=#uMRueif^=Eaj|WH6HxgJ3OrZw8I=d%!!&2srok-yw zdB@`m``;;jC7q90G&xUBnD1g>WS(zPo!JBjr-4&@pnI*`<7nA#IbGr7|B1>)h(l?NxkozsPUc|u1$Lf zEv~tFwAPX48@0Zm2@O+jdveIH8LjrXf8u{Awi-gaaV1f~rt-e+B2tiURG&Ut#%eX0 z@hem#UIuNyLM3-!G2qADU8{KaHp_A-bKcK$;dggV(VPRAJRXV9Yh&C0KG(@|9DOf1 z{te(f>{M|%plY*id}XY)Z?fIiYOMRJ#TKarn5z4(p*-`C6=Hxx-0a$B?<#UtwbPxZ%(BB%HN#axIfGc0JyoN{g>+^3A+&Sd_gQ57e3;*gr}(DVo|5C06|JoTV(sTdRS#`1b#w(6M4YuO$hZ(L)t$Yv@gX3k*4jtTy z>3q#sjk)sMS^|+|;0@n6d=XdWyP==ZcGMIY(`?88!(pSr(pLAOp}KNWdxCUQ!-{vN z+UB~~Y+;E>jvg@Bc5Mi0D!oi^Xxv=HzOdmFFsJ`DffGKp{~ejY*=DUB zz@#pMeDRpAX!rBLk)ug!G)od-L`z27@pyNZ_vA%N%j*~J$Y8McXQ#&s?xsnzE;zi4 z(ooiX@qoX~V2%wTfk5w@4NkAYfV~)92RN}-?3=p&)L87RZcCeZ(Zpk?*e>jX{>-Vg z9^Z9mK!m`}_o&;!7;P%o+~Psa_{K#fl#pDQmM{>(_TzI|IBL2+&KNOEC|HshC( zJBosfme`*9-xFDw>WlRpUcscML+|uxjnK@fjcZRG&c7j3!2T5rOOVq^!EpbMw)|)* zaW|>=^W{C5YCyU#!F_e16$`nMJTR`@>fAtD^2XYxl5JYIDvM;1*};41Ez&ETE44jA zXV!X$&D66r9%CX1{<^~6OHl-kURs*$b;55X&GsPF2c`IE3`;U_{q@G_0$g~M=Vw^K zy+VVQzjJ^0T5%if4ONo(sW}(pDHiS!bU#eV8j8Z_ew0cGE=P@l_{ff{gmWx-V@6v6 zO?o8l%9_V7(Q?wyTp><>`zI048p=%?(99Gs$wN{(mE{X6P5@`{4r|tpXjaw2*4U_< z#wdSYf}h4jKtkg277``$tc}vEQs+_auu;;0 zsX}{?$d1ZJkN4iRaWp6kw|u1scK&z*Nr$)45g%zg5#b!zRTuNTf3UxSAeK?0e`uxO z&#s-`p_fRo>1HT%`@H}kJ&qy!C+s5Efi&fERjk9_q&uL70zR4>{=O_>b+VtD!cv`w z{U)9(7_`^Ap5&_WCd4Pwa4a*8mXLB0-eKbJ^|w8CE$p9%cWY6PF!HEpvjrK!RPK#? z3xotMV!h`-IG?Va>JHwM=6R=car}S-7RJfnD5URSbh7yhf|#ltB<8`u;7OWYM~A;v z+fL_h3+3;vOi2~2)Va{6$~}gy z3^mO8tl_}YbpZ7cO^-aiT2#&I>TzpA^~Y$xux{%@4d`u!tqboFU&Ri9EbO>EjjNwp z=>Vbi&c#wDtN9ETDa%rcTn3)?(%!3z<9s}rlvz(ZvG*L0PI(mhOq&`c5d=JbcGSUE zXu!z;j)bI1sfF;{!xfV)L-lBWSZC-#&&L3S62HznJo4=*!eWN_3xw3XX{x#eUT&-O zx32o`oiwGRFE6o+4i=nW@rRGJl37%%#&ot zVc2>I6@YwC%@J=N`rU$bHP@NTHK67=ICzKN*|&L|Ak(EJu-=jSa+roOpTfUFsmEN= zPnrRvwpq%*T(}KMO$^wGh{(WW`E2YJLGYlZ*e?-d`~-P$mG~qp?!L%^dy8f zD~n2qAcGm%nm!z3#$7J^h=V!74-lJD9>%8OB-W+PM@(CZo5$ZBGGDtw0 z!C=8A+wZ`daCu`^|k!6{ap*_3f_09pl(7d zDM;^NSws$ZD?y>+JTYHh1xoM8^*bII;h)N35khgttFal~gyXVL=nll<;IvMNA)`=g zu8vO8imCAo95|P)R@zzd6iT-JC`{q!Q~O3u-bTM)c2yE?xi)O-BzDd5Qnb37L@T}lHO{VuyOZRv1FzX@i^_krI`!EsNRR&eO zSsDRPSaHxIJ}VXx#?Axu?nrY%Cr$v=^4>ecDTPWqb1-Py!q$t@AUCiuPs&unVh}07E8hAIE~gx;APh`S>2N=9q!E&$T4N zTZbwxGG%7__UpkyXZSC?A-vK|`lC5u)aZV~%iWE#%6x!i2ui!mYMlbU4VHKq{#l@E zq81mP4;n7d5gIxe_NUNs;^3>lj@7aK0{MC5LLnC+i16WMgOVN?6dzs%=8U=?L}12y zu8dwH0mvji)W-Y&+z3c-spp%vV&@>TCD6IXy(98aNUs~@UMeC1AspqmI`>oIp14d~ znOVNN+(2{U4|$0?#jqa_U0!K*L*R};3j6&lMZtYls9S)pEBb(7fyMal&ddQ<)8>yD z2P*%JCW{BfKK&u07)In`Bph(7-i-PRGTpy01%?D*W58SPejH0fziuIagee=Svs+WT zI+X&2nSdks(3o$Q@NBAk;A(I=OKJ^BWTS@gBF#6tTZ zxL_0p4^Va2KE5N+`w|fx87*7CH6%99rtgbP7Qu&%y|&)mU<7h!f=1?J-)M*%9Iz^4U_3JS8seg z8%P;lnafzH(}oHMD6Q`qPbJpN@N*&OLL;CEO*p@!HUMK0HEj|PTDc9cqvEW6wvx#d zVw0;3fT61qo62`2=t3i7=V?_8xBT2T4)-I2op%lNDU@^(aytxrrTs>gGArGN2T>*b zdySehfF(7z0^eq-%}WbV2;A`o?7J~t22JTr#XA^kfEY{(ni#_C0Lji?2Aj0PnaDJ- z%AJpi$G68ufA_6Mbp17o+(4O3BW8 zvL;XMImV1sH>xh&31EH@ssod zO+7RZ$lMlf0bQUUo-2Q$mk6iw`+*-$bDOSJPxkQ56%xEE7a?6MLHG$euxN!gxO^wR z267RD6{k*m4kyVF_z38!8SkO>i~bILI&eZuc%qCDtWJ`n40cIo?TmgJzk`)zu%?s( zzS)a6{t!22Uj$?*=5-vqCW0W~*Eq7Ef@}ENK!F#cN>?E3Qd=@+xEywHw&agxgr@?9 z7?J80Yhl`xHJ)m(Nf&~+s99sbc)8iC2k=$3m0(0U9iF)2%t=pN(-CYF8%9%FWc*Q2 zz*2$OA>96bN4Bn`?VoWgJ#z{M97*fY364l;i5x##Qxv#{~5sm_}pWZ%^wMcofx9@Tf>r6IUtsl|dV$`Xsxr478FBr7|S6LOe91!0gkJ78f2ZKBt%822F ztI8GrQRNejkA&E%%y057{@~rm&WuFlFgUn%8Gtg$@>#sR@Rc7~l956>R+4n(Qj&&f ztZ>i(nyx#1r3Is#7M|DyXKTmkk+aI*fw)fatRo}B>B(bTw>A=n-9XL3T?5NEU2n}h ze9!$fT9Gbn5oiIy^`Lm|XFDtN}s5za%* zpb6@Czn+zG1G-!)yLzg>{U^l%xtx-q#LP-7M%P>r<<@gmBaMZbMPxW5;m8{&l)LCl z4C3QHv`P%Bx=5 zaq7%4&lg(FQ;KM;%!4ukM-aONIyF}xO6XkH#K2Flk=aXs7M>K|2_2iirKyrCQ_;!Q z(Qi6%tt_>I;Z6A&w#}cx1`hx|2G|S1hwHRhdfrjHbJYGIsrXlu2ZV&QMtf;#9s$t+ zLk)tyw@7;zKJ>3Xq2j~&fpUBFx{#(s@Q%CE9*E~L7^z5R!;VSR;u36hNKsy+8gK-x zlvMR^o5LqqHEkB-kr?er`lD2U1AGW?Z+L0i{-eJQxmg?$SSVWVFrZ=#6Ja*_Lh$y` z1p1u_%(7_Sy>M^AU+i2&7_y^e4|Ti#Sz| zu3XhH0H4HaMWEkC=x-%XlN(C+Pep^^MpJFIu2=;-+PP-4OUu-SmLJMRX6Nu_eGHTc z7=}my+T8HwU@(0%Ugo+)PX+!ScqV$oA-N_(L~fe$uW9fwKJa-{Kg2!j5HH2{M@SQZ z0($nVV~eCRjP@aDvL4#w_WDU$$pT#v2z(SD^}R0zWa9HrPjs|2l>#WwjSElP9=L><|8A>jOu1E!zd5G1-TFmblk1ygtqf8x*akr z7K(qKhbTJ=-U8LFsnprRUzQ5HoSS4~4U`0NjAP5S?qhWGs}Gw18o>eDtMwd=N%ESY ztT!i0AW#K&jHBAOcS_xsH=crKg8cnbt_o_shs5GdvejRc-L3XH8>SMc9FK5exLD7G z2JT}j@(8Kml7^5mnS9*_9s_856-FHPN>l_cv+A?h zUII>V?V&P%Ka6&r9aX6l^RBAkPTGv=Csa1f%F&f)&gJNSm!E-1-W_xcM8=FLS}BwQ z&z~uW;GgIFC(k-}lExDpC|HdEq#FV}{)L=l|Jp{x4nG3Q=|0KotNW zX!bwQmH*G0^S{!Swd-i79CJV90)7hv{F=9N-=cRfp;%y8V6^X*`%Ki-HbX|BE!Yfx zzW$E#e2wckBOy`d`Vs*0bl>)@R%>QrG8)BwMGyx$Wcc`#qumoBwM4^Wx9-_WSN%cJH72^*W{hjoH z|GrY^|CL?(V@C6P;y(AopSIVs$J_V&Huc%{@5Su<)Svo0rGMRblGyh#wD*0F%~M>a z|M!re&;OS_`epT>Z=X@8Wm#4uhJ8-M==US~@5S9_o!?XVng2rvP7>@yCh6BRNjA}( zPtOiKe=YOcd7d{U+Zfj3&%Zcsp7=ioKC-{w{C~UneLVN{f8D;V{$65E{eB;qT50+H zPM^Ka+25Lf{EP9;J$|?4=Rm#hXNLdv)SaP8BspEfmw~XQbbHQ23_^c*oAbyUcTVZE z+WqPED*K-oT#)a_B%|n^?ny1sN zY;XG~Wg%TIVr$pc{DT==Srar~OgK7~R8@bQkNzogEy+CQYpf5n3t z@(5MhGF~~bh4epdFJlI1Xg3vReq2AB>IOPE(sAz2-)HKA9ZqKFaNH~{L2}0b(ga74 zrj@s4FJxeq%TKx3n&6)v%C=c{zMCRU#BT>#ezT-)pJl_2l)q(ZY1uT-bXoYN3DyHR zZ+g-fKQA|S2^KPN(f5U*T`QleI}eJ+V75!fzIR94pPKkQxAJ{wv@8A&sju2F_se6?r(j)Un=uL>+R*vJ7^e4c_-oqW zx%Wyhy!Vo`_qWTxZTL6gudvSFt*7j>w;TAm_hf~ayYxQmzF+&f#oybue@V-H`1Jdu z?-+TD6<9?x%Y9b;#RZt}_%-*L{ri^Qr}6hZ-+xuOSMDWsR!M!{=1rV1?EQr2)!6-X zc*XY>yT1jQ>QM8k@s_e|<@WAQ@tqMtT!Zm6V#_kUN5}8XI$fdG;KqyQmP?0sus7s~ zhyLn!q2m2V{cNk~dx+`hsN^!gfy3W-l>Z@yebHspC&O2J77Gr!wX@o6>$P*FG=muD ztAp-^%G)(vlg?XrLF?Bpyo)jY$y|%7zwPEh<1qEfEzEVGNZ7$^?n%mS4l!kH-`Wvh z&UM)3LR-xbPhCIV0Z*IaMWZ$0g9d+NFl!a1?qnN>!)N6!JjZg*b8qPI(ks&o@#hGU zZHU6AqqP~|=e4?AnnP<+8*1x=F~=Z|ReynY*DhSY&RFxKhdMZWwPb4Zsh_>hmHlc~ z_|;17@NG*t?uKD43^>c@x&`e^_s0&dpbH~R+xE^K8=>vsZtKI|?=9dv-T}}lOX`OT zlBm@&{S|?itf4sGblQ*st(T;W3rOhHQ_17f0=jT<1mSBd;G;EBEL@(II}eE4p=_sv z&+-C~asXxj=kLSPV_In%!bf)99K#UCp{Bkawl@S%@d(g}07A-YIPD)A_dmVJBk%m~ zFs(gXh=pITZ`Cx@xZUi=6Hk)z=j@5uXJ=bO!nfp)uu}}4UT;1zCw@Wx2DLOmbyfMjyE3futS^Bp%WPamQQ;x$HnqMDuM=b= z@dj?eO9~5-#&Uahr&vhy3yHoD2uxdf1ZHec`>Bt--SR(6p4N4R%#a-->ars;K1~XX z9VAD|H}S$>9(&M_Gif@`b3eu$6tP|8n2xn%yUFfXwZn{QkHi1Q2vV{2b6>sbmQ%iO z@h9mr=WTCzfyR0Jw_jbKx^|8z@!s!tHqsWi-0>IXmi+Iy!tTkadS3Ko>ASs9TJGxX zd7b_7(a@FvXk@93(XO|Q27rN_%qVoF-G3gPVluhVu5L7%so zgQWaryUCK$OGmCBI|&X^W3W0SLvYfAk>IZr+3BH}em;HRmk5Hl%35~m1i1}8yh9_W z;xm?#4KDPI_&hNmgpc<~0q{BmuXeXe_h!pc4RhQ+;fOTFV;)q?c?-dp1OB*mT+?tR%y;KLM9Rs1_%Pp9s;k$+rvYg=DqCX;0++|nlZv59_K-;}K8 zmISJ#8p^_7F$wa%G9y|}#MYQGT{CU@e*PH#VG6!)E^XP=#BSp;zyo~u-4Ou5&r<@> zMPOV{PgFk|g`g>&*+KgPa{OynbjQ>8?4!YbID!S3(E}@W&q(n&2B>AoxXQgB&@w#% zk_TMHet?-@7r7x4i>KF!xM_Utu2bKkKy}twXYHMS0!R!<4PB)j79<=6d zJ}H0f9+As0$?}_H)89wPn;_R!7iuaEzHQl6Yr1vVc?U+P3g?Y`XgC^@0`qv?4#DgA z;}P#tyQ?1(Xsc_?GXvyOO&$_`_Jy_MNtZ3V=2&A#nWsJ&(N~A}-jse(H@L5#&cFf9 z*4k*$ut~caa$z>C1(5qHF*^D@;N&(&uhvW2ulL$LMrucTSGAK?Re~C+G!HXibCv0sHf4MJ z?Eve1W6m+ufO8@BK@yW!8bbTjGw|W0xxQkxqxfcmo;}yBcQ%#{V6Cd(ecUpva3IWW zL~weXZmeE*yN*CRjufrtZbmy^5x=j9yVt-JJF4G{bM@gHh}2t`0T=1w#C^ziK!7y$ zAmHKBGxRuQcT_3#T3D zMlv|CHUIN-j| zkxn?_fJ%|!zQ7x-@jiW^K+z)>)a4nkI!{;uvzKMi-NASa5*b{)dIHJH8~irD>oL+` z+PtbC*;6-nj>u^N=29`Rr8OL5MVQ0gGw-~$|6H#CLt=vYp5AmSd|R?#7WgpsiLmpe z&1Tmx7I6+H^|U>-0#0{_uU+Nqn9T@9lYv_C6o%iBz;i>)5}H`<%uC-Lbww(%Wb)41 zz25=M1e^4-%{qgZKLT>3^#>n5@|E)NU%AZC3UY2EcqGVE(3O;nYRWM5eB_A$TkZRq z@jMa>gMTr-{`7p&jVdS;I@XgiK;h%Y#Vj6TI}2%SD1dKN+NjjPC1EF)E(EM?GpVA+ zVd}p*^b|?Ymr60C;o0(+5yvA_etOaE1j8{GVNsrQQBp|XYoX%C5Dgh;W)zCN!&XS*Q4#Z z?dR9)I_zb=g(|wvZh8y{-A-wjAkdS=$tk==5B4nn(iU@dppbi-nL+N4oLF{l6J@9* z!a-_4_a_g7az?eU!Pc9He|%z@sZ_v~+KE#|OAG|<{DabtErLUI6%TE(YEGZA*JKyC z+P}dRv7zB82yxA%-u^0Zrg6D^Cg>|FwuJ=9}I3AaRmp&#Abv)H5%B~6aD zL$!W07naTT&Pjy(QEdV=YsryqP})CqLd}cMfX(zIM(W zGwp6b2q5X~`z=M<^i?z4Lc`q5-bn)gbBiU0E!%gH>qUcO2k&BHroMt2ow?Y*l@Nz! z)?X8m@t;E9u$shtnSDzN?nVEg*s#8zIeuDK(R{36EKy_A(`Z**4O#w^1@#1$z z8T((kpkT8iI{f!B>z->l_#{?-?BSUZl6W_hS7Y->%XWGYiRb9ynJ;VziaPU}dJ9F_ z$-@zjk5Yt)gM#fxzy-G=PlkI>q;D(Deup zxiEx~bkxe9w+-*)SB!!Ed72(m=1p#UI1k|DS+K5X)z0qLQ82F!uXOoIkm4gSF9b^4?K4Ssd;hVx4S+RRSgboubfwn_Jh~H~AFFpn7{e&r_U+M{0 z#HbXMQ^vwwbaXKLq2(%5E_R{^9URtM4M=z z;5y*}Bc~uTE*wL=crn5`$XH+tWL7R5{rWJX8W{dEZjQ{K9U#)#3@9Z3`~~+I zKVRQ+1!W=fG)Mgk0mI6{>4nMg3;?jfy_L&XTnJw`P;7yUF$exBke}G$z_yOT)1U%i zCQMH_qs$TZ!#Fa7$0tZK^DCN$q3Mx@$0ebngtW)k|D1mLvg*8I!Nj}2y$!_f=i(-Uhu0|}1Ut)x zezo-O+&hWA;hhGWB!8<1n+7Q290~-a*S;a%FzR8Q*YE&`LApgovlT1(GB(1M=2-|a zs$~Elvp~DB&a~4D_BG+082tJ0=KdQ2%iJC zjPNHgdZ-5*lGAgHqrwcC#T)qrkuK5S==&rYq}%`-ie9E zRtUok9A$fOrssi$Mu(lp`%iruh$kQ9@=l6d|EP+3JN9u844fnp{&ypPr#$8HjW zC9`kxFJt7W4%B1I!y-os4|t%1YUn}oMWhGZqF%M3uts{p45BE^oKun-lc3ce=S8I0c2YP zbj(i3%|jhK9i+ZN!ruI#wd!f)NTzHlB^`t@$p#HN6|!-FDqaS)M;BiR+w4x@ zR7M_e@d)yJ@gOdES&kVo2IuGwphjX+IDm#0o2SK}HAvW((FYT>X73OmJoPaX%2;9C z7e>x3XKD?{FAP$=@vvc=FyngwBtkSAh-sW9-9c2nP)PYmoDR+^BmcP5?sdopQ{#)a zgv8r_WGWmrSZSMvXc!ca-V8HgVHWzSY{40*uCUpM^nzLd`M8?rjD}3`yD32>8nDGQ z1YQdmYV1G1^jPG!AoQq)HbPh#3n$h6%uSeDdVnDVzJQBqB$IrCjDfXis|19)ocFDt zT7Mul5|`J234+2j#03fFV6S8z7TTo?1lhNG^V>Dx6SP#r81J(F$cjOgVUdMRA*%u- z6e|&}W{eyWiW&34*`A0UFftNAvt>B!a^y!tJ0W$WN&#&tppk=&D(~6z)UeI@ZLkKc zn|%N(5&%i7)(XJRgp_xt;*qZpOKiv-c9{l;47@i_!L{Y#n?|3|jMzin+$p{YP_AOo zsJb4HC3?{PWRZKKD2@=9N!8lMyV%|omm74!urZD~@Vl(xHFVey3#E)aNr8*3|KP$k zgWFCudE_k^ocHwiZ|CKr$Tp;1S0tq`=nb$vpM2N`wGee=iEf<1(-b5ziIK>}unBqd zzs4L6xk2y_rXOdq@n~#!kA;6ms)!@>Q(prD3{sBka*HXYwvBkdWq8CdPD7Fx2qHWk zwCPi$5O^?)8K~MG>?oQx5`U%IbDhG*IX_gEohyFSBjbk4l<0pRWaeu<{Rg(Q2Y7b6 z%_VgJB&IPy!>5(}`iFF9W0Gn=yjMh)25`(LS_SI9N30&&L7oWb86?2v2$Ot^xC95w z5e1c__6e*Tin7i1IS`lPfUSsPqcPCpq#)HTk{0{OP7?RGLnsOT$2iIWD{`~=j*BCH zzTL$~)AcoFPIVI3=KEajqQ(ShXVJLx;BF6)h<}G~7xDgE{yf*~`iMXQcJDR!0jhop zcHuO#3c$clAC@81bq_5&lArrmh@VrMwAft9={FoPgE{1k=? za}}B;%K(FBE4(kXgv6EkGUlejuw~wdZ7sAddf$L;QA3nw;qzFX+9XF1jb7|4)Ru{0 zFe*I1yLLh{?1Fr!e3<)#05)ZR+nXJ?ieP2!X$mn#k|$=bpg%&Ly7jR=R)#M)YnfC{ zj0Bi14HE+E+3IFpWSL|cva$tZD_IKU5ulYv@zfnIK=N&?3g*0)*5d{lq4A)$_!X8E z+SQ#~eb9CAXB;N`sUl$j^fU%Is-MWnvjH8y$rOs63nD4C67(@*7(bB^uw=l@3=>0e zLEx1t?HUuv=l4}`OCikszT~832CRvUM-J>|eXfVb{z^g)rXN1k0{W_h+@Bdb33(?D zS3HPucx`us=?SzOY-+K*nD0#j!RMyOrA$E)I*!9y;q(b^GTgAd?UGY-6x=YP=FdEM z#zQ`V61kEBChnbo!jT~on1I8d51d7ay_FW2z;D%m7`l4pKdIzs>L9D|wW*o9K(&f7 zuVuZsj@~Y1x%NI{yA z4$u@4Wy83)^#V=cVOcNibJoDOnDOSP3}Xh!TCBe9X--F)gEw~YEY^Y`!JAE6hxj=O z_F#t2zU&0Q6*6~fKY2GdkfxS!F3Mska<+i+ZOHTqw^Y=iP}kF~*`^}981&i>&7TDE z5Qs7jxmpom&PtW7I~0>&O+GXu3c**=L}-D?G#&^s0G~*Y$ORbp_Ui=Ij6!1Hxy{o0 z<&`M>?0>*S$kp+HIOzofl);=B-Xx=P&!J* zEn}t~SOiq|`uiI%Z8KpXpbS8jFzr3c22Opl@g@I3Oe>en;DQKxB_Q1vZRgV$-q{f zkp4$x-ARB-fL}$3w<&BF@_)h^;cUACnK{=UCdmsoqUEW8iMkR@fud zc^m?@8eVW@egnM=o+r(hl^#*X5Nm8XQrKKGrZh#Py%PIDO?$HMVV^|OSJeD8o(h4%9*VeY@xj?cS^b2x+G zD}mI$R$7c&iveKTq{4C^$L3jwv7=*)8`TV$)VLvIsU{#1ARKlqs(y!Bvf?<_2Uup+ zAn=jX>>v~in1!GthXzF@TrVI(*kYpA1^czj75S5k$UDpu=v6n zg+d`FQn)nlRYPds74OWfAMY@Q3N}Q7WdU${Bw`uVC{0MO?3$zWC_n)(i;;`(QI{<( zPa0~v`L6*Ps*ISt!W1CH-poxnsZ7Qi@h)oqa;w2RT=>9nfr-sPeA;lzye~F)uo1=v zlX8nm@;nD{XMtdan*E*5F6ADGpM;m(i6WEP@ThtN(D=5YJp7Sp6Z2@WEcgm{0voqy zzT;2audREc^nn?aJGSMklzAO6{>mtxL+=TpGun{P8&d0yaJVU9;wxG;Zl)I(p_Rv_ zQ51q9UJr}I(w;JTO8UlJh4H3qVxif`Y~8@&e~N{r;w3y5E7de08-RMri%l9n3Dfo6 z1D2aejgdV1f{$XX5AY>2Qoi1MZMkQT=4}9|uuS36|Ac@nS{ARganpJ6!6zjp2}J@o@C3Tsl2iWb}j}4UxWKLI)fH{!g z!StxC5tOSta1$B1%0M0ngXSCBM|2AnT@_kQH;1@)ESAJzbri-9dYB4JLOZI3Dn3-ttSaB%R@jtv^T0 z3a&0d8L2)G+4@Xa9jUy3P<3Cz;D+5gf(LGP@8oG%EFM!E5$7;{xNYKzRzmm~QxQ{x zXR`HJk6c=-Rz3{J=#W!ThyT13pD!#RjApnjibfH&h*p5s$FLtI!*jWZ!(7M7$4pqQ z(d)tU(ws^^Qhj^32d+RoH8?XubR3N;IYsNU_e<;Hp|aUH6_0}2(CmRW&E$w(h~waN zni~&(k?pCs?xgsRN=_AY452O*{*8P`69@&m|M(_&u}7aq6FXNp{4FfFux}1j%+LyT zMiEoT`_IO5>_}pkBAbM_Z^2Hkf@lam3GS`ukPiaporf3t9}x&*pXMD79vIbZ)>kq% z7=m`{6}Tm19qG2)2F%=S#fa*muWZQ!0CXw&m2eGm%RJ_V!C>@Y3J?Crcybqdv%O{7 zg6Iuv^0%KEF2bO9{ee=O1)DgEJf)UXz1#HU9s4gWfDU4lCW~$|7aCy9>yjDqi3lE6t8HHisGWC{rrSqTIPL zq%f7X-PA&{ciJIxGfy==?eeisC!It?1G%P%&}H}<)DKXi57~7Q?p>-RlZy=Uyww)U zv`_ci(TWhq`BBmbjEGd>^LNKzj20ZQ3Z;HT7zh15D!)6dy9hSNMp;epb133d&-RcJ ziOir&70F~Y)KJ7Dk@o`7Q({d34)yVJRTc$IhO;nxxzrBy@hZWH zZd5MM>A^iDJfa=3X;}9mj(33ha5}w+17hfLCjB_NlP!Ey3BNK%hz5f7c_6_%Yad=& z^7Asc*}#EaRgP%Pssp%qpJre7SpSFG_zF>pCpFmk`S`d$%C;%$m}vZyo8zj7y-dCw z+F~AARDqR2w;cS3GMV+(3v%#dwOldDANW;3D5<6)oOz%jbCe8_@vnl#P49+K^6>e~ zZJ9U@K6utT8T*d)SsW|Xmm}6QPe%T zT_#bO@6>+U!U5{g3}w?BR7O~QtMLGk(q=B7NaQwgXt2wy_+nTYR#AuDOy} zlNz>@T;fXU&-5-Hs(xay19zDhUO*9-8*ffUfPfZUpFPWv7{kF58$2KlQlji`K<*rO zS?On1qLaWS6R#hh^qtgu^`O3r_KCD2Wqo;A(GQhDicc-<^nDn=D9$~p42oDr?&_CZ zgjEm#;vk}B{@67|gAb0`)uE+%-G6_ea0cT**a!3x_EStF+!YKBR5HB`E|;1)7$bHH zSEY$11pow}pHN&o5pT36nT)pkvYeo<(ii+|I{>jUiyblig+)s95L%FQ1{n&EzetUm z%lxs3BvxWc)$Lfu&&AIR>;*&se0N+3)zic_0>-A8z*CDY-%*SLgOI$Jx~ozXG@aZA z*F~7SjV)3!LBEKd7ez77{gXn{)Dy4^lJdbJLLGBH_B88WSwZi_%=BNwR*3+j zsztj{W~IT9iYj8BXKx7;(nZB$hy{u+{c@!#D|@Jb-3f?e@@uiy1hA688&id>siJMD zr8t9A@(ow1-IDii!|%pij$=<@oW!L=`bY(++{k7KzpBz)M}@2!XsiN<$7rRqE9Y9< zgrDl=Znaa7LM7w8O2?|2rbk|XkN3NYBrTEiO=U;y(Ou9hAWTxY`Ez_r>^?AXSf zRm^%G9~MSfM!le^zy`}*w*QSq+VS)oFT5`4s3`wX$au*=m!$gn?LD|u4~-o46I?ee zoV4E;3>Ps(Zi4$3V2j&7z1X`NsB(;UENN~(G-N}S1(k){dS|?6ER#3A~vItu?F9|A-np*dS%%r4!A zqX)?r)+bM%x6DK<&t+co@-cldydLB>wuKs4-DX=-&s!i+hC&)DZY0TZQNS)cP(nK* zV^B)#@vWc8G^B}N@V4hEA6lFiy1B?N>s9(n8wc3d3#hiR&tM~?IQ17}KKW|bL5T>R zNNCm^s>tc8z~fbCH5|vYguM)j?E46gi5aoe#j(TybLOT%!-@K)=77)E#ErDx~_@ zfY#~AJXOe|FH~NsxM;go!Mp0mf=XyCj;g`~Ws*fN(GS+$A5VkV;Kyhacn>h^03f^* zkN{Le&vw4I!FIJbs=V=E(j@TfAfZ!P2UBeD(-Z@i z!!963v#Dssru3B>*C-q)2|oe8VIl1%T!XpVyf)=+8#n-B1S;sZlWB?z0$p%A&>B@& z?w@Or1UY5zY`cTkp=v0y=}o&8Bh=ZxB54>djErW^H?V>WfK@!Js3~fKOuV(IOiY1J zTf$$2-cE(lxT?FMMZxwQex^Y>mzxR=T!Z)HaEnm^wGGv^Ssel8%OI-`?3wr=PSEL2 z9l5#{^bk)iYUGVmAe5k{_mi4K@ua3|N+AEy93uB+CO^+0Ga}tO<4X2ZXB6_tQN6q1 zcwqmCZ%0;U@9-o34b3Nb;akMB2ay2uy7x?)vRLj`?MT1#9g2$MRE!Oe%1{t{|D+9U zUjwV|$7U#?25Kz)?_MZ>5&C469~R&y0XS6~(4Ifc9MCPOy7vYiwm;#X3h35HZJ@(A zZu{z2q`Hyv7cM7U^DkP?e;Bn#uowkQgR0b__uA_S5e`1@&}~Owqw2B!N=`9I{ zSwh-c$6zf?ba6`DWm&L_{odCXamGA>Rnc|mFQX>%Bpsa}45Fw0GmW}u^Qd(%I9LXP zY3UIGLm04k)^S1yvqrag^Y21rX2+^esAGChB^dbI(j@D2)b%8i#{Ec=ovrLs7Fe#;{~tGw$dDJ zx}i46%@#Zw4*Z1t^v>!b@1iYVkBZN%z9Bs#w9rQQgGadWI5=?jCbjpDol$MPkipYE z-g%`F5DNBIJr3b^x}O}uT>OW2=M!Y+yZ(1ur+*owC3T*hk`_8=8E|gcrP_Am6%%NC zPbi`Ic?PR|o2d%YfOB^otP0R(@PE;QYxnUlS@8co4Mu7G{L%*)d{7ID(mYg3QP%0m zeL?$9XP$@}%Gw1?=(K3fR2r@g`?VC)lt zh&5dv3#Q|XvRTL#3F4n=8dxQSRn3p;ZmVj6i_efogV3ACsbWtR`n^KQoQ@T$O}+!G zq;XoS&)Z=GV?_8M(q7v?Jn#!2m>?%{N>d~m4n6Uwcw!OMo63u|X<}lsqzaGMsNi$~Ob((7; zGEt2x>wGY>!A!p4L01%f)m{9U`{rMAjD*WZ*^Pk(y{2RahlZDRzG+w@r68uxZ`?ag#KPgoI zjNkaE$N1Oy$geiA$JJejx9jdt@sK6?d|9*BVAgFj>0I(wFLxD(h&!!y*An;5?faVc z6W4JcDdQy_YfiP~^-w=WW0!J3y-QHqizuYKQ zVdMr8?;l!h61t(M;ZL^OWG%cF4z=PH;H#>slPt)uTT8*pZG?j zUE0?z`6JjXt@v@;Q#HHIr>piXg{ZylwYp@A-*;12zZ6&Uxf8L#9>3P(-LbFDm21n_ zwjtA15p%`!*pYnOj)(7lUBX^aLFZA`^x!bpa=N^&XDpzQxf}rX-uv>}s!=n$xarL< zl}8`@wub1oeAJ-+Mh>XhLUqAz#<^E#l3Mtexl~E>(eK3OtE}7VLB9Rmw}TI?%tBtX zi)PK6UykDlX|HQmt0QyyC0D*6*=^g`kWKv9ungf^Q?8-dt8B+v7anc$y1R5~{6<}p z4qsia*IG`eGtBnPSGZV#Dp^?fPu$Jt7UF7*_aSUig}c|qd%wVXQ$giHOfcCV;CfKe zwT<;MXE=>7Mvl{sf*~koy9TGd@P&uwSdtp zD_$Ah$8`hy<&SjvZRMwsFBHmoSS-u#h5zCS)u(*ba6rcR8n-QOJqz@&*mACiv*&k) z@;en6sP-=%p3oe0aXwC&mZWmoAJ0=YGaj!Zz&eLjakhDd!)_A+puJ9e{jpvts!c6T z46nS7f~J&RD-JTN(^c^NoStzPWSXi0{jCF7nJ;KW@>J$WyR6x4D&AUnqmTWWI{TF2 zv~`*}8s3XIFsa||b{5qO!&{)u{y`CrUX@lEAN5YjM{H6@>~zE(eyYmB6yq~}ok?9c zW4&GM{V6y(1anG@#)>iIJjO>uCTH8Uqa@$DeX44EvmdVOG~=DJI%+a%ZEQszSYH*h zGY;R>@!S#@i+!g8t(aa|nNf9?BL}sdGHF&vTs1>otJI;A0Lyz1SDvZX9IbSpM-Yqd zHGj0J(SP>;=)-&4aK%TBCCXq>$RPhXm131~TQv$Tg-<#kROO(h`J$xC1uji8nevg3>Lu^GdM2S{JotYLG>b_VOyhe=q4w=3&x(o9m7B)uj;lhSNdm$ix||UVpVYb?mE2 z{bsZ!l%H2IKW550VR1;(`%g6PYB7LcF%jM$ort$sGeYvIhJ~wHeH(7|MyZL2)pWSW zz}FGGv#6oM@a{W9c{RRbA{J)@Xtd?46Pwwo-*C~<{2!qFb(NyJ1Wy3Rm#l+7u|B=2 zlK}GZYqd@%&H=Q_T;`&KMc!g8>bTHnwQ9p*i$!s_8uqs|Qq!Gob#24bADq#SW|BG@vP9bKd9N@qk5WrmxK6bU)#p~vf+u$y73@S^ z^b^eMJ`_7twxq*nO_zP#qdMQ(M}IP+mim6h$O|IP7bX!i>n0an^;Fo0)mhX9m|H_Vd*DQYf+ z#rKd1&J*I30#bP)6rS8~9XZm8zRq7nd`As3)Sorz*cCu}PX_Jy01#C^iWQ03DdTks z@CWJd5yHechnn}+W_6T7?8B&Ry_b$-y7Vdz$Fw}I`j*lU^I-vXR?k~hwOyL^B@8uc z>giQV^|+@ndn^McRtfu{2|CsJ=b766_)zc=R?I8ZWaXpELC&DQz%knj*-%ZmjsPwaxL&_Ba=F@UxVgVKZ73 ze8u9r&WF5{(=ukXI*8YmGDgl!r-WXaPL;;_ejP?>tQ`C*ypAyCfP*Q+rB)AN&d)BN z7+iyyC9L~(3>KGAw?{VvG)85`KD4Gj5mC3uJ@;~Bk*rmFrn9z`&$G+c(;&KvKs#{U zRZ3}diGC`D=$@*BA5{%saCjy;hw<51p=<9eXFbBITs*hKkZ1Gd>mUN@qT^@}U$2!vIUU4F#$Oji6>oC; z$`e48TEoh75lP|t2yvGyCamk_w#rKoz^=_6Fn+ZdB^jGl)--FAj6xnns`53rkjZ0C0501$6!hs|fj4{!a)BMAn3I^u3mhO^gg z*{|bd8VkDq!gy8{!LO@_67$|nQ(X?9*L3Y6f#8QRA1eAfH*@SJp75AGXWhfK#-qAw z(3s{p+_EzrHYzV{j^q)n*Tw9Xm3NMX<%!=J+Z*!jb$^Z|w9#>jQFZ-@FE?^T9rUeJ zOHdTQaY4r=zNt%)|3+OP7u4ivtv#x3 z2z^O5JTPqnbYtChNKiM;gr18sDfh?qNgi?15u*m-7u%~JR)r>p#@n~oF>ctsuF;H5 zB+&I|d3wn%#@ktRiSr*CW&|jw)vb0S%y#Me8x>Ny1cSHtQb!L&;uhlY{03FAJ_Gee&dPUt~BBK8jL zwqEz5PF5FE9V@%Fl5shi|S z(D@m!Bi~7tA({DdZ{6UYR4{d=#8JHkt_hwdz>x-rJ`YD~3SBuVRh^u$59 zB#eWx7@exsVZ{;9(WoS!)ZW3~w^I<6 zXeS#GZwZ~6XIYwu>!~JP8C=~g^~jlEeZ}eU{QY@}k_!9olqXX6?rICp{|+YMc3}kY zK)3nk9s#%HddRjd51LMYruDMopF9TQZfRsZWwK(JGtW}D>PJzUEz z;bJU= zO0jwO-0d?__*5&hdqh9b7an`p7vAzJ6sQYf`G_QtrTK?|hur-x#?ES5Qxvvcru4&Ack{b7W+^t7oYk*3_ z#kZa+DkXmsux3GIx2WD$Z4$~1F`M};Df&m*W}R?PYCr?5=%R~o7Xr)ukqdCHbz_uu zb-=lL^dRq^-t40`N;%EN5yHXVwn+cKZ%onh*c`3N&z=7 zeU70{_!E1`z71XF*5-&h`tHrB1g+dXOZ9vnCn{d2dwHLXn9)&ru#k9m>qvM|muOvm zH>PQ+JJXY2{IpIdJ(+IAkQpCGrz)@DeX(j*rn6RR6r_V)t#_i9x-|kGR#n6iUl0!7 zIDW0D;F2s0_HlEFI+&=uHlaST&w86SeW$w z#FmR%c!X$bS6*!KHs8v(<{53(P1&%opMZY=<4o=kXyY<%KAOP<=Cd$hV)mvN7mft zMqu-IwKzq2)LA!*=#-C>ZR+wf6|wRpENI6@bE8Xt5F?mxP(}xSb%SWuPvXa|yT^z@ zz?Pl0yYhJ%u^Kn|2Xg7njJyN%O&xU`=98*g{(wBX1E&LfQ$>k7I9-WW7)!R?%g0uy8U?$7g^XJ*Z@U#b^rC9;!lV|$ zqKB~QBzHoQ%lokMu_o%(68-NiqBq3%ynf&JH1;-8yJ498i`R{eg~)gv<(l+o@ll)gFb zs%GQImQL*{s|C(!>$Mzfz0@!!oL(x;xy8-q!<0Q9?h0u)RRkAGb>@6%-ulm_==s3!8MgvR)zl8uE)x8F%_H_BwMcbE;bv?Yx`P!mx z?h&|z>xiz@9dh(p)CRS^_A6xvA#W(O2Cb=cC`tl2-^s*8QgL+%CT_Ud#}TT~BZK=<{c~(w8fr=f(&8 zOI?%zR>kXF4-z)JPn|ayw*gn$(>0)IsJ{LWRpBFH_^84F$ z+EUNB6JgffDZE79>a2cQx7BRwu83{$$s4HrnSMT8p-PQfqH9Mu)(76t_uA7>N zN?Llq)jnz#ZD)sEYKzHe1O4N=N#uh!w`vnFP zB(AL6q?ViqzlPACPf(%Ef;?sTmBp@MytYW-@B<-Wba%3PV!k~wrC?R~d7B}v^lF)T zPXvTPfz$_s3`O-(x_mnF_KZ4UdWgMh9)I5-MIA%^P-nKrJANtNOHFMm7dr;*KIpCo z<{4Fsk$Kgy4C&$$&G|Wg&XxRkLoARi>Ui{($%9iG<7rY zx?W5NnuqJ^w1HiuKXDn$^MsJlrN~HKi`()uUl*IHa0&28d||^RT*dEu%1blo_8G?O z(2Dv|y=MmflV)g-uIWhSF-sdQ@uEyowWvki{9_;1zI0YMsVh`Ycf=(4%tVThk5U%( z>i0Ur*40`s`K3+WAgJ_5g5jwdKa;Hc$L-Utu1i@8$b?))&M}?+`Mj1e6+EytG?_QL z-&F^ML2xgRe`SswX=b($vj%w=Uy$mj6re2oXcj z&At{;(#0*h4%TTd)ntL!i$NZyCQa{isT;s6)2~KMT~`e7vd#Mb$_**YiiqyDKXITw zvhF3Hb?Dlyq|54N%k6V{bRByQR?T;OR9VpdD(*AxsWYiG7TZ&U2R*;%*Y!?CXCN8A zDvMM3&S1~n;oPq~??%#{&9HJjkVWBTyn3RkuQ^_jA3`bacrV^p-Kx&pxzfVO-@ra& z)U!o10t;HAx{g<6Yw?cThPN&y2K;e%y^9(L5ZISFtV_!NS0$X)|48>id9`I@l0l~> zXrsrdr7?b%Kk{&3$H+b8S`i_yhK)gWjCtUc4d@-}*QhRAQ=1M`ot4_S9rhJ(wXnKB z3dY;)*>sF$_%?FzO96d#=XScwqx-Fv^oRjj5WK`@81wy$<~_+raBII?sk0j!k_;oBGGb zsJH0WsJE)vWV1>EPF*#b33>r+O|5&v>PJy~dzGWb9CYEA&yt3nudhJ7G2-~O29i|(|B)hv^#^woidDt3R`>-LMt zkmIcr0=iMwDpXB|gko>`GgUZ?57~mVaPE$?A)hvsE1fKI~mRFYmWi^y^ym?hPFgkb)JdeZ*d=?^% zC)+wamR$W)l*t`F7FGwg6z-_aNj#?jju4;bA2qIgML7bg$~FCG_OTHFEksFo-TR`h z#Y9LDEZ_L#;|*aCih_}e_Y{K20pvE&p9Xz$`u*^0 zf{!e9+Y@Tc8zsk%^Bd@IDq4x@A~Z+`#%1@{dLq&eG@sk^*Kz{4mNQ-U0U) z74vnTQmDpW*L!PUU;V0j{r%)Cc?WpSuJr;a{APa2W3)dWg3l(S-hj2spNxLlFK@D2 zJ>q-c({cVV?Bl3q1#tE=p!~0OIm_kp$pl^Mz;@*?!$xj~4P(_c!Fw^A&f{SkM?7Ov zPT+Vu1#Qm#*tg>d`7GNJ(46K%ZeJS@-=Xq9{jlwJtw%ohdPUyvwJ>Q*e7(u*b*=T= zU6b~7{0SDh?yT?bVFKmw)m+!+!WmT1_{VzgL}l+WS7UQMj9aW~sH)VxIa$KD?d6W@ zdovL=QCVEnUEv8ZK-*)mpRjB%#~7F-(*JK4<^+aUMA(k zy-rpFIcsIuwQlaGAGRs1;ktWMQaZMLEoD8Ga!6M>oT+>IVc6%o;-|VNsucWnUsiKo z$y}%9Uj*l`soMQGVoq_zEKUak5GDWzw;o4Iy2R}*;FjHOry-&m<|PyrZS5?zjm7Oo z%|m`d+WVuCTUS>fPqc{Hc(3JfX)k9@S4C~xZ6&^*YE@#Cb;8}hVO-vk6uXOcJ625K zTuv->MPrrAo~PNq-luQ^hvCX`4RJdze=Rzzxo^SmDdN=OZTU}#+j`m<{OYSJgSIVR zF0$&LLR(lX?>MJpc#=LONP$TmaQrW)E!{IkqhQtzR#(g)y`XerC58fp`K`nWV=R~uK)D|%0=Iy| z7lM}0rwepEfBJdgp~2*Rb#Nf7ow9(E6>IwczmA zRy2P;UTa=gAo04wS@T;o08EZo0m#lEp^+Y}$G5I^bvi5lbsmo0K?}CB`r`_!nc~S6 zGzpr9^9b>$pNF#s48fSwWy?}+i;e^EuIFKnl@QDT@tKeb0jU&7&o`Xhc(J{@g8zUh zWnYXgojdAT62a_pZ}X6e3OYFM-MOmw)a6}vAnLVl?lMa5zO_Vwx+9frGK~&cFriRqPvZuCI-X z2$B$yiI&*Y30@k%9W|}#dpOE@;qYMI&Z_3)WFD@%X%pJu0l}(uQ?c~ZB#;MT1Bw_6;xX+gq@s8K z-TN7SywshrnK)6djax* zxFf6r<&HPhfdWE@dJ`O|k$pL01#>`+use6)Bg`T(1rIx3D(lSWHi_RG30tVh!Ja@kXYUS1bO=|_EHi#rR{433#1F#_sPaEPpavpS&t_1^MW zy$cDt$NVsl3#fW6tOf!wk3*?U+2o(Y+&>IIT4tUwuj8clXSM7 zd2_5qcIDb@+Kn#Mf+yhA*SVvbV-%D|)MQLPM8Br@CsrZd0UuQJ*)=5XiWdyM9tCEt zvQ0GhT5hr+bjXOxu#Z)lM@U5-!b4E(m*DPy?2Dl(o@|3PfKM z$5Y{NK6lyCp)s$7KD^zqfck)1;*?d+zGbzgT>ZL@rwur`mUvIzSULwQUTx)Sbzi&a7YekG2TPzHSDDDaJac32+=mcwQ zSt^x-@ICKoaWqB9EBY*WSSEO}Z@WYZPU79)*ub9T#u_&41jcEAMjy}}go zwVsQSP3%kn|Aq}@m1F>DkZB)+8h9Co~yb#85z0Xc~`T3*f`Ysv{_>JvP|f<9K6~|tld=LQ_{Ya2zApx zQog$~fU6Yr<#(Tm&FQ0Ta7P<5LzhHna`jkF0uC=^RvY*%pbD8(RSPSg4`x%>NSqNoxcuNYYk@vhSoXCE;o`Dk#_E0;!EwJ` zU)|;i2Eucx$f`Q1-2zZ~h{YwBQF2KQ!b1TZtk79SS?h{F1~AR6E}r&%y@~Tggmoq8 z6rRJpMc5UBd0Ro5*Bx_A@wFeDfncGm_T?%Bdm>Rv<>Y1F*JiWI)a>x18ml#%3M{VR z7&yRK0&bJGq^e5-!3iIUbxCJL*@3057<}|S+8i*KtafL%?3VW;#;VPvdRw~Hg`+~z zz{sfEIlv%DFpg!aIWH@q#E9Q0T7=4}@W{ajE+~j@7I$G~Dj_eK$gleOGgx@6ga7YG zfjV0Rl|hh!D#ynmx5a~TR$brx24tbPKJa!TN?AtF$!Y?_JJgOn<(5z&lEMF_aF=(chiUr`E|Cb*!nVK(Kn+7^kWZhqLN zFGYv{i2iQFnOP$O{{<7?o!a@SiV9#!gr7a9D;&_{bYNBfJD=9sPObDMUW&1v7IR9$ zVJ)jWU+?}}8W4q70cctBAJeNFls}*i%Im!B!Y@D`PDbnz+Ur+80&dT`nF_H2Gp@9_ zGpxS2E1)$&OgI*k9Q^4w2nhbDTeOrvudoFljZ5#)uJc!t1r^=l_lyOdo6A967l>-e zwFTVCD7$pLxB;Gqc1injoTp(4(`REaka|tEqS)<_z zM=I<$%r#53?JyF8Fk$CiSwsnj3)*s?Ye2c8l!7#X@^-tb_oK zWeIV)`WZdap0|S!LPCNevOzV^Ud0pIKjKlX_<8h5zk2Eh7IDVgG7ExQXJAX&5tT_EX*VcCpZ*T|zc^|jr!PvI|qSJm6Oc;fCQMyWLHJ9z+uf$~+! zEvr23vR)C92HU~CaCpC*Fw?ChWJNLzg735*3{{RDLIJOQFI#0ygi2<|AKIH$8ybYV7YUbeEmx^{dX z{#zBwVkGviuPaLTg8npdH@dMDo`FWgSD{cQB>i$+#E)^ic-e}9?B{nbjO0~VQU_3A z+Ftgn_G2kPT>zXNw6ST|l^4eIOKY$dGLk&@Q9X#N?c5(5I%7FM7D;nYd#UB!!lEr|6ZN{v`8y40t7Z@0!2?lhp^@HfwE5kT}-SWl1isICMlw4*S3*b4EF0F>&Y zoq1dta+Z;DYF^{E70QBmtEw@0+a40JMiRQccrdWyHfpYj5%cE+g|LfXQAudYnAO30 zvkSV1M*&{Y`BXppIU;2@tE>hlz}jpu5Ma7&gWd5colBo{+`!30;p6ZXHK(KAz*Ol-|M_4Ju0Di>ik!su}I zbH_`R{XVeoji_|$mRR&%ApB@c0=~i%_XOSBFp)j&7i{%CzFL}tdU_hQ&IJTKZ1_=N)3TQEAgo8=7T~jafK>I zCZOI3x5RuJ~vsx_b%nvvca5mm{9p$<`Msp z-i?mcfzGn{r#hUS_4N2nwy5O|shW=z;4}WmiU!ushUnmoHt#0^0{&JUauC7l6(im^ z?ok|W549jJ)PDx6W{ehT3Ms^E!d5x?iZ-y4a*qI7G6^7Y$x zsW1yVlR;@jHSFClYtjR(@u%00F(`+6+lj*w&9xpM7cuOy<`WvMW{td~nxn0{5*@sO2kU}L#HH@6aWAK2msj~PE6%! zUUl~=005|^000XB8~{g7Rc&EwWoBt?WmQxO00VjVgIam_gIaZX3jhHG=mP)%1n2_* z0PH+#bK1(1pO;@TMb2HDV+)W>u${X;r!Wvqg;xPid@9*ug*1THdPNdo-|~;&?ioqw ziH+mro)7CvY|!*{_w;LedS>+Q-K&2J>^Jd$CXcR14bt#DN1Lxb>Jr&h$;h#mj%>JO z_Y>*+O1g!2WaW9b`=L_VZnx#7xh`AIvf^3`Z!0^rV#xRS%UsJk`&?dmhW@S(pB9=< zg{Eb0sOf2z=>jI?G7FpSP`l!K&@4NuyZgkD6$+D^cCSaSNM){>6?cU^br-~>RHbTR z+8?#LWAZ07dxi~7w=Px5!g5Gs+~1rtnuGRmP%eBN%^KHTgj@k~#L~131KZhuXSp_j zRkzS!*klJjeC#zk6Z|G94gvlhM%5+WiV{_JSHv>O(5B|~q*WL<2EFbz0z0y)Yx6>( zIl^y>UFd(t55}f2?z47-2#Z4Vrax>kfR$mXh5jdh7{n0K0MWNSf z4hJ9EI9-&3t}2$f(3V6n3x)1rGHoy!X(mWd*Mlds(RkPyH~P@>+p+(w6gIXR(?+a? z2nMOwYABnDrOS@y65Fvhnu;byOv@BTma9DwcSUub$R4SzT?f@t&=w~BPL6*&-fF-Z z$d@-g*vlHWmrhFsLOSC%6G^P8vIOlHsP57T1b=3#+5&k2L#KxA5zitj^{8WLCM7G& z^@t%WEBJCs7BJ|!tlT3^(OYS5F=#6n&~K)zcn_j+En4sq|Ju-3UQ*($O&1=PNgsi2 zYS}tv2oxYd5HSNUdSEZqE1nYYKM;&Z8f(w;EK7IGg`44IdPhE>V7Z`vJ8s_HmG~cK zQXpt`ZP)=X(jOI-ZYt&)V4sKr7=;B90frn2M~Fx@WYie{u;`9l8*oMt9ws&3opFR1Fv`B(>N5qoInNL! ze%V|+rNvU1{56@j`>%C9CWc;jaC?^}1Rr;X7>Yg3Tt5_9_kMTK`Ep?QzGim5@b1mO zI$yej1N%20ms`!`2wIKt;Rsr?6CxP2r!bivh+sfH=mZD~w}VE%ofVi|ko13w+zGmw z0_I(_(94=H-N|j{(DHju*5+`6d_m7ybJ!nsd+l+Cc?h2wdzog~Yw!p`y~d#PL!;QS865~_7t?m{$1xv$JJuBC8)AeB_%kFU*4iZ_%khX}88&2> zj?40|3Arou8_m&hJe~YF*&;*+8;H0dqnlyBeLZe}c>}B~%b;_IZi~C=JapI6sfcrW zm_nrnQ^FXWV5M|gtzs_%0=Pr)7?UEj@X0?+qQHa+H(?@5s4*8G2|;t}6dG;_%oXl&jr+%zDt4`JyPH>F@MX4pPz4{MvSXdZPRV4e9+ zI=|IiSu+{L`s*=TfI-n#CeYfZg!w@XQs-q%I34&4D)y>{K5Mp=b*2rdQ5r}lUNffrg~ zVcAZz%J{@E6SBon`HV5#VLD!oJmG?25rr?(;-F#*w3-e+1G?W0Vw@; z+-zUft5s$VuC_E~-DUPLXn(=AbVjs&Aj-)}BAx4_jmqlEQp$>LmmylgA~174FV1|_ zvl%nfw<^d4KOJgPN7mVFh4$|z0p6q_b1l1+1OgyytaoS&wk(Cu4pB9gtw>#)D%#=^ z8;sBxqlr*B?}SZ>I2D>kNDNCMtwF1OecK_z@(lDbJc}Ae4qyn!t%5`6z)C~_*wAuX zbRn;GSc*Gzp*=85!8%h|=m@wUjoTl)Y<0{(5x>l!Td;E9p+oQ6Uwy)w)6BF~T4`wx zL@mpC6heLSic~-o>nE-57>W8HxykyxR9N)$X$O74`1~&XQ@jV(jpFdv-GL9!KgHp( z^b&{f4w}8&R@?8h`xft~nTozvX)J7^LNKA?>j@&3#d0k~i{5t%=_n+QcPxEho}BD@ zf5GC4$!cy)rMxV{3MHE&v1}{=azmXz64lqJBEu72SJK=^rqz&~kEe9%Y)WAr?us}8 z$uL*iMGHuXz*qwW3(Ztr&%voiXvG4~X(V{?V#>}EPp*>C7@i8rXx7A37c9`DOGox# zRI=+*1MI^gTMdHMobthLHE%_PFY>AI-Osl%H|~tVw_3BtWYX?mW4`t$hD<u-j?p1_}u z$6PtSnBbF?v()<`l_762t?js!fJ-qD@Dp30_<}%Q&VMy8;@5NJLke}1VCdr4Gjy?+ zq03*+&}A+&QtekWBYmv}(m9JU6l|q5n_^B0A)_FaMf=+^;P_S|$85yhO8o`ADEhYR zFQOZ&N`%Fz+hl2PkPrM$9~5ePzhl%tB@p&cgOm+`Sn3d+yu(P%Ys;m`jGkN#RIAmz z6bhMmE^$JbRH{_QEJ>fakESO-kge>RM_!PqK!&t7JxwQZbx38gnmx5Q$A68c!_jEg z>P{MvIzbNA&&vtIKm_8C2O*e7sw|C-7*@T!YmWT zawu6)*;~V3Ye60^>a%+7^+p=2!k~u+3vD1dLoitD2nKkBlqjXVj3OIznkLgGYa@v= z;M2bP3h?35v!Ko*?5&5*IR4ozI>sH{aGZ^Cw-FsE5b(#3y|Ws+{ox?9VbpGZN;e!P zu68X~TJ74Q!lJdZ_;P8rYcnxZT<*;fhuHyB1ebKUjMfDDvLL4MK{*^O9wk*lx8!M8ZB!GhudlP69yZSO6mv3 z^*Zx2Wa_?@Zy=JPA$YoTSAa-Z5+`w}r`vSpWv8@G0)L#K6V|t8GE1WN`#PqzdA2c5Mo`H?U!u_zl)-I)qKt??CP?=H)@oz2E z#FP*x)!I!gdxez?ohhz7=q!OD?2k!IdTWVACz&{%)^48KKP2hZLt@eRZO0RxMIuC6 zyLl+^sYvjS1G2!MJLG71KUjqrl;1dv+@vA{5^4EiJzsOl;LUcYRX=n_s+zH5D?ZuS z0%xn%FYvc`QO7^h`6d22lg`=0y2!qX7u9HbA1@b#gLwxdhJ~?%)qYkU{Xp>aD)1NV zgBFRUC~JPi#kCBIYYw8BIv!f{*UFE4g8^ueOLlI9!_{l~aH3eQ`V7Dn^JuMMNp7-( zwYUw?bRKQbIypIVcU=`rrD6Y5;yI5XOL?y246k{}9nARJMpM@?6g>0o#y0}Vnt!Yv+auJx@+oI z#LHcsAy(qeEIr5eN~38G+uzA3j>KiacY${Pv_E0W-z~}{l)twWZqVl_B){ub#u*}1 z186)r8_u`$1*2XolOb03x0*{&2_CAzb+f-;b*NgTvuc4QX4l>6(-W8qO~B!3T|&wFht8?MLH~H zH3EYyM~CiOYe%7YX@c!K&)3U;LC}*c?#kNE;9FT)YJY0#Rqg$`^yB5P>@hPdPMM{^ z{5RMP_6N%9KyQCSf($G#wq2F{d4r8AUO2^S(8npxA-ugBC4( zUd40G0!&@TLbqg3kmnj$IlrBPKnr_)Wm0gn7p-cT+5guJkCrorzWs5OTH!<(C+srJ zZjEygN9ncT;oW14-&atN6^;(?pDd*ujv-NTc?E)aVdhW-F)xjtF~hqBZ)Bbq!i(3` zf!*ylx*W9uo&8z~0CJ2rXwK6~*q$SD-X5#Cz%t?WLOW3$`1> z&Fm6cl4N=eI8pr2FmOtK-AIsh#!%Sf%z9D=wr$(CZQHhOTV1wo+qP}n?yBi~XBIOrW|8}|IvJ5azRWD3 z!~k8T%7XykRQ=-eB258DHtr}~j(8_zIz^y$g-*>B=4@_snv3I(07(1U@Mv#WIGugW zxvL{qJ7lCD4i(&MIvwNf?u^*p82a47_%wOuykrC^~Uy^iIv=_Vo#7C7w=6caoYbk$346y+Rx|L%>gh)7hH%{DiL`kA^kUW2iK4sh;m$4P)(kO} zr;|P*v;A0_=rZ4Viq4W=V&NIAOmwr?)Li5l$7L=;$Bm0zG+kQW-vD1ZlKQlnVS}&r0F%Xr=31xTj2n zET0<(Csz;npAg`$2l#ch6DwD=PRy2(?}5KNX|^tj)Lb7;PIiHy>T9xPJVr$?F$OR;^0*T6ffD#4MjvbnLf}g7zcg9`i{;A(jS9rvZi{ zRu(AwYHRuqNKeMl-iE7uUs^R}zov9s zk*0`x_~V(`<=IegV}<3W!!oes^KmI1?RuC!T-;#{Ye@9yea4RF27kZ9`B(8d2;_*J z?{+_l1>4IQhBLBu=0TPEnpzz%Az0$fk^xhYqv5 zWO!FGz)_S;d&3Z2g%RGdJR027eVb%l?K_Ujh2}{ zefCYC!L*HS&x@O+##OI0~XsOw}=Omm+**nywI)%%#G1Np&H-Q{dY zkpF!a*T0DpF2+zL9Kyp?>o*@hR|>t0<0Xl=RO^N2R{PtPs$?gPU~qVxufLk$ia}Lx zg(Xkj3`w?utE>0M<;QEIi_|TxazSpg54l@P*EFrt5U1F;sixwi9CDf1iF9r#5Z&=Os^Ip^7{PvD+*OpvESJ+9A`u6O4OwgjvHiWPTsmAs zH5uxujC6wT5z5~9eZ|go8`qE+d@!zmuJi9TDf65(Tpqb|{=F6!HXwF%Of(~tzBPm9 z*APWAofZeDQJRS?n4`)p4vzH{299?wyZ$|v^*TFiUay6m{0TP>ejasD)$j!GI>f=s4ck zY=}6N|hC zM}h}r>&UDSFMt2E-Pd)=L6&r#Xli@mz$M(SAZ(1urNtDf>wC|0k=~V*`V>UEEsYYt%H8<6cPOWFsj0{iM%Pw>+IeOcE0{^)=F?Vh=gZu4COCWGk|T}_(7Yy;um zr)*BIO!HxAnhqQV(|Tq$WT(Z1qI(d+@d=;x^FnYP)q_;2;ki{QR7*ZZrDpgN_wW9s zqYd2@bDvLh)u&qh=sVB-Y_r)t&mHIwI65Uu7)$w)bW~}zoi!y#bNl(WI?HZewWEk? z#*iivRt(Gaef_-J>w6?F57{nW#Lxnf)I-yt^&2&4bXz}FZ?sbP_Og=&O5dheV@?QG zl9L)M9)9{fpj!d5`c&$5{nQ;G4Nnk9YJp%sEvAeaL6$+4rU`j7BhOdHdIF`6Eju@? zd+wf>E_ozAN9kwsqU_P3NR2+R5Q*AgE;++CG$x(^2JKQ*4}#}ACD98t2{5-`YSz*3_4@ff+trPQ5(v4f zfJEjK>G0riKB|S6MK{@&lTG1`IUXZ9bbrdYvW>-k-5lfv{Jaz1FD}r5+Ev zc@JlshG{*?mPhR}Q#O&$Y4yADco(}|ey_MY(p&Ns|5(@u`o8FH8=q5lYl49EN5b8s zn6^Z2K~~_OIQx(@a#bOrr$C(!La}2j+)#0&LDp^#Sw4okjn9{$vtW+{@1BeRO0vOW z0p0+pK6xh0RIOAzSqRNBWt_C9fe*|{Mrp^9o*@FP4I%aj=+~aRu07uDjlAW^iGv}# z?g-Oo|J|iGN|iJKk&rskjKNuO%xjLaN@_h!CkO-0G84hZAiqgsM)I)S#~QiwFC3Wl z`)rCR)aV90-Mccyjm0}*5B?O)uhY}jqx72}`~%1lvt-d|8^nzQ;>Z(7={gl>vxP{$ zQH$#-hnOAD8b{PSaNml%(LfAiz>=f&GA)hZPbs9TU?UI;0*4uXY=9^fguVqM9|Y*x z{+pUIr=W&7sDK`Z{IqdMCl{T^)vxz_{awa!aR08+vU&;E@x|F)Ccu$7IzqREGLAMx zQZVSL5yBjYvfvC!LO?^>lo)p*fXdWbFZ01Uw#hIDGsJ|3gW>a`1FopFKaN2?Izah+ zgBu)ngfz_;pX@}G_)%SK%U(^AV9E98QKWzY7|bLDQ>-aL8d+4Q$^vOH52}<>#sp^p zGI~4(h-li{XHaIa#4D9Eoa}L3F=k>e>0$T)m%k`S1&AkEG9++#Da!%PNzP(3!EnSA z@d#%MktG*VEK`ay9bT1#zAexGqW%_-ePMd}LX5(ZdDrtnDYUkvgdkmtpiIb#L^+_B zL?=aZ+BK7+Q8tPy12RwWH_4m^km8Ue1+5#l?9I{w6cu>~NOw>hO70BC6-{b|fuLX^ zjwf&G36wus>CvPz)C~XZfhTpJ+^baBKmiAW0_n&|ctO-gh9WzZagCYUnT0KqRH;8R zva}V!1gTco5BrbjIKiWhS6@%pi;(!DO{zmNjj2*LyuGoQy_9;$5Xm0}uF0mDjr<6c z^=Q5EWU01S3(#~pHgwmxRL>b>lArY8XAq!2MHii zxFq~=@>Kx^DfXbVS}2hNmodpedKC=|=>o&iZ{=OGk8p-0dJ`QcG#yRMA|-J?-|X;3 zD4gnabAimbBp)K+vU=^EDWKu?_xbaIMeaZ zm^B4O10@;Pq8-&xuS~dSP%s1*;(duEEkw+EUYyC9XQHD{8NLTxt%C^|f0m($x@VU5 z)u4=vbC5YiYyc)rSg#E|`izQe7S>gz%89B}6e$Dw2&>jm^HjMz?+y0)=x(GjX9^Yl zVZ(gJm#6gOOiTlJ<)C-jI-^nwC_ zSuak!_Ao-jL})_&<|i>Pag&?8`^> z>0}ZuBCNM6xqgLm3iC_crRaUNq)*k zvo4WeGF%z+PjV>PGg~jJjc|{Bp4p$N%!c;z8@iwYSvQO|BBpS8Kh1EH zjt>jO;?s4Gw6&nQZBB)FS}K#p4Pxr{{(Y)aZi6tZtfFk3+tthI`^Nw;FkH2p|9W`{ zTebYc_O>xtxUk4lCGAf)M5KtV(qoCCaU@hpTFOq5iPNqsiCQlQq%6|D3N_XY(5?|% zc|n#|aFMh`Tc{~zQGKQ9Odes5QJrU^*Sob_eEOm_@@I}F))3minD58T*p%8VYjdRw zSnDkI1rFwg%gNIpKEkUu>=7qE0N()`IHNgG_vKj^k^+A84S+6K6qV#f+)p05s#3zHR@ z7Jbq?v_M-KkPKUFXODF#55~_zen@<>4$(KyNa>eTR8YJmG0$Au~gX>pbfL}@8%U9UgJgWIp!X( z>gVX`FEXCIbM)p=bWjM9lLi1eCDDU%9$i+Pw2IZi-`!14-LNBZYxC=o32#NpW4>}SBll;!sY0H+ zRmUw|D@>~ntw}N3wa~TE-BlUrfJ*L$=|pUkrlEQ${PYv_B$Y`rLzHelm;%EVwnsLG zpdxwW9pK64h{ssY*Ff63iM{M{=S|APO}dOz^A9hZC`dr z-8_oVOwY=&#ZPGB^GBR+BZ)uFRpXegr6~`inlD)s7QA?R+#gs%7oP-HYz*)L^*lF& zX4R5n(PK<=&gXpfY9!+tU&FqaP<+1=@vm>6FICzpq4HaXn=drQ&1lOtZP>cXxNy;r zOkJtYT~L3uIKgdEt>38>Cm;8Zu3NKF2nIi)a+y44(j{moU5ro7>A#)_EO)WzF-*Ak zse|0JpZsG58)hqh#ZFB}jqIQ&SEHs%WtbL5k3w2Q&p1-3e@O-tJv za(8e~QLZ{oGF9HJkHcxIEvJSSUTC_zTBVg+*$dA$hG8Une7T}2uk9IkZea5zC&9Y4ZV=l^fD#0SfmhDqooYjn<5=UvYc(Hy{%8^MG$dE z`WKT~KIfIJ);Ir%DVpq2WT^vcjgt=bgxL+B$d%w=vZSy|iz#!jbQ)VhyMjfxa8zo@ z#x8u)7*}Nk9p&Q7;JT=#G|<{<4^6;@blzI!1Z{9`O0`53{bHw9{Kz-x&qk;FHVPPi zGWg^R>DtkX$#&|%@Wd>b%5sd(zI8~Pk4I36&p87gQKe01=kcxTZU5zov3uxGU39Ha z#4_{0{9UkzfX~L~qx~LrXSlnt4oNEsT`MYHUox6%Y<9wCEb)JoAAQW~Eb`DCHQkdl zw86zldzDtg8#M*730r2w43V{uV#vc-3N|(HJMc8v@4L2rYfUZj@pj~yf9t;jIj=v| zuek=a^@9K2hk&pc|JZ8e8Jj?G#u0|ItKO@QTTVrE=OAx34`3r$hjzlS`e&&Otj&z< zE2vVxtF6@!1`s8qDi^$1RY~@tI_HQyY>u&f@CE$qI66Rl>xJS63*g8ePvoU602`uP zBYj=C}fmsKAKNtr3kXj0)x>*0yhA1Qv6Dk8QZOXH}9EW z*-+xxG6eX^Lj&sq-UPgCZRfHPa&E)Lcz1ukSlGrVhtqj%y&l`Y&h>O}UO#?&f@oI_ z2KlImz)$<-{|^o8)(7tY>-{#7%vW!n#_pP7Cz7q#=FXp`RkM3jPyz0vy@)4G*(%1U zrB%IATsqOYOU&8$FQlp+i9)CGgKhO0TY1si=S3^Okb>9E$;o~FuDxe(%Zj;tUt^|9 zz9c;!k`#RTiz~_|OD#;e?c{B+cf}U{ew=aPjcbQ~nRNBM3C1uhS)u-Bh|N(Qd}`^` z#w=7;I$(=)W-$df5dTC{YeiDAP^hU5qebNuLEofGQXnh>9Ug=q z+*Mx*)%<+1`kHA8_I|a%`9)$7%{%p27|v(ContW*JPyL)?m@*6aMHbdvPd(j-HPwH z*4n`JoL50@i!zpVP1mo(4M(apils0~@)FRK9m z(5EpQn$n=+cIMB?Vudz!40y8n)LMf|`8DX1tjIJ*?bHxU{x(E3a8NM)y$?*&7l4}L zn+%PjOapj%9*I_h^rr8s9>3Q;%I*j?B5y{~VHEA(1x1C&2L3v?r`Ol(@xpIW^zf8L zulF>R_xfG4n`(xzDara(u{vAX_P!(}UFYa)-fDQm^6c)ws6vl+--T8K=1N&bDRmA~ z>=c*jl)>nH7}+p+s(^k~^ZGfJREm))bdcP>J^YfSN7xg7f{1DHSa^=lf`1Tq%s);} z+SL#O$9cs%rMcIBYs0qd5eU&GE3N7bv6?dDLB)3;+@$+>&aGVL9`=+qBGvEIx;6D3 z7%$)OTd6sp`b4OLoNota&Ye~JN*NU5&tP)I?a>re+rl8H&+A+WuE=@jotkl-}Ei+60t!V&55NA5I72{V*h5M`H}EC$2W6#!kRa z)wraE=t~2!ux=irmaq6`xo+{k%M*I~RlnC?3V%(&_VqjqWiv_G9$T~edO8n1=oZ&s z4N!Y0)=+R{ibkMe`?!O;H}wP#ZJ4W_vXscGG2`^-)?j!_HVsi8H<(dlhuu0K?d(c+ z_gues10Kc;yp9i7IGaPWOP&(^27c5`ZVN)}?0u#$q{X)zAc1X3V}bSFLjT^{aMJjB zuaGh094oz<+Y@`qFzmGWy6ax(JwR04>2dX`t`WuzF5P{R22fIDJ9k?7u`kk`%ph?; zToGkxUx^FP2JaY99)GqG)9C|Y56tx=z+U||E!p=~hL;XWLcyuzO*Uufc^5yN!uLco zW8X1yWkq|RI1WzSaAcXX;@@f4fVOT?ldH#^+Q~Mj!@nioOoQXMXuvvC)en-03PO3) zeH1D_1IVyR^=WEttE9HXhM0aWD;~&a%vC*6wR%%2sYjoE)8V_b;9L+1`zUe0t-o;2 zkQnbv;Z=RCxWR`RCQkY3ZhC;V|AXNW7hgXw2d@vkz1uVZVMVhe9O$?wZVHUYb@Hy@ zUa!YGoIPeWm_+!*{mLly`Sd<$7nyxvpt8q+6ZbytZ}d{pQXcsBjN^dL?%cf(YR60| zhiwz+p^0$LbkW}w!x*r?#f=y*S_XIzeo>RjDOOFPH$TD;5vG`nOJveaIZ4b%Xb}pf zM!BEzh6e)Pxbl{j1|<`RgGqtKssb$}-~X3)bVpQH<|6p~RT~)qfI|cT0P+9zj?x-C z**iP`*Fmau9i*l8Z~ljabcWm7d8@TCZ%RMVamRWIwc_1zF=ozDSxd>LC8;Fwy0~Kr z^A8bWB&>co!QXM0TYLU4g8nu=$85*E>YY;x=Uh-0Vb|q+HtX55!Av2Sv z??`0jlnYyX1_JeBUiWV{ZAyU(X>_y0(c-7CyF0ManG_D_LvTJ)d6q(wm>}`7($*x{ zz8)g2x7w{PzjngS#~6zu=R(@izij3Sc|4 z=eM|S&6t&En`-;?*`y0Tq8EFzcd)gcN5P6Z>aWwI$qO^X7=z;n4d=>D1GSF!DPj?) ziEHTS797NJ73iZRa1pY`Se|egwy5>#9;GcoV$n1K3){_ngwulEPV0dz@H6p!g!`G&Qia3j^A*X2K;bM9x|5I^{Q(4qaDE6`3rVBkv`q3w>BH$5k~qVH z`%JnWxUzTt`Pn%h1t}-jXRWgMTYfac2R?tpR4961O zN~q?7zp`=g@tnFXB~&5H8YI0JiY%Iesg(+QZfFdoOBqj}GyjmZEouhk!g6N->3Dcg znBW6=1D7Rm;TC9|PS5Ohf@lOU-={Ay0&Ya9hou<)S-F2diAoG*!oCm~i0OyCeVWiq zF*U26n)*KI&uU%3Mt5eanX%%&f_IAzb6IW@#b5^UV?OxHTnoWdtv{!L|6sTB9~!f6r zJ4+#n*)sVPhS`e;8b8UbJe{Tpp#}0FFqCQrq6Jxq zZ-gKUvSgP=PGUVxUn*nbF`0+*`K@L4 z0LYVcd{o1nd!S`+u(V5qPe1fwsMUa5JRV+JIRb%7WeC3*WOpdh z(^5Od=|5{a>Li;sy=MtdwWG~xi}M}H2yXSOwBuwfuTi(^Mf-)YegJ=7k#PkF>O(PE z@#wG5RMK)$r}lz8B7kufu;k~=%Vtx^z;y?LuSE1_3m6etiLL->jFtc)fK1Od&&Bsw zS&Wlm2>|7CvK&w$?~IW=Q>y{6W|*UaGMJGvEX6NNUO2}?(6kAD(i`xnJ^=&;qxqc0 zL1)`dp##XzFA;49=oIZq{DYklX`=Mu#SAHxB}1B2$AC^U@z5UX)h2MAn$RE$wu4sC z04j=18Z(*@G>-VK^sC6MjK`&oyE1JZQ+hPrtDAAgDy#7*B_N@!M*A~hW0{FRZ*CQM zkT13HiFD-05DcIW&5OTed9)*7F+X#m@&Vh)DP7Alt!<^}D>}c08F&Kf0%MaEQfp~g zEG*@~BM}^s(7{*cw$qpARNFmVUOrz31Q?NSVFKfofXZsC!O%W!a9wzzAbXCaBo|E5 zNHJi9t)4g^m~#A%uyX{j+skDVhfKB^lwIDA|7u$eH}Ofw40y9atmA5#VH)hCgl67tH3&RC)0NqzZeF*yT&l^C*r#6R%FHA4RsY)&NCn7_4SPm3 zr=g!3-{3XetR7gRt@Ml)Z5F z$tvsQTR6o5R8AOrn$y7pnnzKQAWkOZaS8e~>=>$?uAlz?#CFin0|m!>jS9f34wRiu)kS8D+!YK|2%nG{O;rtw_ETz`@9fo{lywS2YsPd<;mm_jR8lpI<%lgmHPKSI~Jvk)sF{ zec5rnm&Fv$JA7TB3fEV4*2di1GVqt-%FPQ{-N1bAeCle$*4+0?_{%RhK@(eefw3YBO+khDi!?6mx_4QKNazEUqdfAWk-5v zZLY!Ab2+Oep!Nq~X4M(aXHfdWbc3$YDk~7E%`mk_39bgJN7cbq*jBhEGZxl>RbVz? zGP)J-%LoGY9snOD5MIQq!Sqn~+ckmDaSyrTUZjYq*?zVjJsW6xNCvVtQwKpGS!2#s z>@m{FdsuhgO|!*MsA69WQPn*#Z?)#z{4yL{PfdlOB@7vm2OXNg$C_(EQxA2@An-fA z3g{-g`7n30I)&`IRq&0w3C+|3OIxhHe}GjB!~5PxLV0~5wWEk|ls}ZYAOJ^*qplco zt+2WojEu^Nbl&>#EC3 z@5RbKT^;BBT`lJln=H!R0E3H$l=rS>9s`DGbRa@&ySGh7DN zo5r1&>>hQwUte{}nfqRW(;La`@{lW%A;S~@(q2< z<`clh;$ielB+w;?ZamG8l~D^C@gG_*y3!wcz{~uL^icOqU>tvG-Q`=0w*7 zT$R0_{keL{;?HvwA1^S$cBDQsYT2L)me=K&ng!GwpXd-!D8;HYMk4ZR~|);WbT z=B67tr<%Y#9vU*CoBnMF%>&uX5R1dWUb4)?ewOc_1CP!_7&=0TsuTEYw#z!A&A^5^ z^INDk{jX<`2JJm<pz&>GK6Fqxe;4? zWN3O3mNNIXe=wcyB!@Yb=9rW+RSTDhj;RQ}B!nxAuiJa=_pg+^=)RefDX=U7c7=n- z`}zJ3=H(a(i?Q{|qWC4#4;F^LgYd9Gb#uhoJ}eQT4A(Vy!+xy0am?3EH7JKZP3=1* zI`n;z5p-SZxcW9tfIwZc>YqbRYss@iT_(TMNrvIH#0$aC7}#(n(`m|^ae z-|bfDNGA*1VWw^4dfn1J?_VI+qBZhTKN^gK?p|H%Wbxm%1w757@)5{B8?rOwt^|F^ z#4x&JhaIW^2r4JP zC9?iX&s23y{~l)togkBpT!VhY-f*U-oSEA`et#Cq;*^_3w`!W8m*iu#Jc<=;Jw(4) z{pg(A6O_{LaAP>*>* zJ{%?YsG4@hII`ba?20EZxreApE~G>s2BuDz#1W9S6Edsl}3PE_wkM!O`GmKRV)jxk z@p&@=cG|=IRMrF}o(+DB*Cgp}s4A77mN-j>zP5U;go<87mZIzaRMScRXJdIyy^kK% z_-62hRzzF6J8|;&4n%Lg(Uc5W^$JV$RD_%da+frMnwQ60CZ9~B(o*~PQDLdjB^VjEo|2_@4P*XCb z420Q}z_ES{64)rp8Dz}$Fb($}ko2z^L5OXhIp18=V*O;cBrZ}en{IyxYU+!1Z4J}!^PNJ z-$^2RQM0J`9+8U=J4*sM=3{}S3|zHG53@0URn{R@Yn5SgtXLI>3S!isEeTNSq(TDB zyOw@XKTPO)qt>sE>f52F^y$?%n1H$iHH|KZ^p+*zl)FQKK2+-GNp!Hk&%vDAO|cB4BuR$?<|oxyBsda=Uroa(Jtc{)aKzh$A0y>dQ-4PHOB9R#mG-7Kd3q zSPlnd>U7xcUKhlFrXIzqtDKf5ae4<<4EK-^-IwaC0zvhfmZ|9crr2)|w$L1O{Bj0; zSa8w#(^c+=Bx5;qVZS8P>#I#mv?E%09BYv1?Nw)=?)6RizR|)p_gUNrD9kzQjJ&zq z2ERt3`k1=|uD*|EteYvyXm&Mh3L>g5@D8;T{}t}Bx)~7fhM{c~)02{BGvpf_w@hRV2 z)D)atOZybek87I6-fSOhPxf?ZmU^olrn~!4s&|(t#%mI2W)BKEgY#|N1m|#sqTGF% zXFs08WjAiYaF*e7WZ<_NNxxfB^=!wm9)rhvfV?^LLjQvQ?}Rtdzl8U{CLNj9QfUBH zZ~%ZnYybe5e^)xOf6;CmOJ^547Y~>J9_TpUgSGxM|KmUxo4ygZ#eo)f2VE{6xs_@| z-eE7}4jkKoF+FV?m}(*2(3;S!`=>0gNvTni92iC6_czBlDyzM`J0o6|Rkn_vwDR<2 zWO+t|P)pVhhB)YoeD9SNocn4r$iD!r$(S=_E0pwHK;#vU`8Ti|vdxb3mt#fbIrB78Wwk3y?Ge*D?HgeN` zwF>`+#D=(|{DpGN%_8`GHruvgIoeDTLHcHNtKlWq$q}XFxwiv{g$Rxa^;u-iGG0_1 z5kDme=@1mRa#zJ23z-U&4&@vh*gr^v85eBpV|>HVgicu+C*0VZh*g&a1gK|8MV;0Q zm{F9!RKb1cQmbbu`#UvhrQs&XRgVZQ^E|8MA}q9v-b_#p-Ch^0tmMrM$O7Hu-0*nV z{YDU*pjPwzYm9z;$XUz-RQKgmY3NEIKA*_inq-l)-5;k zC2Y$;tm7W`MY+^*GH`qQI@5}w2zz-g?4lld% zguHLFF11-P4w^7SxM^Ph>mci|NG#{d&k=3MMf9g(`qK-I>sKKOChsLuIhG~D#=r@Y zooW>vF|is*N|O3vNI}qI#$L`{3uB9F7<#DZvrmcNBdYmvkc=;-u13d#n;K*aFc0l1 z6d}P~F@p@4f!yabs|4XW;}ep6I3n{UUzn$#!B;tBBpE(uv`H)rcTOJ;<;YaE0)Rbi zTsI{ll$8-01{M1i`;EKhyLIP`f8ZFJvSMv|c#=?)YD0LKSc{x!n$RA3;SxwC)5^&ydieXjY~PPDkVxgueV_hu2DFfuAV z-Xk-cy4|5eAEpj$O6Ej}dsaMb@{!Pv5W)vCgsJUGrHzDnV~xu+aKxxGq$$S#^Z2`! zC82$*@0YS&4-J-2t{}j`ct~n|RFJ~cBn@S{ZVtx{=hu*_mD5>N_ga;+vFNJyj+?du zHnl7=yM;Q&z$9{R=S2xutMO`w&J~Vbt8Lk9*c^6oT|y0{t7mqaM9m#B3B-#1?Gbt& z3ru-?+Zs=vN(YPdYXp?W3{F{}I&pG@=us~|(SbguASDUYP9hsV;z{kZVk=7VzI zk~pH>SF`qW;KGr0lYjSUx+`(Q=?_0fIqV6pMS`lHH@A-^g(F(X=x^XLrQ?Me-*=q^PE)@k;fum!{1E*LH?!eQP&q>WiE zfanef3raRR%Mvj6RTl=vuue3HZ5_@dIn;OCud|Bw`o<%*N_AEAtM$W+C+B9*P$HEB zzvflPGNjvBYctULE*O^KkZJ%IXXgw|T)Qf}Z`wRVi$GwRt2}IipMP`A3BR?oy$XZJ z;W-rD*Ri5R!V}#z#Fh<7@ZS8#6@T9z{sz~9`+q<2d(cZvmrV}1y?s8qYi|r}sd~WI z(f>A<-irQicyakAeOTWQ2uzKC1N-d?rs#H4zC*9>?=kTEhab(@li~mySg0|uNJF`Q zr!4Az;*E425r@6>zB|nraCq<;l?#D3eI>GGxi-ieH0=6$hUi*5cLX?Z>>mHiv?_IP zp}-^5!mE}-bRz=LIsfBJGh61k;LcA=0Qx5Bl*9vToh4t{G|rKKv0%!dTME~&Eh7D!Fc`XIu67x++-s(e z2E0bW7g{cC6-7Ik3z)~gqn@gwV~0&m&gV~{JXerru7`=&~w03z$MRvPYv@8R{W`659daB7&l~%13r7F_HDY;eSca%{rf&z^}nQJ z@|Bd!y8Cd4pE(L2DeocpxuD;_+J4(aixMm51pZ7ioVh4SQPw`CWbd?;;CpN*y)wk_ z6_laRf#d^aIwcp>Vp2`2sdM0zXYde^W$>Voq0!ER$E8^g9s|4QMme$jBkoVFo?E<- zUp~LR9mXxcpC8tz>TM|xH83_w!PJPA%?`?o>C80 z4vIGZ8I4=NRG@4d`X&8RpHC@CLnEJ(@H47^C8N|{Jf*5HpHehd%qd;OWr1DFrVV-% zN(1@WFC98$47*uN2|FpsFz#F_W7b+(P#WofS*0)3l9hT^6psIofcBr&{2u`=lZ@y% z2nhhdPzL}2>fdTMGPN_dV5Bp4aQN?HR{Z}fXE!+3?wew-P0n&Z|CkF~sBHE&YoqCS z2Quzm-4f_%>urIkNGPH9f#>sfk*e7}jA%)%L#09w;p_B!{9f2q z(^^V`6s5>0SX`5`%7SK6t`xSwC6!Sp2AVn72@Sbfo+TI6I#H}#PSHk{SKy9vET%$v z^}{sND>uRPES&36?Q)Ld3sOT1YzCzojWwzis(KP=#$2iunr!HVX`@&(LNjSbfNnyu zWF;4JX?S^7-B1_+gs``>qRMN__ z=m?gbG&Qln^mi7@Aro^_XWJTGu5#BH_R+PD#;)3SQMa4@*}W!mOFdmig@NID9{&25 z)xe4gr+s*#-k2XiKn0e;XqtT}$HiEUdPY5v4AulRQXPvT-~(v($cu|l z9c1)j+ePoz$mj1ER8`=Bacgv9IFQz|n&s8|`^6h0j~Z3-c(L&TkDf*eQme_+CqQ2Q z^?rZsdXpG%{ z@9%dV3Lp*12PeQ|)O6C68C%%8$@u>9q=c?PI!OdE@Qkw!XWqB^OnNMg_@V~1fyQMk z*ODcSvqql<%>m+P!5W~B@#1a32Ma?;Ka9WS1ysrJfCB2WHrMGQrU7=yHbCGO5OOb1 z8jXugq4ub1Vc1Is^P3)IVB&L#YyF=+0hD~$h4%o$;aY_CBp|s2!6Y;6@llK!+_CE8 zr&i(#d6Q)o=3M8-hH+`ndGmut553tubh_E8G|qlj7aAJcFgOU%jaGm-or>|%MM>q+ zA_+lijfQ>?5mh3hN9F8N&OI5M>YJ$e*V1~pefGK`0F=BhBO_sa@oad2<3t6T6uI~b zaKqPeV_elLikE0TTv)3W#imrEJCSbe;PdEM+?D#WOqQdj@HQ#aO21(#5H0uuXlpGE zHQSZ>P$4h+Y!d{TNz@o?A6AuV)YANY;=+R>*1Xgi$npNX&j#~GPddz?*g|6As&bb} zN8Fn^KTH4DKnT+DL3tdak#!NiA^Uz}`F^yR3;>|w$p_zuV~|~baV~5TmQEQ4!^-+$ zDFLmv-}Rr9r;b~uz*qE#rXE-IU43^TO`EujaBA-I2#=j3yV4{aBbDK61}J zg|?ByZ^pM=u!?rBq!*L}2H5e5TrmZkb>$%~23mjmDza(c9dZclZE_5>q&QYQ`_ZA- zJ}rVyKm>KXnZyM^d{tT4w^E@B2d@VRImv|+FEWCp=36Jm0X6&0G@5aU1~Jb1P?m^n z_+nb&7i6?W7bn-)&ufG!64#<0i^gmyI#(_TEGOaXc}ujp4$=4Q%NQ7j%ZKdvd~t?Q zqhZ$K5@aYJ-R?(cV)>tJBuv0aiV&b^4WxBYOG6CQp%#uX2weRlq!t1ME~MH7EmPck z7pFld@LBCWCKH=2S6xqYjarM2af3-rEtF^RV3-#3>L49s@Hv?x5#K{mkg@^HASS3HJWg*ShQ6*-Y#M`lkNN!aVFn*Vi@f}9)qkH z`pcSQb$g5_+j#ep_E0?P#5IDZHb}<&(Km5z&V)?9rqAV%>5VDTX+)zjIo<+R__0f* zs*!#DoTVY-QR0BCQ<#rBJr_N7brfd}lwt5`W&0qor`y$`SMJw9NRQd%55SC_Q^VSW zYwDhO|5ovy&(dK?+d*s~6|hg6;&sDrvl;?5!zw?n?Bz>sg*y!{ z@x?mRiM|jYnU#TmD}L-iBBUz9-I~|q=x%)SB>fH>b)Q*xNUw0PEBT0=krGJG+G^SiFT7N0IEG+AlcWUNaSD ziUrbI!kud9e%An< zvL~^L^hSyb^XskLSR6VdYqRxA%sC@#F5__Jrkn-`){O=sP4!IHXS8vE3(TVo_-kcsQF7=eD1uxN;lco1 z?3bE6HV^tU*COg(&D)@m1q}r`ZZ{#vVIyFJl71@|{P8hkVn%WyVDipI%7t-F6B>fT zC78dLIN(n0Ll(Cnip8b85h;b5E*IJcO@12&k6_jrxPAt}R*9N~@PG*sk|#x4FF0)d zK+H9_lS_sb4cQS_UuzeLIGqo-&ay!oii))=DF=zvz!C@|Cs|&lo!a~eR)hF>c5l4j zF^DqnH`La|WWYfnRoXNE8d$Xf!v%Ls46+R-*a-FR#C)xwgZSf(5?3(>a6g7N#K&kN z-Tw|e0(}QIXZ+^4ZUq(Cju+>&5(|KtTT{=L7Vrop1D+OVfoO+_1q{n8k5_q>eDRkXtyZ4);YW-7hVB#{I)ZehWOKu12!??37gF1!>hmIp-;v_bV4`w?nM1^#whakPxju`bSk2CK)a1fQ1 zZ{@p*;loBDhd~C5?cs$GUP=aX?QC$X_H!o;Z^4Ddqz-wX!!qk4-#;my7@lj_h@*d$ z@8jb$Fs%DJ#45qmI*#?_V6PmHVR_}K!64m9?jyIA`nH8fPFGo>?`S%%ltc1aG>!D& zoNnEUP!BX-yau$gI;8@`#tw36;`15JB@zPs__0aeR)mrIb&1e`6!LJ}GHwN~)uJed zK}@Id7mK-7ldrJk4YnTT6b4^aff`s%OySaO^;XjC(*kDPB!#>$vm@gM5IZkr250Zd zgRkZIum+5=*xSE;b!vnmJ?ntFO`&-PPfWkWayGtywaLLaB*9#^w z62#;t6!9^4OfT`aZ(m-B(C5B-$VsdELZxF?lbZocN8!yJ4fh|Bop)ND8c-Lr*2Il zP5qU}(>xAOy3m!y!Z^o_)ouBe@=S>DI|fK_qB^QK&buW!Z1RU~G8f^t!P`>NvGdBT z?K2OVPf4w;O*yjZZ|L3G%diB0UTN{fnlMi0n-i=!Ftnh`UOtUj#736Yk9Y&>r?@+1 z74~XvX0$IVnK*YwB&9J97O!$j(XGd>-(q-9M$=9T#Z=FLdGbN&85P61QxL9HSq700#Y~2}g_q0aIp+h}J{COu*eFX77uaw4?&Ero! ztKUlB^#of$>Y|oy@pXh7x-bPjMGpz45-j2t-yXH3(>P{Q_(CwQCe#hE^(M=PMRC+P zhq^nQ1e%&0h$NB96A}%Zl8S@Ib1`df;PO3mc4BXCD!57|P&&^qdbGY~)0eKas4!2) zEAWIgm?9FlO+3tSWImy_!mF=vW37y-%U455W#GcOZ3K#jCAS4i005) zF+`=|9Tjlus}QxFfq`^#Ks)O+eudY&|UO{0A- zZ<<4kcDV2l+i`GWxIV0yyhlL>3J;|OmA^eN9*%Eih>c)46AA?{A0{?$QqXgo6a!O1-hqJv4^N#-e>yt5B{JG*1BCJU&KIHWTmB1jZieb% zO=}Ns%u>e64ag8Cxq-~zZG=$w<%V_dkAhE={Bvi+2!|EM} zj9Zl&?eigDX=l*l+&7r<5F1@C;;kdoo;OvG&A54C;4GDW=eexP_KJH#Sif~^@1-SI z_z^gQlN1`K7x3>g0VS-|wZ!pTkU?Tme~+rJAcw5vptxsU>RdfewVDD-c&UktPPH%M zQ>@?BFPQ2iWe^WcU?@Wj@zZU)Z}Ly4%WUB3;(T5h&{E+3@IFGi9e?IRJO4FX21NpT zvH})Bp+M2=Px90yKOKnBXQ?ESP<9L16;eq!o?>A2u8{{zh-9`Lghn^oTwC+SJru+& zOb(gSNrgKRHAj#7ymV68^&}$_9Z-Ag#^!0Dgmh(%XbodFF$BpAeL-gR0e@TBXw73`ontjamaX5XcJ zPXb?Cqb@G=R4Uj@A>R9j-yl4Tdk3A5AU!kR^!iwm=`qo| z8{%PHqvQF+B%*!c)Jo`bKxOzrvqR@=GbD4rwJQaOz23(3KHI~tjL*80pWf`gO(L|+ zND~1)_gbzZ@j0+HGnPuseCNlE) ztc`AUO&0TZ9FMJ&hq1H0-IB1mKB!AaeI|j&2urHXEfnmo+HG6hiyODcp*n~Kpu`*z zxd+CQ>@A94P3(!cE}f&ox&5HaecFDJ7mU}#JH<*%;-bB9IK;P!TAWG#?dS#+<9c@R2D9LH>(2~^7p7K~>T=o(icavU3hoDQRlA*Oc z^2<3y1UI2~xSZB0UR1fp-LfqSr`V$8H1cpM3=T#5i)vT;VVX1{3AIBj0Wc0JU2T#H zjUKjxZw-$wl0OJJ?Oy7>JSAFc!Fo%zak}W^*Z@_gh|cEH4V(#AM;qzp@GP{~S}zch zy~~a7fsQk`tNaF!+XMyU)|f#{E%ezb9CQY6wmDLaSI2&9x!oyzaU?Uy8qR`F<5MhZ za&5K1WoZ$ynEcy~^W_l%A3i+#y+q0nG~fv&R>zjY(xXTE9}(R~k{QHbv8J%k+bD1Q z`>Lc_x5rC+T5|Iu!~#6>T*35Vu(8X@MM#tP30|JYLy#;XiV+ zx^addIY;9AfpH;}=hH0ym?ieUC*giJSH4F(wJVJwwcuz$?1gA_NJX-O&6Imr3dI!v z39XyI`=Q+yxWRtWjOGM`U)b_CKhDLX^BsOFUycfra~^&&)Y-&BJK7iedm6G=jY+!m zOwC}WGEwQ8M#G`=Z{t_Mp9a(SU98!!@#O*-01$cS4};0c{F#fnvkTY%w~tl&8fyQA zpYWrhVXhCB4Wdh}a8lf_cH>YRm(Es4HXM8Q$bjx;N~cT)9K`R^fbdcFBeks+-6~Qa zms?py_Mad+>zgq^^(^x0%iS@iyMkfZZjRXAz8FcMd=^|ZJX*rDA!+7_0wE?ejDy3@9&NvBY4wER$Wflo3bbJq;hhLPivcd&IXPSL&U_MvTRxbh z7d~hcQ7x)D>x=A*G^B-e(OsL_<#2{@!YVIwYQKFuk>YXb)8z3!&np&I?L%~BZx7Of zTBgj%@>RP^!ec6HE z5S7P|d>@rS8O)Mg8pK0%7E=j|tB`vw=1cYtM^-psC_CGcFt~(Gnm5g#!HA@l57X^^ z0#T!9bxAMYM_&m$$uy4F9cfHH)j}z1aLzo&bh>UhEPXw1dEI135+p=Zbfo((*(mf) z8{RZ;I#Re_cSElNf>}F=6QkCONh5Pvq+QNiZ{2kZ&eV7ic3Xz1k=c~89q{Q_an%n< z0C5n?s;Al;c~uYayR;GK-}0zQw64LqUzJo0PM5sy@)DVs#l?FcI(IsZh&4Q0F+-vzVVgb$M+B~3sugy)s?WLnK<}2oY_TPruMr%qGA3@mesHcq6Hf@2E;({PK z5rHK9$l*Jd5G%##=T-GG-;7-iTfEndrTVHlxM0OFO*R7JdrREa*Lanv=&RpGVhb9D z>7~C7b8*t@WLCR3wz`OF*V@N3mbj}v4K2n}USE2%o4FAW3y!Tqb_&fr`Q7Cz z>rGS)>89%g&EoPS7e*o(MM*;Pn9TKs!?$|ZdDqCt-up}ixT#Lu!&a>&vZ~)j#1}3+ z(rK9S{c??eCD*33QcPx$K|5etS-el# zt^CO^t@OexB{dMV)tJ^EbfRZa$bE#ZdAW}KpMj1^WGTULO&4-)?E)QV6rH9Gw_jG?GNHcxVR8eUjg%XM7w>@C37 z;BM6@xI%QgRIae=sYMlYlY%`thH88bn}#9f+e&Z?!u*>xc=(ImFZ&N0Ov7x|4v zcqV&~FaywdD81L-i^;`Jlc2!Cvb!V=P<=9%7aCbeDQO>yy#axiJRxj|a=DGq;~E1` zaU16Xrrng1O{hQBmPayGb8@C1xm^FUN1_~Z^HjY_%RO9?X+V5|p_?VRw^QflE7>Rw zeCJudQ0uWzEiRzAeo)xibfVZ?<}rKanBe@8gP|R3Z`a=NCn$6M6Ooyxu3otJc%D9- zGFcSR2)oaopzQPguzr<06fsR5{Z$y2X@89Ry9~Age0AoHr{y!> z@;2x4`GzG*OeSwz;W`y^}M?AI&!6ET+D|SYiuVtO l -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 -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 -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(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 -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(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 InBlock; - InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]); - - switch (m_rounds) - { - case 42: - SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 44: - SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - default: - CRYPTOPP_ASSERT(0);; - } - - // Reverse bytes on LittleEndian; align pointer on BigEndian - typedef PutBlock 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 InBlock; - InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]); - - switch (m_rounds) - { - case 42: - SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 44: - SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - default: - CRYPTOPP_ASSERT(0);; - } - - // Reverse bytes on LittleEndian; align pointer on BigEndian - typedef PutBlock 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 InBlock; - InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]); - - switch (m_rounds) - { - case 68: - SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 69: - SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 72: - SIMON_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - default: - CRYPTOPP_ASSERT(0);; - } - - // Reverse bytes on LittleEndian; align pointer on BigEndian - typedef PutBlock 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 InBlock; - InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]); - - switch (m_rounds) - { - case 68: - SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 69: - SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 72: - SIMON_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - default: - CRYPTOPP_ASSERT(0);; - } - - // Reverse bytes on LittleEndian; align pointer on BigEndian - typedef PutBlock 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 diff --git a/simon.h b/simon.h deleted file mode 100644 index 896e714b..00000000 --- a/simon.h +++ /dev/null @@ -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 The SIMON and SPECK Families of -/// Lightweight Block Ciphers and -/// The Simon and Speck GitHub -/// \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 -struct SIMON_Info : public FixedBlockSize, VariableKeyLength -{ - 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, SIMON on the Crypto++ wiki -/// \since Crypto++ 6.0 -template -struct SIMON_Base -{ - virtual ~SIMON_Base() {} -SIMON_Base() : m_kwords(0), m_rounds(0) {} - - typedef SecBlock > 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, The SIMON and SIMON -/// Families of Lightweight Block Ciphers, -/// The Simon and Speck GitHub, SIMON 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, public BlockCipherImpl > - { - 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; - typedef BlockCipherFinal 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, The SIMON and SIMON -/// Families of Lightweight Block Ciphers, -/// The Simon and Speck GitHub, SIMON 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, public BlockCipherImpl > - { - 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; - typedef BlockCipherFinal Decryption; -}; - -NAMESPACE_END - -#endif // CRYPTOPP_SIMON_H diff --git a/speck-simd.cpp b/speck-simd.cpp deleted file mode 100644 index 91a3806b..00000000 --- a/speck-simd.cpp +++ /dev/null @@ -1,1119 +0,0 @@ -// speck-simd.cpp - written and placed in the public domain by Jeffrey Walton -// -// This source file uses intrinsics and built-ins to gain access to -// SSSE3, ARM NEON and ARMv8a, and Power7 Altivec instructions. A separate -// source file is needed because additional CXXFLAGS are required to enable -// the appropriate instructions sets in some build configurations. - -#include "pch.h" -#include "config.h" - -#include "speck.h" -#include "misc.h" -#include "adv-simd.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 - -#if (CRYPTOPP_SSSE3_AVAILABLE) -# include -# include -#endif - -#if (CRYPTOPP_SSE41_AVAILABLE) -# include -#endif - -#if defined(__AVX512F__) && defined(__AVX512VL__) -# define CRYPTOPP_AVX512_ROTATE 1 -# include -#endif - -#if (CRYPTOPP_ARM_NEON_AVAILABLE) -# include -#endif - -// Can't use CRYPTOPP_ARM_XXX_AVAILABLE because too many -// compilers don't follow ACLE conventions for the include. -#if defined(CRYPTOPP_ARM_ACLE_AVAILABLE) -# include -# include -#endif - -// https://www.spinics.net/lists/gcchelp/msg47735.html and -// https://www.spinics.net/lists/gcchelp/msg47749.html -#if (CRYPTOPP_GCC_VERSION >= 40900) -# define GCC_NO_UBSAN __attribute__ ((no_sanitize_undefined)) -#else -# define GCC_NO_UBSAN -#endif - -ANONYMOUS_NAMESPACE_BEGIN - -using CryptoPP::byte; -using CryptoPP::word32; -using CryptoPP::word64; - -// *************************** ARM NEON ************************** // - -#if defined(CRYPTOPP_ARM_NEON_AVAILABLE) - -template -inline uint32x4_t RotateLeft32(const uint32x4_t& val) -{ - const uint32x4_t a(vshlq_n_u32(val, R)); - const uint32x4_t b(vshrq_n_u32(val, 32 - R)); - return vorrq_u32(a, b); -} - -template -inline uint32x4_t RotateRight32(const uint32x4_t& val) -{ - const uint32x4_t a(vshlq_n_u32(val, 32 - R)); - const uint32x4_t b(vshrq_n_u32(val, R)); - return vorrq_u32(a, b); -} - -#if defined(__aarch32__) || defined(__aarch64__) -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline uint32x4_t RotateLeft32<8>(const uint32x4_t& val) -{ -#if defined(CRYPTOPP_BIG_ENDIAN) - const uint8_t maskb[16] = { 14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3 }; - const uint8x16_t mask = vld1q_u8(maskb); -#else - const uint8_t maskb[16] = { 3,0,1,2, 7,4,5,6, 11,8,9,10, 15,12,13,14 }; - const uint8x16_t mask = vld1q_u8(maskb); -#endif - - return vreinterpretq_u32_u8( - vqtbl1q_u8(vreinterpretq_u8_u32(val), mask)); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline uint32x4_t RotateRight32<8>(const uint32x4_t& val) -{ -#if defined(CRYPTOPP_BIG_ENDIAN) - const uint8_t maskb[16] = { 12,15,14,13, 8,11,10,9, 4,7,6,5, 0,3,2,1 }; - const uint8x16_t mask = vld1q_u8(maskb); -#else - const uint8_t maskb[16] = { 1,2,3,0, 5,6,7,4, 9,10,11,8, 13,14,15,12 }; - const uint8x16_t mask = vld1q_u8(maskb); -#endif - - return vreinterpretq_u32_u8( - vqtbl1q_u8(vreinterpretq_u8_u32(val), mask)); -} -#endif // Aarch32 or Aarch64 - -inline uint32x4_t Shuffle32(const uint32x4_t& val) -{ -#if defined(CRYPTOPP_LITTLE_ENDIAN) - return vreinterpretq_u32_u8( - vrev32q_u8(vreinterpretq_u8_u32(val))); -#else - return val; -#endif -} - -inline void SPECK64_Enc_Block(uint32x4_t &block0, uint32x4_t &block1, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - uint32x4_t x1 = vuzpq_u32(block0, block1).val[0]; - uint32x4_t y1 = vuzpq_u32(block0, block1).val[1]; - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - - for (int i=0; i < static_cast(rounds); ++i) - { - const uint32x4_t rk = vdupq_n_u32(subkeys[i]); - - x1 = RotateRight32<8>(x1); - x1 = vaddq_u32(x1, y1); - x1 = veorq_u32(x1, rk); - y1 = RotateLeft32<3>(y1); - y1 = veorq_u32(y1, x1); - } - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = vzipq_u32(x1, y1).val[0]; - block1 = vzipq_u32(x1, y1).val[1]; -} - -inline void SPECK64_Dec_Block(uint32x4_t &block0, uint32x4_t &block1, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - uint32x4_t x1 = vuzpq_u32(block0, block1).val[0]; - uint32x4_t y1 = vuzpq_u32(block0, block1).val[1]; - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - - for (int i = static_cast(rounds-1); i >= 0; --i) - { - const uint32x4_t rk = vdupq_n_u32(subkeys[i]); - - y1 = veorq_u32(y1, x1); - y1 = RotateRight32<3>(y1); - x1 = veorq_u32(x1, rk); - x1 = vsubq_u32(x1, y1); - x1 = RotateLeft32<8>(x1); - } - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = vzipq_u32(x1, y1).val[0]; - block1 = vzipq_u32(x1, y1).val[1]; -} - -inline void SPECK64_Enc_6_Blocks(uint32x4_t &block0, uint32x4_t &block1, - uint32x4_t &block2, uint32x4_t &block3, uint32x4_t &block4, uint32x4_t &block5, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. If only a single block is available then - // a Zero block is provided to promote vectorizations. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - uint32x4_t x1 = vuzpq_u32(block0, block1).val[0]; - uint32x4_t y1 = vuzpq_u32(block0, block1).val[1]; - uint32x4_t x2 = vuzpq_u32(block2, block3).val[0]; - uint32x4_t y2 = vuzpq_u32(block2, block3).val[1]; - uint32x4_t x3 = vuzpq_u32(block4, block5).val[0]; - uint32x4_t y3 = vuzpq_u32(block4, block5).val[1]; - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - x2 = Shuffle32(x2); y2 = Shuffle32(y2); - x3 = Shuffle32(x3); y3 = Shuffle32(y3); - - for (int i=0; i < static_cast(rounds); ++i) - { - const uint32x4_t rk = vdupq_n_u32(subkeys[i]); - - x1 = RotateRight32<8>(x1); - x2 = RotateRight32<8>(x2); - x3 = RotateRight32<8>(x3); - x1 = vaddq_u32(x1, y1); - x2 = vaddq_u32(x2, y2); - x3 = vaddq_u32(x3, y3); - x1 = veorq_u32(x1, rk); - x2 = veorq_u32(x2, rk); - x3 = veorq_u32(x3, rk); - y1 = RotateLeft32<3>(y1); - y2 = RotateLeft32<3>(y2); - y3 = RotateLeft32<3>(y3); - y1 = veorq_u32(y1, x1); - y2 = veorq_u32(y2, x2); - y3 = veorq_u32(y3, x3); - } - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - x2 = Shuffle32(x2); y2 = Shuffle32(y2); - x3 = Shuffle32(x3); y3 = Shuffle32(y3); - - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = vzipq_u32(x1, y1).val[0]; - block1 = vzipq_u32(x1, y1).val[1]; - block2 = vzipq_u32(x2, y2).val[0]; - block3 = vzipq_u32(x2, y2).val[1]; - block4 = vzipq_u32(x3, y3).val[0]; - block5 = vzipq_u32(x3, y3).val[1]; -} - -inline void SPECK64_Dec_6_Blocks(uint32x4_t &block0, uint32x4_t &block1, - uint32x4_t &block2, uint32x4_t &block3, uint32x4_t &block4, uint32x4_t &block5, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. If only a single block is available then - // a Zero block is provided to promote vectorizations. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - uint32x4_t x1 = vuzpq_u32(block0, block1).val[0]; - uint32x4_t y1 = vuzpq_u32(block0, block1).val[1]; - uint32x4_t x2 = vuzpq_u32(block2, block3).val[0]; - uint32x4_t y2 = vuzpq_u32(block2, block3).val[1]; - uint32x4_t x3 = vuzpq_u32(block4, block5).val[0]; - uint32x4_t y3 = vuzpq_u32(block4, block5).val[1]; - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - x2 = Shuffle32(x2); y2 = Shuffle32(y2); - x3 = Shuffle32(x3); y3 = Shuffle32(y3); - - for (int i = static_cast(rounds-1); i >= 0; --i) - { - const uint32x4_t rk = vdupq_n_u32(subkeys[i]); - - y1 = veorq_u32(y1, x1); - y2 = veorq_u32(y2, x2); - y3 = veorq_u32(y3, x3); - y1 = RotateRight32<3>(y1); - y2 = RotateRight32<3>(y2); - y3 = RotateRight32<3>(y3); - x1 = veorq_u32(x1, rk); - x2 = veorq_u32(x2, rk); - x3 = veorq_u32(x3, rk); - x1 = vsubq_u32(x1, y1); - x2 = vsubq_u32(x2, y2); - x3 = vsubq_u32(x3, y3); - x1 = RotateLeft32<8>(x1); - x2 = RotateLeft32<8>(x2); - x3 = RotateLeft32<8>(x3); - } - - x1 = Shuffle32(x1); y1 = Shuffle32(y1); - x2 = Shuffle32(x2); y2 = Shuffle32(y2); - x3 = Shuffle32(x3); y3 = Shuffle32(y3); - - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = vzipq_u32(x1, y1).val[0]; - block1 = vzipq_u32(x1, y1).val[1]; - block2 = vzipq_u32(x2, y2).val[0]; - block3 = vzipq_u32(x2, y2).val[1]; - block4 = vzipq_u32(x3, y3).val[0]; - block5 = vzipq_u32(x3, y3).val[1]; -} - -#endif // CRYPTOPP_ARM_NEON_AVAILABLE - -#if defined(CRYPTOPP_ARM_NEON_AVAILABLE) - -template -inline T UnpackHigh64(const T& a, const T& b) -{ - const uint64x1_t x(vget_high_u64((uint64x2_t)a)); - const uint64x1_t y(vget_high_u64((uint64x2_t)b)); - return (T)vcombine_u64(x, y); -} - -template -inline T UnpackLow64(const T& a, const T& b) -{ - const uint64x1_t x(vget_low_u64((uint64x2_t)a)); - const uint64x1_t y(vget_low_u64((uint64x2_t)b)); - return (T)vcombine_u64(x, y); -} - -template -inline uint64x2_t RotateLeft64(const uint64x2_t& val) -{ - const uint64x2_t a(vshlq_n_u64(val, R)); - const uint64x2_t b(vshrq_n_u64(val, 64 - R)); - return vorrq_u64(a, b); -} - -template -inline uint64x2_t RotateRight64(const uint64x2_t& val) -{ - const uint64x2_t a(vshlq_n_u64(val, 64 - R)); - const uint64x2_t b(vshrq_n_u64(val, R)); - return vorrq_u64(a, b); -} - -#if defined(__aarch32__) || defined(__aarch64__) -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline uint64x2_t RotateLeft64<8>(const uint64x2_t& val) -{ -#if defined(CRYPTOPP_BIG_ENDIAN) - const uint8_t maskb[16] = { 14,13,12,11, 10,9,8,15, 6,5,4,3, 2,1,0,7 }; - const uint8x16_t mask = vld1q_u8(maskb); -#else - const uint8_t maskb[16] = { 7,0,1,2, 3,4,5,6, 15,8,9,10, 11,12,13,14 }; - const uint8x16_t mask = vld1q_u8(maskb); -#endif - - return vreinterpretq_u64_u8( - vqtbl1q_u8(vreinterpretq_u8_u64(val), mask)); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline uint64x2_t RotateRight64<8>(const uint64x2_t& val) -{ -#if defined(CRYPTOPP_BIG_ENDIAN) - const uint8_t maskb[16] = { 8,15,14,13, 12,11,10,9, 0,7,6,5, 4,3,2,1 }; - const uint8x16_t mask = vld1q_u8(maskb); -#else - const uint8_t maskb[16] = { 1,2,3,4, 5,6,7,0, 9,10,11,12, 13,14,15,8 }; - const uint8x16_t mask = vld1q_u8(maskb); -#endif - - return vreinterpretq_u64_u8( - vqtbl1q_u8(vreinterpretq_u8_u64(val), mask)); -} -#endif - -inline uint64x2_t Shuffle64(const uint64x2_t& val) -{ -#if defined(CRYPTOPP_LITTLE_ENDIAN) - return vreinterpretq_u64_u8( - vrev64q_u8(vreinterpretq_u8_u64(val))); -#else - return val; -#endif -} - -inline void SPECK128_Enc_Block(uint64x2_t &block0, uint64x2_t &block1, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - uint64x2_t x1 = UnpackLow64(block0, block1); - uint64x2_t y1 = UnpackHigh64(block0, block1); - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - - for (int i=0; i < static_cast(rounds); ++i) - { - const uint64x2_t rk = vld1q_dup_u64(subkeys+i); - - x1 = RotateRight64<8>(x1); - x1 = vaddq_u64(x1, y1); - x1 = veorq_u64(x1, rk); - y1 = RotateLeft64<3>(y1); - y1 = veorq_u64(y1, x1); - } - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = UnpackLow64(x1, y1); - block1 = UnpackHigh64(x1, y1); -} - -inline void SPECK128_Enc_6_Blocks(uint64x2_t &block0, uint64x2_t &block1, - uint64x2_t &block2, uint64x2_t &block3, uint64x2_t &block4, uint64x2_t &block5, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - uint64x2_t x1 = UnpackLow64(block0, block1); - uint64x2_t y1 = UnpackHigh64(block0, block1); - uint64x2_t x2 = UnpackLow64(block2, block3); - uint64x2_t y2 = UnpackHigh64(block2, block3); - uint64x2_t x3 = UnpackLow64(block4, block5); - uint64x2_t y3 = UnpackHigh64(block4, block5); - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - x2 = Shuffle64(x2); y2 = Shuffle64(y2); - x3 = Shuffle64(x3); y3 = Shuffle64(y3); - - for (int i=0; i < static_cast(rounds); ++i) - { - const uint64x2_t rk = vld1q_dup_u64(subkeys+i); - - x1 = RotateRight64<8>(x1); - x2 = RotateRight64<8>(x2); - x3 = RotateRight64<8>(x3); - x1 = vaddq_u64(x1, y1); - x2 = vaddq_u64(x2, y2); - x3 = vaddq_u64(x3, y3); - x1 = veorq_u64(x1, rk); - x2 = veorq_u64(x2, rk); - x3 = veorq_u64(x3, rk); - y1 = RotateLeft64<3>(y1); - y2 = RotateLeft64<3>(y2); - y3 = RotateLeft64<3>(y3); - y1 = veorq_u64(y1, x1); - y2 = veorq_u64(y2, x2); - y3 = veorq_u64(y3, x3); - } - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - x2 = Shuffle64(x2); y2 = Shuffle64(y2); - x3 = Shuffle64(x3); y3 = Shuffle64(y3); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = UnpackLow64(x1, y1); - block1 = UnpackHigh64(x1, y1); - block2 = UnpackLow64(x2, y2); - block3 = UnpackHigh64(x2, y2); - block4 = UnpackLow64(x3, y3); - block5 = UnpackHigh64(x3, y3); -} - -inline void SPECK128_Dec_Block(uint64x2_t &block0, uint64x2_t &block1, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - uint64x2_t x1 = UnpackLow64(block0, block1); - uint64x2_t y1 = UnpackHigh64(block0, block1); - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - - for (int i = static_cast(rounds-1); i >= 0; --i) - { - const uint64x2_t rk = vld1q_dup_u64(subkeys+i); - - y1 = veorq_u64(y1, x1); - y1 = RotateRight64<3>(y1); - x1 = veorq_u64(x1, rk); - x1 = vsubq_u64(x1, y1); - x1 = RotateLeft64<8>(x1); - } - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = UnpackLow64(x1, y1); - block1 = UnpackHigh64(x1, y1); -} - -inline void SPECK128_Dec_6_Blocks(uint64x2_t &block0, uint64x2_t &block1, - uint64x2_t &block2, uint64x2_t &block3, uint64x2_t &block4, uint64x2_t &block5, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - uint64x2_t x1 = UnpackLow64(block0, block1); - uint64x2_t y1 = UnpackHigh64(block0, block1); - uint64x2_t x2 = UnpackLow64(block2, block3); - uint64x2_t y2 = UnpackHigh64(block2, block3); - uint64x2_t x3 = UnpackLow64(block4, block5); - uint64x2_t y3 = UnpackHigh64(block4, block5); - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - x2 = Shuffle64(x2); y2 = Shuffle64(y2); - x3 = Shuffle64(x3); y3 = Shuffle64(y3); - - for (int i = static_cast(rounds-1); i >= 0; --i) - { - const uint64x2_t rk = vld1q_dup_u64(subkeys+i); - - y1 = veorq_u64(y1, x1); - y2 = veorq_u64(y2, x2); - y3 = veorq_u64(y3, x3); - y1 = RotateRight64<3>(y1); - y2 = RotateRight64<3>(y2); - y3 = RotateRight64<3>(y3); - x1 = veorq_u64(x1, rk); - x2 = veorq_u64(x2, rk); - x3 = veorq_u64(x3, rk); - x1 = vsubq_u64(x1, y1); - x2 = vsubq_u64(x2, y2); - x3 = vsubq_u64(x3, y3); - x1 = RotateLeft64<8>(x1); - x2 = RotateLeft64<8>(x2); - x3 = RotateLeft64<8>(x3); - } - - x1 = Shuffle64(x1); y1 = Shuffle64(y1); - x2 = Shuffle64(x2); y2 = Shuffle64(y2); - x3 = Shuffle64(x3); y3 = Shuffle64(y3); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = UnpackLow64(x1, y1); - block1 = UnpackHigh64(x1, y1); - block2 = UnpackLow64(x2, y2); - block3 = UnpackHigh64(x2, y2); - block4 = UnpackLow64(x3, y3); - block5 = UnpackHigh64(x3, y3); -} - -#endif // CRYPTOPP_ARM_NEON_AVAILABLE - -// ***************************** IA-32 ***************************** // - -#if defined(CRYPTOPP_SSSE3_AVAILABLE) - -// Clang __m128i casts, http://bugs.llvm.org/show_bug.cgi?id=20670 -#ifndef M128_CAST -# define M128_CAST(x) ((__m128i *)(void *)(x)) -#endif -#ifndef CONST_M128_CAST -# define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x)) -#endif - -// GCC double casts, https://www.spinics.net/lists/gcchelp/msg47735.html -#ifndef DOUBLE_CAST -# define DOUBLE_CAST(x) ((double *)(void *)(x)) -#endif -#ifndef CONST_DOUBLE_CAST -# define CONST_DOUBLE_CAST(x) ((const double *)(const void *)(x)) -#endif - -#if defined(CRYPTOPP_AVX512_ROTATE) -template -inline __m128i RotateLeft64(const __m128i& val) -{ - return _mm_rol_epi64(val, R); -} - -template -inline __m128i RotateRight64(const __m128i& val) -{ - return _mm_ror_epi64(val, R); -} -#else -template -inline __m128i RotateLeft64(const __m128i& val) -{ - return _mm_or_si128( - _mm_slli_epi64(val, R), _mm_srli_epi64(val, 64-R)); -} - -template -inline __m128i RotateRight64(const __m128i& val) -{ - return _mm_or_si128( - _mm_slli_epi64(val, 64-R), _mm_srli_epi64(val, R)); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline __m128i RotateLeft64<8>(const __m128i& val) -{ - const __m128i mask = _mm_set_epi8(14,13,12,11, 10,9,8,15, 6,5,4,3, 2,1,0,7); - return _mm_shuffle_epi8(val, mask); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline __m128i RotateRight64<8>(const __m128i& val) -{ - const __m128i mask = _mm_set_epi8(8,15,14,13, 12,11,10,9, 0,7,6,5, 4,3,2,1); - return _mm_shuffle_epi8(val, mask); -} - -#endif // CRYPTOPP_AVX512_ROTATE - -inline void GCC_NO_UBSAN SPECK128_Enc_Block(__m128i &block0, __m128i &block1, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - __m128i x1 = _mm_unpacklo_epi64(block0, block1); - __m128i y1 = _mm_unpackhi_epi64(block0, block1); - - const __m128i mask = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - for (int i=0; i < static_cast(rounds); ++i) - { - const __m128i rk = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i))); - - x1 = RotateRight64<8>(x1); - x1 = _mm_add_epi64(x1, y1); - x1 = _mm_xor_si128(x1, rk); - y1 = RotateLeft64<3>(y1); - y1 = _mm_xor_si128(y1, x1); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = _mm_unpacklo_epi64(x1, y1); - block1 = _mm_unpackhi_epi64(x1, y1); -} - -inline void GCC_NO_UBSAN SPECK128_Enc_6_Blocks(__m128i &block0, __m128i &block1, - __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - __m128i x1 = _mm_unpacklo_epi64(block0, block1); - __m128i y1 = _mm_unpackhi_epi64(block0, block1); - __m128i x2 = _mm_unpacklo_epi64(block2, block3); - __m128i y2 = _mm_unpackhi_epi64(block2, block3); - __m128i x3 = _mm_unpacklo_epi64(block4, block5); - __m128i y3 = _mm_unpackhi_epi64(block4, block5); - - const __m128i mask = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - for (int i=0; i < static_cast(rounds); ++i) - { - const __m128i rk = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i))); - - x1 = RotateRight64<8>(x1); - x2 = RotateRight64<8>(x2); - x3 = RotateRight64<8>(x3); - x1 = _mm_add_epi64(x1, y1); - x2 = _mm_add_epi64(x2, y2); - x3 = _mm_add_epi64(x3, y3); - x1 = _mm_xor_si128(x1, rk); - x2 = _mm_xor_si128(x2, rk); - x3 = _mm_xor_si128(x3, rk); - y1 = RotateLeft64<3>(y1); - y2 = RotateLeft64<3>(y2); - y3 = RotateLeft64<3>(y3); - y1 = _mm_xor_si128(y1, x1); - y2 = _mm_xor_si128(y2, x2); - y3 = _mm_xor_si128(y3, x3); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = _mm_unpacklo_epi64(x1, y1); - block1 = _mm_unpackhi_epi64(x1, y1); - block2 = _mm_unpacklo_epi64(x2, y2); - block3 = _mm_unpackhi_epi64(x2, y2); - block4 = _mm_unpacklo_epi64(x3, y3); - block5 = _mm_unpackhi_epi64(x3, y3); -} - -inline void GCC_NO_UBSAN SPECK128_Dec_Block(__m128i &block0, __m128i &block1, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - __m128i x1 = _mm_unpacklo_epi64(block0, block1); - __m128i y1 = _mm_unpackhi_epi64(block0, block1); - - const __m128i mask = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - for (int i = static_cast(rounds-1); i >= 0; --i) - { - const __m128i rk = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i))); - - y1 = _mm_xor_si128(y1, x1); - y1 = RotateRight64<3>(y1); - x1 = _mm_xor_si128(x1, rk); - x1 = _mm_sub_epi64(x1, y1); - x1 = RotateLeft64<8>(x1); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = _mm_unpacklo_epi64(x1, y1); - block1 = _mm_unpackhi_epi64(x1, y1); -} - -inline void GCC_NO_UBSAN SPECK128_Dec_6_Blocks(__m128i &block0, __m128i &block1, - __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, - const word64 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. - // [A1 A2][B1 B2] ... => [A1 B1][A2 B2] ... - __m128i x1 = _mm_unpacklo_epi64(block0, block1); - __m128i y1 = _mm_unpackhi_epi64(block0, block1); - __m128i x2 = _mm_unpacklo_epi64(block2, block3); - __m128i y2 = _mm_unpackhi_epi64(block2, block3); - __m128i x3 = _mm_unpacklo_epi64(block4, block5); - __m128i y3 = _mm_unpackhi_epi64(block4, block5); - - const __m128i mask = _mm_set_epi8(8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - for (int i = static_cast(rounds-1); i >= 0; --i) - { - const __m128i rk = _mm_castpd_si128( - _mm_loaddup_pd(CONST_DOUBLE_CAST(subkeys+i))); - - y1 = _mm_xor_si128(y1, x1); - y2 = _mm_xor_si128(y2, x2); - y3 = _mm_xor_si128(y3, x3); - y1 = RotateRight64<3>(y1); - y2 = RotateRight64<3>(y2); - y3 = RotateRight64<3>(y3); - x1 = _mm_xor_si128(x1, rk); - x2 = _mm_xor_si128(x2, rk); - x3 = _mm_xor_si128(x3, rk); - x1 = _mm_sub_epi64(x1, y1); - x2 = _mm_sub_epi64(x2, y2); - x3 = _mm_sub_epi64(x3, y3); - x1 = RotateLeft64<8>(x1); - x2 = RotateLeft64<8>(x2); - x3 = RotateLeft64<8>(x3); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - // [A1 B1][A2 B2] ... => [A1 A2][B1 B2] ... - block0 = _mm_unpacklo_epi64(x1, y1); - block1 = _mm_unpackhi_epi64(x1, y1); - block2 = _mm_unpacklo_epi64(x2, y2); - block3 = _mm_unpackhi_epi64(x2, y2); - block4 = _mm_unpacklo_epi64(x3, y3); - block5 = _mm_unpackhi_epi64(x3, y3); -} - -#endif // CRYPTOPP_SSSE3_AVAILABLE - -#if defined(CRYPTOPP_SSE41_AVAILABLE) - -template -inline __m128i RotateLeft32(const __m128i& val) -{ - return _mm_or_si128( - _mm_slli_epi32(val, R), _mm_srli_epi32(val, 32-R)); -} - -template -inline __m128i RotateRight32(const __m128i& val) -{ - return _mm_or_si128( - _mm_slli_epi32(val, 32-R), _mm_srli_epi32(val, R)); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline __m128i RotateLeft32<8>(const __m128i& val) -{ - const __m128i mask = _mm_set_epi8(14,13,12,15, 10,9,8,11, 6,5,4,7, 2,1,0,3); - return _mm_shuffle_epi8(val, mask); -} - -// Faster than two Shifts and an Or. Thanks to Louis Wingers and Bryan Weeks. -template <> -inline __m128i RotateRight32<8>(const __m128i& val) -{ - const __m128i mask = _mm_set_epi8(12,15,14,13, 8,11,10,9, 4,7,6,5, 0,3,2,1); - return _mm_shuffle_epi8(val, mask); -} - -inline void GCC_NO_UBSAN SPECK64_Enc_Block(__m128i &block0, __m128i &block1, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. Thanks to Peter Cordes for help with the - // SSE permutes below. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - const __m128 t0 = _mm_castsi128_ps(block0); - const __m128 t1 = _mm_castsi128_ps(block1); - __m128i x1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(2,0,2,0))); - __m128i y1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(3,1,3,1))); - - const __m128i mask = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - for (int i=0; i < static_cast(rounds); ++i) - { - const __m128i rk = _mm_set1_epi32(subkeys[i]); - - x1 = RotateRight32<8>(x1); - x1 = _mm_add_epi32(x1, y1); - x1 = _mm_xor_si128(x1, rk); - y1 = RotateLeft32<3>(y1); - y1 = _mm_xor_si128(y1, x1); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - // The is roughly the SSE equivalent to ARM vzp32 - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = _mm_unpacklo_epi32(x1, y1); - block1 = _mm_unpackhi_epi32(x1, y1); -} - -inline void GCC_NO_UBSAN SPECK64_Dec_Block(__m128i &block0, __m128i &block1, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. Thanks to Peter Cordes for help with the - // SSE permutes below. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - const __m128 t0 = _mm_castsi128_ps(block0); - const __m128 t1 = _mm_castsi128_ps(block1); - __m128i x1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(2,0,2,0))); - __m128i y1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(3,1,3,1))); - - const __m128i mask = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - for (int i = static_cast(rounds-1); i >= 0; --i) - { - const __m128i rk = _mm_set1_epi32(subkeys[i]); - - y1 = _mm_xor_si128(y1, x1); - y1 = RotateRight32<3>(y1); - x1 = _mm_xor_si128(x1, rk); - x1 = _mm_sub_epi32(x1, y1); - x1 = RotateLeft32<8>(x1); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - - // The is roughly the SSE equivalent to ARM vzp32 - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = _mm_unpacklo_epi32(x1, y1); - block1 = _mm_unpackhi_epi32(x1, y1); -} - -inline void GCC_NO_UBSAN SPECK64_Enc_6_Blocks(__m128i &block0, __m128i &block1, - __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. Thanks to Peter Cordes for help with the - // SSE permutes below. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - const __m128 t0 = _mm_castsi128_ps(block0); - const __m128 t1 = _mm_castsi128_ps(block1); - __m128i x1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(2,0,2,0))); - __m128i y1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(3,1,3,1))); - - const __m128 t2 = _mm_castsi128_ps(block2); - const __m128 t3 = _mm_castsi128_ps(block3); - __m128i x2 = _mm_castps_si128(_mm_shuffle_ps(t2, t3, _MM_SHUFFLE(2,0,2,0))); - __m128i y2 = _mm_castps_si128(_mm_shuffle_ps(t2, t3, _MM_SHUFFLE(3,1,3,1))); - - const __m128 t4 = _mm_castsi128_ps(block4); - const __m128 t5 = _mm_castsi128_ps(block5); - __m128i x3 = _mm_castps_si128(_mm_shuffle_ps(t4, t5, _MM_SHUFFLE(2,0,2,0))); - __m128i y3 = _mm_castps_si128(_mm_shuffle_ps(t4, t5, _MM_SHUFFLE(3,1,3,1))); - - const __m128i mask = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - for (int i=0; i < static_cast(rounds); ++i) - { - const __m128i rk = _mm_set1_epi32(subkeys[i]); - - x1 = RotateRight32<8>(x1); - x2 = RotateRight32<8>(x2); - x3 = RotateRight32<8>(x3); - x1 = _mm_add_epi32(x1, y1); - x2 = _mm_add_epi32(x2, y2); - x3 = _mm_add_epi32(x3, y3); - x1 = _mm_xor_si128(x1, rk); - x2 = _mm_xor_si128(x2, rk); - x3 = _mm_xor_si128(x3, rk); - y1 = RotateLeft32<3>(y1); - y2 = RotateLeft32<3>(y2); - y3 = RotateLeft32<3>(y3); - y1 = _mm_xor_si128(y1, x1); - y2 = _mm_xor_si128(y2, x2); - y3 = _mm_xor_si128(y3, x3); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - // The is roughly the SSE equivalent to ARM vzp32 - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = _mm_unpacklo_epi32(x1, y1); - block1 = _mm_unpackhi_epi32(x1, y1); - block2 = _mm_unpacklo_epi32(x2, y2); - block3 = _mm_unpackhi_epi32(x2, y2); - block4 = _mm_unpacklo_epi32(x3, y3); - block5 = _mm_unpackhi_epi32(x3, y3); -} - -inline void GCC_NO_UBSAN SPECK64_Dec_6_Blocks(__m128i &block0, __m128i &block1, - __m128i &block2, __m128i &block3, __m128i &block4, __m128i &block5, - const word32 *subkeys, unsigned int rounds) -{ - // Rearrange the data for vectorization. The incoming data was read from - // a big-endian byte array. Depending on the number of blocks it needs to - // be permuted to the following. Thanks to Peter Cordes for help with the - // SSE permutes below. - // [A1 A2 A3 A4][B1 B2 B3 B4] ... => [A1 A3 B1 B3][A2 A4 B2 B4] ... - const __m128 t0 = _mm_castsi128_ps(block0); - const __m128 t1 = _mm_castsi128_ps(block1); - __m128i x1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(2,0,2,0))); - __m128i y1 = _mm_castps_si128(_mm_shuffle_ps(t0, t1, _MM_SHUFFLE(3,1,3,1))); - - const __m128 t2 = _mm_castsi128_ps(block2); - const __m128 t3 = _mm_castsi128_ps(block3); - __m128i x2 = _mm_castps_si128(_mm_shuffle_ps(t2, t3, _MM_SHUFFLE(2,0,2,0))); - __m128i y2 = _mm_castps_si128(_mm_shuffle_ps(t2, t3, _MM_SHUFFLE(3,1,3,1))); - - const __m128 t4 = _mm_castsi128_ps(block4); - const __m128 t5 = _mm_castsi128_ps(block5); - __m128i x3 = _mm_castps_si128(_mm_shuffle_ps(t4, t5, _MM_SHUFFLE(2,0,2,0))); - __m128i y3 = _mm_castps_si128(_mm_shuffle_ps(t4, t5, _MM_SHUFFLE(3,1,3,1))); - - const __m128i mask = _mm_set_epi8(12,13,14,15, 8,9,10,11, 4,5,6,7, 0,1,2,3); - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - for (int i = static_cast(rounds-1); i >= 0; --i) - { - const __m128i rk = _mm_set1_epi32(subkeys[i]); - - y1 = _mm_xor_si128(y1, x1); - y2 = _mm_xor_si128(y2, x2); - y3 = _mm_xor_si128(y3, x3); - y1 = RotateRight32<3>(y1); - y2 = RotateRight32<3>(y2); - y3 = RotateRight32<3>(y3); - x1 = _mm_xor_si128(x1, rk); - x2 = _mm_xor_si128(x2, rk); - x3 = _mm_xor_si128(x3, rk); - x1 = _mm_sub_epi32(x1, y1); - x2 = _mm_sub_epi32(x2, y2); - x3 = _mm_sub_epi32(x3, y3); - x1 = RotateLeft32<8>(x1); - x2 = RotateLeft32<8>(x2); - x3 = RotateLeft32<8>(x3); - } - - x1 = _mm_shuffle_epi8(x1, mask); - y1 = _mm_shuffle_epi8(y1, mask); - x2 = _mm_shuffle_epi8(x2, mask); - y2 = _mm_shuffle_epi8(y2, mask); - x3 = _mm_shuffle_epi8(x3, mask); - y3 = _mm_shuffle_epi8(y3, mask); - - // The is roughly the SSE equivalent to ARM vzp32 - // [A1 A3 B1 B3][A2 A4 B2 B4] => [A1 A2 A3 A4][B1 B2 B3 B4] - block0 = _mm_unpacklo_epi32(x1, y1); - block1 = _mm_unpackhi_epi32(x1, y1); - block2 = _mm_unpacklo_epi32(x2, y2); - block3 = _mm_unpackhi_epi32(x2, y2); - block4 = _mm_unpacklo_epi32(x3, y3); - block5 = _mm_unpackhi_epi32(x3, y3); -} - -#endif // CRYPTOPP_SSE41_AVAILABLE - -ANONYMOUS_NAMESPACE_END - -/////////////////////////////////////////////////////////////////////// - -NAMESPACE_BEGIN(CryptoPP) - -// *************************** ARM NEON **************************** // - -#if defined(CRYPTOPP_ARM_NEON_AVAILABLE) -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) -{ - return AdvancedProcessBlocks64_6x2_NEON(SPECK64_Enc_Block, SPECK64_Enc_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} - -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) -{ - return AdvancedProcessBlocks64_6x2_NEON(SPECK64_Dec_Block, SPECK64_Dec_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} -#endif - -#if (CRYPTOPP_ARM_NEON_AVAILABLE) -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) -{ - return AdvancedProcessBlocks128_6x2_NEON(SPECK128_Enc_Block, SPECK128_Enc_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} - -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) -{ - return AdvancedProcessBlocks128_6x2_NEON(SPECK128_Dec_Block, SPECK128_Dec_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} -#endif // CRYPTOPP_ARM_NEON_AVAILABLE - -// ***************************** IA-32 ***************************** // - -#if defined(CRYPTOPP_SSE41_AVAILABLE) -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) -{ - return AdvancedProcessBlocks64_6x2_SSE(SPECK64_Enc_Block, SPECK64_Enc_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} - -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) -{ - return AdvancedProcessBlocks64_6x2_SSE(SPECK64_Dec_Block, SPECK64_Dec_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} -#endif - -#if defined(CRYPTOPP_SSSE3_AVAILABLE) -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) -{ - return AdvancedProcessBlocks128_6x2_SSE(SPECK128_Enc_Block, SPECK128_Enc_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} - -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) -{ - return AdvancedProcessBlocks128_6x2_SSE(SPECK128_Dec_Block, SPECK128_Dec_6_Blocks, - subKeys, rounds, inBlocks, xorBlocks, outBlocks, length, flags); -} -#endif // CRYPTOPP_SSSE3_AVAILABLE - -NAMESPACE_END diff --git a/speck.cpp b/speck.cpp deleted file mode 100644 index 63aa4f4f..00000000 --- a/speck.cpp +++ /dev/null @@ -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 -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 -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 -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(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 -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(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 -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 -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 -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(m_rkeys, m_wspace); - break; - case 4: - m_rkeys.New(27); - m_rounds = 27; - SPECK_ExpandKey_4W(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 InBlock; - InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]); - - switch (m_rounds) - { - case 26: - SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 27: - SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - default: - CRYPTOPP_ASSERT(0);; - } - - // Reverse bytes on LittleEndian; align pointer on BigEndian - typedef PutBlock 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 InBlock; - InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]); - - switch (m_rounds) - { - case 26: - SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 27: - SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - default: - CRYPTOPP_ASSERT(0);; - } - - // Reverse bytes on LittleEndian; align pointer on BigEndian - typedef PutBlock 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(m_rkeys, m_wspace); - break; - case 3: - m_rkeys.New(33); - m_rounds = 33; - SPECK_ExpandKey_3W(m_rkeys, m_wspace); - break; - case 4: - m_rkeys.New(34); - m_rounds = 34; - SPECK_ExpandKey_4W(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 InBlock; - InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]); - - switch (m_rounds) - { - case 32: - SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 33: - SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 34: - SPECK_Encrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - default: - CRYPTOPP_ASSERT(0);; - } - - // Reverse bytes on LittleEndian; align pointer on BigEndian - typedef PutBlock 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 InBlock; - InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1]); - - switch (m_rounds) - { - case 32: - SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 33: - SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - case 34: - SPECK_Decrypt(m_wspace+2, m_wspace+0, m_rkeys); - break; - default: - CRYPTOPP_ASSERT(0);; - } - - // Reverse bytes on LittleEndian; align pointer on BigEndian - typedef PutBlock 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 diff --git a/speck.h b/speck.h deleted file mode 100644 index 88f87d3b..00000000 --- a/speck.h +++ /dev/null @@ -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 The SIMON and SPECK Families of -/// Lightweight Block Ciphers and -/// The Simon and Speck GitHub -/// \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 -struct SPECK_Info : public FixedBlockSize, VariableKeyLength -{ - 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, SPECK -/// \since Crypto++ 6.0 -template -struct SPECK_Base -{ - virtual ~SPECK_Base() {} - SPECK_Base() : m_kwords(0), m_rounds(0) {} - - typedef SecBlock > 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, The SIMON and SPECK -/// Families of Lightweight Block Ciphers, -/// The Simon and Speck GitHub, SPECK 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, public BlockCipherImpl > - { - 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; - typedef BlockCipherFinal 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, The SIMON and SPECK -/// Families of Lightweight Block Ciphers, -/// The Simon and Speck GitHub, SPECK 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, public BlockCipherImpl > - { - 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; - typedef BlockCipherFinal Decryption; -}; - -NAMESPACE_END - -#endif // CRYPTOPP_SPECK_H diff --git a/validat1.cpp b/validat1.cpp index b3abc879..24df631b 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -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;