Add SM4 block ciphers (GH #540)

This commit is contained in:
Jeffrey Walton 2017-11-23 11:41:40 -05:00
parent 2e63e46747
commit 2c8a618a03
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
11 changed files with 436 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
View 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 &params)
{
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
View 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 &params);
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