Files
libsmx/README.zh-CN.md
T
huangxt 8ad52ecac0 准备发布 v0.1.0
- 添加 Apache-2.0 许可证
- 添加 CHANGELOG.md 变更日志
- 添加 SECURITY.md 安全策略
- 添加 README.zh-CN.md 中文文档
- 添加 rustfmt.toml 代码格式配置
- 添加 scripts/pre_publish_check.sh 发布检查脚本
- 更新 Cargo.toml 元数据(分类、关键词、文档链接)
- 完善 README.md 示例代码
- 优化 SM2/SM9 性能和测试覆盖率
2026-03-07 19:27:41 +08:00

210 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# libsmx
[![Crates.io](https://img.shields.io/crates/v/libsmx.svg)](https://crates.io/crates/libsmx)
[![docs.rs](https://img.shields.io/docsrs/libsmx)](https://docs.rs/libsmx)
[![License](https://img.shields.io/crates/l/libsmx.svg)](LICENSE)
[![MSRV](https://img.shields.io/badge/MSRV-1.72.0-blue.svg)](https://blog.rust-lang.org/2023/08/24/Rust-1.72.0.html)
纯 Rust、`#![no_std]` 实现的中国商用密码算法库,全程常量时间操作。
| 算法 | 标准 | 说明 |
|------|------|------|
| **SM2** | GB/T 32918.1-5-2016 | 椭圆曲线公钥密码 |
| **SM3** | GB/T 32905-2016 | 密码杂凑算法(256 位) |
| **SM4** | GB/T 32907-2016 | 分组密码(128 位密钥,ECB/CBC/CTR/GCM/CCM/XTS |
| **SM9** | GB/T 38635.1-2-2020 | 标识密码(BN256 双线性配对) |
## 特性
- **`#![no_std]`** — 支持嵌入式、WASM 及裸机环境
- **`#![forbid(unsafe_code)]`** — 零 `unsafe`
- **常量时间** — 所有涉密操作均使用 [`subtle`](https://docs.rs/subtle) 原语,防时序侧信道
- **自动清零** — 私钥离开作用域后经由 [`zeroize`](https://docs.rs/zeroize) 自动清零
- **SM4 S 盒抗侧信道** — 布尔电路位切片实现,无任何内存表查询,免疫缓存时序攻击
- **SM2 完备加法公式** — 点加法使用无分支完备公式,杜绝特殊情况侧信道
## 快速开始
`Cargo.toml` 中添加依赖:
```toml
[dependencies]
libsmx = "0.3"
```
### SM3 哈希
```rust
use libsmx::sm3::Sm3Hasher;
// 一次性哈希
let digest = Sm3Hasher::digest(b"abc");
assert_eq!(digest.len(), 32);
// 流式哈希
let mut h = Sm3Hasher::new();
h.update(b"ab");
h.update(b"c");
assert_eq!(h.finalize(), digest);
```
### SM3 HMAC
```rust
use libsmx::sm3::hmac_sm3;
let mac = hmac_sm3(b"secret-key", b"message");
assert_eq!(mac.len(), 32);
```
### SM2 签名 / 验签
```rust
use libsmx::sm2::{generate_keypair, get_z, get_e, sign, verify};
let mut rng = rand::rngs::OsRng;
// 生成密钥对
let (pri_key, pub_key) = generate_keypair(&mut rng);
// 签名:按 GB/T 32918.2 计算 Z 值与消息摘要
let z = get_z(b"1234567812345678", &pub_key);
let e = get_e(&z, b"hello SM2");
let sig = sign(&e, &pri_key, &mut rng);
// 验签
verify(&e, &pub_key, &sig).expect("签名有效");
```
### SM2 加密 / 解密
```rust
use libsmx::sm2::{generate_keypair, sm2_encrypt, sm2_decrypt};
let mut rng = rand::rngs::OsRng;
let (pri_key, pub_key) = generate_keypair(&mut rng);
let plaintext = b"hello SM2 encrypt";
let ciphertext = sm2_encrypt(&pub_key, plaintext, &mut rng).unwrap();
let decrypted = sm2_decrypt(&pri_key, &ciphertext).unwrap();
assert_eq!(decrypted, plaintext);
```
### SM4-GCMAEAD 认证加密)
```rust
use libsmx::sm4::{sm4_encrypt_gcm, sm4_decrypt_gcm};
let key = [0u8; 16];
let nonce = [0u8; 12];
let aad = b"附加认证数据";
let plaintext = b"机密消息";
let (ciphertext, tag) = sm4_encrypt_gcm(&key, &nonce, aad, plaintext);
let decrypted = sm4_decrypt_gcm(&key, &nonce, aad, &ciphertext, &tag).unwrap();
assert_eq!(decrypted, plaintext);
```
### SM4-CBC
```rust
use libsmx::sm4::{sm4_encrypt_cbc, sm4_decrypt_cbc};
let key = [0u8; 16];
let iv = [0u8; 16];
let plaintext = [0u8; 32]; // 须为 16 字节对齐
let ciphertext = sm4_encrypt_cbc(&key, &iv, &plaintext);
let decrypted = sm4_decrypt_cbc(&key, &iv, &ciphertext);
assert_eq!(decrypted, plaintext);
```
### SM9 标识签名 / 验签
```rust
use libsmx::sm9::{generate_sign_master_keypair, generate_sign_user_key};
use libsmx::sm9::{sm9_sign, sm9_verify};
let mut rng = rand::rngs::OsRng;
// 密钥生成中心(KGC)生成主密钥对
let (master_priv, sign_pub) = generate_sign_master_keypair(&mut rng);
// KGC 为用户标识派生签名私钥
let user_id = b"alice@example.com";
let user_key = generate_sign_user_key(&master_priv, user_id).unwrap();
// 用户签名
let msg = b"hello SM9";
let (h, s) = sm9_sign(msg, &user_key, &sign_pub, &mut rng).unwrap();
// 任意方可凭用户标识 + 主公钥验签
sm9_verify(msg, &h, &s, user_id, &sign_pub).unwrap();
```
### SM9 标识加密 / 解密
```rust
use libsmx::sm9::{generate_enc_master_keypair, generate_enc_user_key};
use libsmx::sm9::{sm9_encrypt, sm9_decrypt};
let mut rng = rand::rngs::OsRng;
let (master_priv, enc_pub) = generate_enc_master_keypair(&mut rng);
let user_id = b"bob@example.com";
let user_key = generate_enc_user_key(&master_priv, user_id).unwrap();
let plaintext = b"机密消息";
let ciphertext = sm9_encrypt(user_id, plaintext, &enc_pub, &mut rng).unwrap();
let decrypted = sm9_decrypt(user_id, &ciphertext, &user_key).unwrap();
assert_eq!(decrypted, plaintext);
```
## SM4 支持的工作模式
| 模式 | 加密 | 解密 |
|------|------|------|
| ECB | `sm4_encrypt_ecb` | `sm4_decrypt_ecb` |
| CBC | `sm4_encrypt_cbc` | `sm4_decrypt_cbc` |
| OFB | `sm4_crypt_ofb` | `sm4_crypt_ofb` |
| CFB | `sm4_encrypt_cfb` | `sm4_decrypt_cfb` |
| CTR | `sm4_crypt_ctr` | `sm4_crypt_ctr` |
| GCM | `sm4_encrypt_gcm` | `sm4_decrypt_gcm` |
| CCM | `sm4_encrypt_ccm` | `sm4_decrypt_ccm` |
| XTS | `sm4_encrypt_xts` | `sm4_decrypt_xts` |
## Feature 开关
| Feature | 默认启用 | 说明 |
|---------|----------|------|
| `alloc` | 是 | 启用返回 `Vec` 的 APISM2/SM9 加解密、SM4 各模式) |
| `std` | 否 | 启用 `std::error::Error` trait 实现及 `rand_core/std` 重导出 |
在无 `alloc``no_std` 环境中使用:
```toml
[dependencies]
libsmx = { version = "0.3", default-features = false }
```
`alloc` 时,SM3 哈希、SM3 HMAC、SM2 签名/验签、SM4 ECB 仍可用(固定大小数组 API)。
## 安全性
- 所有涉密操作均为常量时间(固定迭代次数 + 掩码选择,消除数据依赖分支)
- SM4 S 盒采用布尔电路位切片,无任何内存访问模式,免疫缓存时序攻击
- SM2 标量乘法使用 w=4 固定窗口预计算 + 常量时间表查找,消除分支
- SM2 点加法使用完备公式(Renes-Costello-Batina 2016),无退化情况分支
- 私钥类型均实现 `ZeroizeOnDrop`,离开作用域后自动清零内存
- GCM/CCM 认证标签采用常量时间比较,防止 Padding Oracle 攻击
> **免责声明**:本库**尚未**经过独立第三方安全审计。如发现安全漏洞,请参阅 [SECURITY.md](SECURITY.md) 进行报告。
## 最低支持 Rust 版本(MSRV
最低支持版本为 **Rust 1.72.0**。MSRV 提升视为次版本号变更。
## 许可证
Apache License, Version 2.0。详见 [LICENSE](LICENSE)。