Add SM3 hash function (GH #541)

pull/548/head
Jeffrey Walton 2017-11-23 23:19:09 -05:00
parent 13652cf9bf
commit 5267723a49
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
16 changed files with 392 additions and 30 deletions

View File

@ -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

View File

@ -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

19
TestVectors/sm3.txt Normal file
View File

@ -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

View File

@ -471,20 +471,21 @@ void Benchmark1(double t, double hertz)
BenchMarkByNameKeyLess<HashTransformation>("SHA-1");
BenchMarkByNameKeyLess<HashTransformation>("SHA-256");
BenchMarkByNameKeyLess<HashTransformation>("SHA-512");
BenchMarkByNameKeyLess<HashTransformation>("Keccak-224");
BenchMarkByNameKeyLess<HashTransformation>("Keccak-256");
BenchMarkByNameKeyLess<HashTransformation>("Keccak-384");
BenchMarkByNameKeyLess<HashTransformation>("Keccak-512");
BenchMarkByNameKeyLess<HashTransformation>("SHA3-224");
BenchMarkByNameKeyLess<HashTransformation>("SHA3-256");
BenchMarkByNameKeyLess<HashTransformation>("SHA3-384");
BenchMarkByNameKeyLess<HashTransformation>("SHA3-512");
BenchMarkByNameKeyLess<HashTransformation>("Keccak-224");
BenchMarkByNameKeyLess<HashTransformation>("Keccak-256");
BenchMarkByNameKeyLess<HashTransformation>("Keccak-384");
BenchMarkByNameKeyLess<HashTransformation>("Keccak-512");
BenchMarkByNameKeyLess<HashTransformation>("Tiger");
BenchMarkByNameKeyLess<HashTransformation>("Whirlpool");
BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-160");
BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-320");
BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-128");
BenchMarkByNameKeyLess<HashTransformation>("RIPEMD-256");
BenchMarkByNameKeyLess<HashTransformation>("SM3");
BenchMarkByNameKeyLess<HashTransformation>("BLAKE2s");
BenchMarkByNameKeyLess<HashTransformation>("BLAKE2b");
}

View File

@ -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

View File

@ -258,6 +258,7 @@
<None Include="TestVectors\shacal2.txt" />
<None Include="TestVectors\simon.txt" />
<None Include="TestVectors\siphash.txt" />
<Text Include="TestVectors\sm3.txt" />
<None Include="TestVectors\sm4.txt" />
<None Include="TestVectors\sosemanuk.txt" />
<None Include="TestVectors\speck.txt" />

View File

@ -1,20 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="TestVectors">
<UniqueIdentifier>{2e247f14-f75a-4e15-9804-dccce165306f}</UniqueIdentifier>
<Extensions>.txt</Extensions>
<Filter Include="Header Files">
<UniqueIdentifier>{1f4eac20-7b40-40db-a264-4a9256229c5a}</UniqueIdentifier>
<Extensions>.h;.hpp</Extensions>
</Filter>
<Filter Include="Source Code">
<UniqueIdentifier>{4c6077b5-a2d6-498c-bc42-10af523a06cb}</UniqueIdentifier>
<Extensions>.cpp;.h</Extensions>
<Extensions>.cpp</Extensions>
</Filter>
<Filter Include="TestData">
<UniqueIdentifier>{a634d4f4-ddc0-44b4-9c37-d9ffdddc7b06}</UniqueIdentifier>
<Extensions>.dat</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{1f4eac20-7b40-40db-a264-4a9256229c5a}</UniqueIdentifier>
<Filter Include="TestVectors">
<UniqueIdentifier>{2e247f14-f75a-4e15-9804-dccce165306f}</UniqueIdentifier>
<Extensions>.txt</Extensions>
</Filter>
<Filter Include="Miscellaneous">
<UniqueIdentifier>{5e447502-2b0f-49c8-9df5-56ea9e7a8fbd}</UniqueIdentifier>
<Extensions>.proto</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
@ -129,6 +134,9 @@
<None Include="TestVectors\simon.txt">
<Filter>TestVectors</Filter>
</None>
<Text Include="TestVectors\sm3.txt">
<Filter>TestVectors</Filter>
</Text>
<None Include="TestVectors\sm4.txt">
<Filter>TestVectors</Filter>
</None>

