11// online tester: https://lzltool.cn/SM4
22import x.crypto.sm4
33
4- fn test_sm4_ecb () ! {
5- mut key := [u8 (0x01 ), 0x23 , 0x45 , 0x67 , 0x89 , 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 ,
6- 0x54 , 0x32 , 0x10 ]
7- mut input := [u8 (0x01 ), 0x23 , 0x45 , 0x67 , 0x89 , 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 ,
8- 0x54 , 0x32 , 0x10 ]
9- mut output := []u8 {len: 16 }
10-
11- // key = 0123456789abcdeffedcba9876543210
12- // plaintext = 0123456789abcdeffedcba9876543210
13- // ciphertext = 681edf34d206965e86b3e94f536e4246
14- mut c1 := sm4 .new_cipher (.sm4_ encrypt, key)!
15- c1 .crypt_ecb (input, mut output)!
16- assert output.hex () == '681edf34d206965e86b3e94f536e4246'
17- mut d1 := sm4 .new_cipher (.sm4_ decrypt, key)!
18- d1 .crypt_ecb (output, mut output)!
19- assert output.hex () == '0123456789abcdeffedcba9876543210'
20-
21- // key = 0123456789abcdeffedcba9876543210
22- // plaintext = 00112233445566778899aabbccddeeff
23- // ciphertext = 09325c4853832dcb9337a5984f671b9a
24- key = [u8 (0x01 ), 0x23 , 0x45 , 0x67 , 0x89 , 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 , 0x54 ,
25- 0x32 , 0x10 ]
26- input = [u8 (0x00 ), 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc ,
27- 0xdd , 0xee , 0xff ]
28- output = []u8 {len: 16 }
29- mut c2 := sm4 .new_cipher (.sm4_ encrypt, key)!
30- c2 .crypt_ecb (input, mut output)!
31- assert output.hex () == '09325c4853832dcb9337a5984f671b9a'
32- mut d2 := sm4 .new_cipher (.sm4_ decrypt, key)!
33- d2 .crypt_ecb (output, mut output)!
34- assert output.hex () == '00112233445566778899aabbccddeeff'
35-
36- // key = 456789abcdeffedcba98765432100123
37- // plaintext = 2233445566778899aabbccddeeff0011
38- // ciphertext = 58ab414d84fb3008b0bee987f97021e6
39- key = [u8 (0x45 ), 0x67 , 0x89 , 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 , 0x54 , 0x32 , 0x10 ,
40- 0x01 , 0x23 ]
41- input = [u8 (0x22 ), 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee ,
42- 0xff , 0x00 , 0x11 ]
43- output = []u8 {len: 16 }
44- mut c3 := sm4 .new_cipher (.sm4_ encrypt, key)!
45- c3 .crypt_ecb (input, mut output)!
46- assert output.hex () == '58ab414d84fb3008b0bee987f97021e6'
47- mut d3 := sm4 .new_cipher (.sm4_ decrypt, key)!
48- d3 .crypt_ecb (output, mut output)!
49- assert output.hex () == '2233445566778899aabbccddeeff0011'
50-
51- // key = 89abcdeffedcba987654321001234567
52- // plaintext = 445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233
53- // ciphertext = 5937a929a2d9137216c72a28cd9cf6195937a929a2d9137216c72a28cd9cf619
54- key = [u8 (0x89 ), 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 , 0x54 , 0x32 , 0x10 , 0x01 , 0x23 ,
55- 0x45 , 0x67 ]
56- input = [u8 (0x44 ), 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff , 0x00 ,
57- 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ,
58- 0x00 , 0x11 , 0x22 , 0x33 ]
59- output = []u8 {len: 32 }
60- mut c4 := sm4 .new_cipher (.sm4_ encrypt, key)!
61- c4 .crypt_ecb (input, mut output)!
62- assert output.hex () == '5937a929a2d9137216c72a28cd9cf6195937a929a2d9137216c72a28cd9cf619'
63- mut d4 := sm4 .new_cipher (.sm4_ decrypt, key)!
64- d4 .crypt_ecb (output, mut output)!
65- assert output.hex () == '445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233'
4+ struct SM4Data {
5+ key string
6+ iv string
7+ input string
8+ output string
669}
6710
68- fn test_sm4_cbc () ! {
69- mut key := [u8 (0x01 ), 0x23 , 0x45 , 0x67 , 0x89 , 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 ,
70- 0x54 , 0x32 , 0x10 ]
71- mut iv := [u8 (0x01 ), 0x23 , 0x45 , 0x67 , 0x89 , 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 ,
72- 0x54 , 0x32 , 0x10 ]
73- mut orig_iv := iv.clone ()
74- mut input := [u8 (0x01 ), 0x23 , 0x45 , 0x67 , 0x89 , 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 ,
75- 0x54 , 0x32 , 0x10 ]
76- mut output := []u8 {len: 16 }
77-
78- // key = 0123456789abcdeffedcba9876543210
79- // iv = 0123456789abcdeffedcba9876543210
80- // plaintext = 0123456789abcdeffedcba9876543210
81- // ciphertext = 2677f46b09c122cc975533105bd4a22a
82- mut c1 := sm4 .new_cipher (.sm4_ encrypt, key)!
83- c1 .crypt_cbc (mut iv, input, mut output)!
84- assert output.hex () == '2677f46b09c122cc975533105bd4a22a'
85- iv = orig_iv.clone ()
86- mut d1 := sm4 .new_cipher (.sm4_ decrypt, key)!
87- d1 .crypt_cbc (mut iv, output, mut output)!
88- assert output.hex () == '0123456789abcdeffedcba9876543210'
89-
90- // key = 0123456789abcdeffedcba9876543210
91- // iv = 112233445566778899aabbccddeeff00
92- // plaintext = 00112233445566778899aabbccddeeff
93- // ciphertext = c3c0fffdcaac88ed63672b2b28a84e80
94- key = [u8 (0x01 ), 0x23 , 0x45 , 0x67 , 0x89 , 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 , 0x54 ,
95- 0x32 , 0x10 ]
96- iv = [u8 (0x11 ), 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee ,
97- 0xff , 0x00 ]
98- orig_iv = iv.clone ()
99- input = [u8 (0x00 ), 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc ,
100- 0xdd , 0xee , 0xff ]
101- output = []u8 {len: 16 }
102- mut c2 := sm4 .new_cipher (.sm4_ encrypt, key)!
103- c2 .crypt_cbc (mut iv, input, mut output)!
104- assert output.hex () == 'c3c0fffdcaac88ed63672b2b28a84e80'
105- iv = orig_iv.clone ()
106- mut d2 := sm4 .new_cipher (.sm4_ decrypt, key)!
107- d2 .crypt_cbc (mut iv, output, mut output)!
108- assert output.hex () == '00112233445566778899aabbccddeeff'
109-
110- // key = 456789abcdeffedcba98765432100123
111- // iv = 33445566778899aabbccddeeff001122
112- // plaintext = 2233445566778899aabbccddeeff0011
113- // ciphertext = 63dfbfc357c2e040b529c692ec916c6b
114- key = [u8 (0x45 ), 0x67 , 0x89 , 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 , 0x54 , 0x32 , 0x10 ,
115- 0x01 , 0x23 ]
116- iv = [u8 (0x33 ), 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff , 0x00 ,
117- 0x11 , 0x22 ]
118- orig_iv = iv.clone ()
119- input = [u8 (0x22 ), 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee ,
120- 0xff , 0x00 , 0x11 ]
121- output = []u8 {len: 16 }
122- mut c3 := sm4 .new_cipher (.sm4_ encrypt, key)!
123- c3 .crypt_cbc (mut iv, input, mut output)!
124- assert output.hex () == '63dfbfc357c2e040b529c692ec916c6b'
125- iv = orig_iv.clone ()
126- mut d3 := sm4 .new_cipher (.sm4_ decrypt, key)!
127- d3 .crypt_cbc (mut iv, output, mut output)!
128- assert output.hex () == '2233445566778899aabbccddeeff0011'
129-
130- // key = 89abcdeffedcba987654321001234567
131- // iv = 48bb57369d2020c66ded73415bfab211
132- // plaintext = 445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233
133- // ciphertext = 2aac9d5427ddca8f2ef2eaa175012bcb66a1fd8df190a7db9f053f0ee40d79b5
134- key = [u8 (0x89 ), 0xab , 0xcd , 0xef , 0xfe , 0xdc , 0xba , 0x98 , 0x76 , 0x54 , 0x32 , 0x10 , 0x01 , 0x23 ,
135- 0x45 , 0x67 ]
136- iv = [u8 (0x48 ), 0xbb , 0x57 , 0x36 , 0x9d , 0x20 , 0x20 , 0xc6 , 0x6d , 0xed , 0x73 , 0x41 , 0x5b , 0xfa ,
137- 0xb2 , 0x11 ]
138- orig_iv = iv.clone ()
139- input = [u8 (0x44 ), 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff , 0x00 ,
140- 0x11 , 0x22 , 0x33 , 0x44 , 0x55 , 0x66 , 0x77 , 0x88 , 0x99 , 0xaa , 0xbb , 0xcc , 0xdd , 0xee , 0xff ,
141- 0x00 , 0x11 , 0x22 , 0x33 ]
142- output = []u8 {len: 32 }
143- mut c4 := sm4 .new_cipher (.sm4_ encrypt, key)!
144- c4 .crypt_cbc (mut iv, input, mut output)!
145- assert output.hex () == '2aac9d5427ddca8f2ef2eaa175012bcb66a1fd8df190a7db9f053f0ee40d79b5'
146- iv = orig_iv.clone ()
147- mut d4 := sm4 .new_cipher (.sm4_ decrypt, key)!
148- d4 .crypt_cbc (mut iv, output, mut output)!
149- assert output.hex () == '445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233'
11+ const sm4data_ecb = [
12+ SM4 Data{
13+ key: '0123456789abcdeffedcba9876543210'
14+ input: '0123456789abcdeffedcba9876543210'
15+ output: '681edf34d206965e86b3e94f536e4246'
16+ },
17+ SM4 Data{
18+ key: '0123456789abcdeffedcba9876543210'
19+ input: '00112233445566778899aabbccddeeff'
20+ output: '09325c4853832dcb9337a5984f671b9a'
21+ },
22+ SM4 Data{
23+ key: '456789abcdeffedcba98765432100123'
24+ input: '2233445566778899aabbccddeeff0011'
25+ output: '58ab414d84fb3008b0bee987f97021e6'
26+ },
27+ SM4 Data{
28+ key: '89abcdeffedcba987654321001234567'
29+ input: '445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233'
30+ output: '5937a929a2d9137216c72a28cd9cf6195937a929a2d9137216c72a28cd9cf619'
31+ },
32+ ]
33+
34+ const sm4data_cbc = [
35+ SM4 Data{
36+ key: '0123456789abcdeffedcba9876543210'
37+ iv: '0123456789abcdeffedcba9876543210'
38+ input: '0123456789abcdeffedcba9876543210'
39+ output: '2677f46b09c122cc975533105bd4a22a'
40+ },
41+ SM4 Data{
42+ key: '0123456789abcdeffedcba9876543210'
43+ iv: '2677f46b09c122cc975533105bd4a22a'
44+ input: '00112233445566778899aabbccddeeff'
45+ output: '2e7b41173b42b90189bbcf4eeb5b5145'
46+ },
47+ SM4 Data{
48+ key: '0123456789abcdeffedcba9876543210'
49+ iv: '2e7b41173b42b90189bbcf4eeb5b5145'
50+ input: '29860013b6b74c7503c524b62ecd52df'
51+ output: 'cd0cd15a934b3f47476292113d7f35bd'
52+ },
53+ ]
54+
55+ fn test_sm4_ecb () {
56+ mut key := []u8 {}
57+ mut input := []u8 {}
58+ mut output := []u8 {}
59+
60+ mut cipher := & sm4 .SM4 Cipher{}
61+
62+ for data in sm4 data_ecb {
63+ key = '0x${data .key }' .u8_array ()
64+ input = '0x${data .input }' .u8_array ()
65+ output = [u8 (0 )].repeat (input.len) // output must be exactly the same length as input
66+ assert key.len == 16
67+ cipher = sm4 .new_cipher (.sm4_ encrypt, key)!
68+ cipher.crypt_ecb (input, mut output)!
69+ assert output.hex () == data.output
70+
71+ cipher = sm4 .new_cipher (.sm4_ decrypt, key)!
72+ cipher.crypt_ecb (output, mut output)!
73+ assert output.hex () == data.input
74+ }
75+ }
76+
77+ fn test_sm4_cbc () {
78+ mut key := []u8 {}
79+ mut iv := []u8 {}
80+ mut input := []u8 {}
81+ mut output := []u8 {}
82+ mut iv_next := []u8 {}
83+
84+ mut cipher := & sm4 .SM4 Cipher{}
85+
86+ // CBC encrypt
87+ for i, data in sm4 data_cbc {
88+ key = '0x${data .key }' .u8_array ()
89+ iv = '0x${data .iv }' .u8_array ()
90+ input = '0x${data .input }' .u8_array ()
91+ output = [u8 (0 )].repeat (input.len) // output must be exactly the same length as input
92+ assert key.len == 16
93+ assert iv.len == 16
94+ if i != 0 {
95+ assert iv_next == iv
96+ }
97+ cipher = sm4 .new_cipher (.sm4_ encrypt, key)!
98+ iv_next = cipher.crypt_cbc (iv, input, mut output)!
99+ dump (iv_next.hex ())
100+ assert output.hex () == data.output
101+ }
102+ // CBC decrypt
103+ for i, data in sm4 data_cbc {
104+ key = '0x${data .key }' .u8_array ()
105+ iv = '0x${data .iv }' .u8_array ()
106+ input = '0x${data .output }' .u8_array ()
107+ output = [u8 (0 )].repeat (input.len) // output must be exactly the same length as input
108+ assert key.len == 16
109+ assert iv.len == 16
110+ if i != 0 {
111+ assert iv_next == iv
112+ }
113+ cipher = sm4 .new_cipher (.sm4_ decrypt, key)!
114+ iv_next = cipher.crypt_cbc (iv, input, mut output)!
115+ dump (iv_next.hex ())
116+ assert output.hex () == data.input
117+ }
150118}
151119
152120fn test_sm4_wrong_length () ! {
@@ -187,7 +155,7 @@ fn test_sm4_wrong_length() ! {
187155 // wrong iv length test(cbc)
188156 fail_flag = false
189157 mut c3 := sm4 .new_cipher (.sm4_ encrypt, [u8 (0xff )].repeat (16 ))!
190- c3 .crypt_cbc (mut [u8 (0xff )].repeat (22 ), [u8 (0xff )].repeat (16 ), mut [u8 (0xff )].repeat (16 )) or {
158+ c3 .crypt_cbc ([u8 (0xff )].repeat (22 ), [u8 (0xff )].repeat (16 ), mut [u8 (0xff )].repeat (16 )) or {
191159 fail_flag = true
192160 assert err.msg () == 'iv length must be exactly 16 bytes'
193161 }
@@ -196,7 +164,7 @@ fn test_sm4_wrong_length() ! {
196164 // wrong input length test(cbc)
197165 fail_flag = false
198166 mut c4 := sm4 .new_cipher (.sm4_ encrypt, [u8 (0xff )].repeat (16 ))!
199- c4 .crypt_cbc (mut [u8 (0xff )].repeat (16 ), [u8 (0xff )].repeat (111 ), mut output) or {
167+ c4 .crypt_cbc ([u8 (0xff )].repeat (16 ), [u8 (0xff )].repeat (111 ), mut output) or {
200168 fail_flag = true
201169 assert err.msg () == 'input must be padded to multiple of 16 bytes'
202170 }
@@ -205,7 +173,7 @@ fn test_sm4_wrong_length() ! {
205173 // wrong output length test(cbc)
206174 fail_flag = false
207175 mut c5 := sm4 .new_cipher (.sm4_ encrypt, [u8 (0xff )].repeat (16 ))!
208- c5 .crypt_cbc (mut [u8 (0xff )].repeat (16 ), [u8 (0xff )].repeat (16 ), mut output) or {
176+ c5 .crypt_cbc ([u8 (0xff )].repeat (16 ), [u8 (0xff )].repeat (16 ), mut output) or {
209177 fail_flag = true
210178 assert err.msg () == 'output must be exactly the same length as input'
211179 }
0 commit comments