From 10aaeeb54ebdbf1818b0a63a81e4d7035f248495 Mon Sep 17 00:00:00 2001 From: kbkpbot Date: Sat, 27 Jan 2024 02:45:26 +0800 Subject: [PATCH] x.crypto: add sm4 module (#20651) --- vlib/x/crypto/sm4/README.md | 6 + vlib/x/crypto/sm4/SM4.pdf | Bin 0 -> 124083 bytes vlib/x/crypto/sm4/sm4.v | 463 +++++++++++++++++++++++++++++++++++ vlib/x/crypto/sm4/sm4_test.v | 213 ++++++++++++++++ 4 files changed, 682 insertions(+) create mode 100644 vlib/x/crypto/sm4/README.md create mode 100644 vlib/x/crypto/sm4/SM4.pdf create mode 100644 vlib/x/crypto/sm4/sm4.v create mode 100644 vlib/x/crypto/sm4/sm4_test.v diff --git a/vlib/x/crypto/sm4/README.md b/vlib/x/crypto/sm4/README.md new file mode 100644 index 00000000000000..4e52d46a7b9d5e --- /dev/null +++ b/vlib/x/crypto/sm4/README.md @@ -0,0 +1,6 @@ +## Description: + +`crypto.sm4` is a module that assists in the encryption and +decryption of binary data using the `SM4` block cipher. + +`SM4` is the block cipher algorithm in China's Standards of Encryption Algorithms. diff --git a/vlib/x/crypto/sm4/SM4.pdf b/vlib/x/crypto/sm4/SM4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0e3a21410e74dd6b84c46f44d5ebfbcf406f96dc GIT binary patch literal 124083 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 VWtwDr^mL=%ehnN(pYJ~d|1ZWBaKQio literal 0 HcmV?d00001 diff --git a/vlib/x/crypto/sm4/sm4.v b/vlib/x/crypto/sm4/sm4.v new file mode 100644 index 00000000000000..0a17d61d7a01ae --- /dev/null +++ b/vlib/x/crypto/sm4/sm4.v @@ -0,0 +1,463 @@ +// SM4 is the block cipher algorithm in China's Standards of Encryption Algorithms. +// For more information, see ISO/IEC 18033-3:2010/Amd 1:2021(https://www.iso.org/standard/81564.html) +// Based on : https://github.com/scnucrypto/OptimizedSM4/tree/main/LUT-SM4 + +// SM4 is a block symmetric cryptographic algorithm, with plaintext, ciphertext, and key lengths of 128 bits. +// The SM4 algorithm mainly includes encryption and decryption algorithms and key extension algorithms, +// adopting a mathematical structure of 32 rounds of nonlinear iteration, where each iteration operation +// in the algorithm is a round of nonlinear transformation. The main operations include XOR, synthetic permutation, +// nonlinear iteration, inverse transformation, cyclic shift, and S-box transformation. The mathematical architecture, +// operation rules, and operations of encryption and decryption algorithms are completely identical, and decryption +// operations only require the reverse order use of the round keys generated in the encryption algorithm. + +module sm4 + +// vfmt off +// System parameter +const fk = [u32(0xa3b1bac6), 0x56aa3350, 0x677d9197, 0xb27022dc, ]! + +// fixed parameter +const ck = +[ +u32(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, +]! + +// Expanded SM4 S-boxes +// Sbox table: 8bits input convert to 8 bits output +const sbox = [ +u8(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, +]! +// pre-calculated tables for sbox & ROL operations +const table0 = [ +u32(0x8ed55b5b), 0xd0924242, 0x4deaa7a7, 0x06fdfbfb, 0xfccf3333, 0x65e28787, + 0xc93df4f4 , 0x6bb5dede, 0x4e165858, 0x6eb4dada, 0x44145050, 0xcac10b0b, + 0x8828a0a0 , 0x17f8efef, 0x9c2cb0b0, 0x11051414, 0x872bacac, 0xfb669d9d, + 0xf2986a6a , 0xae77d9d9, 0x822aa8a8, 0x46bcfafa, 0x14041010, 0xcfc00f0f, + 0x02a8aaaa , 0x54451111, 0x5f134c4c, 0xbe269898, 0x6d482525, 0x9e841a1a, + 0x1e061818 , 0xfd9b6666, 0xec9e7272, 0x4a430909, 0x10514141, 0x24f7d3d3, + 0xd5934646 , 0x53ecbfbf, 0xf89a6262, 0x927be9e9, 0xff33cccc, 0x04555151, + 0x270b2c2c , 0x4f420d0d, 0x59eeb7b7, 0xf3cc3f3f, 0x1caeb2b2, 0xea638989, + 0x74e79393 , 0x7fb1cece, 0x6c1c7070, 0x0daba6a6, 0xedca2727, 0x28082020, + 0x48eba3a3 , 0xc1975656, 0x80820202, 0xa3dc7f7f, 0xc4965252, 0x12f9ebeb, + 0xa174d5d5 , 0xb38d3e3e, 0xc33ffcfc, 0x3ea49a9a, 0x5b461d1d, 0x1b071c1c, + 0x3ba59e9e , 0x0cfff3f3, 0x3ff0cfcf, 0xbf72cdcd, 0x4b175c5c, 0x52b8eaea, + 0x8f810e0e , 0x3d586565, 0xcc3cf0f0, 0x7d196464, 0x7ee59b9b, 0x91871616, + 0x734e3d3d , 0x08aaa2a2, 0xc869a1a1, 0xc76aadad, 0x85830606, 0x7ab0caca, + 0xb570c5c5 , 0xf4659191, 0xb2d96b6b, 0xa7892e2e, 0x18fbe3e3, 0x47e8afaf, + 0x330f3c3c , 0x674a2d2d, 0xb071c1c1, 0x0e575959, 0xe99f7676, 0xe135d4d4, + 0x661e7878 , 0xb4249090, 0x360e3838, 0x265f7979, 0xef628d8d, 0x38596161, + 0x95d24747 , 0x2aa08a8a, 0xb1259494, 0xaa228888, 0x8c7df1f1, 0xd73becec, + 0x05010404 , 0xa5218484, 0x9879e1e1, 0x9b851e1e, 0x84d75353, 0x00000000, + 0x5e471919 , 0x0b565d5d, 0xe39d7e7e, 0x9fd04f4f, 0xbb279c9c, 0x1a534949, + 0x7c4d3131 , 0xee36d8d8, 0x0a020808, 0x7be49f9f, 0x20a28282, 0xd4c71313, + 0xe8cb2323 , 0xe69c7a7a, 0x42e9abab, 0x43bdfefe, 0xa2882a2a, 0x9ad14b4b, + 0x40410101 , 0xdbc41f1f, 0xd838e0e0, 0x61b7d6d6, 0x2fa18e8e, 0x2bf4dfdf, + 0x3af1cbcb , 0xf6cd3b3b, 0x1dfae7e7, 0xe5608585, 0x41155454, 0x25a38686, + 0x60e38383 , 0x16acbaba, 0x295c7575, 0x34a69292, 0xf7996e6e, 0xe434d0d0, + 0x721a6868 , 0x01545555, 0x19afb6b6, 0xdf914e4e, 0xfa32c8c8, 0xf030c0c0, + 0x21f6d7d7 , 0xbc8e3232, 0x75b3c6c6, 0x6fe08f8f, 0x691d7474, 0x2ef5dbdb, + 0x6ae18b8b , 0x962eb8b8, 0x8a800a0a, 0xfe679999, 0xe2c92b2b, 0xe0618181, + 0xc0c30303 , 0x8d29a4a4, 0xaf238c8c, 0x07a9aeae, 0x390d3434, 0x1f524d4d, + 0x764f3939 , 0xd36ebdbd, 0x81d65757, 0xb7d86f6f, 0xeb37dcdc, 0x51441515, + 0xa6dd7b7b , 0x09fef7f7, 0xb68c3a3a, 0x932fbcbc, 0x0f030c0c, 0x03fcffff, + 0xc26ba9a9 , 0xba73c9c9, 0xd96cb5b5, 0xdc6db1b1, 0x375a6d6d, 0x15504545, + 0xb98f3636 , 0x771b6c6c, 0x13adbebe, 0xda904a4a, 0x57b9eeee, 0xa9de7777, + 0x4cbef2f2 , 0x837efdfd, 0x55114444, 0xbdda6767, 0x2c5d7171, 0x45400505, + 0x631f7c7c , 0x50104040, 0x325b6969, 0xb8db6363, 0x220a2828, 0xc5c20707, + 0xf531c4c4 , 0xa88a2222, 0x31a79696, 0xf9ce3737, 0x977aeded, 0x49bff6f6, + 0x992db4b4 , 0xa475d1d1, 0x90d34343, 0x5a124848, 0x58bae2e2, 0x71e69797, + 0x64b6d2d2 , 0x70b2c2c2, 0xad8b2626, 0xcd68a5a5, 0xcb955e5e, 0x624b2929, + 0x3c0c3030 , 0xce945a5a, 0xab76dddd, 0x867ff9f9, 0xf1649595, 0x5dbbe6e6, + 0x35f2c7c7 , 0x2d092424, 0xd1c61717, 0xd66fb9b9, 0xdec51b1b, 0x94861212, + 0x78186060 , 0x30f3c3c3, 0x897cf5f5, 0x5cefb3b3, 0xd23ae8e8, 0xacdf7373, + 0x794c3535 , 0xa0208080, 0x9d78e5e5, 0x56edbbbb, 0x235e7d7d, 0xc63ef8f8, + 0x8bd45f5f , 0xe7c82f2f, 0xdd39e4e4, 0x68492121, +]! +const table1 = [ +u32(0x5b8ed55b), 0x42d09242, 0xa74deaa7, 0xfb06fdfb, 0x33fccf33, 0x8765e287, + 0xf4c93df4 , 0xde6bb5de, 0x584e1658, 0xda6eb4da, 0x50441450, 0x0bcac10b, + 0xa08828a0 , 0xef17f8ef, 0xb09c2cb0, 0x14110514, 0xac872bac, 0x9dfb669d, + 0x6af2986a , 0xd9ae77d9, 0xa8822aa8, 0xfa46bcfa, 0x10140410, 0x0fcfc00f, + 0xaa02a8aa , 0x11544511, 0x4c5f134c, 0x98be2698, 0x256d4825, 0x1a9e841a, + 0x181e0618 , 0x66fd9b66, 0x72ec9e72, 0x094a4309, 0x41105141, 0xd324f7d3, + 0x46d59346 , 0xbf53ecbf, 0x62f89a62, 0xe9927be9, 0xccff33cc, 0x51045551, + 0x2c270b2c , 0x0d4f420d, 0xb759eeb7, 0x3ff3cc3f, 0xb21caeb2, 0x89ea6389, + 0x9374e793 , 0xce7fb1ce, 0x706c1c70, 0xa60daba6, 0x27edca27, 0x20280820, + 0xa348eba3 , 0x56c19756, 0x02808202, 0x7fa3dc7f, 0x52c49652, 0xeb12f9eb, + 0xd5a174d5 , 0x3eb38d3e, 0xfcc33ffc, 0x9a3ea49a, 0x1d5b461d, 0x1c1b071c, + 0x9e3ba59e , 0xf30cfff3, 0xcf3ff0cf, 0xcdbf72cd, 0x5c4b175c, 0xea52b8ea, + 0x0e8f810e , 0x653d5865, 0xf0cc3cf0, 0x647d1964, 0x9b7ee59b, 0x16918716, + 0x3d734e3d , 0xa208aaa2, 0xa1c869a1, 0xadc76aad, 0x06858306, 0xca7ab0ca, + 0xc5b570c5 , 0x91f46591, 0x6bb2d96b, 0x2ea7892e, 0xe318fbe3, 0xaf47e8af, + 0x3c330f3c , 0x2d674a2d, 0xc1b071c1, 0x590e5759, 0x76e99f76, 0xd4e135d4, + 0x78661e78 , 0x90b42490, 0x38360e38, 0x79265f79, 0x8def628d, 0x61385961, + 0x4795d247 , 0x8a2aa08a, 0x94b12594, 0x88aa2288, 0xf18c7df1, 0xecd73bec, + 0x04050104 , 0x84a52184, 0xe19879e1, 0x1e9b851e, 0x5384d753, 0x00000000, + 0x195e4719 , 0x5d0b565d, 0x7ee39d7e, 0x4f9fd04f, 0x9cbb279c, 0x491a5349, + 0x317c4d31 , 0xd8ee36d8, 0x080a0208, 0x9f7be49f, 0x8220a282, 0x13d4c713, + 0x23e8cb23 , 0x7ae69c7a, 0xab42e9ab, 0xfe43bdfe, 0x2aa2882a, 0x4b9ad14b, + 0x01404101 , 0x1fdbc41f, 0xe0d838e0, 0xd661b7d6, 0x8e2fa18e, 0xdf2bf4df, + 0xcb3af1cb , 0x3bf6cd3b, 0xe71dfae7, 0x85e56085, 0x54411554, 0x8625a386, + 0x8360e383 , 0xba16acba, 0x75295c75, 0x9234a692, 0x6ef7996e, 0xd0e434d0, + 0x68721a68 , 0x55015455, 0xb619afb6, 0x4edf914e, 0xc8fa32c8, 0xc0f030c0, + 0xd721f6d7 , 0x32bc8e32, 0xc675b3c6, 0x8f6fe08f, 0x74691d74, 0xdb2ef5db, + 0x8b6ae18b , 0xb8962eb8, 0x0a8a800a, 0x99fe6799, 0x2be2c92b, 0x81e06181, + 0x03c0c303 , 0xa48d29a4, 0x8caf238c, 0xae07a9ae, 0x34390d34, 0x4d1f524d, + 0x39764f39 , 0xbdd36ebd, 0x5781d657, 0x6fb7d86f, 0xdceb37dc, 0x15514415, + 0x7ba6dd7b , 0xf709fef7, 0x3ab68c3a, 0xbc932fbc, 0x0c0f030c, 0xff03fcff, + 0xa9c26ba9 , 0xc9ba73c9, 0xb5d96cb5, 0xb1dc6db1, 0x6d375a6d, 0x45155045, + 0x36b98f36 , 0x6c771b6c, 0xbe13adbe, 0x4ada904a, 0xee57b9ee, 0x77a9de77, + 0xf24cbef2 , 0xfd837efd, 0x44551144, 0x67bdda67, 0x712c5d71, 0x05454005, + 0x7c631f7c , 0x40501040, 0x69325b69, 0x63b8db63, 0x28220a28, 0x07c5c207, + 0xc4f531c4 , 0x22a88a22, 0x9631a796, 0x37f9ce37, 0xed977aed, 0xf649bff6, + 0xb4992db4 , 0xd1a475d1, 0x4390d343, 0x485a1248, 0xe258bae2, 0x9771e697, + 0xd264b6d2 , 0xc270b2c2, 0x26ad8b26, 0xa5cd68a5, 0x5ecb955e, 0x29624b29, + 0x303c0c30 , 0x5ace945a, 0xddab76dd, 0xf9867ff9, 0x95f16495, 0xe65dbbe6, + 0xc735f2c7 , 0x242d0924, 0x17d1c617, 0xb9d66fb9, 0x1bdec51b, 0x12948612, + 0x60781860 , 0xc330f3c3, 0xf5897cf5, 0xb35cefb3, 0xe8d23ae8, 0x73acdf73, + 0x35794c35 , 0x80a02080, 0xe59d78e5, 0xbb56edbb, 0x7d235e7d, 0xf8c63ef8, + 0x5f8bd45f , 0x2fe7c82f, 0xe4dd39e4, 0x21684921, +]! +const table2 = [ +u32(0x5b5b8ed5), 0x4242d092, 0xa7a74dea, 0xfbfb06fd, 0x3333fccf, 0x878765e2, + 0xf4f4c93d , 0xdede6bb5, 0x58584e16, 0xdada6eb4, 0x50504414, 0x0b0bcac1, + 0xa0a08828 , 0xefef17f8, 0xb0b09c2c, 0x14141105, 0xacac872b, 0x9d9dfb66, + 0x6a6af298 , 0xd9d9ae77, 0xa8a8822a, 0xfafa46bc, 0x10101404, 0x0f0fcfc0, + 0xaaaa02a8 , 0x11115445, 0x4c4c5f13, 0x9898be26, 0x25256d48, 0x1a1a9e84, + 0x18181e06 , 0x6666fd9b, 0x7272ec9e, 0x09094a43, 0x41411051, 0xd3d324f7, + 0x4646d593 , 0xbfbf53ec, 0x6262f89a, 0xe9e9927b, 0xccccff33, 0x51510455, + 0x2c2c270b , 0x0d0d4f42, 0xb7b759ee, 0x3f3ff3cc, 0xb2b21cae, 0x8989ea63, + 0x939374e7 , 0xcece7fb1, 0x70706c1c, 0xa6a60dab, 0x2727edca, 0x20202808, + 0xa3a348eb , 0x5656c197, 0x02028082, 0x7f7fa3dc, 0x5252c496, 0xebeb12f9, + 0xd5d5a174 , 0x3e3eb38d, 0xfcfcc33f, 0x9a9a3ea4, 0x1d1d5b46, 0x1c1c1b07, + 0x9e9e3ba5 , 0xf3f30cff, 0xcfcf3ff0, 0xcdcdbf72, 0x5c5c4b17, 0xeaea52b8, + 0x0e0e8f81 , 0x65653d58, 0xf0f0cc3c, 0x64647d19, 0x9b9b7ee5, 0x16169187, + 0x3d3d734e , 0xa2a208aa, 0xa1a1c869, 0xadadc76a, 0x06068583, 0xcaca7ab0, + 0xc5c5b570 , 0x9191f465, 0x6b6bb2d9, 0x2e2ea789, 0xe3e318fb, 0xafaf47e8, + 0x3c3c330f , 0x2d2d674a, 0xc1c1b071, 0x59590e57, 0x7676e99f, 0xd4d4e135, + 0x7878661e , 0x9090b424, 0x3838360e, 0x7979265f, 0x8d8def62, 0x61613859, + 0x474795d2 , 0x8a8a2aa0, 0x9494b125, 0x8888aa22, 0xf1f18c7d, 0xececd73b, + 0x04040501 , 0x8484a521, 0xe1e19879, 0x1e1e9b85, 0x535384d7, 0x00000000, + 0x19195e47 , 0x5d5d0b56, 0x7e7ee39d, 0x4f4f9fd0, 0x9c9cbb27, 0x49491a53, + 0x31317c4d , 0xd8d8ee36, 0x08080a02, 0x9f9f7be4, 0x828220a2, 0x1313d4c7, + 0x2323e8cb , 0x7a7ae69c, 0xabab42e9, 0xfefe43bd, 0x2a2aa288, 0x4b4b9ad1, + 0x01014041 , 0x1f1fdbc4, 0xe0e0d838, 0xd6d661b7, 0x8e8e2fa1, 0xdfdf2bf4, + 0xcbcb3af1 , 0x3b3bf6cd, 0xe7e71dfa, 0x8585e560, 0x54544115, 0x868625a3, + 0x838360e3 , 0xbaba16ac, 0x7575295c, 0x929234a6, 0x6e6ef799, 0xd0d0e434, + 0x6868721a , 0x55550154, 0xb6b619af, 0x4e4edf91, 0xc8c8fa32, 0xc0c0f030, + 0xd7d721f6 , 0x3232bc8e, 0xc6c675b3, 0x8f8f6fe0, 0x7474691d, 0xdbdb2ef5, + 0x8b8b6ae1 , 0xb8b8962e, 0x0a0a8a80, 0x9999fe67, 0x2b2be2c9, 0x8181e061, + 0x0303c0c3 , 0xa4a48d29, 0x8c8caf23, 0xaeae07a9, 0x3434390d, 0x4d4d1f52, + 0x3939764f , 0xbdbdd36e, 0x575781d6, 0x6f6fb7d8, 0xdcdceb37, 0x15155144, + 0x7b7ba6dd , 0xf7f709fe, 0x3a3ab68c, 0xbcbc932f, 0x0c0c0f03, 0xffff03fc, + 0xa9a9c26b , 0xc9c9ba73, 0xb5b5d96c, 0xb1b1dc6d, 0x6d6d375a, 0x45451550, + 0x3636b98f , 0x6c6c771b, 0xbebe13ad, 0x4a4ada90, 0xeeee57b9, 0x7777a9de, + 0xf2f24cbe , 0xfdfd837e, 0x44445511, 0x6767bdda, 0x71712c5d, 0x05054540, + 0x7c7c631f , 0x40405010, 0x6969325b, 0x6363b8db, 0x2828220a, 0x0707c5c2, + 0xc4c4f531 , 0x2222a88a, 0x969631a7, 0x3737f9ce, 0xeded977a, 0xf6f649bf, + 0xb4b4992d , 0xd1d1a475, 0x434390d3, 0x48485a12, 0xe2e258ba, 0x979771e6, + 0xd2d264b6 , 0xc2c270b2, 0x2626ad8b, 0xa5a5cd68, 0x5e5ecb95, 0x2929624b, + 0x30303c0c , 0x5a5ace94, 0xddddab76, 0xf9f9867f, 0x9595f164, 0xe6e65dbb, + 0xc7c735f2 , 0x24242d09, 0x1717d1c6, 0xb9b9d66f, 0x1b1bdec5, 0x12129486, + 0x60607818 , 0xc3c330f3, 0xf5f5897c, 0xb3b35cef, 0xe8e8d23a, 0x7373acdf, + 0x3535794c , 0x8080a020, 0xe5e59d78, 0xbbbb56ed, 0x7d7d235e, 0xf8f8c63e, + 0x5f5f8bd4 , 0x2f2fe7c8, 0xe4e4dd39, 0x21216849, +]! +const table3 = [ +u32(0xd55b5b8e), 0x924242d0, 0xeaa7a74d, 0xfdfbfb06, 0xcf3333fc, 0xe2878765, + 0x3df4f4c9 , 0xb5dede6b, 0x1658584e, 0xb4dada6e, 0x14505044, 0xc10b0bca, + 0x28a0a088 , 0xf8efef17, 0x2cb0b09c, 0x05141411, 0x2bacac87, 0x669d9dfb, + 0x986a6af2 , 0x77d9d9ae, 0x2aa8a882, 0xbcfafa46, 0x04101014, 0xc00f0fcf, + 0xa8aaaa02 , 0x45111154, 0x134c4c5f, 0x269898be, 0x4825256d, 0x841a1a9e, + 0x0618181e , 0x9b6666fd, 0x9e7272ec, 0x4309094a, 0x51414110, 0xf7d3d324, + 0x934646d5 , 0xecbfbf53, 0x9a6262f8, 0x7be9e992, 0x33ccccff, 0x55515104, + 0x0b2c2c27 , 0x420d0d4f, 0xeeb7b759, 0xcc3f3ff3, 0xaeb2b21c, 0x638989ea, + 0xe7939374 , 0xb1cece7f, 0x1c70706c, 0xaba6a60d, 0xca2727ed, 0x08202028, + 0xeba3a348 , 0x975656c1, 0x82020280, 0xdc7f7fa3, 0x965252c4, 0xf9ebeb12, + 0x74d5d5a1 , 0x8d3e3eb3, 0x3ffcfcc3, 0xa49a9a3e, 0x461d1d5b, 0x071c1c1b, + 0xa59e9e3b , 0xfff3f30c, 0xf0cfcf3f, 0x72cdcdbf, 0x175c5c4b, 0xb8eaea52, + 0x810e0e8f , 0x5865653d, 0x3cf0f0cc, 0x1964647d, 0xe59b9b7e, 0x87161691, + 0x4e3d3d73 , 0xaaa2a208, 0x69a1a1c8, 0x6aadadc7, 0x83060685, 0xb0caca7a, + 0x70c5c5b5 , 0x659191f4, 0xd96b6bb2, 0x892e2ea7, 0xfbe3e318, 0xe8afaf47, + 0x0f3c3c33 , 0x4a2d2d67, 0x71c1c1b0, 0x5759590e, 0x9f7676e9, 0x35d4d4e1, + 0x1e787866 , 0x249090b4, 0x0e383836, 0x5f797926, 0x628d8def, 0x59616138, + 0xd2474795 , 0xa08a8a2a, 0x259494b1, 0x228888aa, 0x7df1f18c, 0x3bececd7, + 0x01040405 , 0x218484a5, 0x79e1e198, 0x851e1e9b, 0xd7535384, 0x00000000, + 0x4719195e , 0x565d5d0b, 0x9d7e7ee3, 0xd04f4f9f, 0x279c9cbb, 0x5349491a, + 0x4d31317c , 0x36d8d8ee, 0x0208080a, 0xe49f9f7b, 0xa2828220, 0xc71313d4, + 0xcb2323e8 , 0x9c7a7ae6, 0xe9abab42, 0xbdfefe43, 0x882a2aa2, 0xd14b4b9a, + 0x41010140 , 0xc41f1fdb, 0x38e0e0d8, 0xb7d6d661, 0xa18e8e2f, 0xf4dfdf2b, + 0xf1cbcb3a , 0xcd3b3bf6, 0xfae7e71d, 0x608585e5, 0x15545441, 0xa3868625, + 0xe3838360 , 0xacbaba16, 0x5c757529, 0xa6929234, 0x996e6ef7, 0x34d0d0e4, + 0x1a686872 , 0x54555501, 0xafb6b619, 0x914e4edf, 0x32c8c8fa, 0x30c0c0f0, + 0xf6d7d721 , 0x8e3232bc, 0xb3c6c675, 0xe08f8f6f, 0x1d747469, 0xf5dbdb2e, + 0xe18b8b6a , 0x2eb8b896, 0x800a0a8a, 0x679999fe, 0xc92b2be2, 0x618181e0, + 0xc30303c0 , 0x29a4a48d, 0x238c8caf, 0xa9aeae07, 0x0d343439, 0x524d4d1f, + 0x4f393976 , 0x6ebdbdd3, 0xd6575781, 0xd86f6fb7, 0x37dcdceb, 0x44151551, + 0xdd7b7ba6 , 0xfef7f709, 0x8c3a3ab6, 0x2fbcbc93, 0x030c0c0f, 0xfcffff03, + 0x6ba9a9c2 , 0x73c9c9ba, 0x6cb5b5d9, 0x6db1b1dc, 0x5a6d6d37, 0x50454515, + 0x8f3636b9 , 0x1b6c6c77, 0xadbebe13, 0x904a4ada, 0xb9eeee57, 0xde7777a9, + 0xbef2f24c , 0x7efdfd83, 0x11444455, 0xda6767bd, 0x5d71712c, 0x40050545, + 0x1f7c7c63 , 0x10404050, 0x5b696932, 0xdb6363b8, 0x0a282822, 0xc20707c5, + 0x31c4c4f5 , 0x8a2222a8, 0xa7969631, 0xce3737f9, 0x7aeded97, 0xbff6f649, + 0x2db4b499 , 0x75d1d1a4, 0xd3434390, 0x1248485a, 0xbae2e258, 0xe6979771, + 0xb6d2d264 , 0xb2c2c270, 0x8b2626ad, 0x68a5a5cd, 0x955e5ecb, 0x4b292962, + 0x0c30303c , 0x945a5ace, 0x76ddddab, 0x7ff9f986, 0x649595f1, 0xbbe6e65d, + 0xf2c7c735 , 0x0924242d, 0xc61717d1, 0x6fb9b9d6, 0xc51b1bde, 0x86121294, + 0x18606078 , 0xf3c3c330, 0x7cf5f589, 0xefb3b35c, 0x3ae8e8d2, 0xdf7373ac, + 0x4c353579 , 0x208080a0, 0x78e5e59d, 0xedbbbb56, 0x5e7d7d23, 0x3ef8f8c6, + 0xd45f5f8b , 0xc82f2fe7, 0x39e4e4dd, 0x49212168, +]! +// vfmt on + +// big_endian_u32 creates a u32 from four bytes in the array b in big endian order. +@[direct_array_access; inline] +fn big_endian_u32(b [4]u8) u32 { + return u32(b[3]) | (u32(b[2]) << u32(8)) | (u32(b[1]) << u32(16)) | (u32(b[0]) << u32(24)) +} + +// big_endian_put_u32 writes a u32 to the first four bytes in the array b in big endian order. +@[direct_array_access; inline] +fn big_endian_put_u32(mut b [4]u8, v u32) { + b[0] = u8(v >> u32(24)) + b[1] = u8(v >> u32(16)) + b[2] = u8(v >> u32(8)) + b[3] = u8(v) +} + +// big_endian_u128 convert 16 bytes in the array `b` into 4 u32 in the array `u` in big endian order. +@[direct_array_access; inline] +fn big_endian_u128(b [16]u8, mut u [4]u32) { + for i in 0 .. 4 { + u[i] = u32(b[i * 4 + 3]) | (u32(b[i * 4 + 2]) << u32(8)) | (u32(b[i * 4 + 1]) << u32(16)) | (u32(b[ + i * 4 + 0]) << u32(24)) + } +} + +// big_endian_put_u128_reverse writes 4 u32 to the 16 bytes in the array `b` in big endian order. +@[direct_array_access; inline] +fn big_endian_put_u128_reverse(mut b [16]u8, v [4]u32) { + for i in 0 .. 4 { + b[i * 4 + 0] = u8(v[3 - i] >> u32(24)) + b[i * 4 + 1] = u8(v[3 - i] >> u32(16)) + b[i * 4 + 2] = u8(v[3 - i] >> u32(8)) + b[i * 4 + 3] = u8(v[3 - i]) + } +} + +// sm4_tl performance the "T algorithm" == "t algorithm" + "L algorithm" funciton. +@[direct_array_access; inline] +fn sm4_tl(ka u32) u32 { + mut a := [4]u8{} + mut b := [4]u8{} + + // Divide ka into 4 bytes, then use sbox transfer, combine again into a new u32 + big_endian_put_u32(mut a, ka) + b[3], b[2], b[1], b[0] = sm4.sbox[a[3]], sm4.sbox[a[2]], sm4.sbox[a[1]], sm4.sbox[a[0]] + bb := big_endian_u32(b) + + // Rotate Left Shift 02, 10, 18, 24 + t_02 := bb << 2 | bb >> (32 - 2) // ROL(bb, 02) + t_10 := bb << 10 | bb >> (32 - 10) // ROL(bb, 10) + t_18 := bb << 18 | bb >> (32 - 18) // ROL(bb, 18) + t_24 := bb << 24 | bb >> (32 - 24) // ROL(bb, 24) + return bb ^ t_02 ^ t_10 ^ t_18 ^ t_24 +} + +// calculate_irk calculating round encryption key. +// args: [in] ka: ka is a 32 bits unsigned value +// return: rk[i]: i{0,1,2,3,...31}. +@[direct_array_access; inline] +fn calculate_irk(ka u32) u32 { + mut a := [4]u8{} + mut b := [4]u8{} + + // Divide ka into 4 bytes, then use sbox transfer, combine them into a new u32 + big_endian_put_u32(mut a, ka) + b[3], b[2], b[1], b[0] = sm4.sbox[a[3]], sm4.sbox[a[2]], sm4.sbox[a[1]], sm4.sbox[a[0]] + bb := big_endian_u32(b) + + // Rotate Left Shift 13, 23 + t_13 := bb << 13 | bb >> (32 - 13) // ROL(bb, 13) + t_23 := bb << 23 | bb >> (32 - 23) // ROL(bb, 23) + return bb ^ t_13 ^ t_23 +} + +// key_expansion +@[direct_array_access] +fn key_expansion(mut rk [32]u32, key [16]u8) { + mut mk := [4]u32{} + mut k := [36]u32{} + + // k = key ^ fk + big_endian_u128(key, mut mk) + k[3], k[2], k[1], k[0] = mk[3] ^ sm4.fk[3], mk[2] ^ sm4.fk[2], mk[1] ^ sm4.fk[1], mk[0] ^ sm4.fk[0] + + // generate the round keys + for i in 0 .. 32 { + // TODO: use 8:32 lookup table speedup + k[i + 4] = k[i] ^ calculate_irk(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ sm4.ck[i]) + rk[i] = k[i + 4] + } +} + +// one_round SM4 standard one round processing +@[direct_array_access] +fn one_round(rk [32]u32, input [16]u8, mut output [16]u8) { + mut x := [4]u32{} + mut tmp := u32(0) + mut tmp1 := u32(0) + + big_endian_u128(input, mut x) + for i in 0 .. 32 { + tmp = x[1] ^ x[2] ^ x[3] ^ rk[i] + $if sm4_slow_version ? { + // use official algorithm + tmp1 = x[0] ^ sm4_tl(tmp) + } $else { + // use 8:32 lookup table + tmp1 = x[0] ^ sm4.table0[(tmp >> 24) & 0xff] ^ sm4.table1[(tmp >> 16) & 0xff] ^ sm4.table2[(tmp >> 8) & 0xff] ^ sm4.table3[(tmp >> 0) & 0xff] + } + x[3], x[2], x[1], x[0] = tmp1, x[3], x[2], x[1] + } + big_endian_put_u128_reverse(mut output, x) +} + +pub enum Mode { + sm4_encrypt = 0 + sm4_decrypt = 1 +} + +pub struct SM4Cipher { +mut: + mode Mode + rk [32]u32 // SM4 round keys +} + +// new_cipher creates and returns a new SM4Cipher. +// The `mode` should be `.sm4_encrypt` or `.sm4_decrypt`. +// The key argument must be the 16 bytes SM4 key. +@[direct_array_access] +pub fn new_cipher(mode Mode, key []u8) !&SM4Cipher { + if key.len != 16 { + return error('SM4 only support 128bit key length') + } + mut c := &SM4Cipher{ + mode: mode + } + // fixed size array, avoid alloc on heap + key_16 := [key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7], key[8], key[9], + key[10], key[11], key[12], key[13], key[14], key[15]]! + key_expansion(mut c.rk, key_16) + if mode == .sm4_decrypt { + // In SM4, encrypt/decrypt use the same process, except the key order is reversed. + // reverse key in decrypt mode + for i in 0 .. 16 { + c.rk[i], c.rk[31 - i] = c.rk[31 - i], c.rk[i] + } + } + return c +} + +// crypt_ecb SM4-ECB block encryption/decryption +// `input` must be padded to mutiple of 16 bytes. +// `output` must be exactly the same length as `input`. +@[direct_array_access] +pub fn (c &SM4Cipher) crypt_ecb(input []u8, mut output []u8) ! { + mut length := input.len + if length & 0x0f != 0 || length == 0 { + return error('input must be padded to mutiple of 16 bytes') + } + if length != output.len { + return error('output must be exactly the same length as input') + } + mut idx := 0 + // fixed size array, avoid alloc on heap + mut input_16 := [16]u8{} + mut output_16 := [16]u8{} + + for length > 0 { + // use round keys encrypt/decrypt the input, 128bit per block + unsafe { vmemcpy(&input_16, &input[idx], 16) } // convert to fixed size array + one_round(c.rk, input_16, mut output_16) + unsafe { vmemcpy(&output[idx], &output_16, 16) } // convert from fixed size array + idx += 16 + length -= 16 + } +} + +// crypt_cbc SM4-CBC buffer encryption/decryption +// `iv` is a 16 bytes Initialization Vector. +// `input` must be padded to mutiple of 16 bytes. +// `output` must be exactly the same length as `input`. +@[direct_array_access] +pub fn (c &SM4Cipher) crypt_cbc(mut iv []u8, input []u8, mut output []u8) ! { + mut idx := 0 + mut length := input.len + if length & 0x0f != 0 || length == 0 { + return error('input must be padded to mutiple of 16 bytes') + } + if length != output.len { + return error('output must be exactly the same length as input') + } + if iv.len != 16 { + return error('iv length must be exactly 16 bytes') + } + + // fixed size array, avoid alloc on heap + mut input_16 := [16]u8{} + mut output_16 := [16]u8{} + + match c.mode { + .sm4_encrypt { + for length > 0 { + // processing a 128bit block + for i in 0 .. 16 { + input_16[i] = input[idx + i] ^ iv[i] // convert to fixed size array + } + // use round keys encrypt the input_16 + one_round(c.rk, input_16, mut output_16) + unsafe { vmemcpy(&iv[0], &output_16, 16) } // update iv with output + unsafe { vmemcpy(&output[idx], &output_16, 16) } // convert from fixed size array + idx += 16 + length -= 16 + } + } + .sm4_decrypt { + for length > 0 { + // processing a 128bit block + unsafe { vmemcpy(&input_16, &input[idx], 16) } // convert to fixed size array + // use round keys decrypt the input_16 + one_round(c.rk, input_16, mut output_16) + for i in 0 .. 16 { + output[idx + i] = output_16[i] ^ iv[i] // update output with iv + iv[i] = input_16[i] // update iv with input + } + idx += 16 + length -= 16 + } + } + } +} diff --git a/vlib/x/crypto/sm4/sm4_test.v b/vlib/x/crypto/sm4/sm4_test.v new file mode 100644 index 00000000000000..536f4654c4f224 --- /dev/null +++ b/vlib/x/crypto/sm4/sm4_test.v @@ -0,0 +1,213 @@ +// online tester: https://lzltool.cn/SM4 +import x.crypto.sm4 + +fn test_sm4_ecb() ! { + mut key := [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, + 0x54, 0x32, 0x10] + mut input := [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, + 0x54, 0x32, 0x10] + mut output := []u8{len: 16} + + // key = 0123456789abcdeffedcba9876543210 + // plaintext = 0123456789abcdeffedcba9876543210 + // ciphertext = 681edf34d206965e86b3e94f536e4246 + mut c1 := sm4.new_cipher(.sm4_encrypt, key)! + c1.crypt_ecb(input, mut output)! + assert output.hex() == '681edf34d206965e86b3e94f536e4246' + mut d1 := sm4.new_cipher(.sm4_decrypt, key)! + d1.crypt_ecb(output, mut output)! + assert output.hex() == '0123456789abcdeffedcba9876543210' + + // key = 0123456789abcdeffedcba9876543210 + // plaintext = 00112233445566778899aabbccddeeff + // ciphertext = 09325c4853832dcb9337a5984f671b9a + key = [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, + 0x32, 0x10] + input = [u8(0x00), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff] + output = []u8{len: 16} + mut c2 := sm4.new_cipher(.sm4_encrypt, key)! + c2.crypt_ecb(input, mut output)! + assert output.hex() == '09325c4853832dcb9337a5984f671b9a' + mut d2 := sm4.new_cipher(.sm4_decrypt, key)! + d2.crypt_ecb(output, mut output)! + assert output.hex() == '00112233445566778899aabbccddeeff' + + // key = 456789abcdeffedcba98765432100123 + // plaintext = 2233445566778899aabbccddeeff0011 + // ciphertext = 58ab414d84fb3008b0bee987f97021e6 + key = [u8(0x45), 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x01, 0x23] + input = [u8(0x22), 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, + 0xff, 0x00, 0x11] + output = []u8{len: 16} + mut c3 := sm4.new_cipher(.sm4_encrypt, key)! + c3.crypt_ecb(input, mut output)! + assert output.hex() == '58ab414d84fb3008b0bee987f97021e6' + mut d3 := sm4.new_cipher(.sm4_decrypt, key)! + d3.crypt_ecb(output, mut output)! + assert output.hex() == '2233445566778899aabbccddeeff0011' + + // key = 89abcdeffedcba987654321001234567 + // plaintext = 445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233 + // ciphertext = 5937a929a2d9137216c72a28cd9cf6195937a929a2d9137216c72a28cd9cf619 + key = [u8(0x89), 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, + 0x45, 0x67] + input = [u8(0x44), 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0x00, 0x11, 0x22, 0x33] + output = []u8{len: 32} + mut c4 := sm4.new_cipher(.sm4_encrypt, key)! + c4.crypt_ecb(input, mut output)! + assert output.hex() == '5937a929a2d9137216c72a28cd9cf6195937a929a2d9137216c72a28cd9cf619' + mut d4 := sm4.new_cipher(.sm4_decrypt, key)! + d4.crypt_ecb(output, mut output)! + assert output.hex() == '445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233' +} + +fn test_sm4_cbc() ! { + mut key := [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, + 0x54, 0x32, 0x10] + mut iv := [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, + 0x54, 0x32, 0x10] + mut orig_iv := iv.clone() + mut input := [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, + 0x54, 0x32, 0x10] + mut output := []u8{len: 16} + + // key = 0123456789abcdeffedcba9876543210 + // iv = 0123456789abcdeffedcba9876543210 + // plaintext = 0123456789abcdeffedcba9876543210 + // ciphertext = 2677f46b09c122cc975533105bd4a22a + mut c1 := sm4.new_cipher(.sm4_encrypt, key)! + c1.crypt_cbc(mut iv, input, mut output)! + assert output.hex() == '2677f46b09c122cc975533105bd4a22a' + iv = orig_iv.clone() + mut d1 := sm4.new_cipher(.sm4_decrypt, key)! + d1.crypt_cbc(mut iv, output, mut output)! + assert output.hex() == '0123456789abcdeffedcba9876543210' + + // key = 0123456789abcdeffedcba9876543210 + // iv = 112233445566778899aabbccddeeff00 + // plaintext = 00112233445566778899aabbccddeeff + // ciphertext = c3c0fffdcaac88ed63672b2b28a84e80 + key = [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, + 0x32, 0x10] + iv = [u8(0x11), 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, + 0xff, 0x00] + orig_iv = iv.clone() + input = [u8(0x00), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, + 0xdd, 0xee, 0xff] + output = []u8{len: 16} + mut c2 := sm4.new_cipher(.sm4_encrypt, key)! + c2.crypt_cbc(mut iv, input, mut output)! + assert output.hex() == 'c3c0fffdcaac88ed63672b2b28a84e80' + iv = orig_iv.clone() + mut d2 := sm4.new_cipher(.sm4_decrypt, key)! + d2.crypt_cbc(mut iv, output, mut output)! + assert output.hex() == '00112233445566778899aabbccddeeff' + + // key = 456789abcdeffedcba98765432100123 + // iv = 33445566778899aabbccddeeff001122 + // plaintext = 2233445566778899aabbccddeeff0011 + // ciphertext = 63dfbfc357c2e040b529c692ec916c6b + key = [u8(0x45), 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x01, 0x23] + iv = [u8(0x33), 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, + 0x11, 0x22] + orig_iv = iv.clone() + input = [u8(0x22), 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, + 0xff, 0x00, 0x11] + output = []u8{len: 16} + mut c3 := sm4.new_cipher(.sm4_encrypt, key)! + c3.crypt_cbc(mut iv, input, mut output)! + assert output.hex() == '63dfbfc357c2e040b529c692ec916c6b' + iv = orig_iv.clone() + mut d3 := sm4.new_cipher(.sm4_decrypt, key)! + d3.crypt_cbc(mut iv, output, mut output)! + assert output.hex() == '2233445566778899aabbccddeeff0011' + + // key = 89abcdeffedcba987654321001234567 + // iv = 48bb57369d2020c66ded73415bfab211 + // plaintext = 445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233 + // ciphertext = 2aac9d5427ddca8f2ef2eaa175012bcb66a1fd8df190a7db9f053f0ee40d79b5 + key = [u8(0x89), 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, + 0x45, 0x67] + iv = [u8(0x48), 0xbb, 0x57, 0x36, 0x9d, 0x20, 0x20, 0xc6, 0x6d, 0xed, 0x73, 0x41, 0x5b, 0xfa, + 0xb2, 0x11] + orig_iv = iv.clone() + input = [u8(0x44), 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0x00, 0x11, 0x22, 0x33] + output = []u8{len: 32} + mut c4 := sm4.new_cipher(.sm4_encrypt, key)! + c4.crypt_cbc(mut iv, input, mut output)! + assert output.hex() == '2aac9d5427ddca8f2ef2eaa175012bcb66a1fd8df190a7db9f053f0ee40d79b5' + iv = orig_iv.clone() + mut d4 := sm4.new_cipher(.sm4_decrypt, key)! + d4.crypt_cbc(mut iv, output, mut output)! + assert output.hex() == '445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233' +} + +fn test_sm4_wrong_length() ! { + // wrong key length test + mut fail_flag := false + sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(33)) or { + fail_flag = true + assert err.msg() == 'SM4 only support 128bit key length' + } + assert fail_flag + + fail_flag = false + sm4.new_cipher(.sm4_decrypt, [u8(0xff)].repeat(33)) or { + fail_flag = true + assert err.msg() == 'SM4 only support 128bit key length' + } + assert fail_flag + + // wrong input length test(ecb) + mut output := []u8{len: 32} + fail_flag = false + mut c1 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))! + c1.crypt_ecb([u8(0xff)].repeat(111), mut output) or { + fail_flag = true + assert err.msg() == 'input must be padded to mutiple of 16 bytes' + } + assert fail_flag + + // wrong output length test(ecb) + fail_flag = false + mut c2 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))! + c2.crypt_ecb([u8(0xff)].repeat(16), mut output) or { + fail_flag = true + assert err.msg() == 'output must be exactly the same length as input' + } + assert fail_flag + + // wrong iv length test(cbc) + fail_flag = false + mut c3 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))! + c3.crypt_cbc(mut [u8(0xff)].repeat(22), [u8(0xff)].repeat(16), mut [u8(0xff)].repeat(16)) or { + fail_flag = true + assert err.msg() == 'iv length must be exactly 16 bytes' + } + assert fail_flag + + // wrong input length test(cbc) + fail_flag = false + mut c4 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))! + c4.crypt_cbc(mut [u8(0xff)].repeat(16), [u8(0xff)].repeat(111), mut output) or { + fail_flag = true + assert err.msg() == 'input must be padded to mutiple of 16 bytes' + } + assert fail_flag + + // wrong output length test(cbc) + fail_flag = false + mut c5 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))! + c5.crypt_cbc(mut [u8(0xff)].repeat(16), [u8(0xff)].repeat(16), mut output) or { + fail_flag = true + assert err.msg() == 'output must be exactly the same length as input' + } + assert fail_flag +}