View File

@ -291,6 +291,7 @@
<ClCompile Include="simon.cpp" />
<ClCompile Include="simple.cpp" />
<ClCompile Include="skipjack.cpp" />
<ClCompile Include="sm3.cpp" />
<ClCompile Include="sm4.cpp" />
<ClCompile Include="socketft.cpp" />
<ClCompile Include="sosemanuk.cpp" />
@ -476,6 +477,7 @@
<ClInclude Include="simon.h" />
<ClInclude Include="siphash.h" />
<ClInclude Include="skipjack.h" />
<ClInclude Include="sm3.h" />
<ClInclude Include="sm4.h" />
<ClInclude Include="smartptr.h" />
<ClInclude Include="socketft.h" />

View File

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{1e9e61cf-0e3c-4b79-955f-9f077eabdb3e}</UniqueIdentifier>
<Extensions>.h;.hpp</Extensions>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{0465ef4f-be03-463e-81e5-5a399f32620f}</UniqueIdentifier>
<Extensions>.cpp</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{1e9e61cf-0e3c-4b79-955f-9f077eabdb3e}</UniqueIdentifier>
<Extensions>.;.h</Extensions>
</Filter>
<Filter Include="Miscellaneous">
<UniqueIdentifier>{5e447502-2b0f-49c8-9df5-45ea9e7fcfbd}</UniqueIdentifier>
</Filter>
@ -368,6 +368,9 @@
<ClCompile Include="skipjack.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sm3.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sm4.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -825,6 +828,9 @@
<ClInclude Include="skipjack.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sm3.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sm4.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -911,17 +917,11 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="adhoc.cpp.proto">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="rdrand.asm">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="x64dll.asm">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="x64masm.asm">
<Filter>Source Files</Filter>
<CustomBuild Include="adhoc.cpp.proto">
<Filter>Miscellaneous</Filter>
</CustomBuild>
</ItemGroup>
</Project>

View File

@ -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<HashTransformation, SHA3_256>();
RegisterDefaultFactoryFor<HashTransformation, SHA3_384>();
RegisterDefaultFactoryFor<HashTransformation, SHA3_512>();
RegisterDefaultFactoryFor<HashTransformation, SM3>();
RegisterDefaultFactoryFor<HashTransformation, BLAKE2s>();
RegisterDefaultFactoryFor<HashTransformation, BLAKE2b>();

254
sm3.cpp Normal file
View File

@ -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<word32, BigEndian, false> 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

61
sm3.h Normal file
View File

@ -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 <A HREF="https://tools.ietf.org/html/draft-shen-sm3-hash">SM3 Hash Function</A>
//! \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 <A HREF="https://tools.ietf.org/html/draft-shen-sm3-hash">SM3 Hash Function</A>
//! \since Crypto++ 6.0
class SM3 : public IteratedHashWithStaticTransform<word32, BigEndian, 64, 32, SM3, 32, true>
{
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 <tt>data</tt>. When the call is invoked
//! <tt>digest</tt> holds initial state. Upon return <tt>digest</tt> 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

View File

@ -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

View File

@ -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;

View File

@ -1939,5 +1939,10 @@ bool ValidateBLAKE2b()
return pass;
}
bool ValidateSM3()
{
return RunTestDataFile(CRYPTOPP_DATA_DIR "TestVectors/sm3.txt");
}
NAMESPACE_END // Test
NAMESPACE_END // CryptoPP

View File

@ -44,6 +44,7 @@ bool ValidateRIPEMD();
bool ValidatePanama();
bool ValidateWhirlpool();
bool ValidateSM3();
bool ValidateBLAKE2s();
bool ValidateBLAKE2b();
bool ValidatePoly1305();