From bc18682aacf4aa7340d1e5024ae34f8f57d35c65 Mon Sep 17 00:00:00 2001 From: Alexander <alex.m.vlasov@gmail.com> Date: Mon, 1 Jun 2020 17:55:43 +0300 Subject: [PATCH] BLS12-381 curve operations (#2537) * draft * Update eip-x.md * add ABI * also mention encoding of boolean vars in pairing * add point decompression * fix decompression, add gas price * expand on square root extraction and checks * Cleanup title * Fix typo and remove optional header fields * set EIP number * hm, html verifier is not satisfied... * update on ABI, costs and subgroup checks * add more information about field-to-curve * add links to implementations * spellcheck * mapping costs are underetmined yet * add mapping operations cost * whoops, spellcheck! * updates: test vectors, prefixes * more explicit pairing output * gas consumption in case of error * fix multiplication -> multiexp * split mapping into two separate ones * spellcheck * update link to Go implementation * add addresses Co-authored-by: Kobi Gurkan <kobigurk@gmail.com> --- EIPS/eip-2537.md | 324 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 EIPS/eip-2537.md diff --git a/EIPS/eip-2537.md b/EIPS/eip-2537.md new file mode 100644 index 00000000000000..abd219255a4c8b --- /dev/null +++ b/EIPS/eip-2537.md @@ -0,0 +1,324 @@ +--- +eip: 2537 +title: Precompile for BLS12-381 curve operations +author: Alex Vlasov (@shamatar) +discussions-to: https://ethereum-magicians.org/t/eip2537-bls12-precompile-discussion-thread/4187 +status: Draft +type: Standards Track +category: Core +created: 2020-02-21 +--- + +<!--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-381 curve as a precompile in a set necessary to *efficiently* perform operations such as BLS signature verification and perform SNARKs verifications. + +## Abstract +<!--A short (~200 word) description of the technical issue being addressed.--> + +If `block.number >= X` we introduce *nine* separate precompiles to perform the following operations: + +- BLS12_G1ADD - to perform point addition on a curve defined over prime field +- BLS12_G1MUL - to perform point multiplication on a curve defined over prime field +- BLS12_G1MULTIEXP - to perform multiexponentiation on a curve defined over prime field +- BLS12_G2ADD - to perform point addition on a curve twist defined over quadratic extension of the base field +- BLS12_G2MUL - to perform point multiplication on a curve twist defined over quadratic extension of the base field +- BLS12_G2MULTIEXP - to perform multiexponentiation on a curve twist defined over quadratic extension of the base field +- BLS12_PAIRING - to perform a pairing operations between a set of *pairs* of (G1, G2) points +- BLS12_MAP_FP_TO_G1 - maps base field element into the G1 point +- BLS12_MAP_FP2_TO_G2 - maps extension field element into the G2 point + +Mapping functions are implemented according to [IEFT specification](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/blob/master/draft-irtf-cfrg-hash-to-curve.md#deterministic-mappings-mappings) version `v7`(!) using an simplified SWU method. It does NOT perform mapping of the byte string into field element that can be implemented in many different ways and can be efficiently performed in EVM, but only does field arithmetic to map field element into curve point. Such functionality is required for signature schemes. + +Multiexponentiation operation is included to efficiently aggregate public keys or individual signer's signatures during BLS signature verification. + +### Proposed addresses table + +|Precompile |Address | +|---|---| +|BLS12_G1ADD | 0x0a | +|BLS12_G1MUL | 0x0b | +|BLS12_G1MULTIEXP | 0x0c | +|BLS12_G2ADD | 0x0d | +|BLS12_G2MUL | 0x0e | +|BLS12_G2MULTIEXP | 0x0f | +|BLS12_PAIRING | 0x10 | +|BLS12_MAP_FP_TO_G1 | 0x11 | +|BLS12_MAP_FP2_TO_G2 | 0x12 | + +## 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 curve is fully defined by the following set of parameters (coefficient `A=0` for all BLS12 curves): + +``` +Base field modulus = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab +B coefficient = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 +Main subgroup order = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 +Extension tower +Fp2 construction: +Fp quadratic non-residue = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa +Fp6/Fp12 construction: +Fp2 cubic non-residue c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +Fp2 cubic non-residue c1 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 +Twist parameters: +Twist type: M +B coefficient for twist c0 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 +B coefficient for twist c1 = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004 +Generators: +G1: +X = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb +Y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1 +G2: +X c0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8 +X c1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e +Y c0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801 +Y c1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be +Pairing parameters: +|x| (miller loop scalar) = 0xd201000000010000 +x is negative = true +``` + +One should note that base field modulus is equal to `3 mod 4` that allows an efficient square root extraction, although as described below gas cost of decompression is larger than gas cost of supplying decompressed point data in `calldata`. + +#### Fine points and encoding of base elements + +##### 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 `64` bytes by performing BigEndian encoding of the corresponding (unsigned) integer (top `16` bytes are always zeroes). `64` bytes are chosen to have `32` byte aligned ABI (representable as e.g. `bytes32[2]` or `uint256[2]`). Corresponding integer **must** be less than field modulus. + +For elements of the quadratic extension field (Fp2) encoding is byte concatenation of individual encoding of the coefficients totaling in `128` 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 (or one can use `bytes32[4]` or `uint256[4]` in terms of Solidity types). + +If encodings do not follow this spec anywhere during parsing in the precompile the precompile *must* return an error. + +##### Encoding of points in G1/G2: + +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 `128` bytes and for G2 point is `256` 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. + +##### 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 `256` bytes as an input that is interpreted as byte concatenation of two G1 points (`128` bytes each). Output is an encoding of addition operation result - single G1 point (`128` bytes). + +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 `160` bytes as an input that is interpreted as byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiplication operation result - single G1 point (`128` bytes). + +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 multiexponentiation call expects `160*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 (`128` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiexponentiation operation result - single G1 point (`128` bytes). + +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 `512` bytes as an input that is interpreted as byte concatenation of two G2 points (`256` bytes each). Output is an encoding of addition operation result - single G2 point (`256` bytes). + +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 `288` bytes as an input that is interpreted as byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiplication operation result - single G2 point (`256` bytes). + +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 multiexponentiation call expects `288*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 (`256` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiexponentiation operation result - single G2 point (`256` bytes). + +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 `384*k` bytes as an inputs that is interpreted as byte concatenation of `k` slices. Each slice has the following structure: +- `128` bytes of G1 point encoding +- `256` bytes of G2 point encoding + +Output is a `32` bytes where first `31` bytes are equal to `0x00` and the last byte is `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 are not in the correct subgroup +- Field elements encoding rules apply (obviously) +- Input has invalid length + +##### ABI for mapping Fp element to G1 point + +Field-to-curve call expects `64` bytes an an input that is interpreted as a an element of the base field. Output of this call is `128` bytes and is G1 point following respective encoding rules. + +Error cases: +- Input has invalid length +- Input is not a valid field element + +##### ABI for mapping Fp2 element to G2 point + +Field-to-curve call expects `128` bytes an an input that is interpreted as a an element of the quadratic extension field. Output of this call is `256` bytes and is G2 point following respective encoding rules. + +Error cases: +- Input has invalid length +- Input is not a valid field element + +#### Prevention of DDoS on error handling + +This precompile performs extensive computations and in case of any errors during execution it MUST consume all gas from the the gas schedule for the corresponding operation. + +#### 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 + +Cost of the pairing operation is `23000*k + 115000` where `k` is a number of pairs. + +##### Fp-to-G1 mappign operation + +Fp -> G1 mapping is `5500` gas. + +##### Fp2-to-G2 mappign operation + +Fp2 -> G2 mapping is `110000` gas + +## 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-381 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). + +## 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. + +## Important notes + +### Subgroup checks + +Subgroup check **is mandatory** during the pairing call. Implementations *should* use fast subgroup checks: at the time of writing multiplication gas cost is based on `double-and-add` multiplication method that has a clear "worst case" (all bits are equal to one). For pairing operation it's expected that implementation uses faster subgroup check, e.g. by using wNAF multiplication method for elliptic curves that is ~ `40%` cheaper with windows size equal to 4. (Tested empirically. Savings are due to lower hamming weight of the group order and even lower hamming weight for wNAF. Concretely, subgroup check for both G1 and G2 points in a pair are around `35000` combined). + +### Field to curve mapping + +Set of parameters for SWU mapping method is provided by [IETF](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/blob/master/draft-irtf-cfrg-hash-to-curve.md#suites-for-bls12-381-suites-bls12381). + +One should pay particular attention to the following fine points during implementation: +- SWU method [itself](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/blob/master/draft-irtf-cfrg-hash-to-curve.md#simplified-swu-for-ab--0-simple-swu-ab0) +- [Cofactor cleanup](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/blob/master/draft-irtf-cfrg-hash-to-curve.md#clearing-the-cofactor-cofactor-clearing) + +Once again, [hash to field](https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/blob/master/draft-irtf-cfrg-hash-to-curve.md#hashing-to-a-finite-field-hashtofield) is NOT a part of this EIP as it can be implemented in EVM and with different strategies. + +## 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 `csv` files in [repo](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537). + +## 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 of the curve operations. It may require extra work to add an ABI: +- BLS12-381 code bases for Eth 2.0 clients + - Chia's library in [C++](https://github.com/Chia-Network/bls-signatures) + - Milagro in [various languages](https://github.com/apache/incubator-milagro) +- EIP1962 code bases with fixed parameters + - [Rust](https://github.com/matter-labs/eip1962) + - [Go](https://github.com/kilic/eip2537) + - [C++](https://github.com/matter-labs/eip1962_cpp) +- Original implementation by zCash in [Rust](https://github.com/zcash/librustzcash/tree/master/pairing) +- [MCL library](https://github.com/herumi/mcl) and it's bindings in other languages + +## 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/).