From d8992d14840f8a521aadc21b563d3d539c1fa286 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 13 Feb 2017 14:37:55 +0100 Subject: [PATCH 01/12] Precompiled contracts for elliptic curve operations. --- EIPS/ecopts.md | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 EIPS/ecopts.md diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md new file mode 100644 index 00000000000000..09884637fb29dc --- /dev/null +++ b/EIPS/ecopts.md @@ -0,0 +1,91 @@ +## Preamble +
+  EIP: 
+  Title: Precompiled contracts for addition and scalar multiplication
+         on the elliptic curve alt_bn128
+  Author: Christian Reitwiessner
+  Type: Standard Track
+  Category: Core
+  Status: Draft
+  Created: 2017-02-02
+
+ +## Simple Summary + +Precompiled contracts for elliptic curve operations are required in order to perform zkSNARK verification within the block gas limit. + +## Abstract + +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 https://github.com/ethereum/EIPs/pull/212 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). + +## Motivation + +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 +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. + +Note that fixing these parameters will in no way limit the use-cases for zkSNARKs, it will even allow for incorporating some advances in zkSNARK research without the need for a further hard fork. + +## Specification + +Add precompiled contracts for point addition (ADD) and scalar multiplication (MUL) on the elliptic curve "alt_bn128". + +Address of ADD: 0x6 +Address for MUL: 0x7 + +The curve is defined by: +``` +Y^2 = X^3 + 3 +over the field F_p with +p = 21888242871839275222246405745257275088696311157297823662689037894645226208583 +``` + +### Encoding + +Field elements 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)`. + +For both precompiled contracts, if the input is shorter than expected, it is padded with zeros at the end. + +The length of the returned data is always as specified (i.e. it is not "unpadded"). + +### Exact semantics + +Invalid input: For both contracts, if any input point does not lie on the curve or any of the field elements (point coordinates or scalar) is equal or larger than the field modulus p, the contract fails. + +ADD: Input: two curve points `(x, y)`. Fail on invalid input. Otherwise, return the curve point `x + y` where `+` is point addition on the elliptic curve `alt_bn128` specified above. + +MUL: Input: curve point and scalar `(x, s)`. Fail on invalid input. Otherwise, return the cureve point `x * s`, where `*` is the scalar multiplication on the elliptic curve `alt_bn128` specified above. + +### Gas costs + +To be determined. + +## Rationale + +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. + +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. + +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). + +## Backwards Compatibility + +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. + +## Test Cases + +To be written. + +## Implementation + +Implementation of these primitives are available here: + + - [libsnark](https://github.com/scipr-lab/libsnark/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.hpp) (C++) + - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) + +In both codebases, a specific group on the curve alt_bn128 is used and is called G1. + + - [Python](https://github.com/ethereum/research/blob/master/zksnark/bn128_curve.py) - probably most self-contained and best readable. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file From bc6de05307869f9a49707bda500658d37ef94f30 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 13:02:04 +0100 Subject: [PATCH 02/12] Update ecopts.md --- EIPS/ecopts.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 09884637fb29dc..8a00763b445a1b 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -41,7 +41,7 @@ p = 2188824287183927522224640574525727508869631115729782366268903789464522620858 ### Encoding -Field elements 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)`. +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)`. For both precompiled contracts, if the input is shorter than expected, it is padded with zeros at the end. @@ -51,9 +51,15 @@ The length of the returned data is always as specified (i.e. it is not "unpadded Invalid input: For both contracts, if any input point does not lie on the curve or any of the field elements (point coordinates or scalar) is equal or larger than the field modulus p, the contract fails. -ADD: Input: two curve points `(x, y)`. Fail on invalid input. Otherwise, return the curve point `x + y` where `+` is point addition on the elliptic curve `alt_bn128` specified above. +#### ADD +Input: two curve points `(x, y)`. +Output: curve point `x + y`, where `+` is point addition on the elliptic curve `alt_bn128` specified above. +Fails on invalid input and consumes all gas provided. -MUL: Input: curve point and scalar `(x, s)`. Fail on invalid input. Otherwise, return the cureve point `x * s`, where `*` is the scalar multiplication on the elliptic curve `alt_bn128` specified above. +#### MUL +Input: curve point and scalar `(x, s)`. +Output: curve point `s * x`, where `*` is the scalar multiplication on the elliptic curve `alt_bn128` specified above. +Fails on invalid input and consumes all gas. ### Gas costs @@ -88,4 +94,4 @@ In both codebases, a specific group on the curve alt_bn128 is used and is called ## Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From fdbf2abfea05e1809fff37bbb7d928786c500117 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 17:00:01 +0100 Subject: [PATCH 03/12] Clarifications. --- EIPS/ecopts.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 8a00763b445a1b..2433d5e28d6567 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -23,7 +23,7 @@ This EIP suggests to add precompiled contracts for addition and scalar multiplic 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 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. -Note that fixing these parameters will in no way limit the use-cases for zkSNARKs, it will even allow for incorporating some advances in zkSNARK research without the need for a further hard fork. +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. ## Specification @@ -43,7 +43,9 @@ p = 2188824287183927522224640574525727508869631115729782366268903789464522620858 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)`. -For both precompiled contracts, if the input is shorter than expected, it is padded with zeros at the end. +Tuples of objects are encoded as their concatenation. + +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). The length of the returned data is always as specified (i.e. it is not "unpadded"). From 0ed49ac9b4376541d0d37a13ef47c8e013af818d Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 14 Feb 2017 17:58:36 +0100 Subject: [PATCH 04/12] Updated preamble. --- EIPS/ecopts.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 2433d5e28d6567..3ecd46a8153c46 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -1,14 +1,13 @@ ## Preamble -
-  EIP: 
-  Title: Precompiled contracts for addition and scalar multiplication
-         on the elliptic curve alt_bn128
-  Author: Christian Reitwiessner
-  Type: Standard Track
-  Category: Core
-  Status: Draft
-  Created: 2017-02-02
-
+ + EIP: + Title: Precompiled contracts for addition and scalar multiplication + on the elliptic curve alt_bn128 + Author: Christian Reitwiessner + Type: Standard Track + Category: Core + Status: Draft + Created: 2017-02-02 ## Simple Summary From 8856795031f2dfdb34e4a69731faa83298bda8d7 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 24 Feb 2017 16:27:09 +0100 Subject: [PATCH 05/12] Test cases and scalars larger than field order. Scalars larger than the field characteristic are allowed because it only makes sense to restrict them to the group order, not the field characteristic and adding the group order as another magic constant here would complicated the specification. --- EIPS/ecopts.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 3ecd46a8153c46..d4b70b84df879d 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -50,7 +50,7 @@ The length of the returned data is always as specified (i.e. it is not "unpadded ### Exact semantics -Invalid input: For both contracts, if any input point does not lie on the curve or any of the field elements (point coordinates or scalar) is equal or larger than the field modulus p, the contract fails. +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`. #### ADD Input: two curve points `(x, y)`. @@ -80,7 +80,14 @@ As with the introduction of any precompiled contract, contracts that already use ## Test Cases -To be written. +Inputs to test: + + - Curve points which would be valid if the numbers were taken mod p (should fail). + - Both contracts should succeed on empty input. + - Truncated input that results in a valid curve point. + - Points not on curve (but valid otherwise). + - Multiply point with scalar that lies between the order of the group and the field (should succeed). + - Multiply point with scalar that is larger than the field order (should succeed). ## Implementation From 5785324724757070a19c3a6995b73e9bf3eb7c53 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 1 Jun 2017 10:16:05 +0200 Subject: [PATCH 06/12] Clarify too long input. --- EIPS/ecopts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index d4b70b84df879d..57f1f05ebdcda6 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -1,6 +1,6 @@ ## Preamble - EIP: + EIP: 213 Title: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 Author: Christian Reitwiessner @@ -44,7 +44,7 @@ Field elements and scalars are encoded as 32 byte big-endian numbers. Curve poin Tuples of objects are encoded as their concatenation. -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). +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. The length of the returned data is always as specified (i.e. it is not "unpadded"). From 350c8b5a915f5d1db57a53998e567a3bc451174b Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 1 Jun 2017 10:20:31 +0200 Subject: [PATCH 07/12] Update external links. --- EIPS/ecopts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 57f1f05ebdcda6..d9cebd8f8c3d9e 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -93,12 +93,12 @@ Inputs to test: Implementation of these primitives are available here: - - [libsnark](https://github.com/scipr-lab/libsnark/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.hpp) (C++) + - [libff](https://github.com/scipr-lab/libff/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.cpp) (C++) - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) In both codebases, a specific group on the curve alt_bn128 is used and is called G1. - - [Python](https://github.com/ethereum/research/blob/master/zksnark/bn128_curve.py) - probably most self-contained and best readable. + - [Python](https://github.com/ethereum/research/blob/master/zksnark/py_pairing/py_pairing/bn128_curve.py) - probably most self-contained and best readable. ## Copyright From 0063de10b489b4eba9ec505dcd573a9c19966326 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 11 Sep 2017 11:41:19 +0200 Subject: [PATCH 08/12] Added gas costs. --- EIPS/ecopts.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index d9cebd8f8c3d9e..614f4ac1361b80 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -64,7 +64,8 @@ Fails on invalid input and consumes all gas. ### Gas costs -To be determined. + - Gas cost for ``ECADD``: 500 + - Gas cost for ``ECMUL``: 40000 ## Rationale From 68fa87eb41bb26a550350db7e32550a6bc35907e Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 17 Nov 2017 19:38:33 +0100 Subject: [PATCH 09/12] Fix links --- EIPS/ecopts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/ecopts.md b/EIPS/ecopts.md index 614f4ac1361b80..c5d32cb7747cf2 100644 --- a/EIPS/ecopts.md +++ b/EIPS/ecopts.md @@ -94,12 +94,12 @@ Inputs to test: Implementation of these primitives are available here: - - [libff](https://github.com/scipr-lab/libff/blob/master/src/algebra/curves/alt_bn128/alt_bn128_g1.cpp) (C++) + - [libff](https://github.com/scipr-lab/libff/blob/master/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp) (C++) - [bn](https://github.com/zcash/bn/blob/master/src/groups/mod.rs) (Rust) In both codebases, a specific group on the curve alt_bn128 is used and is called G1. - - [Python](https://github.com/ethereum/research/blob/master/zksnark/py_pairing/py_pairing/bn128_curve.py) - probably most self-contained and best readable. + - [Python](https://github.com/ethereum/py_pairing/blob/master/py_ecc/bn128/bn128_curve.py) - probably most self-contained and best readable. ## Copyright From e0c717c96c9477691152dca53b82058a79e184ca Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 17 Nov 2017 19:40:05 +0100 Subject: [PATCH 10/12] Move ecopts.md to eip-213.md --- EIPS/{ecopts.md => eip-213.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename EIPS/{ecopts.md => eip-213.md} (100%) diff --git a/EIPS/ecopts.md b/EIPS/eip-213.md similarity index 100% rename from EIPS/ecopts.md rename to EIPS/eip-213.md From 8f686cc31176f368000d8c16a6ba2c4bf120f550 Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 13:27:09 +0100 Subject: [PATCH 11/12] Fix the link format --- EIPS/eip-212.md | 1 + EIPS/eip-213.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 EIPS/eip-212.md diff --git a/EIPS/eip-212.md b/EIPS/eip-212.md new file mode 100644 index 00000000000000..02462ab6c63e80 --- /dev/null +++ b/EIPS/eip-212.md @@ -0,0 +1 @@ +Reserved for https://github.com/ethereum/EIPs/pull/212 diff --git a/EIPS/eip-213.md b/EIPS/eip-213.md index c5d32cb7747cf2..9c3551adc84f04 100644 --- a/EIPS/eip-213.md +++ b/EIPS/eip-213.md @@ -15,7 +15,7 @@ Precompiled contracts for elliptic curve operations are required in order to per ## Abstract -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 https://github.com/ethereum/EIPs/pull/212 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). +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). ## Motivation From a0b9771aded733c8e81e7f43beb6adbf97eefdfc Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 1 Dec 2017 13:41:11 +0100 Subject: [PATCH 12/12] Specify the block number and make the status final --- EIPS/eip-213.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-213.md b/EIPS/eip-213.md index 9c3551adc84f04..4b651fd1c7a207 100644 --- a/EIPS/eip-213.md +++ b/EIPS/eip-213.md @@ -6,7 +6,7 @@ Author: Christian Reitwiessner Type: Standard Track Category: Core - Status: Draft + Status: Final Created: 2017-02-02 ## Simple Summary @@ -26,7 +26,7 @@ Note that while fixing these parameters might look like limiting the use-cases f ## Specification -Add precompiled contracts for point addition (ADD) and scalar multiplication (MUL) on the elliptic curve "alt_bn128". +If `block.number >= BYZANTIUM_FORK_BLKNUM`, add precompiled contracts for point addition (ADD) and scalar multiplication (MUL) on the elliptic curve "alt_bn128". Address of ADD: 0x6 Address for MUL: 0x7