From 3ad07e56665075000dae841af492159483834c34 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 18:39:57 +0300 Subject: [PATCH] fix links --- neps/nep-0488.md | 138 +++++++++++++++++++++++------------------------ 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a2e1d6b40..104caf6b8 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -17,29 +17,29 @@ A pre-compiled NEAR runtime functions for operations on BLS12-381 curve. It is a ## Motivation The BLS12-381[^1][^11][^52] is a wildly -used[^2],[^3](https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md), [4](https://internetcomputer.org/docs/current/references/ic-interface-spec#certificate), [5](https://wiki.tezosagora.org/learn/futuredevelopments/layer2#zkchannels), [6](https://spec.filecoin.io/), [7](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-)] elliptic curve with 120+ bits of security[[8](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1)] which support **the *pairing* operation*.* It is a good alternative for bn254 elliptic curve[[9](https://eprint.iacr.org/2005/133), [12](https://hackmd.io/@jpw/bn254)], which also supports the aggregation, and is currently implemented as NEAR precompiles[[10](https://github.com/near/NEPs/issues/98)]. Recent research shows that it contains only <100 bits of security[[13](https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security)] and we can see the tendency of switching from bn254 to bls12-381(ZCash[[14](https://electriccoin.co/blog/new-snark-curve/)], Ethereum[[15](https://eips.ethereum.org/EIPS/eip-2537)], Tezos[[16](https://medium.com/metastatedev/meanwhile-at-cryptium-labs-2-part-2-adding-the-pairing-equipped-elliptic-curve-bls12-381-to-tezos-cfce907e4be3)]). +used[^2][^3][^4][^5][^6][^7] elliptic curve with 120+ bits of security[^8] which support **the *pairing* operation*.* It is a good alternative for bn254 elliptic curve[^9][^12], which also supports the aggregation, and is currently implemented as NEAR precompiles[^10]. Recent research shows that it contains only <100 bits of security[^13] and we can see the tendency of switching from bn254 to bls12-381(ZCash[^14], Ethereum[^15], Tezos[^16]). The implementation of BLS12-381 curve operations from this NEP as a precompile will allows effective verify the BLS-signature and zkSNARKs. At the moment, BLS signature verification for BLS12-381 is impossible due to the limitation of the gas in 300 TGas for one transaction. -Effective BLS-signature verification based on BLS12-381 elliptic curve will be useful for cross-chain interactions. Some of the blockchains use the BLS signature in the protocols. If we want to implement the clients for this blockchain on-chain in NEAR, we should be able to effectively verify the BLS signature. We can want to have a client for a specific blockchain on Near for creating a bridge to verify the transaction from another blockchain and use it in Near. Examples of blockchains that use BLS signature based on BLS12-381: Eth2.0[[3](https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md)], Filecoin[[6](https://spec.filecoin.io/)] and Tezos[[5](https://wiki.tezosagora.org/learn/futuredevelopments/layer2#zkchannels)]. Especially, it is necessary for Rainbow Bridge[[17](https://near.org/blog/eth-near-rainbow-bridge)] to make trustless transfers from Ethereum 2.0 to Near. +Effective BLS-signature verification based on BLS12-381 elliptic curve will be useful for cross-chain interactions. Some of the blockchains use the BLS signature in the protocols. If we want to implement the clients for this blockchain on-chain in NEAR, we should be able to effectively verify the BLS signature. We can want to have a client for a specific blockchain on Near for creating a bridge to verify the transaction from another blockchain and use it in Near. Examples of blockchains that use BLS signature based on BLS12-381: Eth2.0[^3], Filecoin[^6] and Tezos[^5]. Especially, it is necessary for Rainbow Bridge[^17] to make trustless transfers from Ethereum 2.0 to Near. -zkSNARKs is useful for working with user's private information[[18](https://eips.ethereum.org/EIPS/eip-196),[19](https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b)]. Zeropool[[20](https://zeropool.network/)] is a project who implements zkSNARKs verifier on Near and is currently based on alt-bn128. Implementation of the precompiles for BLS12-381 can make the projects like that more secure. zkSNARKs is also used in Roll Ups[[21](https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders),[22](https://near.org/blog/layer-2),[23](https://www.ledger.com/academy/what-are-blockchain-rollups)] scaling solutions. +zkSNARKs is useful for working with user's private information[^18][^19]. Zeropool[^20] is a project who implements zkSNARKs verifier on Near and is currently based on alt-bn128. Implementation of the precompiles for BLS12-381 can make the projects like that more secure. zkSNARKs is also used in Roll Ups[^21][^22][^23] scaling solutions. -This proposal is based on a similar proposal for Ethereum: EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. +This proposal is based on a similar proposal for Ethereum: EIP-2537[^15]. In this NEP we propose to add the following functions as precompile: -- ***bls12381_g1_sum —*** the function which adds the points from G1 on an elliptic curve. This function is useful for the aggregation of private keys in BLS Signature. Can be used for simple addition in G1. Separate from multiexp function due to gas cost. A similar function exists in Near for BN254 curve[[10](https://github.com/near/NEPs/issues/98)]. +- ***bls12381_g1_sum —*** the function which adds the points from G1 on an elliptic curve. This function is useful for the aggregation of private keys in BLS Signature. Can be used for simple addition in G1. Separate from multiexp function due to gas cost. A similar function exists in Near for BN254 curve[^10]. - ***bls12381_g2_sum —*** the function which adds the points from G2 on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. Can be used for simple addition in G2. Separate from multiexp function due to gas cost. -- ***bls12381_g1_multiexp —*** for points $g_i \in G_1$ and scalars $s_i$ calculate $\sum g_i s_i$. Can be used for multiplication on the scalar. Can be useful for zkSNARKs verification. This operation can be performed in a more optimized way than just straightforward multiplication and addition by using Pippenger algorithm[[25](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf)]. A similar function exists both in NEAR for BN254[[10](https://github.com/near/NEPs/issues/98)] and in EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. +- ***bls12381_g1_multiexp —*** for points $g_i \in G_1$ and scalars $s_i$ calculate $\sum g_i s_i$. Can be used for multiplication on the scalar. Can be useful for zkSNARKs verification. This operation can be performed in a more optimized way than just straightforward multiplication and addition by using Pippenger algorithm[^25]. A similar function exists both in NEAR for BN254[^10] and in EIP-2537[^15]. - ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. Can be used for multiplication on the scalar. -- ***bls12381_g1_map_to_curve —*** map base field element into the $G_1$ point. Doesn’t perform mapping of the byte string into field elements (can be done in different ways and quite fast). Transfer field element into a curve. It is necessary for signature schemes. Function from EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. -- ***bls12381_g2_map_to_curve —*** map extension field element into the $G_2$ point. Doesn’t perform mapping of the byte string into extension field elements. Function from EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. +- ***bls12381_g1_map_to_curve —*** map base field element into the $G_1$ point. Doesn’t perform mapping of the byte string into field elements (can be done in different ways and quite fast). Transfer field element into a curve. It is necessary for signature schemes. Function from EIP-2537[^15]. +- ***bls12381_g2_map_to_curve —*** map extension field element into the $G_2$ point. Doesn’t perform mapping of the byte string into extension field elements. Function from EIP-2537[^15]. - ***bls12381_g1_decompress —*** accepts points from $G_1$ in compressed form and returns in decompressed form. Some protocols provide points in compressed forms (for example, Light Client updates in Ethereum 2), and decompressing is a time-consuming operation. Other functions accept only decompressed points for simplicity and for gas consumption optimization. - ***bls12381_g2_decompress —*** accepts points from $G_2$ in compressed form and returns in decompressed form. -- ***bls12381_pairing —*** verifying that $\prod e(p_i, q_i) = 1$, where $e$ is a pairing operation and $p_i \in G_1 \land q_i \in G_2$. Necessary function for verification BLS-signatures or zkSNARKs. A similar function exists both in NEAR for BN254[[10](https://github.com/near/NEPs/issues/98)] and in EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. +- ***bls12381_pairing —*** verifying that $\prod e(p_i, q_i) = 1$, where $e$ is a pairing operation and $p_i \in G_1 \land q_i \in G_2$. Necessary function for verification BLS-signatures or zkSNARKs. A similar function exists both in NEAR for BN254[^10] and in EIP-2537[^15]. -By using these functions, we can reproduce all functionality from EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. Which can be useful for Aurora[[24](https://doc.aurora.dev/evm/precompiles/)] to support Ethereum functionality on NEAR. +By using these functions, we can reproduce all functionality from EIP-2537[^15]. Which can be useful for Aurora[^24] to support Ethereum functionality on NEAR. ## Specification @@ -59,7 +59,7 @@ $$ together with an imaginary point at infinity 0, where: $A, B \in F_p$, p is prime > 3, and $4A^3 + 27B^2 \not \equiv 0 \mod p$ -In the case of BLS12-381 equation is $y^2 \equiv x^3 + 4 \mod p$ ([[15](https://eips.ethereum.org/EIPS/eip-2537),[51](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-),[14](https://electriccoin.co/blog/new-snark-curve/),[11](https://hackmd.io/@benjaminion/bls12-381)]) +In the case of BLS12-381 equation is $y^2 \equiv x^3 + 4 \mod p$[^15][^51][^14][^11] **Parameters for our case:** @@ -102,7 +102,7 @@ Notation: |G| or #G, where G is group For some technical reason (for `pairing` operation which we will define later), we will work not with the hole $E(F_p)$, but only with the two subgroups $G_1$and $G_2$ with the same **order** $r$. $G_1$ is a subset of $E(F_p)$, $G_2$ is a subgroup of another group, which we will define later. The $r$ should be prime and $G1 \ne G2$ -For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$([[15](https://eips.ethereum.org/EIPS/eip-2537), [51](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-)]): +For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$[^15][^51]: ```rust Main subgroup order r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 @@ -140,7 +140,7 @@ Notation: $F_{p^k} = F_{p}[x] / M(x)$ In BLS12-381 we will need $F_{p^{12}}$ and we will build this field not as an extension from $F_p$ directly, but first we will build $F_{p^2}$ as a quadratic extension of field $F_p$, second we will build $F_{p^6}$ as a cubic extension of $F_{p^2}$, and finally we will build $F_{p^{12}}$ the quadratic extension of field $F_{p^6}$. -For defining these fields, we will need to set up three $M(x)$ irreducible polynomials([[51](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-)]: +For defining these fields, we will need to set up three $M(x)$ irreducible polynomials[^51]: - $F_{p^2} = F_p[u] / (u^2 + 1)$ - $F_{p^6} = F_{p^2}[v] / (v^3 - u - 1)$ @@ -159,7 +159,7 @@ We want to have $\psi \colon E'(F_{p^2}) \rightarrow E(F_{p^{12}})$, such as It is called injective group homomorphism. -For BLS12-381 E’ is defined as([[51](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-)]): +For BLS12-381 E’ is defined as[^51]: $$ E'\colon y^2 = x^3 + 4(u + 1) @@ -173,7 +173,7 @@ In most cases we will work with points from $G_2' \subset E'(F_{p^2})$ and use f -$G_1$ and $G_2$ are cyclic subgroups with the following generators([[15](https://eips.ethereum.org/EIPS/eip-2537), [51](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-)]): +$G_1$ and $G_2$ are cyclic subgroups with the following generators[^15][^51]: ```rust G1: @@ -200,13 +200,13 @@ $$ |G|/|H| $$ -Cofactor $G_1\colon h = |E(F_p)|/r$ ([[51](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-)]) +Cofactor $G_1\colon h = |E(F_p)|/r$[^51] ```rust h = 0x396c8c005555e1568c00aaab0000aaab ``` -Cofactor $G_2\colon h' = |E'(F_{p^2})|/r$ ([[51](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-)]) +Cofactor $G_2\colon h' = |E'(F_{p^2})|/r$[^51] ```rust h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 @@ -229,10 +229,10 @@ x = -0xd201000000010000 You can find this parameter in: -- [[15](https://eips.ethereum.org/EIPS/eip-2537)] section specification, pairing parameters, miller loop scalar -- [[51](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-)] section 4.2.1 Parameter t -- [[14](https://electriccoin.co/blog/new-snark-curve/)] section BLS12-381, parameter u -- [[11](https://hackmd.io/@benjaminion/bls12-381)] section Curve equation and parameters, parameter x +- [^15] section specification, pairing parameters, miller loop scalar +- [^51] section 4.2.1 Parameter t +- [^14] section BLS12-381, parameter u +- [^11] section Curve equation and parameters, parameter x #### Summary @@ -300,23 +300,23 @@ Key BLS12-381 parameter used in Miller Loop: x = -0xd201000000010000 ``` -All parameters were taken from [[15](https://eips.ethereum.org/EIPS/eip-2537)], [[51](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-)] and [[14](https://electriccoin.co/blog/new-snark-curve/)], all of them consistent between sources. +All parameters were taken from[^15][^51] and [^14], all of them consistent between sources. ### Curve points encoding #### bool -The bool is encoded as a little-endian `u64` type in Rust. The `true` value is encoded as `1` and `false` is encoded as `0`. All other values of `u64` are not allowed and should be interpreted as incorrect. Encoding is the same as for alt_bn128 implementation in nearcore[[50](https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs)]. +The bool is encoded as a little-endian `u64` type in Rust. The `true` value is encoded as `1` and `false` is encoded as `0`. All other values of `u64` are not allowed and should be interpreted as incorrect. Encoding is the same as for alt_bn128 implementation in nearcore[^50]. #### Scalar -The scalar value is encoded as a big-endian `[u8;32]`. All possible bytes combination is allowed. Encoding is similar with alt_bn128 implementation in nearcore[[50](https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs)], but `big-endian` encoding is used instead of `little-endian` as in EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. +The scalar value is encoded as a big-endian `[u8;32]`. All possible bytes combination is allowed. Encoding is similar with alt_bn128 implementation in nearcore[^50], but `big-endian` encoding is used instead of `little-endian` as in EIP-2537[^15]. #### Fields elements $F_p$ The value from $F_p$ is encoded as a big-endian `[u8; 48]`. Only values less than `p` are allowed. If the value is equal to or bigger than `p` the error should be returned. -The rule of encoding is consistent with zkcrypto[[53](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md)], with implementation in milagro lib[[29](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474)]. +The rule of encoding is consistent with zkcrypto[^53], with implementation in milagro lib[^29]. #### Extension fields elements $F_{p^2}$ @@ -327,7 +327,7 @@ $q \in F_{p^2}$, $q = c_0 + c_1 v$ encoded as `[u8; 96]`: - $c_1 \in F_p$ `[u8; 48]` - $c_0 \in F_p$ `[u8; 48]` -The rule of encoding is consistent with zkcrypto[[53](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md)] and with implementation in milagro lib[[29](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474)]. +The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. #### Uncompressed points on curve $E(F_p)$ @@ -347,7 +347,7 @@ let x: [u8; 96] = [0; 96]; x[0] = x[0] | 0x40; ``` -The rule of encoding is consistent with zkcrypto[[53](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md)] and with implementation in milagro lib[[29](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474)]. +The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. #### Compressed points on curve $E(F_p)$ @@ -377,7 +377,7 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x40; ``` -The rule of encoding is consistent with zkcrypto[[53](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md)] and with implementation in milagro lib[[29](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474)]. +The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. #### Uncompressed points on twisted curve $E'(F_{p^2})$ @@ -401,7 +401,7 @@ let x: [u8; 192] = [0; 192]; x[0] = x[0] | 0x40; ``` -The rule of encoding is consistent with zkcrypto[[53](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md)] and with implementation in milagro lib[[29](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474)]. +The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. #### Compressed points on twisted curve $E'(F_{p2})$ @@ -431,7 +431,7 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x40; ``` -The rule of encoding is consistent with zkcrypto[[53](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md)] and with implementation in milagro lib[[29](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474)]. +The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. ### Precompile functions @@ -460,7 +460,7 @@ let gas_consumed = A + B * k A and B are constants calculated empirically. -Here you can find benchmark test vectors for EIP-2537[[46](https://eips.ethereum.org/assets/eip-2537/bench_vectors)]. It doesn’t contain a sum function, but we can adopt the test vector for addition by duplicating it many times. +Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain a sum function, but we can adopt the test vector for addition by duplicating it many times. ***Test cases:*** @@ -482,7 +482,7 @@ Here you can find benchmark test vectors for EIP-2537[[46](https://eips.ethereum ***Tests References:*** -We can use all the tests for addition for Ethereum[[47](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537), [48](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)] to check the case with k = 2. Also, we can reuse the `error` points. Can use the vectors for multiexp functions if separately perform multiplication. +We can use all the tests for addition for Ethereum[^47][^48] to check the case with k = 2. Also, we can reuse the `error` points. Can use the vectors for multiexp functions if separately perform multiplication. ***Error cases:*** @@ -549,7 +549,7 @@ let gas_consumed = A + B * k A and B are constants calculated empirically. -Here you can find benchmark test vectors for EIP-2537[[46](https://eips.ethereum.org/assets/eip-2537/bench_vectors)]. It doesn’t contain a sum function, but we can adopt the test vector for addition by duplicating it many times. +Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain a sum function, but we can adopt the test vector for addition by duplicating it many times. ***Test cases:*** @@ -557,7 +557,7 @@ The same as for **`bls12381_g1_sum`** only change points from $G_1$ and $E(F_p)$ ***Tests References:*** -We can use all the tests for addition for Ethereum[[47](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537), [48](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)] to check the case with k = 2. Also, we can reuse the `error` points. Can use the vectors for multiexp functions if separately perform multiplication. +We can use all the tests for addition for Ethereum[^47][^48] to check the case with k = 2. Also, we can reuse the `error` points. Can use the vectors for multiexp functions if separately perform multiplication. ***Error cases:*** @@ -624,7 +624,7 @@ Note: ***Gas Estimation:*** -This function should be calculated by Pippenger’s algorithm[[25](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf)]. The Complexity of this algorithm is $O(\frac{k}{\log(k)})$. For gas calculation we will use the formula $\frac{k}{\max(\log_2(k), 1)}$ the same way as in precompile for `alt_bn128` [10]. +This function should be calculated by Pippenger’s algorithm[^25]. The Complexity of this algorithm is $O(\frac{k}{\log(k)})$. For gas calculation we will use the formula $\frac{k}{\max(\log_2(k), 1)}$ the same way as in precompile for `alt_bn128`[^10]. ```rust let k = (input_bytes+item_size-1)/item_size; @@ -633,7 +633,7 @@ let gas_consumed = A + B*k + C * if k > 1 {k / (k as f32).log2().floor()} else { A, B and C are constants calculated empirically. -For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[[46](https://eips.ethereum.org/assets/eip-2537/bench_vectors)]. +For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[^46]. ***Test cases:*** @@ -650,7 +650,7 @@ Addition test cases: ***Tests References:*** -The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[[47](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537),[48](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)]. +The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47][^48]. ***Error cases:*** @@ -726,7 +726,7 @@ Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ ***Gas Estimation:*** -This function should be calculated by Pippenger’s algorithm[[25](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf)]. The Complexity of this algorithm is $O(\frac{k}{\log(k)})$. For gas calculation we will use the formula $\frac{k}{\max(\log_2(k), 1)}$ the same way as in precompile for `alt_bn128` [[10](https://github.com/near/NEPs/issues/98)]. +This function should be calculated by Pippenger’s algorithm[^25]. The Complexity of this algorithm is $O(\frac{k}{\log(k)})$. For gas calculation we will use the formula $\frac{k}{\max(\log_2(k), 1)}$ the same way as in precompile for `alt_bn128`[^10]. ```rust let k = (input_bytes+item_size-1)/item_size; @@ -735,7 +735,7 @@ let gas_consumed = A + B*k + C * if k > 1 {k / (k as f32).log2().floor()} else { A, B and C are constants calculated empirically. -For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[[46](https://eips.ethereum.org/assets/eip-2537/bench_vectors)]. +For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[^46]. ***Test cases:*** @@ -743,7 +743,7 @@ The same as for **`bls12381_g1_multiexp`** only change points from $G_1$ and $E( ***Tests References:*** -The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[[47](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537), [48](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)]. +The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47][^48]. ***Error cases:*** @@ -796,7 +796,7 @@ pub fn bls12381_g2_multiexp( ***Description:*** -The function takes the element $a \in F_p$ and maps it to the $G_1 \subset E(F_p)$. The specification of the mapping function you can find in the specification for EIP-2537[[49](https://eips.ethereum.org/assets/eip-2537/field_to_curve)]. This function does NOT perform mapping of the byte string into $F_p$, it can be implemented in different ways and this can be performed effectively in contract. +The function takes the element $a \in F_p$ and maps it to the $G_1 \subset E(F_p)$. The specification of the mapping function you can find in the specification for EIP-2537[^49]. This function does NOT perform mapping of the byte string into $F_p$, it can be implemented in different ways and this can be performed effectively in contract. ***Input:*** the function takes as input `48` bytes — the element from $F_p$ (one unsigned integer $< p$). More details are in the Curve Points Encoding section. @@ -811,9 +811,9 @@ The gas consumption is a constant calculated empirically. - Correct $F_p$ element - $a = 0$ - $a \ge p$ -- Edge cases for inner algorithms for mapping[[49](https://eips.ethereum.org/assets/eip-2537/field_to_curve)] +- Edge cases for inner algorithms for mapping[^49] -***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[[47](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537),[48](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)]. +***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47][^48]. ***Error cases:*** @@ -853,7 +853,7 @@ pub fn bls12381_map_fp_to_g1( ***Description:*** -The function takes the element $a \in F_{p^2}$ and maps it to the $G_2 \subset E'(F_{p^2})$. The specification of the mapping function you can find in the specification for EIP-2537[[49](https://eips.ethereum.org/assets/eip-2537/field_to_curve)]. This function does NOT perform mapping of the byte string into $F_{p^2}$, it can be implemented in different ways and this can be performed effectively in the contract. +The function takes the element $a \in F_{p^2}$ and maps it to the $G_2 \subset E'(F_{p^2})$. The specification of the mapping function you can find in the specification for EIP-2537[^49]. This function does NOT perform mapping of the byte string into $F_{p^2}$, it can be implemented in different ways and this can be performed effectively in the contract. ***Input:*** the function takes as input `96 bytes` — the element from $F_{p^2}$ (two unsigned integers $< p$). More details are in the Curve Points Encoding section. @@ -868,9 +868,9 @@ The gas consumption is a constant calculated empirically. - Correct $F_{p^2}$ element - $a = 0$ - One of the `a` value $\ge p$ -- Edge cases for inner algorithms for mapping[[49](https://eips.ethereum.org/assets/eip-2537/field_to_curve)] +- Edge cases for inner algorithms for mapping[^49] -***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[[47](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537),[48](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)]. +***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47][^48]. ***Error cases:*** @@ -944,7 +944,7 @@ let gas_consumed = A + B * k A and B are constants calculated empirically. -Here you can find benchmark test vectors for EIP-2537[[46](https://eips.ethereum.org/assets/eip-2537/bench_vectors)]. +Here you can find benchmark test vectors for EIP-2537[^46]. ***Test cases:*** @@ -957,7 +957,7 @@ Here you can find benchmark test vectors for EIP-2537[[46](https://eips.ethereum - Some points = 0 - The field elements are encoded incorrectly -***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[[47](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537),[48](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)]. +***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47][^48]. ***Error cases:*** @@ -1033,7 +1033,7 @@ A and B are constants calculated empirically. ***Tests References:*** -- Take the correct points on the curve from Ethereum tests[[47](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537),[48](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)] and check the correctness after decompression +- Take the correct points on the curve from Ethereum tests[^47][^48] and check the correctness after decompression - Randomly generate compressed points and check the equation correctness after decompression. ***Error cases:*** @@ -1108,7 +1108,7 @@ A and B are constants calculated empirically. ***Tests References:*** -- Take the correct points on the curve from Ethereum tests[[47](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537),[48]( https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)] and check the correctness after decompression +- Take the correct points on the curve from Ethereum tests[^47][^48] and check the correctness after decompression - Randomly generate compressed points and check the equation correctness after decompression. ***Error cases:*** @@ -1156,26 +1156,26 @@ pub fn bls12381_decompress_g2(&mut self, First of all, for integration with nearcore, we are interested in libraries in the Rust language. The existing BLS12-381 implementations on Rust: -1. ***Milagro Library*** [[29](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474)]. -2. ***BLST*** [[30](https://github.com/supranational/blst),[31](https://github.com/sean-sn/blst_eip2537)]. -3. ***Matter labs EIP-1962 implementation*** [[32](https://github.com/matter-labs/eip1962)] -4. ***zCash origin implementation*** [[33](https://github.com/zcash/zcash/tree/master/src/rust/src)] -5. ***MCL Library*** [[34](https://github.com/herumi/bls)] -6. ***FileCoin implementation*** [[35](https://github.com/filecoin-project/bls-signatures)] -7. ***zkCrypto*** [[36](https://github.com/zkcrypto/pairing)] +1. ***Milagro Library*** [^29]. +2. ***BLST*** [^30][^31]. +3. ***Matter labs EIP-1962 implementation*** [^32] +4. ***zCash origin implementation*** [^33] +5. ***MCL Library*** [^34] +6. ***FileCoin implementation*** [^35] +7. ***zkCrypto*** [^36] -To compile the list, we used the links from EIP-2537[[43](https://github.com/matter-labs-forks/EIPs/blob/bls12_381/EIPS/eip-2537.md)], pairing-curves specification[[44](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-cryptographic-libraries)], and an article with benchmarks[[45](https://hackmd.io/@gnark/eccbench)]. This list may be incomplete but should cover the core BLS12-381 implementations. In any case, to implement precompiles from that NEP we will need to modify any of that libraries. +To compile the list, we used the links from EIP-2537[^43], pairing-curves specification[^44], and an article with benchmarks[^45]. This list may be incomplete but should cover the core BLS12-381 implementations. In any case, to implement precompiles from that NEP we will need to modify any of that libraries. In addition, there are implementations in other languages that are not so interesting to us in this context, but can be used as references: -1. C++, ETH2.0 Client, ***Chia library***[[37](https://github.com/Chia-Network/bls-signatures)] -2. Haskell, ***Adjoint Lib*** [[38](https://github.com/sdiehl/pairing)] -3. Go, ***Go-Ethereum*** [[39](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles)] -4. JavaScript, ***Noble JS*** [[40](https://github.com/paulmillr/noble-bls12-381)] -5. Go, ***Matter Labs Go EIP-1962 implementation*** [[41](https://github.com/kilic/eip2537)] -6. C++, ***Matter Labs Go EIP-1962 implementation*** [[42](https://github.com/matter-labs-archive/eip1962_cpp)] +1. C++, ETH2.0 Client, ***Chia library***[^37] +2. Haskell, ***Adjoint Lib***[^38] +3. Go, ***Go-Ethereum***[^39] +4. JavaScript, ***Noble JS***[^40] +5. Go, ***Matter Labs Go EIP-1962 implementation***[^41] +6. C++, ***Matter Labs Go EIP-1962 implementation***[^42] -The draft implementation to nearcore you can find by this link[[54](https://github.com/near/nearcore/pull/9317)]. This implementation is based on blst library[[30](https://github.com/supranational/blst)]. This library one of the fastest[[45](https://hackmd.io/@gnark/eccbench)] and audited[[55](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf)]. +The draft implementation to nearcore you can find by this link[^54]. This implementation is based on blst library[^30]. This library one of the fastest[^45] and audited[^55]. ## Security Implications @@ -1187,15 +1187,15 @@ The BLS12-381 has more security bits than the already existing pairing-friendly ## Alternatives -In the nearcore the precompiles for another pairing-friendly curve alt-bn128 are already implemented[[10](https://github.com/near/NEPs/issues/98)]. For some projects[[20](https://zeropool.network/)] the alternative is just to use the supported curve. However, according to recent research, this curve contains less than 100 bits of security and is not recommended to use[[13](https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security)]. Moreover, projects with cross-chain interactions, such as Rainbow Bridge, must use the same curve as in a target protocol, and for Eth2.0 it is BLS12-381[[3](https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md)]. As a result, there is no alternative to using another pairing-friendly curve. +In the nearcore the precompiles for another pairing-friendly curve alt-bn128 are already implemented[^10]. For some projects[^20] the alternative is just to use the supported curve. However, according to recent research, this curve contains less than 100 bits of security and is not recommended to use[^13]. Moreover, projects with cross-chain interactions, such as Rainbow Bridge, must use the same curve as in a target protocol, and for Eth2.0 it is BLS12-381[^3]. As a result, there is no alternative to using another pairing-friendly curve. -Another alternative is to create one simple precompile in nearcore for BLS-signature verification. It was the first suggested solution[[26](https://github.com/near/NEPs/pull/446)]. However, this solution is not flexible enough[[28](https://github.com/near/NEPs/pull/446#pullrequestreview-1314601508)]: (1) projects can use different hash functions; (2) some projects can use for public keys G1 subgroup, another G2; (3) the specification for Eth2.0 continue to be in the draft and details can change, (4) in such implementation we can't support precompiles from EIP-2537. +Another alternative is to create one simple precompile in nearcore for BLS-signature verification. It was the first suggested solution[^26]. However, this solution is not flexible enough[^28]: (1) projects can use different hash functions; (2) some projects can use for public keys G1 subgroup, another G2; (3) the specification for Eth2.0 continue to be in the draft and details can change, (4) in such implementation we can't support precompiles from EIP-2537. The next alternative is to execute BLS12-381 operations off-chain. In that case, the applications which used the BLS curve will not be trustless anymore. ## Future possibilities -In the future, it is possible to support work with other curves, not only BLS12-381. In Ethereum, before EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)], EIP-1962 was proposed[[27](https://eips.ethereum.org/EIPS/eip-1962)]. In EIP-1962 was proposed to implement pairing-friendly elliptic curves in a generic format and support not only BLS curves but many others. However, this proposal wasn't accepted due to its large scope and complexity. I don't think it makes sense to implement every possible curve, but it could be a possible extension. +In the future, it is possible to support work with other curves, not only BLS12-381. In Ethereum, before EIP-2537[^15], EIP-1962 was proposed[^27]. In EIP-1962 was proposed to implement pairing-friendly elliptic curves in a generic format and support not only BLS curves but many others. However, this proposal wasn't accepted due to its large scope and complexity. I don't think it makes sense to implement every possible curve, but it could be a possible extension. ## Consequences @@ -1216,7 +1216,7 @@ There are no backward compatibility questions. ## Changelog -The previous NEP for supporting BLS signature based on BLS12-381[[26](https://github.com/nearprotocol/neps/pull/446)] +The previous NEP for supporting BLS signature based on BLS12-381[^26] [^1]: BLS 2002 [https://www.researchgate.net/publication/2894224_Constructing_Elliptic_Curves_with_Prescribed_Embedding_Degrees](https://www.researchgate.net/publication/2894224_Constructing_Elliptic_Curves_with_Prescribed_Embedding_Degrees) [^2]: ZCash protocol: [https://zips.z.cash/protocol/protocol.pdf](https://zips.z.cash/protocol/protocol.pdf)