Skip to content

Commit e49671c

Browse files
Merge 5d571d9 into 6f8ac7b
2 parents 6f8ac7b + 5d571d9 commit e49671c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+9720
-0
lines changed

EIPS/eip-7885.md

Lines changed: 366 additions & 0 deletions
Large diffs are not rendered by default.

assets/eip-7885/README.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# NTT-EIP as a building block for FALCON, DILITHIUM and STARK verifiers
2+
3+
This repository contains the EIP for NTT transform, along with a python reference code, and a solidity implementation.
4+
5+
## Context
6+
7+
### The threat
8+
With the release of Willow cheap, the concern for quantum threat against Ethereum seems to accelerate. Post by [Asanso](https://ethresear.ch/t/so-you-wanna-post-quantum-ethereum-transaction-signature/21291) and [PMiller](https://ethresear.ch/t/tidbits-of-post-quantum-eth/21296) summarize those stakes and possible solutions. Those solutions include use of lattice based signatures such as Dillithium or FALCON (the latter being more optimized for onchain constraints), STARKs and FHE. There is a consensus in the cryptographic research community around lattices as the future of asymetric protocols, and STARKs won the race for ZKEVMs implementation (as used by Scroll, Starknet and ZKsync).
9+
10+
Those protocols have in common to require fast polynomial multiplication over prime fields, and use NTT (a special [FFT](https://vitalik.eth.limo/general/2019/05/12/fft.html) adapted to prime fields). While in the past Montgomery multipliers over elliptic curve fields were the critical target of optimizations (both hardware and software), NTT optimization is the key to a performant PQ implementation.
11+
12+
### Discussion
13+
14+
In the past Ethereum chose specificity by picking secp256k1 as its sole candidate for signature. Later, after dedicated hardware and proving systems working on other hardwares were realeased, a zoo of EIP flourished to propose alternative curves. There where attempt to have higher level EIPs to enable all of those at once, such as EWASM, SIMD, EVMMAX, or RIP7696 (by decreasing order of genericity and complexity).
15+
16+
Picking NTT as EIP instead of a given scheme would provide massive gas cost reduction for all schemes relying on it.
17+
- **pros** : massive reduction to all cited protocols, more agility for evolutions.
18+
- **cons**: requires to be wrapped into implementations, not optimal for a given target compared to dedicated EIP, not stateless.
19+
20+
## Overview
21+
22+
The NTT operates on sequences of numbers (often coefficients of polynomials) in a modular arithmetic system. It maps these sequences into a different domain where convolution operations (e.g., polynomial multiplication) become simpler and faster, akin to how FFT simplifies signal convolution. Compared to FFT which uses root of unity in complex plane, NTT uses roots of unity in a finite field or ring.
23+
24+
The NTT is based on the Discrete Fourier Transform (DFT), defined as:
25+
$$
26+
X[k] = \sum_{j=0}^{N-1} x[j] \cdot \omega^{j \cdot k} \mod q$$
27+
28+
Where:
29+
- $x[j]$: Input sequence of length N.
30+
- $X[k]$: Transformed sequence,
31+
- $q$: A prime modulus,
32+
- $\omega$: A primitive N-th root of unity modulo $q$, with
33+
$\omega^N \equiv 1 \mod q \quad \text{and} \quad \omega^k \not\equiv 1 \mod q \; \forall \; 0 < k < N$
34+
35+
NTT computation uses the a similar approach as Cooley-Tukey algorithm to provide a O(N log N) complexity. The NTT algorithm transforms a sequence $(x[j])$ to $(X[k])$ using modular arithmetic. It is invertible, allowing reconstruction of the original sequence via the Inverse NTT (INTT). The inverse process is similar but requires dividing by \(N\) (mod \(q\)) and using $(\omega^{-1}$) (the modular inverse of $\omega$). The following algorithm is extracted from
36+
[[LN16]](https://eprint.iacr.org/2016/504.pdf), and describe how to compute the NTT when $R_q= \mathbb{Z}_q[X]/X^n+1$ (Negative Wrap Convolution).
37+
38+
![alt text](image.png)
39+
40+
The Inverse NTT is computed through the following algorithm:
41+
42+
![alt text](image-1.png)
43+
44+
## Benchmarks
45+
46+
### Python
47+
48+
| Field | $n$ | Recursive NTT (Tetration) | Iterative NTT (ZKNox) | Iterative InvNTT (ZKNox)|
49+
|-|-|-|-|-|
50+
|Falcon | 512 | 761 μs | 528 μs | 561 μs |
51+
|Falcon | 1024 | 1642 μs | 1076 μs | 1199 μs |
52+
|Dilithium| 128 | 165 μs | 114 μs | 113 μs |
53+
|Dilithium| 256 | 371 μs | 258 μs | 260 μs |
54+
|BabyBear | 256 | 531 μs | 389 μs | 404 μs |
55+
56+
The recursive inverse NTT is very costly because of the required inversions. For Falcon, the field is small enough so that field inversions can be precomputed, but the cost is still higher than the iterative inverse NTT.
57+
The field arithmetic has not been optimized. In the case of BabyBear, this becomes significant and so the comparison is not really significant.
58+
59+
### Solidity
60+
61+
62+
| Function | Description | gas cost | Tests Status |
63+
|------------------------|---------------------|---------------------|---------------------|
64+
| NTT recursive | original gas cost from [falcon-solidity](https://github.com/Tetration-Lab/falcon-solidity/blob/main/src/Falcon.sol) | 6.9M | OK|
65+
| InvNTT recursive | original gas cost from [falcon-solidity](https://github.com/Tetration-Lab/falcon-solidity/blob/main/src/Falcon.sol) | 7.8M | OK|
66+
| Full Falcon verification | original gas cost from [falcon-solidity](https://github.com/Tetration-Lab/falcon-solidity/blob/main/src/Falcon.sol) | 24 M| OK|
67+
| NTT iterative | ZKNOX | 4M | OK|
68+
| InvNTT iterative | ZKNOX | 4.2M | OK|
69+
| Full Falcon verification | ZKNOX | 8.5 M| OK|
70+
71+
72+
### Yul
73+
74+
75+
Further optimizations are reached by using Yul for critical sections and using the CODECOPY and EXTCODECOPY trick detailed in of [[RD23]](https://eprint.iacr.org/2023/939.pdf) (section 3.3, "Hacking EVM memory access cost").
76+
77+
78+
| Function | Description | gas cost | Tests Status |
79+
|------------------------|---------------------|---------------------|---------------------|
80+
| ntt.NTTFW | ZKNOX_NTTFW, iterative yuled | 1.9M | OK|
81+
| falcon.verify_opt | Full falcon verification with precomputated pubkey | 3.6M | OK|
82+
83+
### Go Ethereum (WIP)
84+
85+
ZKNOX is planning a client implementation for node of the considered EIP.
86+
87+
## Conclusion
88+
89+
We provided an optimized version of FALCON, using an optimized version of NTT. This code can be used to speed up Stark verification as well as other lattices primitives (Dilithium, Kyber, etc.). While it seems achievable to use FALCON as a progressive precompile, the cost remains very high. Using a client implementation with NTT-EIP (in a Geth fork for example), ETHEREUM could become from a PQ-Friendly and ZK-Friendly chain. This work is supported by the Ethereum Foundation.
90+
91+
92+
## References
93+
94+
- [[LN16]](https://eprint.iacr.org/2016/504.pdf) Speeding up the Number Theoretic Transform for Faster Ideal Lattice-Based Cryptography. Patrick Longa, Michael Naehrig.
95+
- [[EIP616]](https://eips.ethereum.org/EIPS/eip-616) EIP-616: SIMD Operations for the EVM. Greg Colvin.
96+
- [[RD23]](https://eprint.iacr.org/2023/939.pdf) Speeding up elliptic computations for Ethereum Account Abstraction. Renaud Dubois.
97+
- [[DILITHIUM]](https://eprint.iacr.org/2017/633.pdf) CRYSTALS-Dilithium: A Lattice-Based Digital Signature Scheme. Léo Ducas, Eike Kiltz, Tancrède Lepoint, Vadim Lyubashevsky, Peter Schwabe, Gregor Seiler and Damien Stehlé.

assets/eip-7885/image-1.png

129 KB
Loading

assets/eip-7885/image.png

109 KB
Loading
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Optimism-geth with NTT Precompiles (liboqs Implementation)
2+
3+
Fork of `op-geth` with precompiled contracts for Number Theoretic Transform (NTT) operations using open-quantum-safe liboqs via CGO bindings, enabling efficient on-chain post-quantum cryptographic operations.
4+
5+
## Precompiled Contracts
6+
7+
| Address | Name | Description |
8+
| ------- | --------- | ---------------------------------------------------------------------- |
9+
| `0x12` | NTT_FW | Forward NTT using liboqs (Falcon-512/1024, ML-DSA) |
10+
| `0x13` | NTT_INV | Inverse NTT using liboqs (same schemes as NTT_FW) |
11+
| `0x14` | VECMULMOD | Element-wise modular multiplication: `result[i] = (a[i] * b[i]) mod q` |
12+
| `0x15` | VECADDMOD | Element-wise modular addition: `result[i] = (a[i] + b[i]) mod q` |
13+
14+
### Supported Schemes
15+
16+
| Scheme | Ring Degree | Modulus | Element Size |
17+
| ----------- | ----------- | ------- | ---------------- |
18+
| Falcon-512 | 512 | 12289 | uint16 (2 bytes) |
19+
| Falcon-1024 | 1024 | 12289 | uint16 (2 bytes) |
20+
| ML-DSA | 256 | 8380417 | int32 (4 bytes) |
21+
22+
## Installation
23+
24+
### 1. Install liboqs with NTT CGO Bindings
25+
26+
```bash
27+
# Clone and install dependencies
28+
git clone -b feature/ntt-cgo-bindings https://github.com/yhl125/liboqs.git
29+
sudo apt install astyle cmake gcc ninja-build libssl-dev python3-pytest python3-pytest-xdist unzip xsltproc doxygen graphviz python3-yaml valgrind pkg-config
30+
31+
# Build liboqs and Go bindings
32+
cd liboqs/bindings/go
33+
make all
34+
```
35+
36+
### 2. Configure Environment
37+
38+
```bash
39+
# Set paths (adjust to your installation directory)
40+
export PKG_CONFIG_PATH=/path/to/liboqs/bindings/go/.config:$PKG_CONFIG_PATH
41+
export DYLD_LIBRARY_PATH=/path/to/liboqs/build/lib:$DYLD_LIBRARY_PATH # macOS
42+
export LD_LIBRARY_PATH=/path/to/liboqs/build/lib:$LD_LIBRARY_PATH # Linux
43+
```
44+
45+
### 3. Build op-geth
46+
47+
```bash
48+
make geth
49+
```
50+
51+
## API Reference
52+
53+
### NTT_FW (0x12) - Forward Transform
54+
55+
Transforms coefficients into NTT domain using liboqs.
56+
57+
**Input:**
58+
59+
```
60+
[0:4] ring_degree (uint32, big-endian)
61+
[4:12] modulus (uint64, big-endian)
62+
[12:*] coefficients (Falcon: uint16×N, ML-DSA: int32×N, big-endian)
63+
```
64+
65+
**Output:** NTT-transformed coefficients (same format as input)
66+
67+
**Gas Cost:**
68+
69+
- Falcon-512: 500 gas (~9.4μs, 53 mgas/s)
70+
- Falcon-1024: 1,080 gas (~20.4μs, 53 mgas/s)
71+
- ML-DSA: 256 gas (~4.8μs, 53 mgas/s)
72+
73+
### NTT_INV (0x13) - Inverse Transform
74+
75+
Transforms NTT domain coefficients back to standard representation.
76+
77+
**Input:** Same as NTT_FW (coefficients in NTT domain)
78+
79+
**Output:** Coefficients in standard representation
80+
81+
**Gas Cost:**
82+
83+
- Falcon-512: 500 gas (~9.4μs, 53 mgas/s)
84+
- Falcon-1024: 1,080 gas (~20.3μs, 53 mgas/s)
85+
- ML-DSA: 340 gas (~6.4μs, 53 mgas/s)
86+
87+
### VECMULMOD (0x14) - Vector Multiplication
88+
89+
Element-wise modular multiplication in NTT domain.
90+
91+
**Input:**
92+
93+
```
94+
[0:4] ring_degree (uint32, big-endian)
95+
[4:12] modulus (uint64, big-endian)
96+
[12:12+n*size] vector_a
97+
[12+n*size:*] vector_b
98+
```
99+
100+
**Output:** Element-wise product `(a[i] * b[i]) mod q`
101+
102+
**Gas Cost:** `ceil(0.32 × n)`
103+
104+
- Falcon-512: 164 gas (~2.9μs, 56 mgas/s)
105+
- Falcon-1024: 328 gas (~6.0μs, 55 mgas/s)
106+
- ML-DSA: 82 gas (~2.0μs, 42 mgas/s)
107+
108+
### VECADDMOD (0x15) - Vector Addition
109+
110+
Element-wise modular addition.
111+
112+
**Input:** Same as VECMULMOD
113+
114+
**Output:** Element-wise sum `(a[i] + b[i]) mod q`
115+
116+
**Gas Cost:** `ceil(0.3 × n)`
117+
118+
- Falcon-512: 154 gas (~2.8μs, 55 mgas/s)
119+
- Falcon-1024: 308 gas (~5.8μs, 53 mgas/s)
120+
- ML-DSA: 77 gas (~1.6μs, 47 mgas/s)
121+
122+
## Testing
123+
124+
```bash
125+
cd core/vm
126+
127+
# All NTT tests
128+
go test -v -run TestPrecompiled.*NTT
129+
130+
# Specific tests
131+
go test -v -run TestPrecompiledNTT_FW
132+
go test -v -run TestPrecompiledNTT_VECMULMOD
133+
134+
# Benchmarks
135+
go test -bench=BenchmarkPrecompiledNTT -benchtime=5s
136+
```
137+
138+
**Test Coverage:**
139+
140+
- Scheme detection (Falcon-512/1024, ML-DSA)
141+
- Input validation (malformed inputs, invalid parameters)
142+
- Round-trip verification (`INTT(NTT(x)) = x`)
143+
- Cross-scheme isolation
144+
- Performance benchmarks with crypto standards
145+
146+
### Benchmark Results
147+
148+
Benchmarks were run on an Intel(R) Xeon(R) CPU @ 2.20GHz. For detailed results, please see the files below:
149+
150+
- [Ecrecover Benchmark Test Results](./benchmark_results/BenchmarkPrecompiledEcrecover)
151+
- [NTT & NTT Vector Operations Benchmark Test Results](./benchmark_results/BenchmarkPrecompiledNTT)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
goos: linux
2+
goarch: amd64
3+
pkg: github.com/ethereum/go-ethereum/core/vm
4+
cpu: Intel(R) Xeon(R) CPU @ 2.20GHz
5+
BenchmarkPrecompiledEcrecover/-Gas=3000-4 65388 57182 ns/op 3000 gas/op 52.46 mgas/s 352 B/op 6 allocs/op
6+
BenchmarkPrecompiledEcrecover/-Gas=3000-4 64994 55950 ns/op 3000 gas/op 53.61 mgas/s 352 B/op 6 allocs/op
7+
BenchmarkPrecompiledEcrecover/-Gas=3000-4 61538 56411 ns/op 3000 gas/op 53.18 mgas/s 352 B/op 6 allocs/op
8+
BenchmarkPrecompiledEcrecover/-Gas=3000-4 66052 55283 ns/op 3000 gas/op 54.26 mgas/s 352 B/op 6 allocs/op
9+
BenchmarkPrecompiledEcrecover/-Gas=3000-4 65418 56104 ns/op 3000 gas/op 53.47 mgas/s 352 B/op 6 allocs/op
10+
PASS
11+
ok github.com/ethereum/go-ethereum/core/vm 21.021s

0 commit comments

Comments
 (0)