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

BLS12-377 curve operations #2539

Merged
merged 6 commits into from
Sep 22, 2020
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
269 changes: 269 additions & 0 deletions EIPS/eip-2539.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
---
eip: 2539
title: BLS12-377 curve operations
author: Alex Vlasov (@shamatar)
discussions-to: https://github.com/ethereum/EIPs/pull/2539
status: Draft
type: Standards Track
category: Core
created: 2020-02-26
requires : 1109, 2046
---

<!--You can leave these HTML comments in your merged EIP and delete the visible duplicate text guides, they will not appear and may be helpful to refer to if you edit it again. This is the suggested template for new EIPs. Note that an EIP number will be assigned by an editor. When opening a pull request to submit your EIP, please use an abbreviated title in the filename, `eip-draft_title_abbrev.md`. The title should be 44 characters or less.-->

## Simple Summary
<!--"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the EIP.-->

This precompile adds operation on BLS12-377 curve (from Zexe paper) as a precompile in a set necessary to *efficiently* perform operations such as BLS signature verification and perform SNARKs verifications. Unique properties of BLS12-377 also later allow to have SNARKs that check BLS12-377 pairing in an efficient way and allow e.g. constant-size BLS signature aggregation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove "from Zexe paper". This is a technical document, not a place to give props/kudos/attribution. If you think that the paper is particularly relevant, I recommend adding it to ../assets/eip-2539/zexe-paper.pdf and linking to it in a place where it makes sense that a future reader of this specification would care.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This precompile adds operation on BLS12-377 curve (from Zexe paper) as a precompile in a set necessary to *efficiently* perform operations such as BLS signature verification and perform SNARKs verifications. Unique properties of BLS12-377 also later allow to have SNARKs that check BLS12-377 pairing in an efficient way and allow e.g. constant-size BLS signature aggregation.
Adds BLS12-377 curve operations as precompiles.

Simple summary should be a very terse one-line description. Longer than the title, but not meant to convey much information and instead let the reader quickly identify "am I in the right place?". This may show up in a sub-heading somewhere for example. The rest of this should probably go in the motivation, as it is is discussing why this is useful/interesting.


## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->

If `block.number >= X` we introduce *seven* separate precompiles to perform the following operations (addresses to be determined):

- G1ADD - to perform point addition on a curve defined over prime field
- G1MUL - to perform point multiplication on a curve defined over prime field
- G1MULTIEXP - to perform multiexponentiation on a curve defined over prime field
- G2ADD - to perform point addition on a curve twist defined over quadratic extension of the base field
- G2MUL - to perform point multiplication on a curve twist defined over quadratic extension of the base field
- G2MULTIEXP - to perform multiexponentiation on a curve twist defined over quadratic extension of the base field
- PAIRING - to perform a pairing operations between a set of *pairs* of (G1, G2) points

Multiexponentiation operation is included to efficiently aggregate public keys or individual signer's signatures during BLS signature verification, as well as public inputs in SNARKs.

## Motivation
<!--The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright.-->

Motivation of this precompile is to add a cryptographic primitive that allows to get 120+ bits of security for operations over pairing friendly curve compared to the existing BN254 precompile that only provides 80 bits of security.

## Specification
<!--The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).-->

Curve parameters:

BLS12-377 curve is fully defined by the following set of parameters (coefficient `A=0` for all BLS12 curves):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
BLS12-377 curve is fully defined by the following set of parameters (coefficient `A=0` for all BLS12 curves):
[BLS12-377](../assets/eip-2539/bls12-377.pdf) curve is fully defined by the following set of parameters (coefficient `A=0` for all BLS12 curves):

This would be a good spot to have a relative link out to an attachment of the BLS12-377 paper. (note: if you accept this comment, make sure to actually add the paper as an asset!)


