mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2025-02-03 11:42:08 +00:00
Add SM4 block ciphers (GH #540)
This commit is contained in:
parent
2e63e46747
commit
2c8a618a03
@ -273,10 +273,12 @@ sharkbox.cpp
|
||||
simple.cpp
|
||||
simple.h
|
||||
siphash.h
|
||||
skipjack.cpp
|
||||
skipjack.h
|
||||
simon.cpp
|
||||
simon.h
|
||||
skipjack.cpp
|
||||
skipjack.h
|
||||
sm4.cpp
|
||||
sm4.h
|
||||
smartptr.h
|
||||
socketft.cpp
|
||||
socketft.h
|
||||
|
@ -28,7 +28,9 @@ Test: TestVectors/aes.txt
|
||||
Test: TestVectors/aria.txt
|
||||
Test: TestVectors/kalyna.txt
|
||||
Test: TestVectors/threefish.txt
|
||||
Test: TestVectors/simon.txt
|
||||
Test: TestVectors/speck.txt
|
||||
Test: TestVectors/sm4.txt
|
||||
Test: TestVectors/salsa.txt
|
||||
Test: TestVectors/chacha.txt
|
||||
#Test: TestVectors/tls_chacha.txt
|
||||
|
162
TestVectors/sm4.txt
Normal file
162
TestVectors/sm4.txt
Normal file
@ -0,0 +1,162 @@
|
||||
AlgorithmType: SymmetricCipher
|
||||
Name: SM4/ECB
|
||||
#
|
||||
Source: SM4 paper, https://eprint.iacr.org/2008/329.pdf
|
||||
Comment: SM4 test vector, section 5, p. 5
|
||||
Key: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
|
||||
Plaintext: 01 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10
|
||||
Ciphertext: 68 1e df 34 d2 06 96 5e 86 b3 e9 4f 53 6e 42 46
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: EB23ADD6454757555747395B76661C9A
|
||||
Plaintext: D294D879A1F02C7C5906D6C2D0C54D9F
|
||||
Ciphertext: 865DE90D6B6E99273E2D44859D9C16DF
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 11E3790F430B4729DA1EEF291BCE99CD
|
||||
Plaintext: 04A36E56B2032B725DDE112FCE3F8398
|
||||
Ciphertext: 4076848AD4563B9D8E3FD09BA2E5DCFE
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 4310652E0BB55C2CBA9AEBD4FC2BED5C
|
||||
Plaintext: CB33507774E6E161CD5029E901C6C36A
|
||||
Ciphertext: 64B8D9FB4114D490FFBD105969310EF9
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: FDBA958326CD690F28C7632B5EBEF6A1
|
||||
Plaintext: BAE8A9B1C3319D3FC9D48817E034FE1B
|
||||
Ciphertext: 19C70A4E9FE8D6739863224C8734A79B
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 63AF71AE3CE38FD96AFAAAF12CC3D5D3
|
||||
Plaintext: A505B41E20C73C777F56235261198E56
|
||||
Ciphertext: 2F6071BC04F55844BC8675FABEA3F727
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 03F360D31DA9DBD2F0BFFFEAEFDB1D1E
|
||||
Plaintext: 8177F025DDBC7CE919DC5D2612548878
|
||||
Ciphertext: D7447F601C174AABC62E06BB85BB597C
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: EA326BD4223B2F1BE3CB0319220ADCAE
|
||||
Plaintext: 15DBE19A7FAC233433CB9CA190FAC2F1
|
||||
Ciphertext: 6BC11D09BB46092831E2399CF1525F43
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: F1163693E6E70CBF48E774368142286F
|
||||
Plaintext: 95FF06C4A634E09BAAD6F1B2230662C7
|
||||
Ciphertext: 558614DB4DD8AA43717C14C7B87A8D79
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: CBAD11138E97EE20B140BD8923031488
|
||||
Plaintext: A514119F5AB688278E581CFCA5BDFF5F
|
||||
Ciphertext: 8E4682E2A5F92B777CAFF65275528CAF
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 3198AB4E006A5180966D5075912BC406
|
||||
Plaintext: 5F9B108B715F047B7879E323B0D95C3B
|
||||
Ciphertext: 7B40084F82CAAA25821862F986ABD424
|
||||
Test: Encrypt
|
||||
|
||||
AlgorithmType: SymmetricCipher
|
||||
Name: SM4/CBC
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: B60B64598B7C3B4CACE7F79E0E6A04E4
|
||||
IV: 3976D813A095B411050652196B88F85D
|
||||
Plaintext: 20D88FA20206E4C05B173659B9EB40934534C3528544B7EC1160143C612BA781
|
||||
Ciphertext: 4A9D869BB80D52EBCD6FB3EF459338203DC603466DE779678B725A24F56B3CA3
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 088D295D113C7293D6BCF4672ACFA99A
|
||||
IV: 06EAC32D27F8F7DAABE4C11249ABF9AC
|
||||
Plaintext: 43696982BC5872405F545D4AA5CFB2DBD7F08A55DAFEF734174B32F3F349EFE6
|
||||
Ciphertext: 4120DA4EA4749F7F7A1B720543785D384E1D1DA552B1A8DF849E61C217527EE7
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: C06C1B9A116D395AE2A157C8BB046D1E
|
||||
IV: F022B684F6FF7FBA7DF6FF9D113349A7
|
||||
Plaintext: 7BA4D5C4A0C392E5202E57D7C9545FAA96D5F0A1CDB56AFA12306A17C8ED87A7
|
||||
Ciphertext: E30F019D9A37485B4C7B4D3D0F80D206F1C96D89002860D115BCA1EB7A26FF76
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: E5C52267B2F77B0D91DBC0CFAB664D2D
|
||||
IV: 6DB64FC718DA534FD7F851D3B9296031
|
||||
Plaintext: 13C9F96DCE93C2AB145270392FE94A312EE8E01030BD3273DE5F00A21CC8F661
|
||||
Ciphertext: E8EF3831EDD8D201BF3C31F60C48E75A952F3E525A9598B1BC86A8EEFC97F399
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 24B8D3435647B89307C176A7526A72A9
|
||||
IV: 76546FF53DB565746DE0167A60E6689F
|
||||
Plaintext: DE4871BDC5D0A4E8E7C6191BEF5279B9C0B37AA67B1E68B4EB961FC7910D1AA4
|
||||
Ciphertext: 92F1C46F07634D73FB9A3905335A61FC67991A91013D1335662307512E997FE2
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 78CCB3780A6B1083735768169B25A173
|
||||
IV: 7245637ED3330B6DEB289F6B4BC21C4B
|
||||
Plaintext: 24D349B9ED2A7B11D04759F965D4EA58E4942490A78B6D4DD7EE9411356CEFFC
|
||||
Ciphertext: EE070B41CCDBE7212BA557C796AD5646148477A0F306BFCA15202E71838D2B3B
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: B80C3000FD2C046A69CA7CC0A30EFA37
|
||||
IV: FEC64E270710C10306379AC45224F0AB
|
||||
Plaintext: E34F3E1EF452FD124754648386493FC219F7935603A84F739FABC0945AB99D80
|
||||
Ciphertext: 34FA5DB02B6F4AF1993B6254B098405A078E2B01F920DAAF9682E2D976AF93DC
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 0B35A8FCD48700A8686E31D0DE26D728
|
||||
IV: B0D1FFEACB1ED83284A635F1F29A78F9
|
||||
Plaintext: F21CCC23F69ACE95DB4E4B5297043A492498512D372140EC3D89A84737763C53
|
||||
Ciphertext: 09743B30EEE11B9563062CAE2C1F5A55389C041C6683B535EC027C0434412AAC
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: 26DA145BEC95BB79A9A2F021F5B3D71B
|
||||
IV: 60C4967D68EA166854CE50DAF76417B3
|
||||
Plaintext: 619DDE4377CCC30782EC92AE592745610CEE8019B838DC3AE2F62C6768BCFFF3
|
||||
Ciphertext: 9598619D651378ABB8EB96AA2F016AE358845A128C84A653C832ED329B9F2453
|
||||
Test: Encrypt
|
||||
#
|
||||
Source: Crypto++ 6.0 generated
|
||||
Comment: SM4-128(128)
|
||||
Key: A2B0F85DDEF58297E88ED1A032B5BDB9
|
||||
IV: 4FD854D99894CFFC2C9A7C7F977E2766
|
||||
Plaintext: 62584CC7D1F9DB700C6AB2FF4B9DDF975CD4E8133AA9D7A1C5B077EFBB168A01
|
||||
Ciphertext: F2D73D32D40275E93B268B2256522E8AE54BEFD8F75B9356A40DBCE776C74CA6
|
||||
Test: Encrypt
|
@ -615,6 +615,8 @@ void Benchmark2(double t, double hertz)
|
||||
BenchMarkByName<SymmetricCipher>("SPECK-128/CTR", 16, "SPECK-128(128)/CTR (128-bit key)");
|
||||
BenchMarkByName<SymmetricCipher>("SPECK-128/CTR", 24, "SPECK-128(192)/CTR (192-bit key)");
|
||||
BenchMarkByName<SymmetricCipher>("SPECK-128/CTR", 32, "SPECK-128(256)/CTR (256-bit key)");
|
||||
|
||||
BenchMarkByName<SymmetricCipher>("SM4/CTR");
|
||||
}
|
||||
|
||||
std::cout << "\n<TBODY style=\"background: yellow;\">";
|
||||
|
@ -258,6 +258,7 @@
|
||||
<None Include="TestVectors\shacal2.txt" />
|
||||
<None Include="TestVectors\simon.txt" />
|
||||
<None Include="TestVectors\siphash.txt" />
|
||||
<None Include="TestVectors\sm4.txt" />
|
||||
<None Include="TestVectors\sosemanuk.txt" />
|
||||
<None Include="TestVectors\speck.txt" />
|
||||
<None Include="TestVectors\tea.txt" />
|
||||
|
@ -129,6 +129,9 @@
|
||||
<None Include="TestVectors\simon.txt">
|
||||
<Filter>TestVectors</Filter>
|
||||
</None>
|
||||
<None Include="TestVectors\sm4.txt">
|
||||
<Filter>TestVectors</Filter>
|
||||
</None>
|
||||
<None Include="TestVectors\sosemanuk.txt">
|
||||
<Filter>TestVectors</Filter>
|
||||
</None>
|
||||
|
@ -291,6 +291,7 @@
|
||||
<ClCompile Include="simon.cpp" />
|
||||
<ClCompile Include="simple.cpp" />
|
||||
<ClCompile Include="skipjack.cpp" />
|
||||
<ClCompile Include="sm4.cpp" />
|
||||
<ClCompile Include="socketft.cpp" />
|
||||
<ClCompile Include="sosemanuk.cpp" />
|
||||
<ClCompile Include="speck.cpp" />
|
||||
@ -475,6 +476,7 @@
|
||||
<ClInclude Include="simon.h" />
|
||||
<ClInclude Include="siphash.h" />
|
||||
<ClInclude Include="skipjack.h" />
|
||||
<ClInclude Include="sm4.h" />
|
||||
<ClInclude Include="smartptr.h" />
|
||||
<ClInclude Include="socketft.h" />
|
||||
<ClInclude Include="sosemanuk.h" />
|
||||
|
@ -368,6 +368,9 @@
|
||||
<ClCompile Include="skipjack.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sm4.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="socketft.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -822,6 +825,9 @@
|
||||
<ClInclude Include="skipjack.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sm4.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="smartptr.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "threefish.h"
|
||||
#include "simon.h"
|
||||
#include "speck.h"
|
||||
#include "sm4.h"
|
||||
#include "des.h"
|
||||
#include "idea.h"
|
||||
#include "rc5.h"
|
||||
@ -170,6 +171,10 @@ void RegisterFactories2()
|
||||
RegisterSymmetricCipherDefaultFactories<CTR_Mode<SPECK64> >(); // Benchmarks
|
||||
RegisterSymmetricCipherDefaultFactories<CTR_Mode<SPECK128> >(); // Benchmarks
|
||||
|
||||
RegisterSymmetricCipherDefaultFactories<ECB_Mode<SM4> >(); // Test Vectors
|
||||
RegisterSymmetricCipherDefaultFactories<CBC_Mode<SM4> >(); // Test Vectors
|
||||
RegisterSymmetricCipherDefaultFactories<CTR_Mode<SM4> >(); // Benchmarks
|
||||
|
||||
RegisterDefaultFactoryFor<KeyDerivationFunction, HKDF<SHA1> >();
|
||||
RegisterDefaultFactoryFor<KeyDerivationFunction, HKDF<SHA256> >();
|
||||
RegisterDefaultFactoryFor<KeyDerivationFunction, HKDF<SHA512> >();
|
||||
|
174
sm4.cpp
Normal file
174
sm4.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
// sm4.cpp - written and placed in the public domain by Jeffrey Walton and Han Lulu
|
||||
|
||||
#include "pch.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "sm4.h"
|
||||
#include "misc.h"
|
||||
#include "cpu.h"
|
||||
|
||||
ANONYMOUS_NAMESPACE_BEGIN
|
||||
|
||||
using CryptoPP::byte;
|
||||
using CryptoPP::word32;
|
||||
using CryptoPP::rotlFixed;
|
||||
using CryptoPP::rotrFixed;
|
||||
|
||||
const byte S[256] =
|
||||
{
|
||||
0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05,
|
||||
0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
|
||||
0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62,
|
||||
0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6,
|
||||
0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8,
|
||||
0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35,
|
||||
0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87,
|
||||
0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E,
|
||||
0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1,
|
||||
0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3,
|
||||
0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F,
|
||||
0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51,
|
||||
0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8,
|
||||
0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0,
|
||||
0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84,
|
||||
0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48
|
||||
};
|
||||
|
||||
const word32 CK[32] =
|
||||
{
|
||||
0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
|
||||
0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
|
||||
0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
|
||||
0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
|
||||
0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229,
|
||||
0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
|
||||
0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209,
|
||||
0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
|
||||
};
|
||||
|
||||
inline word32 SM4_H(word32 x)
|
||||
{
|
||||
return (S[GETBYTE(x, 3)] << 24) | (S[GETBYTE(x, 2)] << 16) | (S[GETBYTE(x, 1)] << 8) | (S[GETBYTE(x, 0)]);
|
||||
}
|
||||
|
||||
inline word32 SM4_G(word32 x)
|
||||
{
|
||||
const word32 t = SM4_H(x);
|
||||
return t ^ rotlFixed(t, 13) ^ rotlFixed(t, 23);
|
||||
}
|
||||
|
||||
inline word32 SM4_F(word32 x)
|
||||
{
|
||||
const word32 t = SM4_H(x);
|
||||
return t ^ rotlFixed(t, 2) ^ rotlFixed(t, 10) ^ rotlFixed(t, 18) ^ rotlFixed(t, 24);
|
||||
}
|
||||
|
||||
template <unsigned int R, bool FWD>
|
||||
inline void SM4_Round(word32 wspace[4], const word32 rkeys[32])
|
||||
{
|
||||
if (FWD)
|
||||
{
|
||||
wspace[0] ^= SM4_F(wspace[1] ^ wspace[2] ^ wspace[3] ^ rkeys[R+0]);
|
||||
wspace[1] ^= SM4_F(wspace[0] ^ wspace[2] ^ wspace[3] ^ rkeys[R+1]);
|
||||
wspace[2] ^= SM4_F(wspace[0] ^ wspace[1] ^ wspace[3] ^ rkeys[R+2]);
|
||||
wspace[3] ^= SM4_F(wspace[0] ^ wspace[1] ^ wspace[2] ^ rkeys[R+3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
wspace[0] ^= SM4_F(wspace[1] ^ wspace[2] ^ wspace[3] ^ rkeys[R-0]);
|
||||
wspace[1] ^= SM4_F(wspace[0] ^ wspace[2] ^ wspace[3] ^ rkeys[R-1]);
|
||||
wspace[2] ^= SM4_F(wspace[0] ^ wspace[1] ^ wspace[3] ^ rkeys[R-2]);
|
||||
wspace[3] ^= SM4_F(wspace[0] ^ wspace[1] ^ wspace[2] ^ rkeys[R-3]);
|
||||
}
|
||||
}
|
||||
|
||||
ANONYMOUS_NAMESPACE_END
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
void SM4::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms)
|
||||
{
|
||||
CRYPTOPP_ASSERT(keyLength == 16);
|
||||
CRYPTOPP_UNUSED(params);
|
||||
|
||||
m_rkeys.New(32);
|
||||
m_wspace.New(5);
|
||||
|
||||
GetUserKey(BIG_ENDIAN_ORDER, m_wspace.begin(), 4, userKey, keyLength);
|
||||
m_wspace[0] ^= 0xa3b1bac6; m_wspace[1] ^= 0x56aa3350;
|
||||
m_wspace[2] ^= 0x677d9197; m_wspace[3] ^= 0xb27022dc;
|
||||
|
||||
size_t i=0;
|
||||
do
|
||||
{
|
||||
m_rkeys[i] = (m_wspace[0] ^= SM4_G(m_wspace[1] ^ m_wspace[2] ^ m_wspace[3] ^ CK[i])); i++;
|
||||
m_rkeys[i] = (m_wspace[1] ^= SM4_G(m_wspace[2] ^ m_wspace[3] ^ m_wspace[0] ^ CK[i])); i++;
|
||||
m_rkeys[i] = (m_wspace[2] ^= SM4_G(m_wspace[3] ^ m_wspace[0] ^ m_wspace[1] ^ CK[i])); i++;
|
||||
m_rkeys[i] = (m_wspace[3] ^= SM4_G(m_wspace[0] ^ m_wspace[1] ^ m_wspace[2] ^ CK[i])); i++;
|
||||
}
|
||||
while (i < 32);
|
||||
}
|
||||
|
||||
void SM4::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef GetBlock<word32, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1])(m_wspace[2])(m_wspace[3]);
|
||||
|
||||
// Timing attack countermeasure, see comments in Rijndael for more details.
|
||||
// The hardening does not materially affect benchmarks. SM4 runs at
|
||||
// 30.5 cpb on a Core i5 Skylake with and without the code below.
|
||||
const int cacheLineSize = GetCacheLineSize();
|
||||
volatile word32 _u = 0;
|
||||
word32 u = _u;
|
||||
|
||||
for (unsigned int i=0; i<sizeof(S); i+=cacheLineSize)
|
||||
u |= *(const word32 *)(void*)(S+i);
|
||||
m_wspace[4] = u;
|
||||
|
||||
SM4_Round< 0, true>(m_wspace, m_rkeys);
|
||||
SM4_Round< 4, true>(m_wspace, m_rkeys);
|
||||
SM4_Round< 8, true>(m_wspace, m_rkeys);
|
||||
SM4_Round<12, true>(m_wspace, m_rkeys);
|
||||
SM4_Round<16, true>(m_wspace, m_rkeys);
|
||||
SM4_Round<20, true>(m_wspace, m_rkeys);
|
||||
SM4_Round<24, true>(m_wspace, m_rkeys);
|
||||
SM4_Round<28, true>(m_wspace, m_rkeys);
|
||||
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef PutBlock<word32, BigEndian, false> OutBlock;
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
}
|
||||
|
||||
void SM4::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
||||
{
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef GetBlock<word32, BigEndian, false> InBlock;
|
||||
InBlock iblk(inBlock); iblk(m_wspace[0])(m_wspace[1])(m_wspace[2])(m_wspace[3]);
|
||||
|
||||
// Timing attack countermeasure, see comments in Rijndael for more details.
|
||||
// The hardening does not materially affect benchmarks. SM4 runs at
|
||||
// 30.5 cpb on a Core i5 Skylake with and without the code below.
|
||||
const int cacheLineSize = GetCacheLineSize();
|
||||
volatile word32 _u = 0;
|
||||
word32 u = _u;
|
||||
|
||||
for (unsigned int i=0; i<sizeof(S); i+=cacheLineSize)
|
||||
u |= *(const word32 *)(void*)(S+i);
|
||||
m_wspace[4] = u;
|
||||
|
||||
SM4_Round<31, false>(m_wspace, m_rkeys);
|
||||
SM4_Round<27, false>(m_wspace, m_rkeys);
|
||||
SM4_Round<23, false>(m_wspace, m_rkeys);
|
||||
SM4_Round<19, false>(m_wspace, m_rkeys);
|
||||
SM4_Round<15, false>(m_wspace, m_rkeys);
|
||||
SM4_Round<11, false>(m_wspace, m_rkeys);
|
||||
SM4_Round< 7, false>(m_wspace, m_rkeys);
|
||||
SM4_Round< 3, false>(m_wspace, m_rkeys);
|
||||
|
||||
// Reverse bytes on LittleEndian; align pointer on BigEndian
|
||||
typedef PutBlock<word32, BigEndian, false> OutBlock;
|
||||
OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
75
sm4.h
Normal file
75
sm4.h
Normal file
@ -0,0 +1,75 @@
|
||||
// sm4.h - written and placed in the public domain by Jeffrey Walton and Han Lulu
|
||||
|
||||
//! \file sm4.h
|
||||
//! \brief Classes for the SM4 block cipher
|
||||
//! \details SM4 is a Chinese national block cipher.
|
||||
//! \sa <A HREF="http://eprint.iacr.org/2008/329.pdf">SMS4 Encryption Algorithm for Wireless Networks</A>
|
||||
//! \since Crypto++ 6.0
|
||||
|
||||
#ifndef CRYPTOPP_SM4_H
|
||||
#define CRYPTOPP_SM4_H
|
||||
|
||||
#include "config.h"
|
||||
#include "seckey.h"
|
||||
#include "secblock.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
//! \class SM4_Info
|
||||
//! \brief SM4 block cipher information
|
||||
//! \since Crypto++ 6.0
|
||||
struct SM4_Info : public FixedBlockSize<16>, FixedKeyLength<16>
|
||||
{
|
||||
static const std::string StaticAlgorithmName()
|
||||
{
|
||||
return "SM4";
|
||||
}
|
||||
};
|
||||
|
||||
//! \file sm4.h
|
||||
//! \brief Classes for the SM4 block cipher
|
||||
//! \details SM4 is a Chinese national block cipher.
|
||||
//! \sa <A HREF="http://eprint.iacr.org/2008/329.pdf">SMS4 Encryption Algorithm for Wireless Networks</A>
|
||||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE SM4 : public SM4_Info, public BlockCipherDocumentation
|
||||
{
|
||||
public:
|
||||
//! \brief SM4 block cipher transformation functions
|
||||
//! \details Provides implementation common to encryption and decryption
|
||||
//! \since Crypto++ 6.0
|
||||
class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<SM4_Info>
|
||||
{
|
||||
protected:
|
||||
void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms);
|
||||
protected:
|
||||
SecBlock<word32, AllocatorWithCleanup<word32> > m_rkeys;
|
||||
mutable SecBlock<word32, AllocatorWithCleanup<word32> > m_wspace;
|
||||
};
|
||||
|
||||
//! \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;
|
||||
};
|
||||
|
||||
//! \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;
|
||||
};
|
||||
|
||||
typedef BlockCipherFinal<ENCRYPTION, Enc> Encryption;
|
||||
typedef BlockCipherFinal<DECRYPTION, Dec> Decryption;
|
||||
};
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif // CRYPTOPP_SM4_H
|
Loading…
x
Reference in New Issue
Block a user