Skip to content

Commit ac33ce6

Browse files
authored
Merge pull request #213 from ethereum/ecopts
Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128
2 parents 130153b + a0b9771 commit ac33ce6

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

EIPS/eip-212.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reserved for https://github.com/ethereum/EIPs/pull/212

EIPS/eip-213.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
## Preamble
2+
3+
EIP: 213
4+
Title: Precompiled contracts for addition and scalar multiplication
5+
on the elliptic curve alt_bn128
6+
Author: Christian Reitwiessner<[email protected]>
7+
Type: Standard Track
8+
Category: Core
9+
Status: Final
10+
Created: 2017-02-02
11+
12+
## Simple Summary
13+
14+
Precompiled contracts for elliptic curve operations are required in order to perform zkSNARK verification within the block gas limit.
15+
16+
## Abstract
17+
18+
This EIP suggests to add precompiled contracts for addition and scalar multiplication on a specific pairing-friendly elliptic curve. This can in turn be combined with [EIP-212](./eip-212.md) to verify zkSNARKs in Ethereum smart contracts. The general benefit of zkSNARKs for Ethereum is that it will increase the privacy for users (because of the Zero-Knowledge property) and might also be a scalability solution (because of the succinctness and efficient verifiability property).
19+
20+
## Motivation
21+
22+
Current smart contract executions on Ethereum are fully transparent, which makes them unsuitable for several use-cases that involve private information like the location, identity or history of past transactions. The technology of zkSNARKs could be a solution to this problem. While the Ethereum Virtual Machine can make use of zkSNARKs in theory, they are currently too expensive
23+
to fit the block gas limit. Because of that, this EIP proposes to specify certain parameters for some elementary primitives that enable zkSNARKs so that they can be implemented more efficiently and the gas cost be reduced.
24+
25+
Note that while fixing these parameters might look like limiting the use-cases for zkSNARKs, the primitives are so basic that they can be combined in ways that are flexible enough so that it should even be possible to allow future advances in zkSNARK research without the need for a further hard fork.
26+
27+
## Specification
28+
29+
If `block.number >= BYZANTIUM_FORK_BLKNUM`, add precompiled contracts for point addition (ADD) and scalar multiplication (MUL) on the elliptic curve "alt_bn128".
30+
31+
Address of ADD: 0x6
32+
Address for MUL: 0x7
33+
34+
The curve is defined by:
35+
```
36+
Y^2 = X^3 + 3
37+
over the field F_p with
38+
p = 21888242871839275222246405745257275088696311157297823662689037894645226208583
39+
```
40+
41+
### Encoding
42+
43+
Field elements and scalars are encoded as 32 byte big-endian numbers. Curve points are encoded as two field elements `(x, y)`, where the point at infinity is encoded as `(0, 0)`.
44+
45+
Tuples of objects are encoded as their concatenation.
46+
47+
For both precompiled contracts, if the input is shorter than expected, it is assumed to be virtually padded with zeros at the end (i.e. compatible with the semantics of the `CALLDATALOAD` opcode). If the input is longer than expected, surplus bytes at the end are ignored.
48+
49+
The length of the returned data is always as specified (i.e. it is not "unpadded").
50+
51+
### Exact semantics
52+
53+
Invalid input: For both contracts, if any input point does not lie on the curve or any of the field elements (point coordinates) is equal or larger than the field modulus p, the contract fails. The scalar can be any number between `0` and `2**256-1`.
54+
55+
#### ADD
56+
Input: two curve points `(x, y)`.
57+
Output: curve point `x + y`, where `+` is point addition on the elliptic curve `alt_bn128` specified above.
58+
Fails on invalid input and consumes all gas provided.
59+
60+
#### MUL
61+
Input: curve point and scalar `(x, s)`.
62+
Output: curve point `s * x`, where `*` is the scalar multiplication on the elliptic curve `alt_bn128` specified above.
63+
Fails on invalid input and consumes all gas.
64+
65+
### Gas costs
66+
67+
- Gas cost for ``ECADD``: 500
68+
- Gas cost for ``ECMUL``: 40000
69+
70+
## Rationale
71+
72+
The specific curve `alt_bn128` was chosen because it is particularly well-suited for zkSNARKs, or, more specifically their verification building block of pairing functions. Furthermore, by choosing this curve, we can use synergy effects with ZCash and re-use some of their components and artifacts.
73+
74+
The feature of adding curve and field parameters to the inputs was considered but ultimately rejected since it complicates the specification: The gas costs are much harder to determine and it would be possible to call the contracts on something which is not an actual elliptic curve.
75+
76+
A non-compact point encoding was chosen since it still allows to perform some operations in the smart contract itself (inclusion of the full y coordinate) and two encoded points can be compared for equality (no third projective coordinate).
77+
78+
## Backwards Compatibility
79+
80+
As with the introduction of any precompiled contract, contracts that already use the given addresses will change their semantics. Because of that, the addresses are taken from the "reserved range" below 256.
81+
82+
## Test Cases
83+
84+
Inputs to test:
85+
86+
- Curve points which would be valid if the numbers were taken mod p (should fail).
87+
- Both contracts should succeed on empty input.
88+
- Truncated input that results in a valid curve point.
89+
- Points not on curve (but valid otherwise).
90+
- Multiply point with scalar that lies between the order of the group and the field (should succeed).
91+
- Multiply point with scalar that is larger than the field order (should succeed).
92+
93+
## Implementation
94+
95+
Implementation of these primitives are available here:
96+
97+
- [libff](https://github.com/scipr-lab/libff/blob/master/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp) (C++)
98+
- [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust)
99+
100+
In both codebases, a specific group on the curve alt_bn128 is used and is called G1.
101+
102+
- [Python](https://github.com/ethereum/py_pairing/blob/master/py_ecc/bn128/bn128_curve.py) - probably most self-contained and best readable.
103+
104+
## Copyright
105+
106+
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

0 commit comments

Comments
 (0)