13 releases

0.3.11 Aug 9, 2023
0.3.10 Jun 25, 2022
0.3.7 Jan 31, 2022
0.3.6 Oct 12, 2021
0.1.1 Jul 6, 2020

#39 in Cryptography

Download history 27491/week @ 2023-11-02 24481/week @ 2023-11-09 24398/week @ 2023-11-16 27789/week @ 2023-11-23 32051/week @ 2023-11-30 33138/week @ 2023-12-07 27238/week @ 2023-12-14 19569/week @ 2023-12-21 18643/week @ 2023-12-28 31740/week @ 2024-01-04 35441/week @ 2024-01-11 41588/week @ 2024-01-18 44139/week @ 2024-01-25 38456/week @ 2024-02-01 40282/week @ 2024-02-08 37687/week @ 2024-02-15

169,171 downloads per month
Used in 276 crates (30 directly)


99K SLoC

GNU Style Assembly 68K SLoC // 0.0% comments Assembly 22K SLoC C 5K SLoC // 0.1% comments Rust 4K SLoC // 0.0% comments Shell 41 SLoC Perl 30 SLoC // 0.1% comments

blst Crates.io

The blst crate provides a rust interface to the blst BLS12-381 signature library.


bindgen is used to generate FFI bindings to blst.h. Then build.rs invokes C compiler to compile everything into libblst.a within the rust target build area. On Linux it's possible to choose compiler by setting CC environment variable.

Everything can be built and run with the typical cargo commands:

cargo test
cargo bench

If the target application crashes with an "illegal instruction" exception [after copying to an older system], activate portable feature when building blst. Conversely, if you compile on an older Intel system, but will execute the binary on a newer one, consider instead activating force-adx feature. Though keep in mind that cc passes the value of CFLAGS environment variable to the C compiler, and if set to contain specific flags, it can interfere with feature selection. -D__BLST_PORTABLE__ and -D__ADX__ are the said features' equivalents.

To compile for WebAssembly, your clang has to recognize --target=wasm32. Alternatively you can build your project with CC environment variable set to emcc, the Emscripten compiler, and AR set to emar, naturally, with both commands available on your PATH.

While cargo test's dependencies happen to require at least Rust 1.56, the library by itself can be compiled with earlier compiler versions. Though it takes some version pinning in the dependent's Cargo.toml, zeroize to "=1.3.0" and zeroize_derive to "=1.3.3".


There are two primary modes of operation that can be chosen based on declaration path:

For minimal-pubkey-size operations:

use blst::min_pk::*;

For minimal-signature-size operations:

use blst::min_sig::*;

There are five structs with inherent implementations that provide the BLS12-381 signature functionality.


A simple example for generating a key, signing a message, and verifying the message:

use blst::min_pk::SecretKey;

let mut rng = rand::thread_rng();
let mut ikm = [0u8; 32];
rng.fill_bytes(&mut ikm);

let sk = SecretKey::key_gen(&ikm, &[]).unwrap();
let pk = sk.sk_to_pk();

let dst = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_";
let msg = b"blst is such a blast";
let sig = sk.sign(msg, dst, &[]);

let err = sig.verify(true, msg, dst, &[], &pk, true);
assert_eq!(err, blst:BLST_ERROR::BLST_SUCCESS);

See the tests in src/lib.rs and benchmarks in benches/blst_benches.rs for further examples of usage.


~23K SLoC