// 可复现演示:SM3 与 SM4 全流程
// 运行:moon run cmd/main

///|
fn main {
  println(
    "smcrypto v0.4.0 —— 基于 2d5rrr333/toolsfx-moonbit 的国密工程化扩展",
  )
  println(
    "核心 SM3/SM4 原语委托上游,本项目提供 RFC 8998 合规 GCM、CTR、HMAC 与 PBKDF2",
  )
  println("")
  println("=== SM3 密码杂凑 (GB/T 32905-2016) ===")
  let abc : Bytes = b"abc"
  println("SM3(\"abc\")      = \{@smcrypto.sm3_hex_digest(abc)}")
  println(
    "国标示例 1 期望 = 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0",
  )
  let cn = @utf8.encode("国密算法,安全可靠")
  println("SM3(中文消息)   = \{@smcrypto.sm3_hex_digest(cn)}")
  println("")
  println("=== SM4 分组密码 (GB/T 32907-2016) ===")
  let key = @hexutil.decode("0123456789abcdeffedcba9876543210").unwrap()
  let pt = @utf8.encode("攻击开始于黎明!Attack at dawn!")
  let c = @smcrypto.sm4_new(key).unwrap()
  // ECB
  let ct_ecb = @smcrypto.sm4_encrypt_ecb(key, pt).unwrap()
  let back_ecb = @smcrypto.sm4_decrypt_ecb(key, ct_ecb).unwrap()
  println("明文            = \{@hexutil.encode(pt)}")
  println("ECB 密文        = \{@hexutil.encode(ct_ecb)}")
  println("ECB 解密还原    = \{@hexutil.encode(back_ecb)}")
  println("ECB 还原正确    = \{back_ecb == pt}")
  // CBC
  let iv = @hexutil.decode("000102030405060708090a0b0c0d0e0f").unwrap()
  let ct_cbc = @smcrypto.sm4_encrypt_cbc(key, iv, pt).unwrap()
  let back_cbc = @smcrypto.sm4_decrypt_cbc(key, iv, ct_cbc).unwrap()
  println("CBC 密文        = \{@hexutil.encode(ct_cbc)}")
  println("CBC 解密还原    = \{@hexutil.encode(back_cbc)}")
  println("CBC 还原正确    = \{back_cbc == pt}")
  // 单块国标向量
  let std_pt = @hexutil.decode("0123456789abcdeffedcba9876543210").unwrap()
  let std_ct = c.encrypt_block(std_pt)
  println("")
  println("国标单块向量    = \{@hexutil.encode(std_ct)}")
  println("国标期望        = 681edf34d206965e86b3e94f536e4246")
  println("")
  println("=== HMAC-SM3 消息认证 ===")
  let mac = @smcrypto.sm3_hmac(key, pt)
  println("HMAC-SM3        = \{@hexutil.encode(mac)}")
  // 篡改一个字节后校验失败
  let tampered : FixedArray[Byte] = FixedArray::make(pt.length(), b'\x00')
  for i in 0.. println("GCM 解密还原正确 = \{back_gcm == pt}")
    Err(e) => println("GCM 解密失败: \{e.to_string()}")
  }
  // RFC 8998 A.1 官方向量对拍(固定明文)
  let rfc_pt = @hexutil.decode(
    "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccdddddddddddddddd" +
    "eeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa",
  ).unwrap()
  let (rfc_ct, rfc_tag) = @smcrypto.sm4_encrypt_gcm(
    key, gcm_iv, rfc_pt, gcm_aad,
  ).unwrap()
  println("RFC 8998 密文   = \{@hexutil.encode(rfc_ct)}")
  println(
    "RFC 8998 期望   = 17f399f08c67d5ee19d0dc9969c4bb7d5fd46fd3756489069157b282bb200735d82710ca5c22f0ccfa7cbf93d496ac15a56834cbcf98c397b4024a2691233b8d",
  )
  println("RFC 8998 标签   = \{@hexutil.encode(rfc_tag)}")
  println("RFC 8998 期望   = 83de3541e4c2b58177e065a9bf7b62ec")
  println("")
  println("=== PBKDF2-HMAC-SM3 口令派生 (RFC 8018) ===")
  let dk = @smcrypto.sm3_pbkdf2(b"password", b"salt", 4096, 32)
  println("PBKDF2(4096,32) = \{@hexutil.encode(dk)}")
  println(
    "对拍期望        = b6e8f2074c87432b78f62e5ced980fdff89e86af2f693dab1638e2b3683045dd",
  )
  println("")
  println("=== 错误处理 ===")
  let bad_key = @hexutil.decode("000102030405060708090a0b0c0d0e").unwrap()
  match @smcrypto.sm4_new(bad_key) {
    Err(e) => println("15 字节密钥 -> \{e.to_string()}")
    Ok(_) => println("意外通过")
  }
}