diff --git a/Filelist.txt b/Filelist.txt index 4b82562c..0a59f47d 100644 --- a/Filelist.txt +++ b/Filelist.txt @@ -277,6 +277,8 @@ simon.cpp simon.h skipjack.cpp skipjack.h +sm3.cpp +sm3.h sm4.cpp sm4.h smartptr.h @@ -463,6 +465,7 @@ 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 diff --git a/TestVectors/all.txt b/TestVectors/all.txt index 1581bd95..5bbdda4f 100644 --- a/TestVectors/all.txt +++ b/TestVectors/all.txt @@ -24,6 +24,7 @@ Test: TestVectors/sha1_fips_180.txt Test: TestVectors/sha2_fips_180.txt Test: TestVectors/sha3_fips_202.txt Test: TestVectors/panama.txt +Test: TestVectors/sm3.txt Test: TestVectors/aes.txt Test: TestVectors/aria.txt Test: TestVectors/kalyna.txt diff --git a/TestVectors/sm3.txt b/TestVectors/sm3.txt new file mode 100644 index 00000000..227a0486 --- /dev/null +++ b/TestVectors/sm3.txt @@ -0,0 +1,19 @@ +AlgorithmType: MessageDigest +Name: SM3 +# +Source: SM3 Hash function, https://tools.ietf.org/html/draft-shen-sm3-hash +Comment: Appendix B, test vector 1 +Message: 616263 +Digest: 66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0 +Test: Verify +Digest: 00000000 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0 +Test: NotVerify +# +Source: SM3 Hash function, https://tools.ietf.org/html/draft-shen-sm3-hash +Comment: Appendix B, test vector 1 +Message: 61626364 61626364 61626364 61626364 61626364 61626364 61626364 61626364 \ + 61626364 61626364 61626364 61626364 61626364 61626364 61626364 61626364 +Digest: debe9ff9 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732 +Test: Verify +Digest: 00000000 2275b8a1 38604889 c18e5a4d 6fdb70e5 387e5765 293dcba3 9c0c5732 +Test: NotVerify \ No newline at end of file diff --git a/bench1.cpp b/bench1.cpp index 99244a80..510cd81c 100644 --- a/bench1.cpp +++ b/bench1.cpp @@ -471,20 +471,21 @@ void Benchmark1(double t, double hertz) BenchMarkByNameKeyLess("SHA-1"); BenchMarkByNameKeyLess("SHA-256"); BenchMarkByNameKeyLess("SHA-512"); - BenchMarkByNameKeyLess("Keccak-224"); - BenchMarkByNameKeyLess("Keccak-256"); - BenchMarkByNameKeyLess("Keccak-384"); - BenchMarkByNameKeyLess("Keccak-512"); BenchMarkByNameKeyLess("SHA3-224"); BenchMarkByNameKeyLess("SHA3-256"); BenchMarkByNameKeyLess("SHA3-384"); BenchMarkByNameKeyLess("SHA3-512"); + BenchMarkByNameKeyLess("Keccak-224"); + BenchMarkByNameKeyLess("Keccak-256"); + BenchMarkByNameKeyLess("Keccak-384"); + BenchMarkByNameKeyLess("Keccak-512"); BenchMarkByNameKeyLess("Tiger"); BenchMarkByNameKeyLess("Whirlpool"); BenchMarkByNameKeyLess("RIPEMD-160"); BenchMarkByNameKeyLess("RIPEMD-320"); BenchMarkByNameKeyLess("RIPEMD-128"); BenchMarkByNameKeyLess("RIPEMD-256"); + BenchMarkByNameKeyLess("SM3"); BenchMarkByNameKeyLess("BLAKE2s"); BenchMarkByNameKeyLess("BLAKE2b"); } diff --git a/cryptest.nmake b/cryptest.nmake index 411a3ffa..c1ff63ec 100644 --- a/cryptest.nmake +++ b/cryptest.nmake @@ -47,9 +47,9 @@ # If you use 'make sources' from Linux makefile, then add 'winpipes.cpp' to the list below. -LIB_SRCS = cryptlib.cpp cpu.cpp integer.cpp 3way.cpp adler32.cpp algebra.cpp algparam.cpp arc4.cpp aria-simd.cpp aria.cpp ariatab.cpp asn.cpp authenc.cpp base32.cpp base64.cpp basecode.cpp bfinit.cpp blake2-simd.cpp blake2.cpp blowfish.cpp blumshub.cpp camellia.cpp cast.cpp casts.cpp cbcmac.cpp ccm.cpp chacha.cpp channels.cpp cmac.cpp crc-simd.cpp crc.cpp default.cpp des.cpp dessp.cpp dh.cpp dh2.cpp dll.cpp dsa.cpp eax.cpp ec2n.cpp eccrypto.cpp ecp.cpp elgamal.cpp emsa2.cpp eprecomp.cpp esign.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp gcm-simd.cpp gcm.cpp gf256.cpp gf2_32.cpp gf2n.cpp gfpcrypt.cpp gost.cpp gzip.cpp hex.cpp hmac.cpp hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp keccak.cpp luc.cpp mars.cpp marss.cpp md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp nbtheory.cpp neon-simd.cpp network.cpp oaep.cpp osrng.cpp padlkrng.cpp panama.cpp pkcspad.cpp poly1305.cpp polynomi.cpp pssr.cpp pubkey.cpp queue.cpp rabin.cpp randpool.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp rijndael-simd.cpp rijndael.cpp ripemd.cpp rng.cpp rsa.cpp rw.cpp safer.cpp salsa.cpp seal.cpp seed.cpp serpent.cpp sha-simd.cpp sha.cpp sha3.cpp shacal2-simd.cpp shacal2.cpp shark.cpp sharkbox.cpp simon.cpp skipjack.cpp socketft.cpp sosemanuk.cpp speck.cpp speck-simd.cpp square.cpp squaretb.cpp sse-simd.cpp strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp tigertab.cpp trdlocal.cpp ttmac.cpp twofish.cpp vmac.cpp wait.cpp wake.cpp whrlpool.cpp winpipes.cpp xtr.cpp xtrcrypt.cpp zdeflate.cpp zinflate.cpp zlib.cpp +LIB_SRCS = cryptlib.cpp cpu.cpp integer.cpp 3way.cpp adler32.cpp algebra.cpp algparam.cpp arc4.cpp aria-simd.cpp aria.cpp ariatab.cpp asn.cpp authenc.cpp base32.cpp base64.cpp basecode.cpp bfinit.cpp blake2-simd.cpp blake2.cpp blowfish.cpp blumshub.cpp camellia.cpp cast.cpp casts.cpp cbcmac.cpp ccm.cpp chacha.cpp channels.cpp cmac.cpp crc-simd.cpp crc.cpp default.cpp des.cpp dessp.cpp dh.cpp dh2.cpp dll.cpp dsa.cpp eax.cpp ec2n.cpp eccrypto.cpp ecp.cpp elgamal.cpp emsa2.cpp eprecomp.cpp esign.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp gcm-simd.cpp gcm.cpp gf256.cpp gf2_32.cpp gf2n.cpp gfpcrypt.cpp gost.cpp gzip.cpp hex.cpp hmac.cpp hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp keccak.cpp luc.cpp mars.cpp marss.cpp md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp nbtheory.cpp neon-simd.cpp network.cpp oaep.cpp osrng.cpp padlkrng.cpp panama.cpp pkcspad.cpp poly1305.cpp polynomi.cpp pssr.cpp pubkey.cpp queue.cpp rabin.cpp randpool.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp rijndael-simd.cpp rijndael.cpp ripemd.cpp rng.cpp rsa.cpp rw.cpp safer.cpp salsa.cpp seal.cpp seed.cpp serpent.cpp sha-simd.cpp sha.cpp sha3.cpp shacal2-simd.cpp shacal2.cpp shark.cpp sharkbox.cpp simon.cpp skipjack.cpp sm3.cpp sm4.cpp socketft.cpp sosemanuk.cpp speck.cpp speck-simd.cpp square.cpp squaretb.cpp sse-simd.cpp strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp tigertab.cpp trdlocal.cpp ttmac.cpp twofish.cpp vmac.cpp wait.cpp wake.cpp whrlpool.cpp winpipes.cpp xtr.cpp xtrcrypt.cpp zdeflate.cpp zinflate.cpp zlib.cpp -LIB_OBJS = cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj algparam.obj arc4.obj aria-simd.obj aria.obj ariatab.obj asn.obj authenc.obj base32.obj base64.obj basecode.obj bfinit.obj blake2-simd.obj blake2.obj blowfish.obj blumshub.obj camellia.obj cast.obj casts.obj cbcmac.obj ccm.obj chacha.obj channels.obj cmac.obj crc-simd.obj crc.obj default.obj des.obj dessp.obj dh.obj dh2.obj dll.obj dsa.obj eax.obj ec2n.obj eccrypto.obj ecp.obj elgamal.obj emsa2.obj eprecomp.obj esign.obj files.obj filters.obj fips140.obj fipstest.obj gcm-simd.obj gcm.obj gf256.obj gf2_32.obj gf2n.obj gfpcrypt.obj gost.obj gzip.obj hex.obj hmac.obj hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj kalynatab.obj keccak.obj luc.obj mars.obj marss.obj md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj mqv.obj nbtheory.obj neon-simd.obj network.obj oaep.obj osrng.obj padlkrng.obj panama.obj pkcspad.obj poly1305.obj polynomi.obj pssr.obj pubkey.obj queue.obj rabin.obj randpool.obj rc2.obj rc5.obj rc6.obj rdrand.obj rdtables.obj rijndael-simd.obj rijndael.obj ripemd.obj rng.obj rsa.obj rw.obj safer.obj salsa.obj seal.obj seed.obj serpent.obj sha-simd.obj sha.obj sha3.obj shacal2-simd.obj shacal2.obj shark.obj sharkbox.obj simon.obj skipjack.obj socketft.obj sosemanuk.obj speck.obj speck-simd.obj square.obj squaretb.obj sse-simd.obj strciphr.obj tea.obj tftables.obj threefish.obj tiger.obj tigertab.obj trdlocal.obj ttmac.obj twofish.obj vmac.obj wait.obj wake.obj whrlpool.obj winpipes.obj xtr.obj xtrcrypt.obj zdeflate.obj zinflate.obj zlib.obj +LIB_OBJS = cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj algparam.obj arc4.obj aria-simd.obj aria.obj ariatab.obj asn.obj authenc.obj base32.obj base64.obj basecode.obj bfinit.obj blake2-simd.obj blake2.obj blowfish.obj blumshub.obj camellia.obj cast.obj casts.obj cbcmac.obj ccm.obj chacha.obj channels.obj cmac.obj crc-simd.obj crc.obj default.obj des.obj dessp.obj dh.obj dh2.obj dll.obj dsa.obj eax.obj ec2n.obj eccrypto.obj ecp.obj elgamal.obj emsa2.obj eprecomp.obj esign.obj files.obj filters.obj fips140.obj fipstest.obj gcm-simd.obj gcm.obj gf256.obj gf2_32.obj gf2n.obj gfpcrypt.obj gost.obj gzip.obj hex.obj hmac.obj hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj kalynatab.obj keccak.obj luc.obj mars.obj marss.obj md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj mqv.obj nbtheory.obj neon-simd.obj network.obj oaep.obj osrng.obj padlkrng.obj panama.obj pkcspad.obj poly1305.obj polynomi.obj pssr.obj pubkey.obj queue.obj rabin.obj randpool.obj rc2.obj rc5.obj rc6.obj rdrand.obj rdtables.obj rijndael-simd.obj rijndael.obj ripemd.obj rng.obj rsa.obj rw.obj safer.obj salsa.obj seal.obj seed.obj serpent.obj sha-simd.obj sha.obj sha3.obj shacal2-simd.obj shacal2.obj shark.obj sharkbox.obj simon.obj skipjack.obj sm3.obj sm4.obj socketft.obj sosemanuk.obj speck.obj speck-simd.obj square.obj squaretb.obj sse-simd.obj strciphr.obj tea.obj tftables.obj threefish.obj tiger.obj tigertab.obj trdlocal.obj ttmac.obj twofish.obj vmac.obj wait.obj wake.obj whrlpool.obj winpipes.obj xtr.obj xtrcrypt.obj zdeflate.obj zinflate.obj zlib.obj TEST_SRCS = bench1.cpp bench2.cpp test.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp fipsalgt.cpp dlltest.cpp fipstest.cpp diff --git a/cryptest.vcxproj b/cryptest.vcxproj index 3b4d5080..40078795 100644 --- a/cryptest.vcxproj +++ b/cryptest.vcxproj @@ -258,6 +258,7 @@ + diff --git a/cryptest.vcxproj.filters b/cryptest.vcxproj.filters index 9fced422..894c4ce5 100644 --- a/cryptest.vcxproj.filters +++ b/cryptest.vcxproj.filters @@ -1,20 +1,25 @@ - - {2e247f14-f75a-4e15-9804-dccce165306f} - .txt + + {1f4eac20-7b40-40db-a264-4a9256229c5a} + .h;.hpp {4c6077b5-a2d6-498c-bc42-10af523a06cb} - .cpp;.h + .cpp {a634d4f4-ddc0-44b4-9c37-d9ffdddc7b06} .dat - - {1f4eac20-7b40-40db-a264-4a9256229c5a} + + {2e247f14-f75a-4e15-9804-dccce165306f} + .txt + + + {5e447502-2b0f-49c8-9df5-56ea9e7a8fbd} + .proto @@ -129,6 +134,9 @@ TestVectors + + TestVectors + TestVectors diff --git a/cryptlib.vcxproj b/cryptlib.vcxproj index 6d1811cd..ccdb3c2c 100644 --- a/cryptlib.vcxproj +++ b/cryptlib.vcxproj @@ -291,6 +291,7 @@ + @@ -476,6 +477,7 @@ + diff --git a/cryptlib.vcxproj.filters b/cryptlib.vcxproj.filters index ff86bced..ad4ac081 100644 --- a/cryptlib.vcxproj.filters +++ b/cryptlib.vcxproj.filters @@ -1,14 +1,14 @@ + + {1e9e61cf-0e3c-4b79-955f-9f077eabdb3e} + .h;.hpp + {0465ef4f-be03-463e-81e5-5a399f32620f} .cpp - - {1e9e61cf-0e3c-4b79-955f-9f077eabdb3e} - .;.h - {5e447502-2b0f-49c8-9df5-45ea9e7fcfbd} @@ -368,6 +368,9 @@ Source Files + + Source Files + Source Files @@ -825,6 +828,9 @@ Header Files + + Header Files + Header Files @@ -911,17 +917,11 @@ - - Source Files - Source Files - - Source Files - - - Source Files + + Miscellaneous \ No newline at end of file diff --git a/regtest1.cpp b/regtest1.cpp index a8fdc9ef..3daa810e 100644 --- a/regtest1.cpp +++ b/regtest1.cpp @@ -16,6 +16,8 @@ #include "sha3.h" #include "blake2.h" #include "sha.h" +#include "sha3.h" +#include "sm3.h" #include "tiger.h" #include "ripemd.h" #include "panama.h" @@ -96,6 +98,7 @@ void RegisterFactories1() RegisterDefaultFactoryFor(); RegisterDefaultFactoryFor(); RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); RegisterDefaultFactoryFor(); RegisterDefaultFactoryFor(); diff --git a/sm3.cpp b/sm3.cpp new file mode 100644 index 00000000..12e18cb0 --- /dev/null +++ b/sm3.cpp @@ -0,0 +1,254 @@ +// sm3.cpp - written and placed in the public domain by Jeffrey Walton and Han Lulu +// Based on the specification provided by Sean Shen and Xiaodong Lee. +// Based on code by Krzysztof Kwiatkowski and Jack Lloyd. +// Also see https://tools.ietf.org/html/draft-shen-sm3-hash. + +#include "pch.h" +#include "config.h" + +#include "sm3.h" +#include "misc.h" +#include "cpu.h" + +ANONYMOUS_NAMESPACE_BEGIN + +using CryptoPP::byte; +using CryptoPP::word32; +using CryptoPP::rotlFixed; + +using CryptoPP::SM3; +using CryptoPP::GetBlock; +using CryptoPP::BigEndian; + +inline word32 P0(word32 X) +{ + return X ^ rotlFixed(X, 9) ^ rotlFixed(X, 17); +} + +inline word32 FF1(word32 X, word32 Y, word32 Z) +{ + return (X & Y) | ((X | Y) & Z); +} + +inline word32 GG1(word32 X, word32 Y, word32 Z) +{ + return ((Z ^ (X & (Y ^ Z)))); +} + +inline void R1(word32 A, word32& B, word32 C, word32& D, word32 E, word32& F, + word32 G, word32& H, word32 TJ, word32 Wi, word32 Wj) +{ + const word32 A12 = rotlFixed(A, 12); + const word32 SS1 = rotlFixed(A12 + E + TJ, 7); + const word32 TT1 = (A ^ B ^ C) + D + (SS1 ^ A12) + Wj; + const word32 TT2 = (E ^ F ^ G) + H + SS1 + Wi; + + B = rotlFixed(B, 9); + D = TT1; + F= rotlFixed(F, 19); + H = P0(TT2); +} + +inline void R2(word32 A, word32& B, word32 C, word32& D, word32 E, word32& F, + word32 G, word32& H, word32 TJ, word32 Wi, word32 Wj) +{ + const word32 A12 = rotlFixed(A, 12); + const word32 SS1 = rotlFixed(A12 + E + TJ, 7); + const word32 TT1 = FF1(A, B, C) + D + (SS1 ^ A12) + Wj; + const word32 TT2 = GG1(E, F, G) + H + SS1 + Wi; + + B = rotlFixed(B, 9); + D = TT1; + F = rotlFixed(F, 19); + H = P0(TT2); +} + +inline word32 P1(word32 X) +{ + return X ^ rotlFixed(X, 15) ^ rotlFixed(X, 23); +} + +inline word32 SM3_E(word32 W0, word32 W7, word32 W13, word32 W3, word32 W10) +{ + return P1(W0 ^ W7 ^ rotlFixed(W13, 15)) ^ rotlFixed(W3, 7) ^ W10; +} + +static size_t SM3_HashMultipleBlocks_CXX(word32 *state, const word32 *input, size_t length) +{ + CRYPTOPP_ASSERT(input); + + word32 A = state[0], B = state[1], C = state[2], D = state[3]; + word32 E = state[4], F = state[5], G = state[6], H = state[7]; + + size_t blocks = length / SM3::BLOCKSIZE; + for(size_t i = 0; i < blocks; ++i) + { + // Reverse bytes on LittleEndian; align pointer on BigEndian + typedef GetBlock InBlock; + InBlock iblk(input); + + word32 W00, W01, W02, W03, W04, W05, W06, W07, W08, W09, W10, W11, W12, W13, W14, W15; + iblk(W00)(W01)(W02)(W03)(W04)(W05)(W06)(W07)(W08)(W09)(W10)(W11)(W12)(W13)(W14)(W15); + + R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04); + W00 = SM3_E(W00, W07, W13, W03, W10); + R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05); + W01 = SM3_E(W01, W08, W14, W04, W11); + R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06); + W02 = SM3_E(W02, W09, W15, W05, W12); + R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07); + W03 = SM3_E(W03, W10, W00, W06, W13); + R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08); + W04 = SM3_E(W04, W11, W01, W07, W14); + R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09); + W05 = SM3_E(W05, W12, W02, W08, W15); + R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10); + W06 = SM3_E(W06, W13, W03, W09, W00); + R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11); + W07 = SM3_E(W07, W14, W04, W10, W01); + R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12); + W08 = SM3_E(W08, W15, W05, W11, W02); + R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13); + W09 = SM3_E(W09, W00, W06, W12, W03); + R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14); + W10 = SM3_E(W10, W01, W07, W13, W04); + R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15); + W11 = SM3_E(W11, W02, W08, W14, W05); + R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00); + W12 = SM3_E(W12, W03, W09, W15, W06); + R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01); + W13 = SM3_E(W13, W04, W10, W00, W07); + R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02); + W14 = SM3_E(W14, W05, W11, W01, W08); + R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03); + W15 = SM3_E(W15, W06, W12, W02, W09); + R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); + W00 = SM3_E(W00, W07, W13, W03, W10); + R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); + W01 = SM3_E(W01, W08, W14, W04, W11); + R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); + W02 = SM3_E(W02, W09, W15, W05, W12); + R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); + W03 = SM3_E(W03, W10, W00, W06, W13); + R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); + W04 = SM3_E(W04, W11, W01, W07, W14); + R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); + W05 = SM3_E(W05, W12, W02, W08, W15); + R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); + W06 = SM3_E(W06, W13, W03, W09, W00); + R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); + W07 = SM3_E(W07, W14, W04, W10, W01); + R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); + W08 = SM3_E(W08, W15, W05, W11, W02); + R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); + W09 = SM3_E(W09, W00, W06, W12, W03); + R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); + W10 = SM3_E(W10, W01, W07, W13, W04); + R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); + W11 = SM3_E(W11, W02, W08, W14, W05); + R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); + W12 = SM3_E(W12, W03, W09, W15, W06); + R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); + W13 = SM3_E(W13, W04, W10, W00, W07); + R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); + W14 = SM3_E(W14, W05, W11, W01, W08); + R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); + W15 = SM3_E(W15, W06, W12, W02, W09); + R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04); + W00 = SM3_E(W00, W07, W13, W03, W10); + R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05); + W01 = SM3_E(W01, W08, W14, W04, W11); + R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06); + W02 = SM3_E(W02, W09, W15, W05, W12); + R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07); + W03 = SM3_E(W03, W10, W00, W06, W13); + R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08); + W04 = SM3_E(W04, W11, W01, W07, W14); + R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09); + W05 = SM3_E(W05, W12, W02, W08, W15); + R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10); + W06 = SM3_E(W06, W13, W03, W09, W00); + R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11); + W07 = SM3_E(W07, W14, W04, W10, W01); + R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12); + W08 = SM3_E(W08, W15, W05, W11, W02); + R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13); + W09 = SM3_E(W09, W00, W06, W12, W03); + R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14); + W10 = SM3_E(W10, W01, W07, W13, W04); + R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15); + W11 = SM3_E(W11, W02, W08, W14, W05); + R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00); + W12 = SM3_E(W12, W03, W09, W15, W06); + R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01); + W13 = SM3_E(W13, W04, W10, W00, W07); + R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02); + W14 = SM3_E(W14, W05, W11, W01, W08); + R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03); + W15 = SM3_E(W15, W06, W12, W02, W09); + R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04); + W00 = SM3_E(W00, W07, W13, W03, W10); + R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05); + W01 = SM3_E(W01, W08, W14, W04, W11); + R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06); + W02 = SM3_E(W02, W09, W15, W05, W12); + R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07); + W03 = SM3_E(W03, W10, W00, W06, W13); + R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08); + R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09); + R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10); + R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11); + R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12); + R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13); + R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14); + R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15); + R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00); + R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01); + R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02); + R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03); + + A = (state[0] ^= A); + B = (state[1] ^= B); + C = (state[2] ^= C); + D = (state[3] ^= D); + E = (state[4] ^= E); + F = (state[5] ^= F); + G = (state[6] ^= G); + H = (state[7] ^= H); + + input += SM3::BLOCKSIZE/sizeof(word32); + } + + return length & (SM3::BLOCKSIZE-1); +} + +ANONYMOUS_NAMESPACE_END + +NAMESPACE_BEGIN(CryptoPP) + +void SM3::InitState(HashWordType *state) +{ + const word32 s[] = { + 0x7380166fU, 0x4914b2b9U, 0x172442d7U, 0xda8a0600U, + 0xa96f30bcU, 0x163138aaU, 0xe38dee4dU, 0xb0fb0e4eU + }; + + std::memcpy(state, s, sizeof(s)); +} + +void SM3::Transform(word32 *state, const word32 *data) +{ + CRYPTOPP_ASSERT(state); + CRYPTOPP_ASSERT(data); + + SM3_HashMultipleBlocks_CXX(state, data, SM3::BLOCKSIZE); +} + +size_t SM3::HashMultipleBlocks(const HashWordType *input, size_t length) +{ + const size_t res = length & (SM3::BLOCKSIZE - 1); + SM3_HashMultipleBlocks_CXX(m_state, input, length-res); + return res; +} + +NAMESPACE_END diff --git a/sm3.h b/sm3.h new file mode 100644 index 00000000..9a21f88a --- /dev/null +++ b/sm3.h @@ -0,0 +1,61 @@ +// sm3.h - written and placed in the public domain by Jeffrey Walton and Han Lulu +// Based on the specification provided by Sean Shen and Xiaodong Lee. +// Based on code by Krzysztof Kwiatkowski and Jack Lloyd. +// Also see https://tools.ietf.org/html/draft-shen-sm3-hash. + +//! \file sm3.h +//! \brief Classes for the SM3 hash function +//! \details SM3 is a Chinese national hash function designed by Xiaoyun Wang, et al. +//! \sa SM3 Hash Function +//! \since Crypto++ 6.0 + +#ifndef CRYPTOPP_SM3_H +#define CRYPTOPP_SM3_H + +#include "config.h" +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! \class SM3 +//! \brief SM3 hash function +//! \details SM3 is a Chinese national hash function designed by Xiaoyun Wang, et al. +//! \sa SM3 Hash Function +//! \since Crypto++ 6.0 +class SM3 : public IteratedHashWithStaticTransform +{ +public: + //! \brief Initialize state array + //! \param state the state of the hash + //! \details InitState sets a state array to SHA256 initial values + //! \details Hashes which derive from IteratedHashWithStaticTransform provide static + //! member functions InitState and Transform. External classes, like SEAL and MDC, + //! can initialize state with a user provided key and operate the hash on the data + //! with the user supplied state. + //! \note On Intel platforms the state array must be 16-byte aligned for SSE2. + static void InitState(HashWordType *state); + + //! \brief Operate the hash + //! \param digest the state of the hash + //! \param data the data to be digested + //! \details Transform operates the hash on data. When the call is invoked + //! digest holds initial state. Upon return digest holds the hash + //! or updated state. + //! \details Hashes which derive from IteratedHashWithStaticTransform provide static + //! member functions InitState and Transform. External classes, like SEAL and MDC, + //! can initialize state with a user provided key and operate the hash on the data + //! with the user supplied state. + //! \note On Intel platforms the state array and data must be 16-byte aligned for SSE2. + static void Transform(HashWordType *digest, const HashWordType *data); + + //! \brief The algorithm name + //! \returns C-style string "SM3" + CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() { return "SM3"; } + +protected: + size_t HashMultipleBlocks(const HashWordType *input, size_t length); +}; + +NAMESPACE_END + +#endif // CRYPTOPP_SM3_H diff --git a/test.cpp b/test.cpp index 4a390811..d3c57c07 100644 --- a/test.cpp +++ b/test.cpp @@ -939,12 +939,13 @@ bool Validate(int alg, bool thorough, const char *seedInput) case 71: result = ValidateGCM(); break; case 72: result = ValidateCMAC(); break; case 73: result = ValidateHKDF(); break; - case 74: result = ValidateBLAKE2s(); break; - case 75: result = ValidateBLAKE2b(); break; - case 76: result = ValidatePoly1305(); break; - case 77: result = ValidateSipHash(); break; - case 78: result = ValidateHashDRBG(); break; - case 79: result = ValidateHmacDRBG(); break; + case 74: result = ValidateSM3(); break; + case 75: result = ValidateBLAKE2s(); break; + case 76: result = ValidateBLAKE2b(); break; + case 77: result = ValidatePoly1305(); break; + case 78: result = ValidateSipHash(); break; + case 79: result = ValidateHashDRBG(); break; + case 80: result = ValidateHmacDRBG(); break; #if defined(CRYPTOPP_EXTENDED_VALIDATION) // http://github.com/weidai11/cryptopp/issues/92 diff --git a/validat1.cpp b/validat1.cpp index c9494e3a..f2ab8737 100644 --- a/validat1.cpp +++ b/validat1.cpp @@ -132,6 +132,7 @@ bool ValidateAll(bool thorough) pass=ValidatePanama() && pass; pass=ValidateWhirlpool() && pass; + pass=ValidateSM3() && pass; pass=ValidateBLAKE2s() && pass; pass=ValidateBLAKE2b() && pass; pass=ValidatePoly1305() && pass; @@ -173,6 +174,7 @@ bool ValidateAll(bool thorough) 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; pass=ValidateGCM() && pass; diff --git a/validat3.cpp b/validat3.cpp index 660d3be7..902d073e 100644 --- a/validat3.cpp +++ b/validat3.cpp @@ -1939,5 +1939,10 @@ bool ValidateBLAKE2b() return pass; } +bool ValidateSM3() +{ + return RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/sm3.txt"); +} + NAMESPACE_END // Test NAMESPACE_END // CryptoPP diff --git a/validate.h b/validate.h index 46c7f573..733674f2 100644 --- a/validate.h +++ b/validate.h @@ -44,6 +44,7 @@ bool ValidateRIPEMD(); bool ValidatePanama(); bool ValidateWhirlpool(); +bool ValidateSM3(); bool ValidateBLAKE2s(); bool ValidateBLAKE2b(); bool ValidatePoly1305();