```
Base field modulus = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
B coefficient = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
Main subgroup order = 0x12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001
Extension tower:
Fp2 construction:
Fp quadratic non-residue = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508bffffffffffc
Fp6/Fp12 construction:
Fp2 cubic non-residue c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Fp2 cubic non-residue c1 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
Twist parameters:
Twist type: D
B coefficient for twist c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
B coefficient for twist c1 = 0x010222f6db0fd6f343bd03737460c589dc7b4f91cd5fd889129207b63c6bf8000dd39e5c1ccccccd1c9ed9999999999a
Generators:
G1:
X = 0x008848defe740a67c8fc6225bf87ff5485951e2caa9d41bb188282c8bd37cb5cd5481512ffcd394eeab9b16eb21be9ef
Y = 0x01914a69c5102eff1f674f5d30afeec4bd7fb348ca3e52d96d182ad44fb82305c2fe3d3634a9591afd82de55559c8ea6
G2:
X c0 = 0x018480be71c785fec89630a2a3841d01c565f071203e50317ea501f557db6b9b71889f52bb53540274e3e48f7c005196
X c1 = 0x00ea6040e700403170dc5a51b1b140d5532777ee6651cecbe7223ece0799c9de5cf89984bff76fe6b26bfefa6ea16afe
Y c0 = 0x00690d665d446f7bd960736bcbb2efb4de03ed7274b49a58e458c282f832d204f2cf88886d8c7c2ef094094409fd4ddf
Y c1 = 0x00f8169fd28355189e549da3151a70aa61ef11ac3d591bf12463b01acee304c24279b83f5e52270bd9a1cdd185eb8f93
Pairing parameters:
|x| (miller loop scalar) = 0x8508c00000000001
x is negative = false
```

#### Fine points and encoding of base elements
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#### Fine points and encoding of base elements
### Fine points and encoding of base elements

You skipped ### here, this can sometimes break some rendering systems particularly when they try to render table of contents.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing with all of the following sections, they are all 1 too deep.


##### Field elements encoding:

To encode points involved in the operation one has to encode elements of the base field and the extension field.

Base field element (Fp) is encoded as `48` bytes by performing BigEndian encoding of the corresponding (unsigned) integer. Corresponding integer **must** be less than field modulus.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shamatar to be compatible with 32-byte 'words' of the EVM/Solidity (and to allow easy mload and mstore operations of 32-byte values in assembly), perhaps elements of Fp should be encoded as 64 bytes instead?

The first 16-bytes could be enforced to be all zeros, or ignored by the builtin contracts.

It'd be great to get your thoughts.


For elements of the quadratic extension field (Fp2) encoding is byte concatenation of individual encoding of the coefficients totaling in `96` bytes for a total encoding. For an Fp2 element in a form `el = c0 + c1 * v` where `v` is formal quadratic non-residue and `c0` and `c1` are Fp elements the corresponding byte encoding will be `encode(c0) || encode(c1)` where `||` means byte concatenation.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shamatar perhaps elements of Fp2 could be 128 bytes, to enable easier field arithmetic in solidity (since real and 'imaginary' coefficients could each be stored in a uint[2] or bytes32[2]).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ll make similar adjustments to 2537 and will largely copy-paste and updated spec here


If encodings to not follow this spec anywhere during parsing in the precompile the precompile *must* return an error.

##### Encoding of uncompressed points:

Points in either G1 (in base field) or in G2 (in extension field) are encoded as byte concatenation of encodings of the `x` and `y` affine coordinates. Total encoding length for G1 point is thus `96` bytes and for G2 point is `192` bytes.

##### Point of infinity encoding:

Also referred as "zero point". For BLS12 curves point with coordinates `(0, 0)` (formal zeroes in Fp or Fp2) is *not* on the curve, so encoding of such point `(0, 0)` is used as a convention to encode point of infinity.

##### Boolean encoding for subgroup checks:

For subgroup checks it's required to encode whether it's required to run a subgroup check for the G1/G2 point or not. For this we encode a boolean as a *single byte* `0x00` for `false` and `0x01` for `true`.

##### Encoding of scalars for multiplication operation:

Scalar for multiplication operation is encoded as `32` bytes by performing BigEndian encoding of the corresponding (unsigned) integer. Corresponding integer is **not** required to be less than or equal than main subgroup size.

#### ABI for operations

##### ABI for G1 addition

G1 addition call expects `192` bytes as an input that is interpreted as byte concatenation of two G1 points (`96` bytes each). Output is an encoding of addition operation result.

Error cases:
- Either of points being not on the curve must result in error
- Field elements encoding rules apply (obviously)
- Input has invalid length

##### ABI for G1 multiplication

