Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128 #213

Merged
merged 12 commits into from Dec 1, 2017

Conversation

@chriseth
Copy link
Contributor

chriseth commented Feb 13, 2017

Precompiled contracts for elliptic curve operations are required in order to perform zkSNARK verification within the block gas limit.

Replaces #196


### 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)`.

This comment has been minimized.

Copy link
@axic

axic Feb 13, 2017

Member

Should also mention how is a scalar encoded.


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.

This comment has been minimized.

Copy link
@axic

axic Feb 13, 2017

Member

Probably better to format it as:

#### ADD
Input: two curve points `(x, y)`...
Output: resulting curve point
...description...
@pirapira pirapira mentioned this pull request Feb 13, 2017
12 of 12 tasks complete
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.

This comment has been minimized.

Copy link
@pirapira

pirapira Feb 14, 2017

Member

I cannot immediately grasp how fixing parameters makes it easier to incorporate advances.

This comment has been minimized.

Copy link
@chriseth

chriseth Feb 14, 2017

Author Contributor

Changed the wording.


### Encoding

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)`.

This comment has been minimized.

Copy link
@pirapira

pirapira Feb 14, 2017

Member

Isn't zero already used? I guess the elements of F_p are represented by numbers in the range of [0, that prime number - 1].

This comment has been minimized.

Copy link
@chriseth

chriseth Feb 14, 2017

Author Contributor

Yes, but (0,0) should not satisfy the curve equation.

This comment has been minimized.

Copy link
@pirapira

pirapira Feb 14, 2017

Member

OK. Somehow I was thinking about (0, y)s that might satisfy the equations. Now I realize there (0, y)s are just interpreted as they are when y is not zero.


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.

This comment has been minimized.

Copy link
@pirapira

pirapira Feb 14, 2017

Member

Is the padding bit-wise or byte-wise?

This comment has been minimized.

Copy link
@pirapira

pirapira Feb 14, 2017

Member

Also, does it make sense to pad a big-endian number at the end? 1 and 256 would look the same.

This comment has been minimized.

Copy link
@chriseth

chriseth Feb 14, 2017

Author Contributor

Changed the wording, please see if you come to the conclusion that these questions are irrelevant :-)

This comment has been minimized.

Copy link
@pirapira

pirapira Feb 14, 2017

Member

I was reading "if any parameter is less than 2^255, thus any parameter is shorter than expected, the caller should pad the input at the end before calling the contract". Now this interpretation is impossible.

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)`.

This comment has been minimized.

Copy link
@pirapira

pirapira Feb 14, 2017

Member

Does this mean the input has 128 bytes, or are field elements put in RLP or some structure?

This comment has been minimized.

Copy link
@chriseth

chriseth Feb 14, 2017

Author Contributor

Clarified above.

@@ -0,0 +1,99 @@
## Preamble
<pre>

This comment has been minimized.

Copy link
@axic

axic Feb 14, 2017

Member

Why the <pre>?

This comment has been minimized.

Copy link
@chriseth

chriseth Feb 14, 2017

Author Contributor

That was part of the template.

This comment has been minimized.

Copy link
@axic

axic Feb 14, 2017

Member

You might be using an old template.

@chriseth chriseth mentioned this pull request Feb 22, 2017
8 of 8 tasks complete
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.
@chriseth
Copy link
Contributor Author

chriseth commented Mar 9, 2017

TODO: change semantics to throw an exception both for too short and too long input.

@arkpar arkpar mentioned this pull request Mar 9, 2017
12 of 12 tasks complete
@chfast
Copy link
Contributor

chfast commented Mar 21, 2017

A comment from my perspective. @chriseth and me are in the process of "implementing" this and #212 EIPs. "Implementing" means to integrate the external library: libff which was a part of bigger libsnark just a month ago. The libff supports only Linux at the moment and nothing indicates that it is activelly developed. After the split the libff does not have tests properly integrated. It also depends on GMP what is another issue.

My personal opinion is this piece of code if to be integrated to any Ethereum client needs full code review and good set of unit tests.

I don't know why alt_bn128 curve is so special, but if we plan to stick with only this one for a long time, we can modify the code base of libff to be less generic and support only this single curve. Such fork can be joint effort of multiple teams if others are interested.

I wander what other libraries do you use. And what is used by ZCash?

@chriseth
Copy link
Contributor Author

