//| SM4 demo (GM/T 0002-2012): single block, ECB and CBC modes with PKCS7
//| padding. Run with `moon run cmd/sm4`.
///|
fn main {
try {
println("========== SM4 Demo (GM/T 0002-2012) ==========")
let key = @byteutil.hex_to_bytes("0123456789ABCDEFFEDCBA9876543210")
let plain = @byteutil.hex_to_bytes("0123456789ABCDEFFEDCBA9876543210")
let iv = @byteutil.hex_to_bytes("00000000000000000000000000000000")
// 1. Single block encryption (KAT from GM/T 0002-2012 Appendix A)
let cipher = @gmsm_sm4.sm4_encrypt_block(key, plain)
let expected = "681edf34d206965e86b3e94f536e4246"
let got = @byteutil.bytes_to_hex(cipher)
println(
"Block encrypt : " +
got +
" [" +
(if got == expected { "OK" } else { "FAIL" }) +
"]",
)
let dec = @gmsm_sm4.sm4_decrypt_block(key, cipher)
println(
"Block decrypt : " +
@byteutil.bytes_to_hex(dec) +
" [" +
(if @byteutil.bytes_eq(dec, plain) { "OK" } else { "FAIL" }) +
"]",
)
// 2. ECB mode with PKCS7 padding (needs padded input length multiple of 16)
let msg = b"Hello SM4 ECB mode demo."
let padded = @byteutil.pkcs7_pad(msg, 16)
let ecb_c = @gmsm_sm4.sm4_encrypt_ecb(key, padded)
let ecb_d = match
@byteutil.pkcs7_unpad(@gmsm_sm4.sm4_decrypt_ecb(key, ecb_c)) {
Ok(b) => b
Err(_) => b""
}
println("")
println("ECB ciphertext: " + @byteutil.bytes_to_hex(ecb_c))
println("ECB roundtrip : " + @byteutil.bstr(@byteutil.bytes_eq(ecb_d, msg)))
// 3. CBC mode with PKCS7 padding
let cbc_c = @gmsm_sm4.sm4_encrypt_cbc(key, iv, padded)
let cbc_d = match
@byteutil.pkcs7_unpad(@gmsm_sm4.sm4_decrypt_cbc(key, iv, cbc_c)) {
Ok(b) => b
Err(_) => b""
}
println("CBC ciphertext: " + @byteutil.bytes_to_hex(cbc_c))
println("CBC roundtrip : " + @byteutil.bstr(@byteutil.bytes_eq(cbc_d, msg)))
// 4. PKCS7 padding sanity
let unpadded = match
@byteutil.pkcs7_unpad(@byteutil.pkcs7_pad(b"short", 16)) {
Ok(b) => b
Err(_) => b""
}
println(
"PKCS7 roundtrip: " +
@byteutil.bstr(@byteutil.bytes_eq(unpadded, b"short")),
)
println("========== SM4 Demo Done ==========")
} catch {
_ => println("Error occurred during SM4 demo")
}
}