2026-03-07 13:03:10 +08:00
# libsmx
2026-03-07 19:54:34 +08:00
[](https://github.com/kintaiW/libsmx/actions/workflows/ci.yml)
2026-03-07 19:27:41 +08:00
[](https://crates.io/crates/libsmx)
[](https://docs.rs/libsmx)
2026-03-07 19:54:34 +08:00
[](https://codecov.io/gh/kintaiW/libsmx)
2026-03-07 19:27:41 +08:00
[](LICENSE)
2026-03-07 20:38:34 +08:00
[](https://blog.rust-lang.org/2024/11/28/Rust-1.83.0.html)
2026-03-07 13:03:10 +08:00
2026-03-09 18:51:40 +08:00
Pure-Rust, `#![no_std]` implementation of Chinese commercial cryptography standards (国密/GuoMi) with constant-time operations throughout. Designed for embedded systems, WASM, and production use.
> **Security Notice**: This library has **not** been independently audited. While all secret-dependent operations are constant-time and `#![forbid(unsafe_code)]` is enforced, you should evaluate the risks before using it in production. Report vulnerabilities via [SECURITY.md](SECURITY.md) or email [kintai@foxmail.com](mailto:kintai@foxmail.com).
2026-03-07 13:03:10 +08:00
2026-03-07 19:27:41 +08:00
| 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) |
2026-03-08 20:02:06 +08:00
| **BLS ** | IETF RFC 9380 | BLS Signatures & Threshold Signatures (BN256) |
| **FPE ** | NIST SP 800-38G | Format-Preserving Encryption (FF1-like) |
2026-03-07 13:03:10 +08:00
2026-03-07 19:27:41 +08:00
## Features
2026-03-07 13:03:10 +08:00
2026-03-07 19:27:41 +08:00
- **`#![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
2026-03-07 13:03:10 +08:00
2026-03-07 19:27:41 +08:00
## Quick Start
Add to `Cargo.toml` :
2026-03-07 13:03:10 +08:00
``` toml
[ dependencies ]
2026-03-09 10:13:09 +08:00
libsmx = "0.3"
2026-03-07 13:03:10 +08:00
```
2026-03-07 19:27:41 +08:00
### SM3 Hash
2026-03-07 13:03:10 +08:00
``` rust
use libsmx ::sm3 ::Sm3Hasher ;
2026-03-07 19:27:41 +08:00
// One-shot hash
let digest = Sm3Hasher ::digest ( b " abc " ) ;
assert_eq! ( digest . len ( ) , 32 ) ;
// Streaming hash
2026-03-07 13:03:10 +08:00
let mut h = Sm3Hasher ::new ( ) ;
2026-03-07 19:27:41 +08:00
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 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 " ) ;
2026-03-07 13:03:10 +08:00
```
2026-03-07 19:27:41 +08:00
### SM4 GCM (AEAD)
2026-03-07 13:03:10 +08:00
``` rust
2026-03-07 19:27:41 +08:00
use libsmx ::sm4 ::{ sm4_encrypt_gcm , sm4_decrypt_gcm } ;
2026-03-07 13:03:10 +08:00
let key = [ 0 u8 ; 16 ] ;
2026-03-07 19:27:41 +08:00
let nonce = [ 0 u8 ; 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 ) ;
2026-03-07 13:03:10 +08:00
```
2026-03-07 19:27:41 +08:00
### SM4 CBC
2026-03-07 13:03:10 +08:00
``` rust
2026-03-07 19:27:41 +08:00
use libsmx ::sm4 ::{ sm4_encrypt_cbc , sm4_decrypt_cbc } ;
let key = [ 0 u8 ; 16 ] ;
let iv = [ 0 u8 ; 16 ] ;
let plaintext = [ 0 u8 ; 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 ) ;
2026-03-07 13:03:10 +08:00
```
2026-03-07 19:27:41 +08:00
### SM9 Identity-Based Sign / Verify
2026-03-07 13:03:10 +08:00
``` rust
2026-03-07 19:27:41 +08:00
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 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 ( ) ;
2026-03-07 13:03:10 +08:00
2026-03-07 19:27:41 +08:00
// Anyone can verify with user's identity + master public key
sm9_verify ( msg , & h , & s , user_id , & sign_pub ) . unwrap ( ) ;
2026-03-07 13:03:10 +08:00
```
2026-03-07 19:27:41 +08:00
## Supported SM4 Modes
| 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
| 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` |
2026-03-09 18:51:40 +08:00
| `rustls-provider` | No | Enables rustls `CryptoProvider` with RFC 8998 ShangMi TLS 1.3 cipher suites |
2026-03-07 19:27:41 +08:00
For `no_std` without `alloc` :
``` toml
[ dependencies ]
2026-03-09 10:13:09 +08:00
libsmx = { version = "0.3" , default-features = false }
2026-03-07 19:27:41 +08:00
```
2026-03-09 18:51:40 +08:00
With rustls TLS 1.3 provider:
``` toml
[ dependencies ]
libsmx = { version = "0.3" , features = [ "rustls-provider" ] }
```
2026-03-07 20:23:16 +08:00
## Benchmarks
Measured on Linux x86_64 (single core). All operations are constant-time.
### Throughput
| Algorithm | Data Size | Time | Throughput |
|-----------|-----------|------|------------|
| SM3 hash | 64 B | 349 ns | — |
| SM3 hash | 1 KiB | 2.80 µs | — |
| SM3 hash | 64 KiB | 167 µs | **374 MiB/s ** |
| SM4-ECB encrypt | 16 B | 1.14 µs | — |
| SM4-ECB encrypt | 1 KiB | 37.0 µs | — |
| SM4-ECB encrypt | 64 KiB | 2.32 ms | **27 MiB/s ** |
### SM2 (256-bit ECC)
| Operation | Time |
|-----------|------|
| Key generation | 221 µs |
| Sign | 258 µs |
| Verify | 316 µs |
| Encrypt | 639 µs |
| Decrypt | 417 µs |
### SM9 (BN256 pairing-based)
| Operation | Time |
|-----------|------|
| Master keygen | 753 µs |
| User keygen | 324 µs |
| Sign | 3.44 ms |
| Verify | 5.50 ms |
| Encrypt | 4.68 ms |
| Decrypt | 1.54 ms |
Run benchmarks locally:
``` bash
cargo bench
```
2026-03-07 19:27:41 +08:00
## 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.
2026-03-09 18:51:40 +08:00
## Contributing
Bug reports, feature requests, and pull requests are welcome on [GitHub ](https://github.com/kintaiW/libsmx ).
For **security vulnerabilities ** , please do **not ** open public issues. Instead, email [kintai@foxmail.com ](mailto:kintai@foxmail.com ) directly. See [SECURITY.md ](SECURITY.md ) for details.
2026-03-07 19:27:41 +08:00
## MSRV Policy
2026-03-07 13:03:10 +08:00
2026-03-07 20:38:34 +08:00
The minimum supported Rust version is **1.83.0 ** . MSRV bumps are treated as minor version changes.
2026-03-07 13:03:10 +08:00
2026-03-07 19:27:41 +08:00
## License
2026-03-07 13:03:10 +08:00
2026-03-07 19:27:41 +08:00
Licensed under the Apache License, Version 2.0. See [LICENSE ](LICENSE ) for details.