mirror of
https://github.com/vlang/v.git
synced 2025-09-14 23:12:33 +03:00
213 lines
8.5 KiB
V
213 lines
8.5 KiB
V
// 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 multiple 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 multiple 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
|
|
}
|