From 5759acec220503aad491c96cb3bce42923e61e28 Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Wed, 26 Feb 2020 21:55:28 +0300 Subject: [PATCH 1/5] BLS12-377 initial spec --- EIPS/eip-x.md | 286 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 EIPS/eip-x.md diff --git a/EIPS/eip-x.md b/EIPS/eip-x.md new file mode 100644 index 00000000000000..79ca7b268cc345 --- /dev/null +++ b/EIPS/eip-x.md @@ -0,0 +1,286 @@ +--- +eip: TBD +title: BLS12-377 curve operations +author: Alex Vlasov (@shamatar) +discussions-to: https://github.com/ethereum/EIPs/pull/2537 +status: Draft +type: Standards Track +category: Core +created: 2020-02-26 +requires : 1109, 2046 +--- + + + +## Simple Summary + + +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. + +## Abstract + + +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 + + +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 + + +Curve parameters: + +BLS12-377 curve is fully defined by the following set of parameters (coefficient `A=0` for all BLS12 curves): + +``` +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 + +##### 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. + +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. + +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. + +##### Encoding of compressed points: + +Points in compressed form only take half the number of bytes compared to the uncompressed form. Base field modulus is `381` bit long, so three most significant bits are available to use for extra encoding. + +The most-significant three bits of a G1 or most-significant three bits of each `48` byte chunk of G2 encoding **must** be masked away before the coordinate(s) are interpreted. These bits are used to unambiguously represent the underlying element. + +For compressed G1 point format is the following: + - The most significant bit indicates that the point is at infinity. If this bit is set, the remaining bits of the group element's encoding **must be* to zero (as in our convention for encoding of point of infinity). + - The second-most significant bit is set if it is *not* the point at infinity *and* this bit is equal to the of recovered y-coordinate's least significant bit. (There are two candidates for y-coordinate when square root is extracted during reconstruction from x-coordinate and these candidates always have different parity). + +For compressed G2 point format is the following: +- For the first `48` bytes (encoding of `c0` coefficient): + - The most significant bit indicates that the point is at infinity. If this bit is set, the remaining bits of the group element's encoding should be set to zero (as in our convention for encoding of point of infinity). + - The second-most significant bit is set if it is *not* the point at infinity *and* is equal to the of y-coordinate's `c1` coefficient's least significant bit if `c1 != 0`. (There are two candidates for y-coordinate when square root is extracted during reconstruction from x-coordinate). +- For the next `48` bytes (encoding of `c1` coefficient): + - Three most significant bits **must be** zero. + +##### 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 + +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 + +There are no backward compatibility questions. + +## Test Cases + + +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 + +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 + +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/). From 41dea96153774201ec403169cf2b25d6794ebe17 Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Wed, 26 Feb 2020 21:57:48 +0300 Subject: [PATCH 2/5] set eip number --- EIPS/{eip-x.md => eip-2539.md} | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) rename EIPS/{eip-x.md => eip-2539.md} (90%) diff --git a/EIPS/eip-x.md b/EIPS/eip-2539.md similarity index 90% rename from EIPS/eip-x.md rename to EIPS/eip-2539.md index 79ca7b268cc345..c35b8132c5d220 100644 --- a/EIPS/eip-x.md +++ b/EIPS/eip-2539.md @@ -1,8 +1,8 @@ --- -eip: TBD +eip: 2539 title: BLS12-377 curve operations author: Alex Vlasov (@shamatar) -discussions-to: https://github.com/ethereum/EIPs/pull/2537 +discussions-to: https://github.com/ethereum/EIPs/pull/2539 status: Draft type: Standards Track category: Core @@ -88,23 +88,6 @@ If encodings to not follow this spec anywhere during parsing in the precompile t 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. -##### Encoding of compressed points: - -Points in compressed form only take half the number of bytes compared to the uncompressed form. Base field modulus is `381` bit long, so three most significant bits are available to use for extra encoding. - -The most-significant three bits of a G1 or most-significant three bits of each `48` byte chunk of G2 encoding **must** be masked away before the coordinate(s) are interpreted. These bits are used to unambiguously represent the underlying element. - -For compressed G1 point format is the following: - - The most significant bit indicates that the point is at infinity. If this bit is set, the remaining bits of the group element's encoding **must be* to zero (as in our convention for encoding of point of infinity). - - The second-most significant bit is set if it is *not* the point at infinity *and* this bit is equal to the of recovered y-coordinate's least significant bit. (There are two candidates for y-coordinate when square root is extracted during reconstruction from x-coordinate and these candidates always have different parity). - -For compressed G2 point format is the following: -- For the first `48` bytes (encoding of `c0` coefficient): - - The most significant bit indicates that the point is at infinity. If this bit is set, the remaining bits of the group element's encoding should be set to zero (as in our convention for encoding of point of infinity). - - The second-most significant bit is set if it is *not* the point at infinity *and* is equal to the of y-coordinate's `c1` coefficient's least significant bit if `c1 != 0`. (There are two candidates for y-coordinate when square root is extracted during reconstruction from x-coordinate). -- For the next `48` bytes (encoding of `c1` coefficient): - - Three most significant bits **must be** zero. - ##### 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. From c5ca07e3500264c025112adec10da45d87350f92 Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Tue, 22 Sep 2020 12:21:18 +0300 Subject: [PATCH 3/5] update to follow 2537 --- EIPS/eip-2539.md | 121 ++++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/EIPS/eip-2539.md b/EIPS/eip-2539.md index c35b8132c5d220..906090e475ad64 100644 --- a/EIPS/eip-2539.md +++ b/EIPS/eip-2539.md @@ -2,7 +2,7 @@ eip: 2539 title: BLS12-377 curve operations author: Alex Vlasov (@shamatar) -discussions-to: https://github.com/ethereum/EIPs/pull/2539 +discussions-to: https://ethereum-magicians.org/t/eip-2539-bls12-377-precompile-discussion-thread/4659 status: Draft type: Standards Track category: Core @@ -10,35 +10,45 @@ created: 2020-02-26 requires : 1109, 2046 --- - - ## Simple Summary - - 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. ## Abstract - -If `block.number >= X` we introduce *seven* separate precompiles to perform the following operations (addresses to be determined): +If `block.number >= X` we introduce *nine* separate precompiles to perform the following operations: -- 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 +- BLS12_377_G1ADD - to perform point addition on a curve defined over prime field +- BLS12_377_G1MUL - to perform point multiplication on a curve defined over prime field +- BLS12_377_G1MULTIEXP - to perform multiexponentiation on a curve defined over prime field +- BLS12_377_G2ADD - to perform point addition on a curve twist defined over quadratic extension of the base field +- BLS12_377_G2MUL - to perform point multiplication on a curve twist defined over quadratic extension of the base field +- BLS12_377_G2MULTIEXP - to perform multiexponentiation on a curve twist defined over quadratic extension of the base field +- BLS12_377_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 - +Multiexponentiation operation is included to efficiently aggregate public keys or individual signer's signatures during BLS signature verification. + +### Proposed addresses table -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. +|Precompile |Address | +|---|---| +|BLS12_377_G1ADD | 0x13 | +|BLS12_377_G1MUL | 0x14 | +|BLS12_377_G1MULTIEXP | 0x15 | +|BLS12_377_G2ADD | 0x16 | +|BLS12_377_G2MUL | 0x17 | +|BLS12_377_G2MULTIEXP | 0x18 | +|BLS12_377_PAIRING | 0x19 | + + +## Motivation +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. In addition it allows efficient one-time recursive proof aggregations, e.g. proofs about existence of BLS12-377 based signature. ## Specification - Curve parameters: @@ -78,24 +88,20 @@ x is negative = false 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. +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 `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. +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 to not follow this spec anywhere during parsing in the precompile the precompile *must* return an error. +If encodings do not follow this spec anywhere during parsing in the precompile the precompile *must* return an error. -##### Encoding of uncompressed points: +##### 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 `96` bytes and for G2 point is `192` bytes. +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. -##### 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. @@ -104,7 +110,7 @@ Scalar for multiplication operation is encoded as `32` bytes by performing BigEn ##### 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. +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 @@ -113,7 +119,7 @@ Error cases: ##### 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. +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 @@ -122,7 +128,7 @@ Error cases: ##### 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. +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 @@ -131,7 +137,7 @@ Error cases: ##### 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. +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 @@ -140,7 +146,7 @@ Error cases: ##### 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. +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 @@ -149,7 +155,7 @@ Error cases: ##### 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. +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 @@ -158,21 +164,23 @@ Error cases: ##### 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 +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 single byte `0x01` if pairing result is equal to multiplicative identity in a pairing target field and `0x00` otherwise. +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 for which subgroup check is requested in not actually in a subgroup +- Any of G1 or G2 points are not in the correct subgroup - Field elements encoding rules apply (obviously) - Input has invalid length +#### 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. @@ -209,30 +217,25 @@ Discounts table as a vector of pairs `[k, discount]`: ##### 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. +Cost of the pairing operation is `23000*k + 115000` where `k` is a number of pairs. ## Rationale - 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 +## Backwards Compatibility +There are no backward compatibility questions. -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. +## Important notes -Concretely, G2 subgroup check is around `55000` gas. +### Subgroup checks -## Backwards Compatibility - -There are no backward compatibility questions. +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). ## Test Cases - 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. @@ -250,20 +253,20 @@ 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. +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 - -There is a various choice of existing implementations: -- BLS12-377 code from Celo -- BLS12-377 code from Zexe +There is a various choice of existing implementations of the curve operations. It may require extra work to add an ABI: - EIP1962 code bases with fixed parameters + - [Rust](https://github.com/matter-labs/eip1962) + - [C++](https://github.com/matter-labs/eip1962_cpp) +- Original implementation linked in Zexe paper in [Rust](https://github.com/scipr-lab/zexe) +- Standalone in [Go](https://github.com/kilic/bls12-377) ## Security Considerations - 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/). +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file From 4388b02ec98cf58e731c1961ded87413ada11c50 Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Tue, 22 Sep 2020 12:30:37 +0300 Subject: [PATCH 4/5] cleanup and spellcheck --- EIPS/eip-2539.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/EIPS/eip-2539.md b/EIPS/eip-2539.md index 906090e475ad64..626eaafe7aab04 100644 --- a/EIPS/eip-2539.md +++ b/EIPS/eip-2539.md @@ -24,10 +24,6 @@ If `block.number >= X` we introduce *nine* separate precompiles to perform the f - BLS12_377_G2MUL - to perform point multiplication on a curve twist defined over quadratic extension of the base field - BLS12_377_G2MULTIEXP - to perform multiexponentiation on a curve twist defined over quadratic extension of the base field - BLS12_377_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. @@ -42,8 +38,6 @@ Multiexponentiation operation is included to efficiently aggregate public keys o |BLS12_377_G2MUL | 0x17 | |BLS12_377_G2MULTIEXP | 0x18 | |BLS12_377_PAIRING | 0x19 | - ## Motivation 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. In addition it allows efficient one-time recursive proof aggregations, e.g. proofs about existence of BLS12-377 based signature. @@ -215,7 +209,7 @@ Discounts table as a vector of pairs `[k, discount]`: `max_discount = 174` -##### Pairing operaiton +##### Pairing operation Cost of the pairing operation is `23000*k + 115000` where `k` is a number of pairs. From 47e4503e5b825409e704b58d36f5faf36cc83d22 Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Tue, 22 Sep 2020 12:34:30 +0300 Subject: [PATCH 5/5] extra whitespace? --- EIPS/eip-2539.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-2539.md b/EIPS/eip-2539.md index 626eaafe7aab04..fdf32c595a74de 100644 --- a/EIPS/eip-2539.md +++ b/EIPS/eip-2539.md @@ -7,7 +7,7 @@ status: Draft type: Standards Track category: Core created: 2020-02-26 -requires : 1109, 2046 +requires: 1109, 2046 --- ## Simple Summary