准备发布 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 性能和测试覆盖率
This commit is contained in:
huangxt
2026-03-07 19:27:41 +08:00
parent bec7f277ce
commit 8ad52ecac0
23 changed files with 1275 additions and 361 deletions
+136 -44
View File
@@ -1,82 +1,174 @@
# libsmx
生产级中国商用密码算法库,纯 Rust 实现。
[![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)
## 算法支持
Pure-Rust, `#![no_std]` implementation of Chinese commercial cryptography standards with constant-time operations throughout.
| 算法 | 标准 | 功能 |
|------|------|------|
| SM2 | GB/T 32918.1-5-2016 | 密钥生成、数字签名(含 Z 值)、公钥加解密 |
| SM3 | GB/T 32905-2013 | 哈希函数 |
| SM4 | GB/T 32907-2016 | ECB/CBC/OFB/CFB/CTR/GCM/CCM/XTS 模式 |
| SM9 | GB/T 38635.1-2-2020 | BN256 配对密码,签名、加密 |
| Algorithm | Standard | Description |
|-----------|----------|-------------|
| **SM2** | GB/T 32918.1-5-2016 | Elliptic Curve Public Key Cryptography |
| **SM3** | GB/T 32905-2016 | Cryptographic Hash Algorithm (256-bit) |
| **SM4** | GB/T 32907-2016 | Block Cipher (128-bit key, ECB/CBC/CTR/GCM/CCM/XTS) |
| **SM9** | GB/T 38635.1-2-2020 | Identity-Based Cryptography (BN256 pairing) |
## 特性
## Features
- **常量时间**:使用 `crypto-bigint::ConstMontyForm``subtle::ConstantTimeEq`
- **内存安全**:私钥通过 `zeroize::ZeroizeOnDrop` 在 Drop 时自动清零
- **no_std 兼容**:默认启用 `alloc` feature,核心算法支持裸机环境
- **零 unsafe**(除 crypto-bigint 内部)
- **`#![no_std]`** — works in embedded, WASM, and bare-metal environments
- **`#![forbid(unsafe_code)]`** — zero `unsafe` blocks
- **Constant-time** — all secret-dependent operations use [`subtle`](https://docs.rs/subtle) primitives
- **Auto-zeroize** — private keys cleared on drop via [`zeroize`](https://docs.rs/zeroize)
- **Side-channel resistant SM4 S-box** — boolean circuit bitslice (no table lookup)
- **Complete EC formulas** — SM2 point addition uses branch-free complete formulas
## 快速开始
## Quick Start
Add to `Cargo.toml`:
```toml
[dependencies]
libsmx = "0.1"
libsmx = "0.3"
```
### SM3 哈希
### SM3 Hash
```rust
use libsmx::sm3::Sm3Hasher;
// One-shot hash
let digest = Sm3Hasher::digest(b"abc");
assert_eq!(digest.len(), 32);
// Streaming hash
let mut h = Sm3Hasher::new();
h.update(b"hello");
let digest = h.finalize(); // [u8; 32]
h.update(b"ab");
h.update(b"c");
assert_eq!(h.finalize(), digest);
```
### SM4-GCM 加密
### SM3 HMAC
```rust
use libsmx::sm4::modes::{sm4_encrypt_gcm, sm4_decrypt_gcm};
use libsmx::sm3::hmac_sm3;
let mac = hmac_sm3(b"secret-key", b"message");
assert_eq!(mac.len(), 32);
```
### SM2 Sign / Verify
```rust
use libsmx::sm2::{generate_keypair, get_z, get_e, sign, verify};
let mut rng = rand::rngs::OsRng;
// Key generation
let (pri_key, pub_key) = generate_keypair(&mut rng);
// Sign: compute Z value and message digest per GB/T 32918.2
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
verify(&e, &pub_key, &sig).expect("signature valid");
```
### SM4 GCM (AEAD)
```rust
use libsmx::sm4::{sm4_encrypt_gcm, sm4_decrypt_gcm};
let key = [0u8; 16];
let nonce = [1u8; 12];
let (ciphertext, tag) = sm4_encrypt_gcm(&key, &nonce, b"aad", b"plaintext");
let plaintext = sm4_decrypt_gcm(&key, &nonce, b"aad", &ciphertext, &tag).unwrap();
let nonce = [0u8; 12];
let aad = b"additional data";
let plaintext = b"secret message";
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);
```
### SM2 签名
### SM4 CBC
```rust
use libsmx::sm2::{generate_keypair, sign, verify, get_z, get_e};
use rand::rngs::OsRng;
use libsmx::sm4::{sm4_encrypt_cbc, sm4_decrypt_cbc};
let (priv_key, pub_key) = generate_keypair(&mut OsRng);
let id = b"1234567812345678";
let msg = b"hello sm2";
let z = get_z(id, &pub_key);
let e = get_e(&z, msg);
let sig = sign(&e, &priv_key, &mut OsRng);
verify(&e, &pub_key, &sig).unwrap();
let key = [0u8; 16];
let iv = [0u8; 16];
let plaintext = [0u8; 32]; // must be 16-byte aligned
let ciphertext = sm4_encrypt_cbc(&key, &iv, &plaintext);
let decrypted = sm4_decrypt_cbc(&key, &iv, &ciphertext);
assert_eq!(decrypted, plaintext);
```
### SM9 配对
### SM9 Identity-Based Sign / Verify
```rust
use libsmx::sm9::{generate_sign_master_keypair, generate_sign_user_key, sm9_sign, sm9_verify};
use rand::rngs::OsRng;
use libsmx::sm9::{generate_sign_master_keypair, generate_sign_user_key};
use libsmx::sm9::{sm9_sign, sm9_verify};
let (ks, ppub) = generate_sign_master_keypair(&mut OsRng);
let da = generate_sign_user_key(&ks, b"Alice").unwrap();
let (h, s) = sm9_sign(b"message", &da, &ppub, &mut OsRng).unwrap();
sm9_verify(b"message", &h, &s, b"Alice", &ppub).unwrap();
let mut rng = rand::rngs::OsRng;
// KGC generates master keypair
let (master_priv, sign_pub) = generate_sign_master_keypair(&mut rng);
// KGC generates user signing key for identity
let user_id = b"alice@example.com";
let user_key = generate_sign_user_key(&master_priv, user_id).unwrap();
// User signs message
let msg = b"hello SM9";
let (h, s) = sm9_sign(msg, &user_key, &sign_pub, &mut rng).unwrap();
// Anyone can verify with user's identity + master public key
sm9_verify(msg, &h, &s, user_id, &sign_pub).unwrap();
```
## MSRV
## Supported SM4 Modes
Rust 1.72.0
| Mode | Encrypt | Decrypt |
|------|---------|---------|
| 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 Flags
Apache-2.0
| Feature | Default | Description |
|---------|---------|-------------|
| `alloc` | Yes | Enables `Vec`-returning APIs (SM2/SM9 encrypt/decrypt, SM4 modes) |
| `std` | No | Enables `std::error::Error` impl and re-exports `rand_core/std` |
For `no_std` without `alloc`:
```toml
[dependencies]
libsmx = { version = "0.3", default-features = false }
```
## Security
- All secret-dependent operations are constant-time (fixed iteration counts, mask-based selection)
- SM4 S-box uses boolean circuit bitslice — zero memory access patterns, immune to cache-timing attacks
- SM2 scalar multiplication uses complete addition formulas with no data-dependent branches
- Private keys implement `ZeroizeOnDrop` for automatic cleanup
- GCM/CCM authentication tags are verified in constant time
> **Disclaimer**: This library has **not** been independently audited. See [SECURITY.md](SECURITY.md) for vulnerability reporting.
## MSRV Policy
The minimum supported Rust version is **1.72.0**. MSRV bumps are treated as minor version changes.
## License
Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.