G1 multiplication call expects `128` bytes as an input that is interpreted as byte concatenation of encoding of G1 point (`96` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiplication operation result.

Error cases:
- Point being not on the curve must result in error
- Field elements encoding rules apply (obviously)
- Input has invalid length

##### ABI for G1 multiexponentiation

G1 multiplication call expects `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G1 point (`96` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiexponentiation operation result.

Error cases:
- Any of G1 points being not on the curve must result in error
- Field elements encoding rules apply (obviously)
- Input has invalid length

##### ABI for G2 addition

G2 addition call expects `384` bytes as an input that is interpreted as byte concatenation of two G2 points (`192` bytes each). Output is an encoding of addition operation result.

Error cases:
- Either of points being not on the curve must result in error
- Field elements encoding rules apply (obviously)
- Input has invalid length

##### ABI for G2 multiplication

G2 multiplication call expects `224` bytes as an input that is interpreted as byte concatenation of encoding of G2 point (`192` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiplication operation result.

Error cases:
- Point being not on the curve must result in error
- Field elements encoding rules apply (obviously)
- Input has invalid length

##### ABI for G2 multiexponentiation

G2 multiplication call expects `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G2 point (`192` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiexponentiation operation result.

Error cases:
- Any of G2 points being not on the curve must result in error
- Field elements encoding rules apply (obviously)
- Input has invalid length

##### ABI for pairing

Pairing call expects `290*k` bytes as an inputs that is interpreted as byte concatenation of `k` slices. Each slice has the following structure:
- single byte to encode if the following G1 point needs a subgroup check
- `96` bytes of G1 point encoding
- single byte to encode if the following G2 point needs a subgroup check
- `192` bytes of G2 point encoding

Output is a single byte `0x01` if pairing result is equal to multiplicative identity in a pairing target field and `0x00` otherwise.

Error cases:
- Invalid encoding of any boolean variable must result in error
- Any of G1 or G2 points being not on the curve must result in error
- Any of G1 or G2 points for which subgroup check is requested in not actually in a subgroup
- Field elements encoding rules apply (obviously)
- Input has invalid length

#### Gas schedule

Assuming a constant `30 MGas/second` following prices are suggested.

##### G1 addition

`600` gas

##### G1 multiplication

`12000` gas

##### G2 addition

`4500` gas

##### G2 multiplication

`55000` gas

##### G1/G2 Multiexponentiation

Multiexponentiations are expected to be performed by the Peppinger algorithm (we can also say that is **must** be performed by Peppinger algorithm to have a speedup that results in a discount over naive implementation by multiplying each pair separately and adding the results). For this case there was a table prepared for discount in case of `k <= 128` points in the multiexponentiation with a discount cup `max_discount` for `k > 128`.

To avoid non-integer arithmetic call cost is calculated as `k * multiplication_cost * discount / multiplier` where `multiplier = 1000`, `k` is a number of (scalar, point) pairs for the call, `multiplication_cost` is a corresponding single multiplication call cost for G1/G2.

Discounts table as a vector of pairs `[k, discount]`:

```
[[1, 1200], [2, 888], [3, 764], [4, 641], [5, 594], [6, 547], [7, 500], [8, 453], [9, 438], [10, 423], [11, 408], [12, 394], [13, 379], [14, 364], [15, 349], [16, 334], [17, 330], [18, 326], [19, 322], [20, 318], [21, 314], [22, 310], [23, 306], [24, 302], [25, 298], [26, 294], [27, 289], [28, 285], [29, 281], [30, 277], [31, 273], [32, 269], [33, 268], [34, 266], [35, 265], [36, 263], [37, 262], [38, 260], [39, 259], [40, 257], [41, 256], [42, 254], [43, 253], [44, 251], [45, 250], [46, 248], [47, 247], [48, 245], [49, 244], [50, 242], [51, 241], [52, 239], [53, 238], [54, 236], [55, 235], [56, 233], [57, 232], [58, 231], [59, 229], [60, 228], [61, 226], [62, 225], [63, 223], [64, 222], [65, 221], [66, 220], [67, 219], [68, 219], [69, 218], [70, 217], [71, 216], [72, 216], [73, 215], [74, 214], [75, 213], [76, 213], [77, 212], [78, 211], [79, 211], [80, 210], [81, 209], [82, 208], [83, 208], [84, 207], [85, 206], [86, 205], [87, 205], [88, 204], [89, 203], [90, 202], [91, 202], [92, 201], [93, 200], [94, 199], [95, 199], [96, 198], [97, 197], [98, 196], [99, 196], [100, 195], [101, 194], [102, 193], [103, 193], [104, 192], [105, 191], [106, 191], [107, 190], [108, 189], [109, 188], [110, 188], [111, 187], [112, 186], [113, 185], [114, 185], [115, 184], [116, 183], [117, 182], [118, 182], [119, 181], [120, 180], [121, 179], [122, 179], [123, 178], [124, 177], [125, 176], [126, 176], [127, 175], [128, 174]]
```

`max_discount = 174`

##### Pairing operaiton

Base cost of the pairing operation is `23000*k + 80000` where `k` is a number of pairs.

Each point (either G1 or G2) for which subgroup check is requested and performed adds the corresponding G1/G2 multiplication cost to it.

## Rationale
<!--The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.-->
Motivation section covers a total motivation to have operations over BLS12-377 curve available. We also extend a rationale for move specific fine points.

#### Multiexponentiation as a separate call

Explicit separate multiexponentiation operation that allows one to save execution time (so gas) by both the algorithm used (namely Peppinger algorithm) and (usually forgotten) by the fact that `CALL` operation in Ethereum is expensive (at the time of writing), so one would have to pay non-negigible overhead if e.g. for multiexponentiation of `100` points would have to call the multipication precompile `100` times and addition for `99` times (roughly `138600` would be saved).

#### Explicit subgroup checks

Subgroup checks are made optional both due to the fact that they can be performed explicitly by the caller (by multiplication operation) and due to the fact that subgroup checks in G2 that are expensive are not required in most of the cases cause G2 points are usually "hardcoded" and not supplied by the untrusted third party.

Concretely, G2 subgroup check is around `55000` gas.

## Backwards Compatibility
<!--All EIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The EIP must explain how the author proposes to deal with these incompatibilities. EIP submissions without a sufficient backwards compatibility treatise may be rejected outright.-->
There are no backward compatibility questions.

## Test Cases
<!--Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable.-->

Due to the large test parameters space we first provide properties that various operations must satisfy. We use additive notation for point operations, capital letters (`P`, `Q`) for points, small letters (`a`, `b`) for scalars. Generator for G1 is labeled as `G`, generator for G2 is labeled as `H`, otherwise we assume random point on a curve in a correct subgroup. `0` means either scalar zero or point of infinity. `1` means either scalar one or multiplicative identity. `group_order` is a main subgroup order. `e(P, Q)` means pairing operation where `P` is in G1, `Q` is in G2.

Requeired properties for basic ops (add/multiply):

- Commutativity: `P + Q = Q + P`
- Additive negation: `P + (-P) = 0`
- Doubling `P + P = 2*P`
- Subgroup check: `group_order * P = 0`
- Trivial multiplication check: `1 * P = P`
- Multiplication by zero: `0 * P = 0`
- Multiplication by the unnormalized scalar `(scalar + group_order) * P = scalar * P`

Required properties for pairing operation:
- Degeneracy `e(P, 0*Q) = e(0*P, Q) = 1`
- Bilinearity `e(a*P, b*Q) = e(a*b*P, Q) = e(P, a*b*Q)` (internal test, not visible through ABI)

Test vector for all operations are expanded in this [gist](https://gist.github.com/shamatar/506ab3193a7932fe9302a2f3a31a23e8) until it's final.

## Implementation
<!--The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details.-->
There is a various choice of existing implementations:
- BLS12-377 code from Celo
- BLS12-377 code from Zexe
- EIP1962 code bases with fixed parameters

## Security Considerations
<!--All EIPs must contain a section that discusses the security implications/considerations relevant to the proposed change. Include information that might be important for security discussions, surfaces risks and can be used throughout the life cycle of the proposal. E.g. include security-relevant design decisions, concerns, important discussions, implementation-specific guidance and pitfalls, an outline of threats and risks and how they are being addressed. EIP submissions missing the "Security Considerations" section will be rejected. An EIP cannot proceed to status "Final" without a Security Considerations discussion deemed sufficient by the reviewers.-->
Strictly following the spec will eliminate security implications or consensus implications in a contrast to the previous BN254 precompile.

Important topic is a "constant time" property for performed operations. We explicitly state that this precompile **IS NOT REQUIRED** to perform all the operations using constant time algorithms.

## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).