unsafe.
Constant-time.
SM2 / SM3 / SM4 / SM9 / BLS / FPE — six algorithms, fully implemented, strictly conforming to GB/T national standards.
#![no_std] ready.
From bare-metal MCUs to WASM — runs everywhere.
Six Standards. One Crate.
Elliptic Curve PKC — sign, verify, encrypt, decrypt, key exchange, DER codec
256-bit cryptographic hash — streaming, one-shot, HMAC, HKDF
128-bit block cipher — ECB, CBC, OFB, CFB, CTR, GCM, CCM, XTS
Identity-based crypto — BN256 pairing, sign, encrypt, key encapsulation
BLS signatures — aggregate verification, Shamir threshold signing
Format-preserving encryption — FNR algorithm, 7-round Feistel with SM4
Built for Security Engineers
Complete SM2/SM3/SM4/SM9 implementations, plus BLS signatures and format-preserving encryption. Every algorithm validated against official GB/T standard test vectors.
All secret-dependent ops use subtle primitives. SM2 scalar multiplication iterates all 256 bits. SM4 S-box uses boolean-circuit bitslice — zero cache-timing leaks.
unsafe Code
#![forbid(unsafe_code)] enforced at the crate root. Private keys implement ZeroizeOnDrop — automatic cleanup on scope exit.
#![no_std] Ready
Runs on embedded MCUs, WASM runtimes, and bare-metal targets. Optional alloc and std feature flags. Zero runtime dependencies.
SM3 hashing at 374 MiB/s. SM2 signing in 258 µs. SM4-ECB at 27 MiB/s — all measured under constant-time constraints. No shortcuts.
Feature-gated rustls-provider delivers RFC 8998 ShangMi cipher suites (SM4-GCM-SM3 / SM4-CCM-SM3). Plug directly into the Rust TLS ecosystem.
Clean API. Real Cryptography.
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");
OS-level CSPRNG generates a 256-bit SM2 key pair on the standard curve (GB/T 32918.5).
Computes the user-distinguishing Z value per the national standard — SM3 hash of ID length, ID, curve params, and public key coordinates.
Digest e = SM3(Z || M), then sign. Scalar multiplication runs all 256 rounds — constant-time against timing attacks.
Constant-time verification returns Result<()>. Failures leak zero timing information.
use libsmx::sm4::{sm4_encrypt_gcm, sm4_decrypt_gcm};
let key = [0u8; 16];
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);
Standard AEAD parameters per NIST GCM specification. The 128-bit key matches SM4's native block size.
aad is authenticated but not encrypted — ideal for protocol headers that need integrity without confidentiality.
Returns ciphertext + 128-bit authentication tag. The tag ensures tamper detection via GMAC.
Decryption verifies the tag in constant time. Any tampering returns Err — no timing oracle.
Security Is Not a Performance Trade-off
All measurements are constant-time. Linux x86_64, single core. Run cargo bench for your own numbers.
64 KiB data, constant-time
Elliptic curve operations
Identity-based cryptography
Why Trust libsmx?
unsafe
#![forbid(unsafe_code)] is enforced at the crate root — compile-time guarantee. Private keys implement ZeroizeOnDrop. GCM/CCM tags verified in constant time.
Minimum supported Rust version: 1.83.0. MSRV bumps are treated as minor version changes. CI matrix enforces compatibility. No nightly required — ever.
Business-friendly license. No copyleft obligations. Free to use in commercial products, internal systems, and government compliance projects.
Disclaimer: This library has not been independently audited. Report vulnerabilities via SECURITY.md.
Add libsmx to your project and start using Chinese cryptography today.
# Add to your project
$ cargo add libsmx
# Or with no_std (no alloc)
$ cargo add libsmx --no-default-features
# With rustls TLS provider
$ cargo add libsmx --features rustls-provider