mratsim/constantine
GitHub: mratsim/constantine
面向区块链和零知识证明系统的高性能、零依赖、常量时间密码学原语库,提供以太坊协议原生支持和多语言绑定。
Stars: 488 | Forks: 62
# Constantine
[](https://opensource.org/licenses/Apache-2.0)
[](https://opensource.org/licenses/MIT)
\
[](https://github.com/mratsim/constantine/actions?query=workflow%3A%22Constantine+CI%22+branch%3Amaster)
_Constantine:面向证明系统和区块链协议的高性能密码学_
本库提供了密码学原语的[常量时间](https://en.wikipedia.org/wiki/Timing_attack)实现
特别关注区块链和零知识证明系统中使用的密码学。
- [Constantine](#constantine)
- [公共 API:曲线与协议](#public-api-curves--protocols)
- [协议](#protocols)
- [椭圆曲线](#elliptic-curves)
- [通用密码学](#general-cryptography)
- [线程池](#threadpool)
- [安装](#installation)
- [从 Rust 调用](#from-rust)
- [从 Go 调用](#from-go)
- [从 C 调用](#from-c)
- [从 Nim 调用](#from-nim)
- [依赖与要求](#dependencies--requirements)
- [性能](#performance)
- [汇编与硬件加速](#assembly--hardware-acceleration)
- [安全性](#security)
- [免责声明](#disclaimer)
- [安全披露](#security-disclosure)
- [为什么选择 Nim](#why-nim)
- [许可证](#license)
本库旨在成为用于椭圆曲线密码学需求的快速、紧凑且经过加固的库,尤其适用于区块链协议和零知识证明系统。
本库侧重于以下特性,并按此顺序排列:
- 常量时间(不通过[侧信道](https://en.wikipedia.org/wiki/Side-channel_attack)泄露秘密数据)
- 性能
- 生成的代码大小、数据类型大小和栈使用量
## 公共 API:曲线与协议
协议是一组例程,专为特定目标或其组合而设计:
- 机密性:只有消息的预期接收者才能读取它
- 认证:通信中的另一方是预期的对象
- 完整性:接收到的消息未被篡改
- 不可否认性:消息的发送者无法否认它
**图例**
- :white_check_mark::完全支持
- :building_construction::部分支持:
- 在 C 中,未提供某些 API。
- 在 Rust 中,仅提供低级别的 constantine-sys API,但没有高级别的包装器。
- :see_no_evil::缺失支持
### 协议
Constantine 在其公共 API 中支持以下协议。
| | Nim | C | Rust | Go |
|------------------------------------------------------------------------|:-----------------------:|:------------------:|--------------------|:------------------:|
| Ethereum BLS 签名 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| 用于 EIP-4844 的 Ethereum KZG 承诺 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| 用于 Verkle Trie 的 Ethereum IPA 承诺 | :building_construction: | :see_no_evil: | :see_no_evil: | :see_no_evil: |
| Ethereum Virtual Machine BN254 预编译合约 ECADD, ECMUL, ECPAIRING | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| EVM BLS12-381 预编译合约 (EIP-2537) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| EVM 杂项:SHA256, modexp | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| 用于 Halo2 证明系统的 Zk Accel 层(实验性) | 不适用 | 不适用 | :white_check_mark: | 不适用 |
### 椭圆曲线
Constantine 在其公共 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 曲线 (Pallas & Vesta) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :see_no_evil: |
对于所有椭圆曲线,支持以下算术运算
- 域算术
- 在 Fr 上(即对 255 位曲线阶取模)
- 在 Fp 上(即对 381 位素数模数取模)
- 椭圆曲线算术:
- 在 Fp 上的椭圆曲线 (EC 𝔾₁),支持仿射、雅可比和齐次射影坐标
- 在 Fp2 上的椭圆曲线 (EC 𝔾₂),支持仿射、雅可比和齐次射影坐标
- 包括标量乘法、多标量乘法 (MSM) 和并行 MSM
_除非明确说明为 vartime,否则所有操作均为常量时间_。
对于配对友好的曲线,还暴露了 Fp2 算术。\
:building_construction: 配对和多配对已实现,但尚未暴露。
### 通用密码学
Constantine 在其公共 API 中支持以下哈希函数和 CSPRNG。
| | Nim | C | Rust | Go |
|--------------------------------------------------------------|:------------------:|:------------------:|-------------------------|:------------------:|
| SHA256 | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| 来自操作系统的密码学安全 RNG (sysrand) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
### 线程池
Constantine 还为 Nim 暴露了一个高性能线程池,它继承了以下各项的性能和 API:
- 任务并行 API RFC:https://github.com/nim-lang/RFCs/issues/347
+ Weave 数据并行 API:
- `spawn` 和 `sync`
- `parallelFor` 和 `syncScope`
- `parallelFor` 支持任意复杂的归约。
Constantine 广泛使用它来进行并行椭圆曲线求和归约。
- `isSpawned` 和 `isReady`
- CPU 拓扑 - 查询在 OS/VM 级别可用于运行计算的线程数:
- 在 C 中为 `ctt_cpu_get_num_threads_os`
- 在 Nim 中为 `getNumThreadsOS`
- 在 Rust 中为 `constantine_core::hardware::get_num_threads_os`
- https://github.com/mratsim/weave
- https://github.com/status-im/nim-taskpools
该线程池支持嵌套并行,以利用高核心数量,并且不会受到 OpenMP 嵌套并行循环的限制。对于批量 KZG 验证,Constantine 并行发出 3 个多标量乘法,每个多标量乘法使用 3 个嵌套并行循环。
有关线程池性能细节、设计和研究,请参阅以下文档:
- [./README-PERFORMANCE.md#parallelism](./README-PERFORMANCE.md#parallelism)
- [./docs/threadpool-design.md](./docs/threadpool-design.md)
- https://github.com/mratsim/weave/tree/7682784/research
## 安装
### 从 Rust 调用
1. 安装 ``clang`` 编译器,例如:
- Debian/Ubuntu `sudo apt update && sudo apt install build-essential clang`
- Archlinux `pacman -S base-devel clang`
2. 安装 nim,它在大多数 Linux 发行版的包管理器和 MacOS 的 Homebrew 中均可用
Windows 二进制文件可在官方网站上找到:https://nim-lang.org/install_unix.html
- Debian/Ubuntu `sudo apt install nim`
- Archlinux `pacman -S nim`
3. 测试以下两项:
- 用于 Halo2-KZG 的实验性 ZK Accel API (ZAL)
- Ethereum EIP4844 KZG 多项式承诺
git clone https://github.com/mratsim/constantine
cd constantine
cargo test
cargo bench
4. 在 Cargo.toml 中将 Constantine 添加为依赖项
- 用于 Halo2-KZG Zk Accel 层
[dependencies]
constantine-halo2-zal = { git = 'https://github.com/mratsim/constantine' }
- 用于 Ethereum EIP-4844 KZG 多项式承诺
[dependencies]
constantine-ethereum-kzg = { git = 'https://github.com/mratsim/constantine' }
或者,可以使用 Nim 和 Rust 之间的跨语言 LTO,请参阅 https://doc.rust-lang.org/rustc/linker-plugin-lto.html:
将一个 `.cargo/config.toml` 添加到您的项目中,内容如下:
```
# .cargo/config.toml
[build]
rustflags="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld"
```
并修改 Constantine 的 [`build.rs`](https://github.com/mratsim/constantine/blob/8991b16/constantine-rust/constantine-sys/build.rs#L16-L17) 以传递 `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");
```
### 从 Go 调用
1. 安装任意 C 编译器,推荐使用 `clang`,例如:
- Debian/Ubuntu `sudo apt update && sudo apt install build-essential clang`
- Archlinux `pacman -S base-devel clang`
2. 安装 nim,它在大多数 Linux 发行版的包管理器和 MacOS 的 Homebrew 中均可用
Windows 二进制文件可在官方网站上找到:https://nim-lang.org/install_unix.html
- Debian/Ubuntu `sudo apt install nim`
- Archlinux `pacman -S nim`
3. 在 `./include` 中将 Constantine 编译为静态(和共享)库
cd constantine
CC=clang nimble make_lib
4. 测试 go API。
cd constantine-go
go test -modfile=../go_test.mod
### 从 C 调用
1. 安装 C 编译器,推荐使用 `clang`,例如:
- Debian/Ubuntu `sudo apt update && sudo apt install build-essential clang`
- Archlinux `pacman -S base-devel clang`
2. 安装 nim,它在大多数 Linux 发行版的包管理器和 MacOS 的 Homebrew 中均可用
Windows 二进制文件可在官方网站上找到:https://nim-lang.org/install_unix.html
- Debian/Ubuntu `sudo apt install nim`
- Archlinux `pacman -S nim`
3. 编译动态和静态库。
- 推荐:\
`CC=clang nimble make_lib`
- 或者 `CTT_ASM=0 nimble make_lib`\
在不使用汇编的情况下编译(否则会自动检测支持情况)
- 或者使用默认编译器\
`nimble make_lib`
4. 确保库能正常工作
- `nimble test_lib`
5. 库的位置
- 库被放置在 `./lib/` 文件夹中
- 头文件位于 [./include/](./include) 中,例如 [Ethereum BLS 签名](./include/constantine/protocols/ethereum_bls_signatures.h)
6. 阅读 [examples-c](./examples-c) 中的示例:
- 使用[来自 C 的 Ethereum BLS 签名绑定](./examples-c/ethereum_bls_signatures.c)
- 测试 Constantine BLS12-381 与 GMP 的对比 [./examples-c/t_libctt_bls12_381.c](./examples-c/t_libctt_bls12_381.c)
### 从 Nim 调用
您可以通过 nimble 使用以下命令安装该库的开发版本
```
nimble install https://github.com/mratsim/constantine@#master
```
## 依赖与要求
为了速度,建议使用 Clang(参见[编译器注意事项](#Compiler-caveats))。
特别是 GCC 会生成低效的带进位加法代码。
Constantine 至少需要:
- GCC 7 \
以前的版本会生成不正确的带进位加法代码。
- Clang 14 \
在 x86-64 上,使用内联汇编来绕过编译器在优化大整数算术时的问题,
并确保常量时间代码。\
Constantine 使用 Intel 汇编语法,以解决 Clang 中默认 AT&T 语法和常量传播的问题。\
Clang 14 增加了对 `-masm=intel` 的支持。\
\
在 MacOS 上,Apple Clang 不支持 Intel 汇编语法,请改用 Homebrew Clang 或在不使用汇编的情况下编译。\
_请注意,Apple 正在其整个产品线中逐步淘汰 Intel CPU,因此这只会影响较旧的型号和 Mac Pro_
在 Windows 上,Constant 使用 MinGW 进行了测试。Microsoft Visual C++ 编译器尚未配置。
除了编译器之外,Constantine 没有 C、Nim、Rust、Go 依赖项,甚至对 Nim 标准库也没有依赖,除非:
- 用于测试和基准测试
- 被测试语言的 json 和 yaml 解析器用于测试向量
- 被测试语言的标准库用于测试、计时和消息格式化。
- GMP 用于与 GMP 进行对比测试
- 用于 Nvidia GPU 后端:
- LLVM 运行时(不需要带头文件的 "dev" 版本)
- CUDA 运行时(不需要带头文件的 "dev" 版本)
- 在编译时
- 我们需要 std/macros 库来生成 Nim 代码。
## 性能
本节内容变得太长,因此有专门的文件。\
参见 [./README-PERFORMANCE.md](./README-PERFORMANCE.md)
## 汇编与硬件加速
- 在 x86 和 x86-64 上使用汇编,除非传递了 `CTT_ASM=0`。
- ARM 汇编已在计划中。
- GPU 加速已在计划中。
汇编同时解决了:
- 安全性:[与编译器抗争以实现常量时间代码](./README-PERFORMANCE.md)
- 性能:[编译器注意事项](./README-PERFORMANCE.md#compiler-caveats)
## 安全性
针对所有现有和未来的攻击向量对实现进行加固是一项极其复杂的任务。
本库按“原样”提供,至少在以下情况完成之前不提供任何保证:
- 它通过了审计
- 产生了正确性的形式化证明
- 能够对常量时间实现进行形式化验证
针对常见攻击向量的防御是在尽力而为的基础上提供的。
请注意,Constantine 没有外部包依赖,因此不易受到
供应链攻击(除非它们影响了编译器或操作系统)。
攻击者可能会不择手段地检索秘密数据,包括:
- 测量椭圆曲线上乘法所用的时间
- 分析嵌入式设备的功耗
- 检测使用查找表时的缓存未命中
- 内存攻击,如页面错误、分配器、内存保留攻击
如果不提到硬件、操作系统和编译器
通过以下方式主动阻碍你,那是不完整的:
- 硬件:有时不以常量时间实现乘法。
- 操作系统:不提供防止内存分页到磁盘、核心转储、调试器附加到你的进程或上下文切换(协程)泄露寄存器数据的方法。
- 编译器:优化掉你精心制作的无分支代码并泄露服务器秘密,或者优化掉你的安全擦除例程,因为该例程被认为是“无用”的,因为在函数结束时数据不再被使用。
越来越多的攻击向量正被收集起来供您阅览
,地址为 https://github.com/mratsim/constantine/wiki/Constant-time-arithmetics
### 免责声明
Constantine 的作者尽最大努力实现一个安全的密码库
特别是针对远程攻击向量(如定时攻击)。
请注意,Constantine 按“原样”提供,不做任何保证。
使用风险自负。
在将数据置于风险之前,强烈建议您对自己的威胁模型、您正在考虑的任何密码库的安全性以及您将面临的秘密风险进行彻底评估。
作者想提醒用户,最好的代码只能减轻
但不能防止人为错误,而人为错误是当今被利用的
秘密中最薄弱的环节和最大的后门。
### 安全披露
您可以通过“安全”选项卡私下报告安全漏洞。
`Security > Report a vulnerability`
## 为什么选择 Nim
Nim 语言为密码学提供了以下好处:
- 通过 C 或 C++ 编译为机器码,或者编译为 Javascript。易于与这些语言进行 FFI。
- 可以针对带有专有 C 编译器的冷门嵌入式设备。
- 可以针对 WASM。
- 在 C 中可以达到的性能,在 Nim 中也可以轻松达到。
- 丰富的类型系统:泛型、依赖类型、可变性跟踪和副作用分析、借用检查、编译器强制执行的 distinct 类型(Miles != Meters,SecretBool != bool 且 SecretWord != uint64)。
- 编译时评估,包括解析十六进制字符串,将其转换为 BigInt 或有限域元素以及进行大整数运算。
- 支持内联汇编或仅需一个简单的 `{.compile: "myasm.S".}`
- 如果不使用受 GC 管理的类型,则没有 GC(自动内存管理在类型级别进行设置,默认针对延迟/软实时进行优化,并且可以完全停用)。
- 直接在 AST 上工作的过程宏,用于
- 创建通用曲线配置,
- 派生常量
- 编写与大小无关的内联汇编代码生成器
- 即将通过 Z3 实现用于形式化验证的证明系统([DrNim](https://nim-lang.org/docs/drnim.html),[构造即正确 RFC](https://github.com/nim-lang/RFCs/issues/222))
## 许可证
在以下任一许可证下授权和分发:
* MIT 许可证:[LICENSE-MIT](LICENSE-MIT) 或 http://opensource.org/licenses/MIT
或
* Apache 许可证,版本 2.0,([LICENSE-APACHEv2](LICENSE-APACHEv2) 或 http://www.apache.org/licenses/LICENSE-2.0)
由您选择。除非根据这些条款,否则不得复制、修改或分发此文件。
本库**没有外部依赖项**。
特别是 GMP 仅用于测试和差分模糊测试
,并未链接到库中。
标签:C互操作, Go互操作, Nim语言, Rust互操作, WebAssembly, 侧信道防护, 共识协议, 加密算法, 区块链, 可视化界面, 可验证计算, 密码学, 恒定时间, 手动系统调用, 日志审计, 椭圆曲线密码学, 硬件加速, 网络安全, 证明系统, 隐私保护, 零依赖, 零知识证明