v2 / vlib / x / crypto / sm4 / sm4_test.v
181 lines · 164 sloc · 4.96 KB · c1d1efb2091e989dbb09e38b308c82c2cade1aa8
Raw
1// online tester: https://lzltool.cn/SM4
2import x.crypto.sm4
3
4struct SM4Data {
5 key string
6 iv string
7 input string
8 output string
9}
10
11const sm4data_ecb = [
12 SM4Data{
13 key: '0123456789abcdeffedcba9876543210'
14 input: '0123456789abcdeffedcba9876543210'
15 output: '681edf34d206965e86b3e94f536e4246'
16 },
17 SM4Data{
18 key: '0123456789abcdeffedcba9876543210'
19 input: '00112233445566778899aabbccddeeff'
20 output: '09325c4853832dcb9337a5984f671b9a'
21 },
22 SM4Data{
23 key: '456789abcdeffedcba98765432100123'
24 input: '2233445566778899aabbccddeeff0011'
25 output: '58ab414d84fb3008b0bee987f97021e6'
26 },
27 SM4Data{
28 key: '89abcdeffedcba987654321001234567'
29 input: '445566778899aabbccddeeff00112233445566778899aabbccddeeff00112233'
30 output: '5937a929a2d9137216c72a28cd9cf6195937a929a2d9137216c72a28cd9cf619'
31 },
32]
33
34const sm4data_cbc = [
35 SM4Data{
36 key: '0123456789abcdeffedcba9876543210'
37 iv: '0123456789abcdeffedcba9876543210'
38 input: '0123456789abcdeffedcba9876543210'
39 output: '2677f46b09c122cc975533105bd4a22a'
40 },
41 SM4Data{
42 key: '0123456789abcdeffedcba9876543210'
43 iv: '2677f46b09c122cc975533105bd4a22a'
44 input: '00112233445566778899aabbccddeeff'
45 output: '2e7b41173b42b90189bbcf4eeb5b5145'
46 },
47 SM4Data{
48 key: '0123456789abcdeffedcba9876543210'
49 iv: '2e7b41173b42b90189bbcf4eeb5b5145'
50 input: '29860013b6b74c7503c524b62ecd52df'
51 output: 'cd0cd15a934b3f47476292113d7f35bd'
52 },
53]
54
55fn test_sm4_ecb() {
56 mut key := []u8{}
57 mut input := []u8{}
58 mut output := []u8{}
59
60 mut cipher := &sm4.SM4Cipher{}
61
62 for data in sm4data_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
77fn 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.SM4Cipher{}
85
86 // CBC encrypt
87 for i, data in sm4data_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 sm4data_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 }
118}
119
120fn test_sm4_wrong_length() ! {
121 // wrong key length test
122 mut fail_flag := false
123 sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(33)) or {
124 fail_flag = true
125 assert err.msg() == 'SM4 only support 128bit key length'
126 }
127 assert fail_flag
128
129 fail_flag = false
130 sm4.new_cipher(.sm4_decrypt, [u8(0xff)].repeat(33)) or {
131 fail_flag = true
132 assert err.msg() == 'SM4 only support 128bit key length'
133 }
134 assert fail_flag
135
136 // wrong input length test(ecb)
137 mut output := []u8{len: 32}
138 fail_flag = false
139 mut c1 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))!
140 c1.crypt_ecb([u8(0xff)].repeat(111), mut output) or {
141 fail_flag = true
142 assert err.msg() == 'input must be padded to multiple of 16 bytes'
143 }
144 assert fail_flag
145
146 // wrong output length test(ecb)
147 fail_flag = false
148 mut c2 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))!
149 c2.crypt_ecb([u8(0xff)].repeat(16), mut output) or {
150 fail_flag = true
151 assert err.msg() == 'output must be exactly the same length as input'
152 }
153 assert fail_flag
154
155 // wrong iv length test(cbc)
156 fail_flag = false
157 mut c3 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))!
158 c3.crypt_cbc([u8(0xff)].repeat(22), [u8(0xff)].repeat(16), mut [u8(0xff)].repeat(16)) or {
159 fail_flag = true
160 assert err.msg() == 'iv length must be exactly 16 bytes'
161 }
162 assert fail_flag
163
164 // wrong input length test(cbc)
165 fail_flag = false
166 mut c4 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))!
167 c4.crypt_cbc([u8(0xff)].repeat(16), [u8(0xff)].repeat(111), mut output) or {
168 fail_flag = true
169 assert err.msg() == 'input must be padded to multiple of 16 bytes'
170 }
171 assert fail_flag
172
173 // wrong output length test(cbc)
174 fail_flag = false
175 mut c5 := sm4.new_cipher(.sm4_encrypt, [u8(0xff)].repeat(16))!
176 c5.crypt_cbc([u8(0xff)].repeat(16), [u8(0xff)].repeat(16), mut output) or {
177 fail_flag = true
178 assert err.msg() == 'output must be exactly the same length as input'
179 }
180 assert fail_flag
181}
182