diff --git a/Filelist.txt b/Filelist.txt index 95fca88e..102b2fbe 100644 --- a/Filelist.txt +++ b/Filelist.txt @@ -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 diff --git a/TestVectors/all.txt b/TestVectors/all.txt index ffd304cf..1581bd95 100644 --- a/TestVectors/all.txt +++ b/TestVectors/all.txt @@ -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 diff --git a/TestVectors/sm4.txt b/TestVectors/sm4.txt new file mode 100644 index 00000000..5fd33a3a --- /dev/null +++ b/TestVectors/sm4.txt @@ -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 diff --git a/bench1.cpp b/bench1.cpp index 644a10b0..99244a80 100644 --- a/bench1.cpp +++ b/bench1.cpp @@ -615,6 +615,8 @@ void Benchmark2(double t, double hertz) BenchMarkByName("SPECK-128/CTR", 16, "SPECK-128(128)/CTR (128-bit key)"); BenchMarkByName("SPECK-128/CTR", 24, "SPECK-128(192)/CTR (192-bit key)"); BenchMarkByName("SPECK-128/CTR", 32, "SPECK-128(256)/CTR (256-bit key)"); + + BenchMarkByName("SM4/CTR"); } std::cout << "\n"; diff --git a/cryptest.vcxproj b/cryptest.vcxproj index b84e9d59..3b4d5080 100644 --- a/cryptest.vcxproj +++ b/cryptest.vcxproj @@ -258,6 +258,7 @@ + diff --git a/cryptest.vcxproj.filters b/cryptest.vcxproj.filters index 136df945..9fced422 100644 --- a/cryptest.vcxproj.filters +++ b/cryptest.vcxproj.filters @@ -129,6 +129,9 @@ TestVectors + + TestVectors + TestVectors diff --git a/cryptlib.vcxproj b/cryptlib.vcxproj index 0c87aaa7..6d1811cd 100644 --- a/cryptlib.vcxproj +++ b/cryptlib.vcxproj @@ -291,6 +291,7 @@ + @@ -475,6 +476,7 @@ + diff --git a/cryptlib.vcxproj.filters b/cryptlib.vcxproj.filters index 7db0d3de..ff86bced 100644 --- a/cryptlib.vcxproj.filters +++ b/cryptlib.vcxproj.filters @@ -368,6 +368,9 @@ Source Files + + Source Files + Source Files @@ -822,6 +825,9 @@ Header Files + + Header Files + Header Files diff --git a/regtest2.cpp b/regtest2.cpp index dccd2902..f58c49e3 100644 --- a/regtest2.cpp +++ b/regtest2.cpp @@ -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 >(); // Benchmarks RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Test Vectors + RegisterSymmetricCipherDefaultFactories >(); // Benchmarks + RegisterDefaultFactoryFor >(); RegisterDefaultFactoryFor >(); RegisterDefaultFactoryFor >(); diff --git a/sm4.cpp b/sm4.cpp new file mode 100644 index 00000000..1a157c1d --- /dev/null +++ b/sm4.cpp @@ -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 +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 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(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 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 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(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 OutBlock; + OutBlock oblk(xorBlock, outBlock); oblk(m_wspace[3])(m_wspace[2])(m_wspace[1])(m_wspace[0]); +} + +NAMESPACE_END diff --git a/sm4.h b/sm4.h new file mode 100644 index 00000000..37cf4727 --- /dev/null +++ b/sm4.h @@ -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 SMS4 Encryption Algorithm for Wireless Networks +//! \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 SMS4 Encryption Algorithm for Wireless Networks +//! \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 + { + protected: + void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms); + protected: + SecBlock > m_rkeys; + mutable SecBlock > 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; + typedef BlockCipherFinal Decryption; +}; + +NAMESPACE_END + +#endif // CRYPTOPP_SM4_H