chriseth commented Mar 21, 2017

@chfast at least in the latest version, zcash uses libsnark (or some fork of it). Note that geth will use a different library, I think it might be this one here: https://github.com/golang/crypto/tree/master/bn256 and there is yet another implementation in rust: https://github.com/zcash/bn

So I think this is a C++-only discussion. We might take libff and swap out GMP for something else.


Add precompiled contracts for point addition (ADD) and scalar multiplication (MUL) on the elliptic curve "alt_bn128".

Address of ADD: 0x6

This comment has been minimized.

Copy link
@pirapira

pirapira Apr 13, 2017

Member

EIP 101 also uses this address.

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

This comment has been minimized.

Copy link
@pirapira

pirapira Apr 13, 2017

Member

EIP 101 uses this address too.

This comment has been minimized.

Copy link
@chfast

chfast Apr 13, 2017

Contributor

Can we make sure the precompiled addresses are continuous in the end?

This comment has been minimized.

Copy link
@pirapira

pirapira Apr 13, 2017

Member

I don't think so. 0x10 and 0x20 are taken in #96 .

This comment has been minimized.

Copy link
@pirapira

pirapira Apr 21, 2017

Member

The available addresses seem to be 0xa and 0xb.

This comment has been minimized.

Copy link
@axic

axic Apr 23, 2017

Member

Would it make sense changing #96 to use continuous addresses?

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

This comment has been minimized.

Copy link
@axic

axic Apr 23, 2017

Member

Can someone create those tests cases and include them here?

@axic
Copy link
Member

axic commented Sep 8, 2017

I am 100% too late to the party with this, but it could be actually useful to have the inputs ABI encoded and reside on the same address for this reason: in WASM this precompile can be implemented natively as a contract, but with the current API it would be present in two copies.

This of course assumes WASM would come to life in a reasonable timeframe, otherwise the current API is more useful from the implementation perspective.

From in-contract usage perspective having it ABI encoded would enable using them without any complicated bindings, a simple interface contract would be enough in Solidity without the need of touching assembly.

pirapira added 2 commits Nov 17, 2017
- 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).

This comment has been minimized.

Copy link
@cdetrio

cdetrio Nov 17, 2017

Member

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 1, 2017

Member

@cdetrio do you think a link to the test filler should be added to the EIP?

This comment has been minimized.

Copy link
@cdetrio

cdetrio Dec 1, 2017

Member

@pirapira I was intending to link the test cases. But on second thought, we don't do that for other EIPs so I guess having the links in the PR/discussion is enough.

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

This comment has been minimized.

Copy link
@cdetrio

cdetrio Nov 17, 2017

Member
  • Multiply point with scalar that lies between the order of the group and the field (should succeed).
    • YES
    • order of the group: curve_order = 21888242871839275222246405745257275088548364400416034343698204186575808495617 (in hex: 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001)
    • order of the field (same as modulus of the field): field_modulus = 21888242871839275222246405745257275088696311157297823662689037894645226208583 (in hex: 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47)
    • https://github.com/ethereum/tests/blob/develop/src/GeneralStateTestsFiller/stZeroKnowledge/pointMulAdd2Filler.json#L692-L693
      • uses ECMUL with scalars -1 mod field_order and -2 mod field_order (0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46 and 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45)
- 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).

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

This comment has been minimized.

Copy link
@cdetrio

cdetrio Nov 17, 2017

Member

This comment has been minimized.

Copy link
@pirapira

pirapira Nov 20, 2017

Member

Added such cases in the test google spreadsheet

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.
pirapira added 2 commits Dec 1, 2017
Copy link
Member

pirapira left a comment

Looks good to me.

@shamatar
Copy link
Contributor

shamatar commented May 11, 2018

Hello @pirapira

As important optimizations were merged in 1.8.x and actual processor time for every operation (especially MUL) was significantly reduced, what are the plans to reduce a precompile costs?

Sincerely, Alex

@pirapira
Copy link
Member

pirapira commented May 14, 2018

@shamatar thanks for the news. Many people would be happier with the lower gas amounts, so my suggestion is to file an EIP about the newer gas costs (if there is none yet).

@Shadowfiend
Copy link
Contributor

Shadowfiend commented May 17, 2018

I've opened #1088 to propose this, as I didn't see any other EIPs on the matter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

You can’t perform that action at this time.