Constantine: modular, high-performance, zero-dependency cryptography stack for proof systems and blockchain protocols.
Constantine: High performance cryptography for proof systems and blockchain protocols
“A cryptographic system should be secure even if everything about the system, except the key, is public knowledge.”
— Auguste Kerckhoffs
This library provides constant-time implementation of cryptographic primitives with a particular focus on cryptography used in blockchains and zero-knowledge proof systems.
The library aims to be a fast, compact and hardened library for elliptic curve cryptography needs, in particular for blockchain protocols and zero-knowledge proofs system.
The library focuses on following properties:
in this order.
Protocols are a set of routines, designed for specific goals or a combination thereof:
Legend
Constantine supports the following protocols in its public API.
Nim | C | Rust | Go | |
---|---|---|---|---|
Ethereum BLS signatures | :white_check_mark: | :building_construction: | :building_construction: | :see_no_evil: |
Ethereum KZG commitments for EIP-4844 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
Ethereum Virtual Machine Precompiles (ECADD, ECMUL, ECPAIRING, MODEXP) | :white_check_mark: | :see_no_evil: | :see_no_evil: | :see_no_evil: |
Zk Accel layer for Halo2 proof system (experimental) | not applicable | not applicable | :white_check_mark: | not applicable |
Constantine supports the following curves in its public API.
Nim | C | Rust | Go | |
---|---|---|---|---|
BN254-Snarks | :white_check_mark: | :white_check_mark: | :white_check_mark: | :see_no_evil: |
BLS12-381 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :see_no_evil: |
Pasta curves (Pallas & Vesta) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :see_no_evil: |
For all elliptic curves, the following arithmetic is supported
All operations are constant-time unless explicitly mentioned vartime.
For pairing-friendly curves Fp2 arithmetic is also exposed.
:building_construction: Pairings and multi-pairings are implemented but not exposed yet.
Constantine supports the following hash functions and CSPRNGs in its public API.
Nim | C | Rust | Go | |
---|---|---|---|---|
SHA256 | :white_check_mark: | :white_check_mark: | :building_construction: | |
Cryptographically-secure RNG from Operating System (sysrand) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
Constantine also exposes a high-performance threadpool for Nim that inherits performance and API from:
Task parallelism API RFC: https://github.com/nim-lang/RFCs/issues/347
spawn
and sync
parallelFor
and syncScope
parallelFor
supports arbitrarily complex reduction.
Constantine uses it extensively for parallel elliptic curve sum reductions.isSpawned
and isReady
CPU Topology - Query the number of threads available at the OS/VM-level to run computations:
ctt_cpu_get_num_threads_os
in CgetNumThreadsOS
in Nimconstantine_core::hardware::get_num_threads_os
in RustThe threadpool supports nested parallelism to exploit high core counts and does not suffer from OpenMP limitations of nested parallel loops. For batching KZG verification, Constantine issues 3 multi-scalar multiplication in parallel, each using at 3 nested parallel loops.
See the following documents on the threadpool performance details, design and research:
:exclamation: Constantine can be compiled by Nim v1.6.x or v2.0.2 but not Nim v2.0.0 due to a compile-time integer regression |
Install clang
compiler, for example:
sudo apt update && sudo apt install build-essential clang
pacman -S base-devel clang
:memo: | We require Clang as it's significantly more performant than GCC for cryptographic code, especially for ARM where Constantine has no assembly optimizations. And Rust, like Clang both rely on LLVM. This can be changed to any C compiler by deleting this line. |
Install nim, it is available in most distros package manager for Linux and Homebrew for MacOS Windows binaries are on the official website: https://nim-lang.org/install_unix.html
sudo apt install nim
pacman -S nim
Test both:
git clone https://github.com/mratsim/constantine
cd constantine
cargo test
cargo bench
Add Constantine as a dependency in Cargo.toml
[dependencies]
constantine-halo2-zal = { git = 'https://github.com/mratsim/constantine' }
[dependencies]
constantine-ethereum-kzg = { git = 'https://github.com/mratsim/constantine' }
Optionally, cross-language LTO between Nim and Rust can be used, see https://doc.rust-lang.org/rustc/linker-plugin-lto.html:
Add a .cargo/config.toml
to your project with the following:
# .cargo/config.toml
[build]
rustflags="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld"
and modify Constantine's build.rs
to pass CTT_LTO=1
Command::new("nimble")
.env("CC", "clang")
.env("CTT_LTO", "1") // <--
.arg("make_lib_rust")
.current_dir(root_dir)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.status()
.expect("failed to execute process");
Install any C compiler, clang
is recommended, for example:
sudo apt update && sudo apt install build-essential clang
pacman -S base-devel clang
Install nim, it is available in most distros package manager for Linux and Homebrew for MacOS Windows binaries are on the official website: https://nim-lang.org/install_unix.html
sudo apt install nim
pacman -S nim
Compile Constantine as a static (and shared) library in ./include
cd constantine
CC=clang nimble make_lib
Test the go API.
cd constantine-go
go test -modfile=../go_test.mod
:memo: | Constantine uses a separate modfile for tests. It has no dependencies (key to avoid supply chain attacks) except for testing. |
Install a C compiler, clang
is recommended, for example:
sudo apt update && sudo apt install build-essential clang
pacman -S base-devel clang
Install nim, it is available in most distros package manager for Linux and Homebrew for MacOS Windows binaries are on the official website: https://nim-lang.org/install_unix.html
sudo apt install nim
pacman -S nim
Compile the dynamic and static library.
CC=clang nimble make_lib
CTT_ASM=0 nimble make_lib
nimble make_lib
Ensure the libraries work
nimble test_lib
Libraries location
./lib/
folderRead the examples in examples-c:
You can install the developement version of the library through nimble with the following command
nimble install https://github.com/mratsim/constantine@#master
For speed it is recommended to use Clang (see Compiler-caveats). In particular GCC generates inefficient add-with-carry code.
Constantine requires at least:
-masm=intel
. On Windows, Constantine is tested with MinGW. The Microsoft Visual C++ Compiler is not configured.
Constantine has no C, Nim, Rust, Go dependencies, besides compilers, even on Nim standard library except:
This section got way too long and has its own file.
See ./README-PERFORMANCE.md
CTT_ASM=0
is passed.Assembly solves both:
Hardening an implementation against all existing and upcoming attack vectors is an extremely complex task. The library is provided as is, without any guarantees at least until:
Defense against common attack vectors are provided on a best effort basis. Do note that Constantine has no external package dependencies hence it is not vulnerable to supply chain attacks (unless they affect a compiler or the OS).
Attackers may go to great lengths to retrieve secret data including:
This is would be incomplete without mentioning that the hardware, OS and compiler actively hinder you by:
A growing number of attack vectors is being collected for your viewing pleasure at https://github.com/mratsim/constantine/wiki/Constant-time-arithmetics
Constantine's authors do their utmost to implement a secure cryptographic library in particular against remote attack vectors like timing attacks.
Please note that Constantine is provided as-is without guarantees. Use at your own risks.
Thorough evaluation of your threat model, the security of any cryptographic library you are considering, and the secrets you put in jeopardy is strongly advised before putting data at risk. The author would like to remind users that the best code can only mitigate but not protect against human failures which are the weakest link and largest backdoors to secrets exploited today.
You can privately report a security vulnerability through the Security tab.
Security > Report a vulnerability
The Nim language offers the following benefits for cryptography:
{.compile: "myasm.S".}
awayLicensed and distributed under either of
or
at your option. This file may not be copied, modified, or distributed except according to those terms.
This library has no external dependencies. In particular GMP is used only for testing and differential fuzzing and is not linked in the library.