mratsim / constantine

Constantine: modular, high-performance, zero-dependency cryptography stack for proof systems and blockchain protocols.
Other
272 stars 38 forks source link
barreto-naehrig bigint bignum bls bls-signature bls12-381 constant-time cryptography digital-signature elliptic-curve-arithmetic elliptic-curve-cryptography elliptic-curves finite-fields galois-field hash-to-curve pairing pairing-cryptography public-key-cryptography side-channels zkp

Constantine

License: Apache License: MIT Stability: experimental\ Github Actions CI

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.

Public API: Curves & Protocols

Protocols are a set of routines, designed for specific goals or a combination thereof:

Legend

Protocols

Constantine supports the following protocols in its public API.

Nim C Rust Go
Ethereum BLS signatures :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
Ethereum KZG commitments for EIP-4844 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
Ethereum IPA commitments for Verkle Tries :building_construction: :see_no_evil: :see_no_evil: :see_no_evil:
Ethereum Virtual Machine BN254 Precompiles ECADD, ECMUL, ECPAIRING :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
EVM BLS12-381 precompiles (EIP-2537) :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
EVM Misc: SHA256, modexp :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
Zk Accel layer for Halo2 proof system (experimental) not applicable not applicable :white_check_mark: not applicable

Elliptic Curves

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.

General cryptography

Constantine supports the following hash functions and CSPRNGs in its public API.

Nim C Rust Go
SHA256 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
Cryptographically-secure RNG from Operating System (sysrand) :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:

Threadpool

Constantine also exposes a high-performance threadpool for Nim that inherits performance and API from:

The 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:

Installation

[!IMPORTANT] Constantine can be compiled by Nim v1.6.x, v2.0.2 and v2.0.4 but not Nim v2.0.0 (due to a compile-time evaluation crash)

From Rust

  1. Install clang compiler, for example:

    • Debian/Ubuntu sudo apt update && sudo apt install build-essential clang
    • Archlinux pacman -S base-devel clang

    [!TIP] 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.

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

    • Debian/Ubuntu sudo apt install nim
    • Archlinux pacman -S nim
  3. Test both:

    • the experimental ZK Accel API (ZAL) for Halo2-KZG
    • Ethereum EIP4844 KZG polynomial commitments
      git clone https://github.com/mratsim/constantine
      cd constantine
      cargo test
      cargo bench
  4. Add Constantine as a dependency in Cargo.toml

    • for Halo2-KZG Zk Accel Layer
      [dependencies]
      constantine-halo2-zal = { git = 'https://github.com/mratsim/constantine' }
    • for Ethereum EIP-4844 KZG polynomial commitments
      [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");

From Go

  1. Install any C compiler, clang is recommended, for example:

    • Debian/Ubuntu sudo apt update && sudo apt install build-essential clang
    • Archlinux pacman -S base-devel clang
  2. 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

    • Debian/Ubuntu sudo apt install nim
    • Archlinux pacman -S nim
  3. Compile Constantine as a static (and shared) library in ./include

    cd constantine
    CC=clang nimble make_lib
  4. Test the go API.

    cd constantine-go
    go test -modfile=../go_test.mod

    [!IMPORTANT] Constantine uses a separate modfile for tests.
    It has no dependencies (key to avoid supply chain attacks) except for testing.

From C

  1. Install a C compiler, clang is recommended, for example:

    • Debian/Ubuntu sudo apt update && sudo apt install build-essential clang
    • Archlinux pacman -S base-devel clang
  2. 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

    • Debian/Ubuntu sudo apt install nim
    • Archlinux pacman -S nim
  3. Compile the dynamic and static library.

    • Recommended: \ CC=clang nimble make_lib
    • or CTT_ASM=0 nimble make_lib\ to compile without assembly (otherwise it autodetects support)
    • or with default compiler\ nimble make_lib
  4. Ensure the libraries work

    • nimble test_lib
  5. Libraries location

  6. Read the examples in examples-c:

From Nim

You can install the developement version of the library through nimble with the following command

nimble install https://github.com/mratsim/constantine@#master

Dependencies & Requirements

For speed it is recommended to use Clang (see Compiler-caveats). In particular GCC generates inefficient add-with-carry code.

Constantine requires at least:

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:

Performance

This section got way too long and has its own file.\ See ./README-PERFORMANCE.md

Assembly & Hardware acceleration

Assembly solves both:

Security

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

Disclaimer

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.

Security disclosure

You can privately report a security vulnerability through the Security tab.

Security > Report a vulnerability

Why Nim

The Nim language offers the following benefits for cryptography:

License

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