Pure-Rust Chinese Cryptography.
Zero 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.

View on GitHub

Algorithm Coverage

Six Standards. One Crate.

SM2 GB/T 32918

Elliptic Curve PKC — sign, verify, encrypt, decrypt, key exchange, DER codec

SM3 GB/T 32905

256-bit cryptographic hash — streaming, one-shot, HMAC, HKDF

SM4 GB/T 32907

128-bit block cipher — ECB, CBC, OFB, CFB, CTR, GCM, CCM, XTS

SM9 GB/T 38635

Identity-based crypto — BN256 pairing, sign, encrypt, key encapsulation

BLS RFC 9380

BLS signatures — aggregate verification, Shamir threshold signing

FPE SP 800-38G

Format-preserving encryption — FNR algorithm, 7-round Feistel with SM4

Why libsmx

Built for Security Engineers

Full GB/T Compliance

Complete SM2/SM3/SM4/SM9 implementations, plus BLS signatures and format-preserving encryption. Every algorithm validated against official GB/T standard test vectors.

Constant-Time Everywhere

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.

Zero 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.

Production Performance

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.

rustls TLS 1.3

Feature-gated rustls-provider delivers RFC 8998 ShangMi cipher suites (SM4-GCM-SM3 / SM4-CCM-SM3). Plug directly into the Rust TLS ecosystem.

Code Examples

Clean API. Real Cryptography.

sm2_example.rs
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");
1 generate_keypair

OS-level CSPRNG generates a 256-bit SM2 key pair on the standard curve (GB/T 32918.5).

2 get_z

Computes the user-distinguishing Z value per the national standard — SM3 hash of ID length, ID, curve params, and public key coordinates.

3 get_e → sign

Digest e = SM3(Z || M), then sign. Scalar multiplication runs all 256 rounds — constant-time against timing attacks.

4 verify

Constant-time verification returns Result<()>. Failures leak zero timing information.

Performance

Security Is Not a Performance Trade-off

All measurements are constant-time. Linux x86_64, single core. Run cargo bench for your own numbers.

Throughput

64 KiB data, constant-time

SM3 Hash 374 MiB/s
167 µs @ 64 KiB
SM4-ECB 27 MiB/s
2.32 ms @ 64 KiB

SM2 (256-bit ECC)

Elliptic curve operations

Key Generation 221 µs
Sign 258 µs
Verify 316 µs
Encrypt 639 µs
Decrypt 417 µs

SM9 (BN256 Pairing)

Identity-based cryptography

Master Keygen 753 µs
User Keygen 324 µs
Sign 3.44 ms
Verify 5.50 ms
Encrypt 4.68 ms
Decrypt 1.54 ms

Trust

Why Trust libsmx?

Zero unsafe

#![forbid(unsafe_code)] is enforced at the crate root — compile-time guarantee. Private keys implement ZeroizeOnDrop. GCM/CCM tags verified in constant time.

MSRV Policy

Minimum supported Rust version: 1.83.0. MSRV bumps are treated as minor version changes. CI matrix enforces compatibility. No nightly required — ever.

Apache-2.0

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.

Get Started in Seconds

Add libsmx to your project and start using Chinese cryptography today.

terminal

# 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