From 81d2c46bc399ca2e5516a1e8b8faa36828b417d6 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 17:49:27 +0300 Subject: [PATCH 001/163] NEP-486 draft --- neps/nep-0486.md | 1259 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1259 insertions(+) create mode 100644 neps/nep-0486.md diff --git a/neps/nep-0486.md b/neps/nep-0486.md new file mode 100644 index 000000000..d4bafc2bb --- /dev/null +++ b/neps/nep-0486.md @@ -0,0 +1,1259 @@ +# NEP-486 Precompile for BLS12-381 curve operations + +--- +NEP: 486 +Title: Precompile for BLS12-381 curve operations +Author: Olga Kuniavskaia [olga.kunyavskaya@aurora.dev](mailto:olga.kunyavskaya@aurora.dev) +DiscussionsTo: [https://github.com/nearprotocol/neps/pull/486](https://github.com/nearprotocol/neps/pull/486) +Status: Draft +Type: Runtime Spec +Category: Contract +Created: 17-Jul-2023 +--- + +# Summary + +A pre-compiled NEAR runtime functions for operations on BLS12-381 curve. It is a necessary set to efficiently perform operations such as BLS signature and zkSNARKs verifications. + +# Motivation + +The BLS12-381[1, 11, 52] is a wildly used[2-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 c*ross-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 users' 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-23] scaling solutions. + +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]. +- ***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]. 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]. +- ***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] and in EIP-2537[15]. + +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 + +## BLS12-381 Curve Specification + +### Elliptic Curve + +**Definition:** The field $F_p$ for some *prime* $p$ is a set of integer elements $\{0, 1, \ldots, p - 1\}$ with two operations: multiplication $\cdot$ and addition $+$. These operations are performed as multiplication/addition for integers number and then taking the remainder modulo $p$. + + + +**Definition:** The elliptic curve $E(F_p)$ is a set of all pairs $(x, y) \in F_p$: + +$$ +y^2 \equiv x^3 + Ax + B \mod p +$$ + +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$ ([1-4]) + +**Parameters for our case:** + +```rust +A = 0 +B = 4 +p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab +``` + +**Definition:** Let’s $P \in E(F_q)$ have coordinates (x, y), define $-P$ as a point on a curve with coordinates (x, -y). + +**Definition:** The addition operation for Elliptic Curve is a function $+\colon E(F_p) \times E(F_p) \rightarrow E(F_p)$ defined with following rules: let’s P and Q $\in E(F_p)$ + +- if $P \ne Q$ and $P \ne -Q$ + - draw a line passing through P and Q. This line intersects the curve at a third point R + - reflect the point R about the x-axis by changing the sign of the y-coordinate. The resulting point is P+Q. +- if $P=Q$ + - draw a tangent line throw P for an elliptic curve. The line will intersect the curve at the second point R. + - reflect the point R about the x-axis the same way to get point 2P +- $P = -Q$ + - $P + Q = P + (-P) = 0$ — the point on infinity +- Q = 0 + - $P + Q = P + 0 = P$ + +With the addition operation, Elliptic Curve forms a **group**. + +### Subgroups + +**Definition:** Subgroup H is a subset of the group G with the following properties: + +- $\forall h_1, h_2 \in H\colon h_1 + h_2 \in H$ +- $0 \in H$ +- $\forall h \in H \colon -h \in H$ + +Notation: $H \subseteq G$ + +**Definition:** group/subgroup **order** is the number of elements in group/subgroup. + +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$([1, 2]): + +```rust +Main subgroup order r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 +``` + +### Field extension + +**Definition:** The field extension $F_{p^k}$ is a set of all polynomials with degree < k and coefficients from $F_p$ and defined operations $\cdot$ , $+$ + +$$ +a_{k - 1}x^{k - 1} + \ldots + a_1x + a_0 = A(x) \in F_{p^k} \vert a_i \in F_p +$$ + +The $+$ operation is defined as a regular addition for polynomials: + +$$ +A(x) + B(x) = C(x)\\ +\sum a_i x^i + \sum b_i x^i = \sum c_i x^i\\ +c_i = (a_i + b_i) \mod p +$$ + +The multiplication $\cdot$ is defined as a regular polynomials’ multiplication by modulo M(x), where M(x) is an ***irreducible*** polynomial of degree k with coefficients from $F_p$ + +$$ +C(x) = A(x) \cdot B(x)\mod M(x) +$$ + +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]): + +- $F_{p^2} = F_p[u] / (u^2 + 1)$ +- $F_{p^6} = F_{p^2}[v] / (v^3 - u - 1)$ +- $F_{p^{12}} = F_{p^6}[w]/(w^2 - v)$ + +Our second subgroup of order r, which we will use, is a subgroup of the same Elliptic Curve but with elements from $F_{p^{12}}$. $G_2 \subset E(F_{p^{12}})$, where $E: y^2 = x^3 + 4$ + +### Twist + +Store elements from $E(F_{p^{12}})$ takes a lot of memory. ***The twist*** operation transforms the origin curve $E(F_{p^{12}})$ into another curve under another space $E'(F_{p^2})$. It is important that the new curve also has a $G'_2$ subgroup with order r and we can easily transform it to origin $G_2$. + +We want to have $\psi \colon E'(F_{p^2}) \rightarrow E(F_{p^{12}})$, such as + +- $\forall a, b \in E'(F_{p^2}) \colon \psi(a + b) = \psi(a) + \psi(b)$ +- $\forall a, b \in E'(F_{p^2}) \colon \psi(a) = \psi(b) \Rightarrow a = b$ + +It is called injective group homomorphism. + +For BLS12-381 E’ is defined as([51]): + +$$ +E'\colon y^2 = x^3 + 4(u + 1) +$$ + +In most cases we will work with points from $G'_2 \subset E'(F_{p^2})$ and use for this subgroup just the notation $G_2$. + +### Generators + +**Definition:** if in the group $G$ exists element g, such as $\{g, 2g, 3g, \ldots, |G|g\} = G$, the group G called ***cyclic group*** and g called ***generator*** + + + +$G_1$ and $G_2$ are cyclic subgroups with the following generators([15], [51]): + +```rust +G1: +X = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb +Y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1 +``` + +For $(x', y') \in G_2 \subset E'(F_{p^2}): \\ +x' = x_0 + x_1u\\ +y' = y_0 + y_1u$ + +```rust +G2: +x0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8 +x1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e +y0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801 +y1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be +``` + +**Definition:** ***Cofactor*** is the ratio of the size of the whole group G to the size of subgroup H: + +$$ +|G|/|H| +$$ + +Cofactor $G_1\colon h = |E(F_p)|/r$ ([51]) + +```rust +h = 0x396c8c005555e1568c00aaab0000aaab +``` + +Cofactor $G_2\colon h' = |E'(F_{p^2})|/r$ ([51]) + +```rust +h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 +``` + +### Pairing + +Pairing is an operation, which we will need for digital signature verification. Pairing operation $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{p^{12}}$. + +The main pairing properties is: + +- $e(P, Q + R) = e(P, Q) \cdot e(P, R)$ +- $e(P + S, R) = e(P, R)\cdot e(S, R)$ + +For calculating this function we will need the algorithm, called Miller Loop, and to effectively perform this algorithm we will need to know the key parameter for BLS curve $x$ + +```rust +x = -0xd201000000010000 +``` + +You can find this parameter in: + +- [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 + +The parameters for the BLS12-381: + +```rust +Base field modulus p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab +``` + +$$ +E\colon y^2 \equiv x^3 + 4\\ +E'\colon y^2 \equiv x^3 + 4(u + 1) +$$ + +```rust +Main subgroup order r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 +``` + +$$ +F_{p^2} = F_p[u] / (u^2 + 1)\\ +F_{p^6} = F_{p^2}[v] / (v^3 - u - 1)\\ +F_{p^{12}} = F_{p^6}[w] / (w^2 - v) +$$ + +Generator for G1: + +```rust +X = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb +Y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1 +``` + +Generator for G2: + +```rust +x0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8 +x1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e +y0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801 +y1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be +``` + +Cofactor for G1: + +```rust +h = 0x396c8c005555e1568c00aaab0000aaab +``` + +Cofactor for G2: + +```rust +h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 +``` + +Key BLS12-381 parameter used in Miller Loop: + +```rust +x = -0xd201000000010000 +``` + +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]. + +### 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], 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], with implementation in milagro lib[29]. + +### Extension fields elements $F_{p^2}$ + +The $q \in F_{p^{2}}$ could be written as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$ The element from $F_{p^2}$ encoded in `[u8; 96]` as a bytes’ concatenation of $c_1$ and $c_0$. The $c_1$ and $c_0$ are encoded by the rule described in the previous section. + +$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] and with implementation in milagro lib[29]. + +### Uncompressed points on curve $E(F_p)$ + +The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ encoded in `[u8; 96]` as bytes’ concatenation of `x` and `y` point coordinates, where $x, y \in F_p$. The $x, y$ are encoded according to the rules described in the section “Fields elements $F_p$” . + +$E(F_p)$ is encoded as `[u8; 96]`: + +- $x \in F_p$ `[u8; 48]` +- $y \in F_p$ `[u8; 48]` + +*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. + +Encoding point on infinity: + +```bash +let x: [u8; 96] = [0; 96]; +x[0] = x[0] | 0x40; +``` + +The rule of encoding is consistent with zkcrypto[53] and with implementation in milagro lib[29]. + +### Compressed points on curve $E(F_p)$ + +The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ in compressed form are encoded in `[u8; 48]` as *big-endian* encoded $x \in F_p$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. + +*The first bit* should be set as 1. This bit indicates that point is encoded in compressed form. + +*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. + +To represent the sign of the $y$ *the third bit* of x encoding is used. If the first bit = 0 the $y$ is positive, if the first bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y = p - y$. + +The $x \in F_p$ encoded as `[u8; 48]` bytes according to the rules from section “Extension fields elements $F_{p}$” . + +The point on $E(F_p)$ with negative $y$ coordinate encoded as `[u8; 48]` bytes: + +```rust +let x: [u8; 48] = encodeFp(x) +x[0] = x[0] | 0x80; +x[0] = x[0] | 0x20; +``` + +For encoding point of infinity: + +```rust +let x: [u8; 48] = [0; 48]; +x[0] = x[0] | 0x80; +x[0] = x[0] | 0x40; +``` + +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})$ + +The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ encoded in `[u8; 192]` as bytes’ concatenation of `x` and `y` point coordinates, where $x, y \in F_{p^2}$. The $x, y$ are encoded according to the rules described in the section “Extension fields elements $F_{p^2}$” . + +$E'(F_{p^2})$ is encoded as `[u8; 192]`: + +- $x \in F_{p^2}$ `[u8; 96]`: + - $c_1 \in F_p$ `[u8; 48]` + - $c_0 \in F_p$ `[u8; 48]` +- $y \in F_{p^2}$ `[u8; 96]`: + - $c_1 \in F_p$ `[u8; 48]` + - $c_0 \in F_p$ `[u8; 48]` + +*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. + +Encoding point on infinity: + +```bash +let x: [u8; 192] = [0; 192]; +x[0] = x[0] | 0x40; +``` + +The rule of encoding is consistent with zkcrypto[53] and with implementation in milagro lib[29]. + +### Compressed points on twisted curve $E'(F_{p2})$ + +The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ in compressed form are encoded in `[u8; 96]` as *big-endian* encoded $x \in F_{p^2}$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. + +*The first bit* should be set as 1. This bit indicates that point is encoded in compressed form. + +*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. + +To represent the sign of the $y$ *the third bit* of x encoding is used. If the first bit = 0 the $y$ is positive, if the first bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y$: first compare $c_1$ and second $c_0$. + +The $x \in F_{p^2}$ encoded as `[u8; 96]` bytes according to the rules from section “Extension fields elements $F_{p^2}$” . + +The point on $E'(F_{p^2})$ with negative $y$ coordinate encoded as `[u8; 96]` bytes: + +```rust +let x: [u8; 96] = encodeFp2(x); +x[0] = x[0] | 0x80; +x[0] = x[0] | 0x20; +``` + +Encoding point of infinity: + +```rust +let x: [u8; 96] = [0; 96]; +x[0] = x[0] | 0x80; +x[0] = x[0] | 0x40; +``` + +The rule of encoding is consistent with zkcrypto[53] and with implementation in milagro lib[29]. + +## Precompile functions + +### **bls12381_g1_sum **** + +***Description:*** + +The function computes the sum of the elements of the BLS12-381 curve. The input is an arbitrary number of points $p_i \in E(F_p)$, and the output is one point from $E(F_p)$ equal to $\sum p_i$. + +The $E(F_p)$ curve, points on the curve and the addition operation are defined in the BLS12-381 Curve Specification section. + +Note: we take as input any points on the curve, not only from $G_1$ + +***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$. More details are in the Curve Points Encoding section. + +***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. + +***Gas Estimation:*** + +The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula + +```rust +let k = (input_bytes + item_size - 1)/item_size +let gas_consumed = A + B * k +``` + +A and B are constants calculated empirically. + +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:*** + +- Correct points in G1 group +- One of the points is 0 +- One of the points is not in G1 group but on the curve +- The result is 0 +- Correct addition with one point +- Point not on the curve +- The coding of field elements is incorrect, but if take only the suffix it will be the correct point on the curve +- The coding of field elements is incorrect, but by modulo p it is a correct element on the curve +- The coding of field elements is incorrect, an incorrect extra bit, which shows that it is decompressed encoding. +- Sum with the maximum number of elements +- Too many points for sum +- Incorrect len of input +- Empty input +- Generate points on the curve and check that the result doesn’t depend on permutation +- Generate points and cross-test the result with multiexp function. + +***Tests References:*** + +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:*** + +- The input length is not divided by 96 +- The input is empty +- Too much memory is used +- Field elements encoded incorrectly (see Curve points encoded section) +- Any points not on the curve + +***Annotation:*** + +```rust +/// Computes sum for elements on BLS12-381 curve +/// \sum_i p_i should be the equal result. +/// +/// # Arguments +/// +/// * `value` - sequence of pi points(x:Fp, y:Fp) on BLS-381 curve +/// BLS12-381 is Y^2 = X^3 + 4 curve over Fp. +/// +/// `value` is encoded as packed, big-endian +/// `[([u8; 48], [u8; 48])]` slice. +/// +/// # Errors +/// +/// If `value_len + value_ptr` points outside the memory or the registers +/// use more memory than the limit, the function returns `MemoryAccessViolation`. +/// +/// If point coordinates are not on curve or `value.len()%96 != 0`, +/// the function returns `BLS12381InvalidInput`. +/// +/// # Cost +/// +/// `base + write_register_base + write_register_byte * num_bytes + +/// bls12381_g1_sum_base + bls12381_g1_sum_element * num_elements` +pub fn bls12381_g1_sum(&mut self, + value_len: u64, + value_ptr: u64, + register_id: u64) -> Result<()>; +``` + +### bls12381_g2_sum + +***Description:*** + +The function computes the sum of the elements of the BLS12-381 curve. The input is an arbitrary number of points $p_i \in E'(F_{p^2})$, and the output is one point from $E'(F_{p^2})$ equal to $\sum p_i$. + +The $E'(F_{p^2})$ curve, points on the curve and the addition operation are defined in the BLS12-381 Curve Specification section. + +Note: we take as input any points on the curve, not only from $G_2$ + +***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$. Expected `192*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. + +***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. + +***Gas Estimation:*** + +The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula + +```rust +let k = (input_bytes + item_size - 1)/item_size +let gas_consumed = A + B * k +``` + +A and B are constants calculated empirically. + +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:*** + +The same as for **`bls12381_g1_sum`** only change points from $G_1$ and $E(F_p)$ into $G_2$ and $E'(F_{p^2})$. + +***Tests References:*** + +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:*** + +- The input length is not divided by 192 +- The input is empty +- Too much memory is used +- Extension field elements encoded incorrectly (see Curve points encoded section) +- Any points not on the curve + +***Annotation:*** + +```rust +/// Computes sum for elements on BLS12-381 curve +/// \sum_i p_i should be the equal result. +/// +/// # Arguments +/// +/// * `value` - sequence of pi points(x:Fp^2, y:Fp^2) on BLS-381 curve +/// BLS12-381 is Y^2 = X^3 + 4(i + 1) curve over Fp^2. +/// +/// `value` is encoded as packed, big-endian +/// `[([u8; 96], [u8; 96])]` slice. +/// +/// # Errors +/// +/// If `value_len + value_ptr` points outside the memory or the registers +/// use more memory than the limit, the function returns `MemoryAccessViolation`. +/// +/// If point coordinates are not on curve or `value.len()%192 != 0`, +/// the function returns `BLS12381InvalidInput`. +/// +/// # Cost +/// +/// `base + write_register_base + write_register_byte * num_bytes + +/// bls12381_g2_sum_base + bls12381_g2_sum_element * num_elements` +pub fn bls12381_g2_sum(&mut self, + value_len: u64, + value_ptr: u64, + register_id: u64) -> Result<()>; +``` + +### ***bls12381_g1_multiexp*** + +***Description:*** + +The function takes as input the list of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. The function calculates $\sum s_i \cdot p_i$. + +The multiplication on the scalar is the addition of that point a scalar number of times: + +$$ +s \cdot p = \underbrace{p + p + \ldots + p}_{s} +$$ + +The $E(F_p)$ curve, points on the curve and the addition operation are defined in the BLS12-381 Curve Specification section. + +Note: + +- We take as input any points on the curve, not only from $G_1$. +- The scalar is an arbitrary unsigned integer and can be bigger than the group order. + +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. + +***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. + +***Gas Estimation:*** + +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; +let gas_consumed = A + B*k + C * if k > 1 {k / (k as f32).log2().floor()} else {k}; +``` + +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]. + +***Test cases:*** + +The same test cases as for the bls12381_g1_sum section. + +Addition test cases: + +- `group_order * P = 0` +- `(scalar + groupt_order) * P = scalar * P` +- `P + P + P .. + P = N*P` +- `0 * P = 0` +- `1 * P = P` +- Scalar is a MAX_INT + +***Tests References:*** + +The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[47-48]. + +***Error cases:*** + +- The input length is not divided by 128 +- The input is empty +- Too much memory is used +- Field elements encoded incorrectly (see Curve points encoded section) +- Any points not on the curve + +***Annotation:*** + +```rust +/// Computes multiexp on BLS12-381 curve using Pippenger's algorithm +///\sum_i si*pi should be equal result. +/// +/// # Arguments +/// +/// * `value` - sequence of (pi, si), where +/// pi is point (x:Fp, y:Fp) on BLS12-381, and si is u256. +/// BLS12-381 is Y^2 = X^3 + 4 curve over Fp. +/// +/// `value` is encoded as packed, big-endian +/// `[(([u8; 48], [u8; 48]), u256)]` slice. +/// +/// # Errors +/// +/// If `value_len + value_ptr` points outside the memory or the registers +/// use more memory than the limit, the function returns +/// `MemoryAccessViolation`. +/// +/// If point coordinates are not on curve, point is not in the subgroup, +/// scalar is not in the field or `value.len()%128!=0`, the function returns +/// `BLS12381InvalidInput`. +/// +/// # Cost +/// +/// `base + write_register_base + write_register_byte * num_bytes + +/// bls12381_g1_multiexp_base + +/// bls12381_g1_multiexp_element * num_elements + +/// bls12381_g1_multiexp_element_div_log * num_elements/max(1, log(num_elements))` +pub fn bls12381_g1_multiexp( + &mut self, + value_len: u64, + value_ptr: u64, + register_id: u64, +) -> Result<()>; +``` + +### ***bls12381_g2_multiexp*** + +***Description:*** + +The function takes as input the list of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. The function calculates $\sum s_i \cdot p_i$. + +The multiplication on the scalar is the addition of that point a scalar number of times: + +$$ +s \cdot p = \underbrace{p + p + \ldots + p}_{s} +$$ + +The $E'(F_{p^2})$ curve, points on the curve and the addition operation are defined in the BLS12-381 Curve Specification section. + +Note: + +- We take as input any points on the curve, not only from $G_2$. +- The scalar is an arbitrary unsigned integer and can be bigger than the group order. + +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. + +***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. + +***Gas Estimation:*** + +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; +let gas_consumed = A + B*k + C * if k > 1 {k / (k as f32).log2().floor()} else {k}; +``` + +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]. + +***Test cases:*** + +The same as for **`bls12381_g1_multiexp`** only change points from $G_1$ and $E(F_p)$ into $G_2$ and $E'(F_{p^2})$. + +***Tests References:*** + +The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[47-48]. + +***Error cases:*** + +- The input length is not divided by 224 +- The input is empty +- Too much memory is used +- Field elements encoded incorrectly (see Curve points encoded section) +- Any points not on the curve + +***Annotation:*** + +```rust +/// Computes multiexp on BLS12-381 curve using Pippenger's algorithm +///\sum_i si*pi should be equal result. +/// +/// # Arguments +/// +/// * `value` - sequence of (pi, si), where +/// pi is point (x:Fp^2, y:Fp^2) on BLS12-381, and si is u256. +/// BLS12-381 is Y^2 = X^3 + 4(i + 1) curve over Fp^2. +/// +/// `value` is encoded as packed, big-endian +/// `[(([u8; 96], [u8; 96]), u256)]` slice. +/// +/// # Errors +/// +/// If `value_len + value_ptr` points outside the memory or the registers +/// use more memory than the limit, the function returns +/// `MemoryAccessViolation`. +/// +/// If point coordinates are not on curve, point is not in the subgroup, +/// scalar is not in the field or `value.len()%224!=0`, the function returns +/// `BLS12381InvalidInput`. +/// +/// # Cost +/// +/// `base + write_register_base + write_register_byte * num_bytes + +/// bls12381_g2_multiexp_base + +/// bls12381_g2_multiexp_element * num_elements + +/// bls12381_g2_multiexp_element_div_log * num_elements/max(1, log(num_elements))` +pub fn bls12381_g2_multiexp( + &mut self, + value_len: u64, + value_ptr: u64, + register_id: u64, +) -> Result<()>; +``` + +### bls12381_map_fp_to_g1 + +***Description:*** + +The function takes the element $a \in F_p$ and maps it to the $G_1 \sub 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. + +***Output:*** the output is `96 bytes` — one point $\in G_1 \sub E(F_p)$ in decompressed format. More details are in the Curve Points Encoding section. + +***Gas Estimation:*** + +The gas consumption is a constant calculated empirically. + +***Test cases:*** + +- Correct $F_p$ element +- $a = 0$ +- $a \ge p$ +- 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-48]. + +***Error cases:*** + +- Incorrect input length +- $a \ge p$ + +***Annotation:*** + +```rust +/// Map elements from Fp to G1 subset of BLS12-381 curve +/// +/// # Arguments +/// +/// * `value` - 48 bytes, the element from Fp -- unsigned integer < p +/// +/// # Errors +/// +/// If `value_len + value_ptr` points outside the memory or the registers +/// use more memory than the limit, the function returns +/// `MemoryAccessViolation`. +/// +/// If value_len != 48 or the value >= p the function return `BLS12381InvalidInput`. +/// +/// # Cost +/// +/// `base + write_register_base + write_register_byte * num_bytes + +/// bls12381_map_fp_to_g1_base` +pub fn bls12381_map_fp_to_g1( + &mut self, + value_len: u64, + value_ptr: u64, + register_id: u64, +) -> Result<()>; +``` + +### bls12381_map_fp2_to_g2 + +***Description:*** + +The function takes the element $a \in F_{p^2}$ and maps it to the $G_2 \sub 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. + +***Output:*** the output is `192 bytes` — one point $\in G_2 \sub E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. + +***Gas Estimation:*** + +The gas consumption is a constant calculated empirically. + +***Test cases:*** + +- Correct $F_{p^2}$ element +- $a = 0$ +- One of the `a` value $\ge p$ +- 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-48]. + +***Error cases:*** + +- Incorrect input length +- Value is not a valid extension field $F_{p^2}$ element + +***Annotation:*** + +```rust +/// Map elements from Fp2 to G2 subset of E'(Fp2) BLS12-381 curve +/// +/// # Arguments +/// +/// * `value` - 96 bytes, the element from Fp2 -- two unsigned integer < p +/// +/// # Errors +/// +/// If `value_len + value_ptr` points outside the memory or the registers +/// use more memory than the limit, the function returns +/// `MemoryAccessViolation`. +/// +/// If value_len != 96 or the value is not correct Fp2 element the function return `BLS12381InvalidInput`. +/// +/// # Cost +/// +/// `base + write_register_base + write_register_byte * num_bytes + +/// bls12381_map_fp2_to_g2_base` +pub fn bls12381_map_fp2_to_g2( + &mut self, + value_len: u64, + value_ptr: u64, + register_id: u64, +) -> Result<()>; +``` + +### bls12381_pairing_check + +***Description:*** + +The pairing function $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \sub F_{q^{12}}$. The pairing function has the following properties: + +- $e(P, Q + R) = e(P, Q) \cdot e(P, R)$ +- $e(P + S, R) = e(P, R)\cdot e(S, R)$ + +The consequence: + +$e([a]P, [b]Q) = e(P, Q)^{ab} = e([b]P, [a]Q)$ + +We need this function to verify BLS signature. + +This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \sub E(F_{p})$ and $q_i \in G_2 \sub E'(F_{p^2})$ and check: + +$$ +\sum e(p_i, q_i) = 1 +$$ + +We don’t calculate the pairing function itself: the result will be in the huge field, and in all known applications only such a check is necessary. + +***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \sub E(F_{p})$ and $q_i \in G_2 \sub E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $G_1 \sub E(F_p)$ — `96 bytes` and point from $G_2 \sub E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. + +***Output:*** returns `bool` — the result of the pairing check. The `true` value means that the pairing result is equal to multiplicative identity and `false` otherwise. + +***Gas Estimation:*** + +The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula + +```rust +let k = (input_bytes + item_size - 1)/item_size +let gas_consumed = A + B * k +``` + +A and B are constants calculated empirically. + +Here you can find benchmark test vectors for EIP-2537[46]. + +***Test cases:*** + +- The correct input with different lengths with results true +- The correct input with different lengths with results false +- The first point on the curve but not in G1 +- The second point on the curve but not in G2 +- The input with incorrect length +- The points not on the curve +- 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-48]. + +***Error cases:*** + +- The input length is not divided by 288 +- The input is empty +- Too much memory is used +- Field elements encoded incorrectly (see Curve points encoded section) +- Any points not on the curve +- Any points not in $G_1/G_2$ + +***Annotation:*** + +```rust +/// Computes pairing check on BLS12-381 curve. +/// \sum_i e(g_{1 i}, g_{2 i}) should be equal one (in additive notation), e(g1, g2) is pairing +/// +/// # Arguments +/// +/// * `value` - sequence of (g1:G1, g2:G2), where +/// G2 is subgroup point (x:Fp2, y:Fp2) on BLS12-381 twist, +/// BLS12-381 twist is Y^2 = X^3 + 4(i + 1) curve over Fp2 +/// Fp2 is complex field element (re: Fp, im: Fp) +/// G1 is point (x:Fp, y:Fp) on BLS12-381, +/// BLS12-381 is Y^2 = X^3 + 4 curve over Fp +/// +/// `value` is encoded a as packed, big-endian +/// `[(([u8; 48], [u8; 48]), ([u8; 96], [u8; 96]))]` slice. +/// +/// # Errors +/// +/// If `value_len + value_ptr` points outside the memory than +/// the function returns `MemoryAccessViolation`. +/// +/// If point coordinates are not on curve, point is not in the subgroup +// or data are wrong serialized, for example, +/// `value.len()%288!=0`, the function returns `BLS12381InvalidInput`. +/// +/// # Cost +/// +/// `base + write_register_base + write_register_byte * num_bytes + +/// bls12381_pairing_base + bls12381_pairing_element * num_elements` +pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Result { +``` + +### bls12381_decompress_g1 + +***Description:*** Function decompress compressed points from $E(F_p)$. The input is an arbitrary number of points $p_i \in E(F_p)$ in compressed format, and the output is the same number of points from $E(F_p)$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. + + + +***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in compressed form. Expected `48*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E(F_p)$. More details are in the Curve Points Encoding section. + +***Output:*** the sequence of point $p_i \in E(F_p)$, each point encoded in decompressed form. Expected `96*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E(F_p)$. `k` the same as in input. More details are in the Curve Points Encoding section. + +***Gas Estimation:*** The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula + +```rust +let k = (input_bytes + item_size - 1)/item_size +let gas_consumed = A + B * k +``` + +A and B are constants calculated empirically. + +***Test cases:*** + +- the correct input with different length +- the input with incorrect size +- the points with the negative `y` coordinate +- 0 points +- points not on the curve +- incorrectly encoded points +- very long input + +***Tests References:*** + +- 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:*** + +- The input length is not divided by 48 +- The input is empty +- Too much memory is used +- Field elements encoded incorrectly (see Curve points encoded section) +- Any points not on the curve + +***Annotation:*** + +```rust +/// Decompress points on BLS12-381 curve. +/// +/// # Arguments +/// +/// * `value` - sequence of pi points (x:Fp) on BLS-381 curve +/// BLS12-381 is Y^2 = X^3 + 4 curve over Fp. +/// +/// `value` is encoded as packed `[[u8; 48]]` slice. +/// +/// # Output +/// sequence of pi points (x: Fp; y: Fp) in decompress format: [([u8; 48], [u8; 48])] +/// +/// # Errors +/// +/// If `value_len + value_ptr` points outside the memory or the registers +/// use more memory than the limit, the function returns `MemoryAccessViolation`. +/// +/// If point coordinates are not on curve or `value.len()%48 != 0`, +/// the function returns `BLS12381InvalidInput`. +/// +/// # Cost +/// +/// `base + write_register_base + write_register_byte * num_bytes + +/// bls12381_g1_decompress_base + bls12381_g1_decompress_element * num_elements` +pub fn bls12381_decompress_g1(&mut self, + value_len: u64, + value_ptr: u64, + register_id: u64) -> Result<()>; +``` + +### bls12381_decompress_g2 + +***Description:*** Function decompress compressed points from $E'(F_{p^2})$. The input is an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format, and the output is the same number of points from $E'(F_{p^2})$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. + + + +***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in compressed form. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. + +***Output:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in decompressed form. Expected `192*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E'(F_{p^2})$. `k` the same as in input. More details are in the Curve Points Encoding section. + +***Gas Estimation:*** The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula + +```rust +let k = (input_bytes + item_size - 1)/item_size +let gas_consumed = A + B * k +``` + +A and B are constants calculated empirically. + +***Test cases:*** + +- the correct input with different length +- the input with incorrect size +- the points with the negative `y` coordinate +- 0 points +- points not on the curve +- incorrectly encoded points +- very long input + +***Tests References:*** + +- 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:*** + +- The input length is not divided by 96 +- The input is empty +- Too much memory is used +- Field elements encoded incorrectly (see Curve points encoded section) +- Any points not on the curve + +***Annotation:*** + +```rust +/// Decompress points on twisted BLS12-381 curve. +/// +/// # Arguments +/// +/// * `value` - sequence of pi points (x:Fp2) on twisted BLS-381 curve +/// BLS12-381 is Y^2 = X^3 + (4 + i) curve over Fp2. +/// +/// `value` is encoded as packed `[[u8; 96]]` slice. +/// +/// # Output +/// sequence of pi points (x: Fp2; y: Fp2) in decompress format: [([u8; 96], [u8; 96])] +/// +/// # Errors +/// +/// If `value_len + value_ptr` points outside the memory or the registers +/// use more memory than the limit, the function returns `MemoryAccessViolation`. +/// +/// If point coordinates are not on curve or `value.len()%96 != 0`, +/// the function returns `BLS12381InvalidInput`. +/// +/// # Cost +/// +/// `base + write_register_base + write_register_byte * num_bytes + +/// bls12381_g2_decompress_base + bls12381_g2_decompress_element * num_elements` +pub fn bls12381_decompress_g2(&mut self, + value_len: u64, + value_ptr: u64, + register_id: u64) -> Result<()>; +``` + +# Reference Implementation + +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]. +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], 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] +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]. This implementation is based on blst library[30]. This library one of the fastest[45] and audited[55]. + +# Security Implications + +The implementation security relies on the security of the chosen library, which supports operations with BLS curves. + +In this NEP, we do not require a constant execution time for all operations. This is not a problem if you use precompiles to verify the BLS signature. These precompiles should not be used if you need a constant-time algorithm. + +The BLS12-381 has more security bits than the already existing pairing-friendly curve BN254, as a result, the security of the projects which need the pairing-friendly curve will improve. + +# Alternatives + +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]. 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], 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 + +## Positive + +- Projects, which used BN254 will be able to switch on BLS12-381 curve, and it will improve security. +- The trustless cross-chain interactions with blockchains that use BLS12-381 in protocols(such as Ethereum 2) will become possible. + +## Neutral + +## Negative + +- The appearance of dependence on the library which supports BLS12-381 curves operations. + +## Backward Compatibility + +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](https://github.com/nearprotocol/neps/pull/446) + +# References: + +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) +3. Ethereum 2 specification: [https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md](https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md) +4. Dfinity: [https://internetcomputer.org/docs/current/references/ic-interface-spec#certificate](https://internetcomputer.org/docs/current/references/ic-interface-spec#certificate) +5. Tezos: [https://wiki.tezosagora.org/learn/futuredevelopments/layer2#zkchannels](https://wiki.tezosagora.org/learn/futuredevelopments/layer2#zkchannels) +6. Filecoin: [https://spec.filecoin.io/](https://spec.filecoin.io/) +7. Specification of pairing friendly curves with a list of applications in the table: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-) +8. Specification of pairing friendly curves, the security level for BLS12-381: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1) +9. BN2005: [https://eprint.iacr.org/2005/133](https://eprint.iacr.org/2005/133) +10. NEP-98 for BN254 precompile on NEAR: https://github.com/near/NEPs/issues/98 +11. BLS12-381 for the Rest of Us: [https://hackmd.io/@benjaminion/bls12-381](https://hackmd.io/@benjaminion/bls12-381) +12. BN254 for the Rest of Us: [https://hackmd.io/@jpw/bn254](https://hackmd.io/@jpw/bn254) +13. Some analytics of different curve security: [https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security](https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security) +14. ZCash Transfer from bn254 to bls12-381: [https://electriccoin.co/blog/new-snark-curve/](https://electriccoin.co/blog/new-snark-curve/) +15. EIP-2537 Precompiles for Ethereum for BLS12-381: [https://eips.ethereum.org/EIPS/eip-2537](https://eips.ethereum.org/EIPS/eip-2537) +16. The article, where Tezos announce the support of BLS12-381 [https://medium.com/metastatedev/meanwhile-at-cryptium-labs-2-part-2-adding-the-pairing-equipped-elliptic-curve-bls12-381-to-tezos-cfce907e4be3](https://medium.com/metastatedev/meanwhile-at-cryptium-labs-2-part-2-adding-the-pairing-equipped-elliptic-curve-bls12-381-to-tezos-cfce907e4be3) +17. Article about Rainbow Bridge [https://near.org/blog/eth-near-rainbow-bridge](https://near.org/blog/eth-near-rainbow-bridge) +18. EIP-196. Precompiles for BN254: [https://eips.ethereum.org/EIPS/eip-196](https://eips.ethereum.org/EIPS/eip-196) +19. Intro into zkSNARKs: [https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b](https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b) +20. Zeropool project: [https://zeropool.network/](https://zeropool.network/) +21. Motivation for EIP-2537: [https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders](https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders) +22. Near blog post about Roll Ups: [https://near.org/blog/layer-2](https://near.org/blog/layer-2) +23. Ledger post about Roll Ups: [https://www.ledger.com/academy/what-are-blockchain-rollups](https://www.ledger.com/academy/what-are-blockchain-rollups) +24. Precompiles on Aurora: [https://doc.aurora.dev/evm/precompiles/](https://doc.aurora.dev/evm/precompiles/) +25. Pippenger Algorithm: [https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf) +26. NEP-446 proposal for BLS-signature verification precompile: [https://github.com/nearprotocol/neps/pull/446](https://github.com/nearprotocol/neps/pull/446) +27. EIP-1962 EC arithmetic and pairings with runtime definitions: [https://eips.ethereum.org/EIPS/eip-1962](https://eips.ethereum.org/EIPS/eip-1962) +28. Drawbacks of NEP-446: [https://github.com/near/NEPs/pull/446#pullrequestreview-1314601508](https://github.com/near/NEPs/pull/446#pullrequestreview-1314601508) +29. BLS12-381 Milagro: [https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474) +30. BLST: [https://github.com/supranational/blst](https://github.com/supranational/blst), +31. BLST EIP-2537 adaptation: [https://github.com/sean-sn/blst_eip2537](https://github.com/sean-sn/blst_eip2537) +32. EIP-1962 implementation matter labs Rust: https://github.com/matter-labs/eip1962 +33. zCash origin rust implementation: [https://github.com/zcash/zcash/tree/master/src/rust/src](https://github.com/zcash/zcash/tree/master/src/rust/src) +34. MCL library: [https://github.com/herumi/bls](https://github.com/herumi/bls) +35. filecoin/bls-signature: [https://github.com/filecoin-project/bls-signatures](https://github.com/filecoin-project/bls-signatures) +36. zkCrypto: [https://github.com/zkcrypto/bls12_381](https://github.com/zkcrypto/bls12_381), [https://github.com/zkcrypto/pairing](https://github.com/zkcrypto/pairing) +37. BLS12-381 code bases for ETH2.0 client Chia library C++: [https://github.com/Chia-Network/bls-signatures](https://github.com/Chia-Network/bls-signatures) +38. Adjoint Lib: [https://github.com/sdiehl/pairing](https://github.com/sdiehl/pairing) +39. Ethereum Go implementation for EIP-2537: [https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles) +40. Noble JS implementation: [https://github.com/paulmillr/noble-bls12-381](https://github.com/paulmillr/noble-bls12-381) +41. EIP-1962 implementation matter labs Go: https://github.com/kilic/eip2537, +42. EIP-1962 implementation matter labs C++: https://github.com/matter-labs-archive/eip1962_cpp +43. EIP-2537 with links: [https://github.com/matter-labs-forks/EIPs/blob/bls12_381/EIPS/eip-2537.md](https://github.com/matter-labs-forks/EIPs/blob/bls12_381/EIPS/eip-2537.md) +44. Pairing-friendly curves specification, crypto libs: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-cryptographic-libraries](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-cryptographic-libraries) +45. Comparing different libs for pairing-friendly curves: [https://hackmd.io/@gnark/eccbench](https://hackmd.io/@gnark/eccbench) +46. Bench vectors from EIP2537: [https://eips.ethereum.org/assets/eip-2537/bench_vectors](https://eips.ethereum.org/assets/eip-2537/bench_vectors) +47. Metter Labs tests for EIP2537: [https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537) +48. Tests from Go Ethereum implementation: [https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles) +49. EIP-2537 Map To Curve specification: [https://eips.ethereum.org/assets/eip-2537/field_to_curve](https://eips.ethereum.org/assets/eip-2537/field_to_curve) +50. The current implementation of BN254: [https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs](https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs) +51. draft-irtf-cfrg-pairing-friendly-curves-11 [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-) *(*[https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md) → [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04) → this ref*)* +52. Paper with BLS12-381: [https://eprint.iacr.org/2019/403.pdf](https://eprint.iacr.org/2019/403.pdf) +53. Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) +54. Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 +55. Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) \ No newline at end of file From 1d83ce0243bd37b55f9cd33d49711226cca7565d Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 17:56:25 +0300 Subject: [PATCH 002/163] fix header --- neps/nep-0486.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index d4bafc2bb..886d038d3 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -1,5 +1,3 @@ -# NEP-486 Precompile for BLS12-381 curve operations - --- NEP: 486 Title: Precompile for BLS12-381 curve operations From b590edf63e56445e15aed7edbd582ab30bd75e41 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:00:12 +0300 Subject: [PATCH 003/163] fix header level --- neps/nep-0486.md | 82 ++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 886d038d3..c055f1e91 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -9,11 +9,11 @@ Category: Contract Created: 17-Jul-2023 --- -# Summary +## Summary A pre-compiled NEAR runtime functions for operations on BLS12-381 curve. It is a necessary set to efficiently perform operations such as BLS signature and zkSNARKs verifications. -# Motivation +## Motivation The BLS12-381[1, 11, 52] is a wildly used[2-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]). @@ -39,11 +39,11 @@ In this NEP we propose to add the following functions as precompile: 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 +## Specification -## BLS12-381 Curve Specification +### BLS12-381 Curve Specification -### Elliptic Curve +#### Elliptic Curve **Definition:** The field $F_p$ for some *prime* $p$ is a set of integer elements $\{0, 1, \ldots, p - 1\}$ with two operations: multiplication $\cdot$ and addition $+$. These operations are performed as multiplication/addition for integers number and then taking the remainder modulo $p$. @@ -84,7 +84,7 @@ p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb1 With the addition operation, Elliptic Curve forms a **group**. -### Subgroups +#### Subgroups **Definition:** Subgroup H is a subset of the group G with the following properties: @@ -106,7 +106,7 @@ For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$([1, 2]): Main subgroup order r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 ``` -### Field extension +#### Field extension **Definition:** The field extension $F_{p^k}$ is a set of all polynomials with degree < k and coefficients from $F_p$ and defined operations $\cdot$ , $+$ @@ -140,7 +140,7 @@ For defining these fields, we will need to set up three $M(x)$ irreducible polyn Our second subgroup of order r, which we will use, is a subgroup of the same Elliptic Curve but with elements from $F_{p^{12}}$. $G_2 \subset E(F_{p^{12}})$, where $E: y^2 = x^3 + 4$ -### Twist +#### Twist Store elements from $E(F_{p^{12}})$ takes a lot of memory. ***The twist*** operation transforms the origin curve $E(F_{p^{12}})$ into another curve under another space $E'(F_{p^2})$. It is important that the new curve also has a $G'_2$ subgroup with order r and we can easily transform it to origin $G_2$. @@ -159,7 +159,7 @@ $$ In most cases we will work with points from $G'_2 \subset E'(F_{p^2})$ and use for this subgroup just the notation $G_2$. -### Generators +#### Generators **Definition:** if in the group $G$ exists element g, such as $\{g, 2g, 3g, \ldots, |G|g\} = G$, the group G called ***cyclic group*** and g called ***generator*** @@ -203,7 +203,7 @@ Cofactor $G_2\colon h' = |E'(F_{p^2})|/r$ ([51]) h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 ``` -### Pairing +#### Pairing Pairing is an operation, which we will need for digital signature verification. Pairing operation $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{p^{12}}$. @@ -225,7 +225,7 @@ You can find this parameter in: - [14] section BLS12-381, parameter u - [11] section Curve equation and parameters, parameter x -### Summary +#### Summary The parameters for the BLS12-381: @@ -284,23 +284,23 @@ x = -0xd201000000010000 All parameters were taken from [15], [51] and [14], all of them consistent between sources. -## Curve points encoding +### Curve points encoding -### bool +#### 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]. -### Scalar +#### 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], but `big-endian` encoding is used instead of `little-endian` as in EIP-2537[15]. -### Fields elements $F_p$ +#### 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], with implementation in milagro lib[29]. -### Extension fields elements $F_{p^2}$ +#### Extension fields elements $F_{p^2}$ The $q \in F_{p^{2}}$ could be written as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$ The element from $F_{p^2}$ encoded in `[u8; 96]` as a bytes’ concatenation of $c_1$ and $c_0$. The $c_1$ and $c_0$ are encoded by the rule described in the previous section. @@ -311,7 +311,7 @@ $q \in F_{p^2}$, $q = c_0 + c_1 v$ encoded as `[u8; 96]`: The rule of encoding is consistent with zkcrypto[53] and with implementation in milagro lib[29]. -### Uncompressed points on curve $E(F_p)$ +#### Uncompressed points on curve $E(F_p)$ The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ encoded in `[u8; 96]` as bytes’ concatenation of `x` and `y` point coordinates, where $x, y \in F_p$. The $x, y$ are encoded according to the rules described in the section “Fields elements $F_p$” . @@ -331,7 +331,7 @@ x[0] = x[0] | 0x40; The rule of encoding is consistent with zkcrypto[53] and with implementation in milagro lib[29]. -### Compressed points on curve $E(F_p)$ +#### Compressed points on curve $E(F_p)$ The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ in compressed form are encoded in `[u8; 48]` as *big-endian* encoded $x \in F_p$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. @@ -361,7 +361,7 @@ x[0] = x[0] | 0x40; 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})$ +#### Uncompressed points on twisted curve $E'(F_{p^2})$ The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ encoded in `[u8; 192]` as bytes’ concatenation of `x` and `y` point coordinates, where $x, y \in F_{p^2}$. The $x, y$ are encoded according to the rules described in the section “Extension fields elements $F_{p^2}$” . @@ -385,7 +385,7 @@ x[0] = x[0] | 0x40; The rule of encoding is consistent with zkcrypto[53] and with implementation in milagro lib[29]. -### Compressed points on twisted curve $E'(F_{p2})$ +#### Compressed points on twisted curve $E'(F_{p2})$ The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ in compressed form are encoded in `[u8; 96]` as *big-endian* encoded $x \in F_{p^2}$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. @@ -415,9 +415,9 @@ x[0] = x[0] | 0x40; The rule of encoding is consistent with zkcrypto[53] and with implementation in milagro lib[29]. -## Precompile functions +### Precompile functions -### **bls12381_g1_sum **** +#### bls12381_g1_sum ***Description:*** @@ -506,7 +506,7 @@ pub fn bls12381_g1_sum(&mut self, register_id: u64) -> Result<()>; ``` -### bls12381_g2_sum +#### bls12381_g2_sum ***Description:*** @@ -581,7 +581,7 @@ pub fn bls12381_g2_sum(&mut self, register_id: u64) -> Result<()>; ``` -### ***bls12381_g1_multiexp*** +#### ***bls12381_g1_multiexp*** ***Description:*** @@ -681,7 +681,7 @@ pub fn bls12381_g1_multiexp( ) -> Result<()>; ``` -### ***bls12381_g2_multiexp*** +#### ***bls12381_g2_multiexp*** ***Description:*** @@ -772,7 +772,7 @@ pub fn bls12381_g2_multiexp( ) -> Result<()>; ``` -### bls12381_map_fp_to_g1 +#### bls12381_map_fp_to_g1 ***Description:*** @@ -829,7 +829,7 @@ pub fn bls12381_map_fp_to_g1( ) -> Result<()>; ``` -### bls12381_map_fp2_to_g2 +#### bls12381_map_fp2_to_g2 ***Description:*** @@ -886,7 +886,7 @@ pub fn bls12381_map_fp2_to_g2( ) -> Result<()>; ``` -### bls12381_pairing_check +#### bls12381_pairing_check ***Description:*** @@ -982,7 +982,7 @@ Here you can find benchmark test vectors for EIP-2537[46]. pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Result { ``` -### bls12381_decompress_g1 +#### bls12381_decompress_g1 ***Description:*** Function decompress compressed points from $E(F_p)$. The input is an arbitrary number of points $p_i \in E(F_p)$ in compressed format, and the output is the same number of points from $E(F_p)$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. @@ -1057,7 +1057,7 @@ pub fn bls12381_decompress_g1(&mut self, register_id: u64) -> Result<()>; ``` -### bls12381_decompress_g2 +#### bls12381_decompress_g2 ***Description:*** Function decompress compressed points from $E'(F_{p^2})$. The input is an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format, and the output is the same number of points from $E'(F_{p^2})$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. @@ -1132,7 +1132,7 @@ pub fn bls12381_decompress_g2(&mut self, register_id: u64) -> Result<()>; ``` -# Reference Implementation +## Reference Implementation First of all, for integration with nearcore, we are interested in libraries in the Rust language. The existing BLS12-381 implementations on Rust: @@ -1157,7 +1157,7 @@ In addition, there are implementations in other languages that are not so intere 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 +## Security Implications The implementation security relies on the security of the chosen library, which supports operations with BLS curves. @@ -1165,7 +1165,7 @@ In this NEP, we do not require a constant execution time for all operations. Thi The BLS12-381 has more security bits than the already existing pairing-friendly curve BN254, as a result, the security of the projects which need the pairing-friendly curve will improve. -# Alternatives +## Alternatives 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. @@ -1173,32 +1173,32 @@ Another alternative is to create one simple precompile in nearcore for BLS-signa 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 +## Future possibilities 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 +## Consequences -## Positive +### Positive - Projects, which used BN254 will be able to switch on BLS12-381 curve, and it will improve security. - The trustless cross-chain interactions with blockchains that use BLS12-381 in protocols(such as Ethereum 2) will become possible. -## Neutral +### Neutral -## Negative +### Negative - The appearance of dependence on the library which supports BLS12-381 curves operations. -## Backward Compatibility +### Backward Compatibility There are no backward compatibility questions. -# Changelog +## Changelog The previous NEP for supporting BLS signature based on BLS12-381[26]: [https://github.com/nearprotocol/neps/pull/446](https://github.com/nearprotocol/neps/pull/446) -# References: +## References: 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) From e2c9fb732656adff7486d1410180b115b225d678 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:02:21 +0300 Subject: [PATCH 004/163] update header table --- neps/nep-0486.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index c055f1e91..27bb87039 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -2,11 +2,12 @@ NEP: 486 Title: Precompile for BLS12-381 curve operations Author: Olga Kuniavskaia [olga.kunyavskaya@aurora.dev](mailto:olga.kunyavskaya@aurora.dev) -DiscussionsTo: [https://github.com/nearprotocol/neps/pull/486](https://github.com/nearprotocol/neps/pull/486) Status: Draft +DiscussionsTo: [https://github.com/nearprotocol/neps/pull/486](https://github.com/nearprotocol/neps/pull/486) Type: Runtime Spec -Category: Contract +Version: 0.0.1 Created: 17-Jul-2023 +LastUpdated: 17-Jul-2023 --- ## Summary From 16990a76f1a176bf95481258609f97d10c204a1c Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:03:09 +0300 Subject: [PATCH 005/163] update header table --- neps/nep-0486.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 27bb87039..8a57a69d5 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -1,7 +1,7 @@ --- NEP: 486 Title: Precompile for BLS12-381 curve operations -Author: Olga Kuniavskaia [olga.kunyavskaya@aurora.dev](mailto:olga.kunyavskaya@aurora.dev) +Authors: Olga Kuniavskaia [olga.kunyavskaya@aurora.dev](mailto:olga.kunyavskaya@aurora.dev) Status: Draft DiscussionsTo: [https://github.com/nearprotocol/neps/pull/486](https://github.com/nearprotocol/neps/pull/486) Type: Runtime Spec From 4a521618136952aaa0da6882443c557187d15352 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:05:42 +0300 Subject: [PATCH 006/163] update header table --- neps/nep-0486.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 8a57a69d5..8301f6520 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -1,13 +1,13 @@ --- NEP: 486 Title: Precompile for BLS12-381 curve operations -Authors: Olga Kuniavskaia [olga.kunyavskaya@aurora.dev](mailto:olga.kunyavskaya@aurora.dev) +Authors: Olga Kuniavskaia Status: Draft -DiscussionsTo: [https://github.com/nearprotocol/neps/pull/486](https://github.com/nearprotocol/neps/pull/486) +DiscussionsTo: https://github.com/nearprotocol/neps/pull/486 Type: Runtime Spec Version: 0.0.1 -Created: 17-Jul-2023 -LastUpdated: 17-Jul-2023 +Created: 2023-07-17 +LastUpdated: 2023-07-17 --- ## Summary From 48199160200bd7a84d3aba909e9e44c5f4c5c962 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:18:25 +0300 Subject: [PATCH 007/163] fix formuls --- neps/nep-0486.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 8301f6520..cb1878f3c 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -36,7 +36,7 @@ In this NEP we propose to add the following functions as precompile: - ***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] and in EIP-2537[15]. +- ***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]. Which can be useful for Aurora[24] to support Ethereum functionality on Near. @@ -174,9 +174,9 @@ X = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff9 Y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1 ``` -For $(x', y') \in G_2 \subset E'(F_{p^2}): \\ -x' = x_0 + x_1u\\ -y' = y_0 + y_1u$ +For $(x', y') \in G_2 \subset E'(F_{p^2}):$ +$$x' = x_0 + x_1u$$ +$$y' = y_0 + y_1u$$ ```rust G2: @@ -777,11 +777,11 @@ pub fn bls12381_g2_multiexp( ***Description:*** -The function takes the element $a \in F_p$ and maps it to the $G_1 \sub 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. +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. -***Output:*** the output is `96 bytes` — one point $\in G_1 \sub E(F_p)$ in decompressed format. More details are in the Curve Points Encoding section. +***Output:*** the output is `96 bytes` — one point $\in G_1 \subset E(F_p)$ in decompressed format. More details are in the Curve Points Encoding section. ***Gas Estimation:*** @@ -834,11 +834,11 @@ 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 \sub 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. +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. -***Output:*** the output is `192 bytes` — one point $\in G_2 \sub E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. +***Output:*** the output is `192 bytes` — one point $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. ***Gas Estimation:*** @@ -891,7 +891,7 @@ pub fn bls12381_map_fp2_to_g2( ***Description:*** -The pairing function $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \sub F_{q^{12}}$. The pairing function has the following properties: +The pairing function $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{q^{12}}$. The pairing function has the following properties: - $e(P, Q + R) = e(P, Q) \cdot e(P, R)$ - $e(P + S, R) = e(P, R)\cdot e(S, R)$ @@ -902,7 +902,7 @@ $e([a]P, [b]Q) = e(P, Q)^{ab} = e([b]P, [a]Q)$ We need this function to verify BLS signature. -This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \sub E(F_{p})$ and $q_i \in G_2 \sub E'(F_{p^2})$ and check: +This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \sub E'(F_{p^2})$ and check: $$ \sum e(p_i, q_i) = 1 @@ -910,7 +910,7 @@ $$ We don’t calculate the pairing function itself: the result will be in the huge field, and in all known applications only such a check is necessary. -***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \sub E(F_{p})$ and $q_i \in G_2 \sub E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $G_1 \sub E(F_p)$ — `96 bytes` and point from $G_2 \sub E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $G_1 \subset E(F_p)$ — `96 bytes` and point from $G_2 \subset E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. ***Output:*** returns `bool` — the result of the pairing check. The `true` value means that the pairing result is equal to multiplicative identity and `false` otherwise. From 107f4ae746a1f0a343bd3419a938435f902b6681 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:24:48 +0300 Subject: [PATCH 008/163] fix formuls --- neps/nep-0486.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index cb1878f3c..0cdafb2cb 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -118,8 +118,12 @@ $$ The $+$ operation is defined as a regular addition for polynomials: $$ -A(x) + B(x) = C(x)\\ -\sum a_i x^i + \sum b_i x^i = \sum c_i x^i\\ +A(x) + B(x) = C(x) +$$ +$$ +\sum a_i x^i + \sum b_i x^i = \sum c_i x^i +$$ +$$ c_i = (a_i + b_i) \mod p $$ @@ -701,7 +705,9 @@ Note: - We take as input any points on the curve, not only from $G_2$. - The scalar is an arbitrary unsigned integer and can be bigger than the group order. -***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and +$s_i \in \mathbb{N}_0$ is a scalar. +Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. From fa42b1891252b4f62dd3dc3189a293dd24c2c1ae Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:27:27 +0300 Subject: [PATCH 009/163] fix formuls --- neps/nep-0486.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 0cdafb2cb..1d19623e5 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -705,8 +705,8 @@ Note: - We take as input any points on the curve, not only from $G_2$. - The scalar is an arbitrary unsigned integer and can be bigger than the group order. -***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and -$s_i \in \mathbb{N}_0$ is a scalar. +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. + Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. From dcfab7b29028221249d705edcdad378343d43218 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:30:26 +0300 Subject: [PATCH 010/163] fix formuls --- neps/nep-0486.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 1d19623e5..a0f187e29 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -162,7 +162,7 @@ $$ E'\colon y^2 = x^3 + 4(u + 1) $$ -In most cases we will work with points from $G'_2 \subset E'(F_{p^2})$ and use for this subgroup just the notation $G_2$. +In most cases we will work with points from $G_2' \subset E'(F_{p^2})$ and use for this subgroup just the notation $G_2$. #### Generators From 88dfdea92dbacadb9cd69ba387e274ddc350b0b6 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:31:42 +0300 Subject: [PATCH 011/163] fix formuls --- neps/nep-0486.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index a0f187e29..a14ca4ffc 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -239,7 +239,9 @@ Base field modulus p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a ``` $$ -E\colon y^2 \equiv x^3 + 4\\ +E\colon y^2 \equiv x^3 + 4 +$$ +$$ E'\colon y^2 \equiv x^3 + 4(u + 1) $$ @@ -248,8 +250,12 @@ Main subgroup order r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffff ``` $$ -F_{p^2} = F_p[u] / (u^2 + 1)\\ -F_{p^6} = F_{p^2}[v] / (v^3 - u - 1)\\ +F_{p^2} = F_p[u] / (u^2 + 1) +$$ +$$ +F_{p^6} = F_{p^2}[v] / (v^3 - u - 1) +$$ +$$ F_{p^{12}} = F_{p^6}[w] / (w^2 - v) $$ From 0b3e4ef58a261821352db0cb756ec4c867d2c710 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:33:01 +0300 Subject: [PATCH 012/163] fix formuls --- neps/nep-0486.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index a14ca4ffc..a3aaf8e64 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -120,9 +120,11 @@ The $+$ operation is defined as a regular addition for polynomials: $$ A(x) + B(x) = C(x) $$ + $$ \sum a_i x^i + \sum b_i x^i = \sum c_i x^i $$ + $$ c_i = (a_i + b_i) \mod p $$ @@ -180,6 +182,7 @@ Y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2 For $(x', y') \in G_2 \subset E'(F_{p^2}):$ $$x' = x_0 + x_1u$$ + $$y' = y_0 + y_1u$$ ```rust @@ -241,6 +244,7 @@ Base field modulus p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a $$ E\colon y^2 \equiv x^3 + 4 $$ + $$ E'\colon y^2 \equiv x^3 + 4(u + 1) $$ @@ -252,9 +256,11 @@ Main subgroup order r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffff $$ F_{p^2} = F_p[u] / (u^2 + 1) $$ + $$ F_{p^6} = F_{p^2}[v] / (v^3 - u - 1) $$ + $$ F_{p^{12}} = F_{p^6}[w] / (w^2 - v) $$ From 81081cc2a3cb108b6d5932ef04b92138a64d7c7c Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:39:25 +0300 Subject: [PATCH 013/163] fix formuls --- neps/nep-0486.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index a3aaf8e64..ce434dcb6 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -168,7 +168,7 @@ In most cases we will work with points from $G_2' \subset E'(F_{p^2})$ and use f #### Generators -**Definition:** if in the group $G$ exists element g, such as $\{g, 2g, 3g, \ldots, |G|g\} = G$, the group G called ***cyclic group*** and g called ***generator*** +**Definition:** if in the group $G$ exists element g, such as $\textbraceleft g, 2g, 3g, \ldots, |G|g \textbraceright = G$, the group G called ***cyclic group*** and g called ***generator*** @@ -920,7 +920,7 @@ $e([a]P, [b]Q) = e(P, Q)^{ab} = e([b]P, [a]Q)$ We need this function to verify BLS signature. -This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \sub E'(F_{p^2})$ and check: +This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$ and check: $$ \sum e(p_i, q_i) = 1 From 6e6b4c84b9d6cbf0fe9cdaa2e18a9b9357de5fd0 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:40:17 +0300 Subject: [PATCH 014/163] fix formuls --- neps/nep-0486.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index ce434dcb6..43e0e4a05 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -46,7 +46,7 @@ By using these functions, we can reproduce all functionality from EIP-2537[15]. #### Elliptic Curve -**Definition:** The field $F_p$ for some *prime* $p$ is a set of integer elements $\{0, 1, \ldots, p - 1\}$ with two operations: multiplication $\cdot$ and addition $+$. These operations are performed as multiplication/addition for integers number and then taking the remainder modulo $p$. +**Definition:** The field $F_p$ for some *prime* $p$ is a set of integer elements $\textbraceleft 0, 1, \ldots, p - 1 \textbraceright$ with two operations: multiplication $\cdot$ and addition $+$. These operations are performed as multiplication/addition for integers number and then taking the remainder modulo $p$. From c577f780dd1db9b1e4883faf3df102043c38c9eb Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:43:39 +0300 Subject: [PATCH 015/163] links --- neps/nep-0486.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 43e0e4a05..7887275b9 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -16,7 +16,7 @@ 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-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 BLS12-381 [[1](https://www.researchgate.net/publication/2894224_Constructing_Elliptic_Curves_with_Prescribed_Embedding_Degrees), [11](https://hackmd.io/@benjaminion/bls12-381), [52](https://eprint.iacr.org/2019/403.pdf)] is a wildly used[2-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. From b5a5cfb7794722a2a525033b7e4c6790dc32cde7 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 18:56:42 +0300 Subject: [PATCH 016/163] links --- neps/nep-0486.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 7887275b9..48d9dd61d 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -16,29 +16,30 @@ A pre-compiled NEAR runtime functions for operations on BLS12-381 curve. It is a ## Motivation -The BLS12-381 [[1](https://www.researchgate.net/publication/2894224_Constructing_Elliptic_Curves_with_Prescribed_Embedding_Degrees), [11](https://hackmd.io/@benjaminion/bls12-381), [52](https://eprint.iacr.org/2019/403.pdf)] is a wildly used[2-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 BLS12-381 [[1](https://www.researchgate.net/publication/2894224_Constructing_Elliptic_Curves_with_Prescribed_Embedding_Degrees), [11](https://hackmd.io/@benjaminion/bls12-381), [52](https://eprint.iacr.org/2019/403.pdf)] is a wildly +used[[2](https://zips.z.cash/protocol/protocol.pdf),[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)]). 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 c*ross-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. +Effective BLS-signature verification based on BLS12-381 elliptic curve will be useful for c*ross-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](https://near.org/blog/eth-near-rainbow-bridge)] to make trustless transfers from Ethereum 2.0 to Near. -zkSNARKs is useful for working with users' 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-23] scaling solutions. +zkSNARKs is useful for working with users' 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. -This proposal is based on a similar proposal for Ethereum: EIP-2537[15]. +This proposal is based on a similar proposal for Ethereum: EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. 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]. +- ***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_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]. A similar function exists both in Near for BN254[10] and in EIP-2537[15]. +- ***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_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]. -- ***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_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_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] and in EIP-2537[15]. +- ***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)]. -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. +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. ## Specification @@ -58,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$ ([1-4]) +In the case of BLS12-381 equation is $y^2 \equiv x^3 + 4 \mod p$ ([[15],[51],[14],[11]]) **Parameters for our case:** From 0ce5e73acd5d57d0ce869b86e00d420e5c5b6dde Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 19:42:31 +0300 Subject: [PATCH 017/163] links --- neps/nep-0486.md | 120 +++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 48d9dd61d..a155f47bf 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -21,7 +21,7 @@ used[[2](https://zips.z.cash/protocol/protocol.pdf),[3](https://github.com/ether 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 c*ross-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](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 c*ross-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. zkSNARKs is useful for working with users' 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. @@ -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],[51],[14],[11]]) +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)]) **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$([1, 2]): +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-)]): ```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]): +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-)]: - $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]): +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-)]): $$ 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], [51]): +$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-)]): ```rust G1: @@ -200,13 +200,13 @@ $$ |G|/|H| $$ -Cofactor $G_1\colon h = |E(F_p)|/r$ ([51]) +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-)]) ```rust h = 0x396c8c005555e1568c00aaab0000aaab ``` -Cofactor $G_2\colon h' = |E'(F_{p^2})|/r$ ([51]) +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-)]) ```rust h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 @@ -229,10 +229,10 @@ x = -0xd201000000010000 You can find this parameter in: -- [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 +- [[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 #### Summary @@ -300,23 +300,23 @@ Key BLS12-381 parameter used in Miller Loop: x = -0xd201000000010000 ``` -All parameters were taken from [15], [51] and [14], all of them consistent between sources. +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. ### 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]. +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)]. #### 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], but `big-endian` encoding is used instead of `little-endian` as in EIP-2537[15]. +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)]. #### 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], with implementation in milagro lib[29]. +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)]. #### 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] and with implementation in milagro lib[29]. +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)]. #### 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] and with implementation in milagro lib[29]. +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)]. #### 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] and with implementation in milagro lib[29]. +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)]. #### 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] and with implementation in milagro lib[29]. +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)]. #### 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] and with implementation in milagro lib[29]. +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)]. ### 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]. 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](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. ***Test cases:*** @@ -482,7 +482,7 @@ Here you can find benchmark test vectors for EIP-2537[46]. It doesn’t contain ***Tests References:*** -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. +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. ***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]. 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](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. ***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-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. +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. ***Error cases:*** @@ -624,7 +624,7 @@ Note: ***Gas Estimation:*** -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]. +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]. ```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]. +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)]. ***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-48]. +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)]. ***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]. 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](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)]. ```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]. +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)]. ***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-48]. +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)]. ***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]. 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](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. ***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] +- Edge cases for inner algorithms for mapping[[49](https://eips.ethereum.org/assets/eip-2537/field_to_curve)] -***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[47-48]. +***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)]. ***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]. 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](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. ***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] +- Edge cases for inner algorithms for mapping[[49](https://eips.ethereum.org/assets/eip-2537/field_to_curve)] -***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[47-48]. +***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)]. ***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]. +Here you can find benchmark test vectors for EIP-2537[[46](https://eips.ethereum.org/assets/eip-2537/bench_vectors)]. ***Test cases:*** @@ -957,7 +957,7 @@ Here you can find benchmark test vectors for EIP-2537[46]. - 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-48]. +***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)]. ***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-48] and check the correctness after decompression +- 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 - 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-48] and check the correctness after decompression +- 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 - 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]. -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] +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)] -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. +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. 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] -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] +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)] -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]. +The draft implementation to nearcore you can find by this link[[54](near/nearcore#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)]. ## 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]. 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. +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. -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. +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. 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], 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. +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. ## 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](https://github.com/nearprotocol/neps/pull/446) +The previous NEP for supporting BLS signature based on BLS12-381[[26](https://github.com/nearprotocol/neps/pull/446)] ## References: From 7f1f5eb46020d95fa9c06e189c16d387e11bd980 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 19:44:31 +0300 Subject: [PATCH 018/163] links --- neps/nep-0486.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index a155f47bf..1bf9726e8 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -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](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-)]): ```rust G1: From 926b75a4f0884d3ccf9a4f33907eaefde53fd157 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 17 Jul 2023 19:50:00 +0300 Subject: [PATCH 019/163] update name --- neps/nep-0486.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0486.md b/neps/nep-0486.md index 1bf9726e8..2a17da699 100644 --- a/neps/nep-0486.md +++ b/neps/nep-0486.md @@ -1,9 +1,9 @@ --- -NEP: 486 +NEP: 488 Title: Precompile for BLS12-381 curve operations Authors: Olga Kuniavskaia Status: Draft -DiscussionsTo: https://github.com/nearprotocol/neps/pull/486 +DiscussionsTo: https://github.com/nearprotocol/neps/pull/488 Type: Runtime Spec Version: 0.0.1 Created: 2023-07-17 From 3cc35f4e4816340f922a24eefc7f2a518566bcec Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 18 Jul 2023 11:10:25 +0300 Subject: [PATCH 020/163] rename nep --- neps/{nep-0486.md => nep-0488.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename neps/{nep-0486.md => nep-0488.md} (100%) diff --git a/neps/nep-0486.md b/neps/nep-0488.md similarity index 100% rename from neps/nep-0486.md rename to neps/nep-0488.md From f26f71f0cc61a1c93ca5ef0f921a9621d3d3c9d0 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 18 Jul 2023 21:17:43 +0300 Subject: [PATCH 021/163] fix formating --- neps/nep-0488.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 2a17da699..372f7ee64 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -74,15 +74,15 @@ p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb1 **Definition:** The addition operation for Elliptic Curve is a function $+\colon E(F_p) \times E(F_p) \rightarrow E(F_p)$ defined with following rules: let’s P and Q $\in E(F_p)$ - if $P \ne Q$ and $P \ne -Q$ - - draw a line passing through P and Q. This line intersects the curve at a third point R - - reflect the point R about the x-axis by changing the sign of the y-coordinate. The resulting point is P+Q. + - draw a line passing through P and Q. This line intersects the curve at a third point R + - reflect the point R about the x-axis by changing the sign of the y-coordinate. The resulting point is P+Q. - if $P=Q$ - - draw a tangent line throw P for an elliptic curve. The line will intersect the curve at the second point R. - - reflect the point R about the x-axis the same way to get point 2P + - draw a tangent line throw P for an elliptic curve. The line will intersect the curve at the second point R. + - reflect the point R about the x-axis the same way to get point 2P - $P = -Q$ - - $P + Q = P + (-P) = 0$ — the point on infinity + - $P + Q = P + (-P) = 0$ — the point on infinity - Q = 0 - - $P + Q = P + 0 = P$ + - $P + Q = P + 0 = P$ With the addition operation, Elliptic Curve forms a **group**. @@ -386,11 +386,11 @@ The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The $E'(F_{p^2})$ is encoded as `[u8; 192]`: - $x \in F_{p^2}$ `[u8; 96]`: - - $c_1 \in F_p$ `[u8; 48]` - - $c_0 \in F_p$ `[u8; 48]` + - $c_1 \in F_p$ `[u8; 48]` + - $c_0 \in F_p$ `[u8; 48]` - $y \in F_{p^2}$ `[u8; 96]`: - - $c_1 \in F_p$ `[u8; 48]` - - $c_0 \in F_p$ `[u8; 48]` + - $c_1 \in F_p$ `[u8; 48]` + - $c_0 \in F_p$ `[u8; 48]` *The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. From e3e63e040518ba60f7bd207c15be25b214870cfd Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 18 Jul 2023 21:19:37 +0300 Subject: [PATCH 022/163] fix formating --- neps/nep-0488.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 372f7ee64..8abebb138 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1218,7 +1218,7 @@ There are no backward compatibility questions. The previous NEP for supporting BLS signature based on BLS12-381[[26](https://github.com/nearprotocol/neps/pull/446)] -## References: +## References 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) @@ -1274,4 +1274,4 @@ The previous NEP for supporting BLS signature based on BLS12-381[[26](https://gi 52. Paper with BLS12-381: [https://eprint.iacr.org/2019/403.pdf](https://eprint.iacr.org/2019/403.pdf) 53. Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) 54. Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 -55. Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) \ No newline at end of file +55. Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) From 51b5f2ab6278d092085933a63beb8017e6d1c664 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 17:25:23 +0300 Subject: [PATCH 023/163] Fix link to implementation Co-authored-by: Marcelo Fornet --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 8abebb138..a6a1c9d04 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1175,7 +1175,7 @@ In addition, there are implementations in other languages that are not so intere 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)] -The draft implementation to nearcore you can find by this link[[54](near/nearcore#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](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)]. ## Security Implications From c14bb2c440a737a2c9d7dbbb8be569d9ddf6d6c3 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 17:25:58 +0300 Subject: [PATCH 024/163] Remove extra space Co-authored-by: Marcelo Fornet --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a6a1c9d04..0f172874c 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -37,7 +37,7 @@ In this NEP we propose to add the following functions as precompile: - ***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_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](https://github.com/near/NEPs/issues/98)] and in EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. 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. From 12a134266c1a5c7bf6cbce0ae0fe913208275576 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 17:26:43 +0300 Subject: [PATCH 025/163] Remove extra space Co-authored-by: Marcelo Fornet --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 0f172874c..ae55a6b03 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -32,7 +32,7 @@ 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_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_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_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_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. From e71de6472965ab2a9a073ce7cce7780560dfcbca Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 17:27:48 +0300 Subject: [PATCH 026/163] Fix grammer Co-authored-by: Marcelo Fornet --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index ae55a6b03..baf0f041d 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -23,7 +23,7 @@ The implementation of BLS12-381 curve operations from this NEP as a precompile Effective BLS-signature verification based on BLS12-381 elliptic curve will be useful for c*ross-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. -zkSNARKs is useful for working with users' 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](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. This proposal is based on a similar proposal for Ethereum: EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. From 61f540bb655ea434b7f6fe4e478b36957b9315b8 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 17:33:32 +0300 Subject: [PATCH 027/163] Make dash bold for consistency Co-authored-by: Marcelo Fornet --- neps/nep-0488.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index baf0f041d..95a1bda03 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -29,8 +29,8 @@ This proposal is based on a similar proposal for Ethereum: EIP-2537[[15](https:/ 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_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_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_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_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)]. From 664373f49804838b718ea8d6b6ea8a8d954246cd Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 17:36:48 +0300 Subject: [PATCH 028/163] fix naming --- neps/nep-0488.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 95a1bda03..890d85d48 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -21,7 +21,7 @@ used[[2](https://zips.z.cash/protocol/protocol.pdf),[3](https://github.com/ether 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 c*ross-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](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. 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. @@ -31,15 +31,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_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](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_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_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](https://github.com/near/NEPs/issues/98)] and in EIP-2537[[15](https://eips.ethereum.org/EIPS/eip-2537)]. -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](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. ## Specification @@ -1241,7 +1241,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[[26](https://gi 19. Intro into zkSNARKs: [https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b](https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b) 20. Zeropool project: [https://zeropool.network/](https://zeropool.network/) 21. Motivation for EIP-2537: [https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders](https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders) -22. Near blog post about Roll Ups: [https://near.org/blog/layer-2](https://near.org/blog/layer-2) +22. NEAR blog post about Roll Ups: [https://near.org/blog/layer-2](https://near.org/blog/layer-2) 23. Ledger post about Roll Ups: [https://www.ledger.com/academy/what-are-blockchain-rollups](https://www.ledger.com/academy/what-are-blockchain-rollups) 24. Precompiles on Aurora: [https://doc.aurora.dev/evm/precompiles/](https://doc.aurora.dev/evm/precompiles/) 25. Pippenger Algorithm: [https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf) From 6cd7f07812a407db61acc4f771f5652495c36187 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 17:40:49 +0300 Subject: [PATCH 029/163] test ref --- neps/nep-0488.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 890d85d48..acd7a121d 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -16,7 +16,7 @@ A pre-compiled NEAR runtime functions for operations on BLS12-381 curve. It is a ## Motivation -The BLS12-381 [[1](https://www.researchgate.net/publication/2894224_Constructing_Elliptic_Curves_with_Prescribed_Embedding_Degrees), [11](https://hackmd.io/@benjaminion/bls12-381), [52](https://eprint.iacr.org/2019/403.pdf)] is a wildly +The BLS12-381[^1], [11](https://hackmd.io/@benjaminion/bls12-381), [52](https://eprint.iacr.org/2019/403.pdf)] is a wildly used[[2](https://zips.z.cash/protocol/protocol.pdf),[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)]). 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. @@ -1220,7 +1220,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[[26](https://gi ## References -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) +[^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) 3. Ethereum 2 specification: [https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md](https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md) 4. Dfinity: [https://internetcomputer.org/docs/current/references/ic-interface-spec#certificate](https://internetcomputer.org/docs/current/references/ic-interface-spec#certificate) From ffde1547e3cbb97969df4173b10125073deb7474 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 17:50:50 +0300 Subject: [PATCH 030/163] test multilink --- neps/nep-0488.md | 114 +++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 58 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index acd7a121d..a2e1d6b40 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -16,8 +16,8 @@ A pre-compiled NEAR runtime functions for operations on BLS12-381 curve. It is a ## Motivation -The BLS12-381[^1], [11](https://hackmd.io/@benjaminion/bls12-381), [52](https://eprint.iacr.org/2019/403.pdf)] is a wildly -used[[2](https://zips.z.cash/protocol/protocol.pdf),[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)]). +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)]). 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. @@ -1218,60 +1218,58 @@ There are no backward compatibility questions. The previous NEP for supporting BLS signature based on BLS12-381[[26](https://github.com/nearprotocol/neps/pull/446)] -## References - [^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) -3. Ethereum 2 specification: [https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md](https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md) -4. Dfinity: [https://internetcomputer.org/docs/current/references/ic-interface-spec#certificate](https://internetcomputer.org/docs/current/references/ic-interface-spec#certificate) -5. Tezos: [https://wiki.tezosagora.org/learn/futuredevelopments/layer2#zkchannels](https://wiki.tezosagora.org/learn/futuredevelopments/layer2#zkchannels) -6. Filecoin: [https://spec.filecoin.io/](https://spec.filecoin.io/) -7. Specification of pairing friendly curves with a list of applications in the table: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-) -8. Specification of pairing friendly curves, the security level for BLS12-381: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1) -9. BN2005: [https://eprint.iacr.org/2005/133](https://eprint.iacr.org/2005/133) -10. NEP-98 for BN254 precompile on NEAR: https://github.com/near/NEPs/issues/98 -11. BLS12-381 for the Rest of Us: [https://hackmd.io/@benjaminion/bls12-381](https://hackmd.io/@benjaminion/bls12-381) -12. BN254 for the Rest of Us: [https://hackmd.io/@jpw/bn254](https://hackmd.io/@jpw/bn254) -13. Some analytics of different curve security: [https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security](https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security) -14. ZCash Transfer from bn254 to bls12-381: [https://electriccoin.co/blog/new-snark-curve/](https://electriccoin.co/blog/new-snark-curve/) -15. EIP-2537 Precompiles for Ethereum for BLS12-381: [https://eips.ethereum.org/EIPS/eip-2537](https://eips.ethereum.org/EIPS/eip-2537) -16. The article, where Tezos announce the support of BLS12-381 [https://medium.com/metastatedev/meanwhile-at-cryptium-labs-2-part-2-adding-the-pairing-equipped-elliptic-curve-bls12-381-to-tezos-cfce907e4be3](https://medium.com/metastatedev/meanwhile-at-cryptium-labs-2-part-2-adding-the-pairing-equipped-elliptic-curve-bls12-381-to-tezos-cfce907e4be3) -17. Article about Rainbow Bridge [https://near.org/blog/eth-near-rainbow-bridge](https://near.org/blog/eth-near-rainbow-bridge) -18. EIP-196. Precompiles for BN254: [https://eips.ethereum.org/EIPS/eip-196](https://eips.ethereum.org/EIPS/eip-196) -19. Intro into zkSNARKs: [https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b](https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b) -20. Zeropool project: [https://zeropool.network/](https://zeropool.network/) -21. Motivation for EIP-2537: [https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders](https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders) -22. NEAR blog post about Roll Ups: [https://near.org/blog/layer-2](https://near.org/blog/layer-2) -23. Ledger post about Roll Ups: [https://www.ledger.com/academy/what-are-blockchain-rollups](https://www.ledger.com/academy/what-are-blockchain-rollups) -24. Precompiles on Aurora: [https://doc.aurora.dev/evm/precompiles/](https://doc.aurora.dev/evm/precompiles/) -25. Pippenger Algorithm: [https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf) -26. NEP-446 proposal for BLS-signature verification precompile: [https://github.com/nearprotocol/neps/pull/446](https://github.com/nearprotocol/neps/pull/446) -27. EIP-1962 EC arithmetic and pairings with runtime definitions: [https://eips.ethereum.org/EIPS/eip-1962](https://eips.ethereum.org/EIPS/eip-1962) -28. Drawbacks of NEP-446: [https://github.com/near/NEPs/pull/446#pullrequestreview-1314601508](https://github.com/near/NEPs/pull/446#pullrequestreview-1314601508) -29. BLS12-381 Milagro: [https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474) -30. BLST: [https://github.com/supranational/blst](https://github.com/supranational/blst), -31. BLST EIP-2537 adaptation: [https://github.com/sean-sn/blst_eip2537](https://github.com/sean-sn/blst_eip2537) -32. EIP-1962 implementation matter labs Rust: https://github.com/matter-labs/eip1962 -33. zCash origin rust implementation: [https://github.com/zcash/zcash/tree/master/src/rust/src](https://github.com/zcash/zcash/tree/master/src/rust/src) -34. MCL library: [https://github.com/herumi/bls](https://github.com/herumi/bls) -35. filecoin/bls-signature: [https://github.com/filecoin-project/bls-signatures](https://github.com/filecoin-project/bls-signatures) -36. zkCrypto: [https://github.com/zkcrypto/bls12_381](https://github.com/zkcrypto/bls12_381), [https://github.com/zkcrypto/pairing](https://github.com/zkcrypto/pairing) -37. BLS12-381 code bases for ETH2.0 client Chia library C++: [https://github.com/Chia-Network/bls-signatures](https://github.com/Chia-Network/bls-signatures) -38. Adjoint Lib: [https://github.com/sdiehl/pairing](https://github.com/sdiehl/pairing) -39. Ethereum Go implementation for EIP-2537: [https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles) -40. Noble JS implementation: [https://github.com/paulmillr/noble-bls12-381](https://github.com/paulmillr/noble-bls12-381) -41. EIP-1962 implementation matter labs Go: https://github.com/kilic/eip2537, -42. EIP-1962 implementation matter labs C++: https://github.com/matter-labs-archive/eip1962_cpp -43. EIP-2537 with links: [https://github.com/matter-labs-forks/EIPs/blob/bls12_381/EIPS/eip-2537.md](https://github.com/matter-labs-forks/EIPs/blob/bls12_381/EIPS/eip-2537.md) -44. Pairing-friendly curves specification, crypto libs: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-cryptographic-libraries](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-cryptographic-libraries) -45. Comparing different libs for pairing-friendly curves: [https://hackmd.io/@gnark/eccbench](https://hackmd.io/@gnark/eccbench) -46. Bench vectors from EIP2537: [https://eips.ethereum.org/assets/eip-2537/bench_vectors](https://eips.ethereum.org/assets/eip-2537/bench_vectors) -47. Metter Labs tests for EIP2537: [https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537) -48. Tests from Go Ethereum implementation: [https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles) -49. EIP-2537 Map To Curve specification: [https://eips.ethereum.org/assets/eip-2537/field_to_curve](https://eips.ethereum.org/assets/eip-2537/field_to_curve) -50. The current implementation of BN254: [https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs](https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs) -51. draft-irtf-cfrg-pairing-friendly-curves-11 [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-) *(*[https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md) → [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04) → this ref*)* -52. Paper with BLS12-381: [https://eprint.iacr.org/2019/403.pdf](https://eprint.iacr.org/2019/403.pdf) -53. Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) -54. Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 -55. Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) +[^2]: ZCash protocol: [https://zips.z.cash/protocol/protocol.pdf](https://zips.z.cash/protocol/protocol.pdf) +[^3]: Ethereum 2 specification: [https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md](https://github.com/ethereum/consensus-specs/blob/master/specs/phase0/beacon-chain.md) +[^4]: Dfinity: [https://internetcomputer.org/docs/current/references/ic-interface-spec#certificate](https://internetcomputer.org/docs/current/references/ic-interface-spec#certificate) +[^5]: Tezos: [https://wiki.tezosagora.org/learn/futuredevelopments/layer2#zkchannels](https://wiki.tezosagora.org/learn/futuredevelopments/layer2#zkchannels) +[^6]: Filecoin: [https://spec.filecoin.io/](https://spec.filecoin.io/) +[^7]: Specification of pairing friendly curves with a list of applications in the table: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-) +[^8]: Specification of pairing friendly curves, the security level for BLS12-381: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1) +[^9]: BN2005: [https://eprint.iacr.org/2005/133](https://eprint.iacr.org/2005/133) +[^10]: NEP-98 for BN254 precompile on NEAR: https://github.com/near/NEPs/issues/98 +[^11]: BLS12-381 for the Rest of Us: [https://hackmd.io/@benjaminion/bls12-381](https://hackmd.io/@benjaminion/bls12-381) +[^12]: BN254 for the Rest of Us: [https://hackmd.io/@jpw/bn254](https://hackmd.io/@jpw/bn254) +[^13]: Some analytics of different curve security: [https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security](https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security) +[^14]: ZCash Transfer from bn254 to bls12-381: [https://electriccoin.co/blog/new-snark-curve/](https://electriccoin.co/blog/new-snark-curve/) +[^15]: EIP-2537 Precompiles for Ethereum for BLS12-381: [https://eips.ethereum.org/EIPS/eip-2537](https://eips.ethereum.org/EIPS/eip-2537) +[^16]: The article, where Tezos announce the support of BLS12-381 [https://medium.com/metastatedev/meanwhile-at-cryptium-labs-2-part-2-adding-the-pairing-equipped-elliptic-curve-bls12-381-to-tezos-cfce907e4be3](https://medium.com/metastatedev/meanwhile-at-cryptium-labs-2-part-2-adding-the-pairing-equipped-elliptic-curve-bls12-381-to-tezos-cfce907e4be3) +[^17]: Article about Rainbow Bridge [https://near.org/blog/eth-near-rainbow-bridge](https://near.org/blog/eth-near-rainbow-bridge) +[^18]: EIP-196. Precompiles for BN254: [https://eips.ethereum.org/EIPS/eip-196](https://eips.ethereum.org/EIPS/eip-196) +[^19]: Intro into zkSNARKs: [https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b](https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b) +[^20]: Zeropool project: [https://zeropool.network/](https://zeropool.network/) +[^21]: Motivation for EIP-2537: [https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders](https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders) +[^22]: NEAR blog post about Roll Ups: [https://near.org/blog/layer-2](https://near.org/blog/layer-2) +[^23]: Ledger post about Roll Ups: [https://www.ledger.com/academy/what-are-blockchain-rollups](https://www.ledger.com/academy/what-are-blockchain-rollups) +[^24]: Precompiles on Aurora: [https://doc.aurora.dev/evm/precompiles/](https://doc.aurora.dev/evm/precompiles/) +[^25]: Pippenger Algorithm: [https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf) +[^26]: NEP-446 proposal for BLS-signature verification precompile: [https://github.com/nearprotocol/neps/pull/446](https://github.com/nearprotocol/neps/pull/446) +[^27]: EIP-1962 EC arithmetic and pairings with runtime definitions: [https://eips.ethereum.org/EIPS/eip-1962](https://eips.ethereum.org/EIPS/eip-1962) +[^28]: Drawbacks of NEP-446: [https://github.com/near/NEPs/pull/446#pullrequestreview-1314601508](https://github.com/near/NEPs/pull/446#pullrequestreview-1314601508) +[^29]: BLS12-381 Milagro: [https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474) +[^30]: BLST: [https://github.com/supranational/blst](https://github.com/supranational/blst), +[^31]: BLST EIP-2537 adaptation: [https://github.com/sean-sn/blst_eip2537](https://github.com/sean-sn/blst_eip2537) +[^32]: EIP-1962 implementation matter labs Rust: https://github.com/matter-labs/eip1962 +[^33]: zCash origin rust implementation: [https://github.com/zcash/zcash/tree/master/src/rust/src](https://github.com/zcash/zcash/tree/master/src/rust/src) +[^34]: MCL library: [https://github.com/herumi/bls](https://github.com/herumi/bls) +[^35]: filecoin/bls-signature: [https://github.com/filecoin-project/bls-signatures](https://github.com/filecoin-project/bls-signatures) +[^36]: zkCrypto: [https://github.com/zkcrypto/bls12_381](https://github.com/zkcrypto/bls12_381), [https://github.com/zkcrypto/pairing](https://github.com/zkcrypto/pairing) +[^37]: BLS12-381 code bases for ETH2.0 client Chia library C++: [https://github.com/Chia-Network/bls-signatures](https://github.com/Chia-Network/bls-signatures) +[^38]: Adjoint Lib: [https://github.com/sdiehl/pairing](https://github.com/sdiehl/pairing) +[^39]: Ethereum Go implementation for EIP-2537: [https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles) +[^40]: Noble JS implementation: [https://github.com/paulmillr/noble-bls12-381](https://github.com/paulmillr/noble-bls12-381) +[^41]: EIP-1962 implementation matter labs Go: https://github.com/kilic/eip2537, +[^42]: EIP-1962 implementation matter labs C++: https://github.com/matter-labs-archive/eip1962_cpp +[^43]: EIP-2537 with links: [https://github.com/matter-labs-forks/EIPs/blob/bls12_381/EIPS/eip-2537.md](https://github.com/matter-labs-forks/EIPs/blob/bls12_381/EIPS/eip-2537.md) +[^44]: Pairing-friendly curves specification, crypto libs: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-cryptographic-libraries](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-cryptographic-libraries) +[^45]: Comparing different libs for pairing-friendly curves: [https://hackmd.io/@gnark/eccbench](https://hackmd.io/@gnark/eccbench) +[^46]: Bench vectors from EIP2537: [https://eips.ethereum.org/assets/eip-2537/bench_vectors](https://eips.ethereum.org/assets/eip-2537/bench_vectors) +[^47]: Metter Labs tests for EIP2537: [https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537) +[^48]: Tests from Go Ethereum implementation: [https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles) +[^49]: EIP-2537 Map To Curve specification: [https://eips.ethereum.org/assets/eip-2537/field_to_curve](https://eips.ethereum.org/assets/eip-2537/field_to_curve) +[^50]: The current implementation of BN254: [https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs](https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs) +[^51]: draft-irtf-cfrg-pairing-friendly-curves-11 [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-) *(*[https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md) → [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04) → this ref*)* +[^52]: Paper with BLS12-381: [https://eprint.iacr.org/2019/403.pdf](https://eprint.iacr.org/2019/403.pdf) +[^53]: Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) +[^54]: Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 +[^55]: Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) From 3ad07e56665075000dae841af492159483834c34 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 18:39:57 +0300 Subject: [PATCH 031/163] 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) From 9c5076575b166d7f8561d1baeafcd151424775e0 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 14 Aug 2023 18:59:28 +0300 Subject: [PATCH 032/163] fix git actions --- neps/nep-0488.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 104caf6b8..83def827f 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -16,14 +16,14 @@ 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][^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 BLS12-381([^1],[^11],[^52]) is a wildly +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], 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][^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. +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]. @@ -482,7 +482,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain ***Tests References:*** -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. +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:*** From 489ef31ad21868a061e74e1d230c03819a6e55fe Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 15 Aug 2023 14:02:59 +0300 Subject: [PATCH 033/163] Light Client -> light client --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 83def827f..aa659059a 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -35,7 +35,7 @@ In this NEP we propose to add the following functions as precompile: - ***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]. - ***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_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] and in EIP-2537[^15]. From bb845d6e586c232eea7d8ee68d9755bd89a0b00d Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 2 Oct 2023 15:00:10 +0300 Subject: [PATCH 034/163] For sum operations support signs --- neps/nep-0488.md | 54 ++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index aa659059a..3b7727c2f 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -29,8 +29,8 @@ 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]. -- ***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_sum —*** the function which adds the signed 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 signed 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]. 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]. @@ -304,10 +304,14 @@ All parameters were taken from[^15][^51] and [^14], all of them consistent betwe ### Curve points encoding -#### bool +#### Bool as output 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]. +#### Sign + +The sign of the point on the elliptic curve is encoded as `u8` type in Rust with two possible values: `0` and `1`. `0` for positive sign, and `1` for negative sign. All other value of `u8` is not allowed and should be interpreted as incorrect. + #### 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], but `big-endian` encoding is used instead of `little-endian` as in EIP-2537[^15]. @@ -439,13 +443,13 @@ The rule of encoding is consistent with zkcrypto[^53] and with implementation in ***Description:*** -The function computes the sum of the elements of the BLS12-381 curve. The input is an arbitrary number of points $p_i \in E(F_p)$, and the output is one point from $E(F_p)$ equal to $\sum p_i$. +The function computes the sum of the signed elements of the BLS12-381 curve. The input is an arbitrary number of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is point on elliptic curve and $s_i \in \textbraceleft 0, 1 \textbraceright$ is the point sign. The output is one point from $E(F_p)$ equal to $\sum (-1)^{s_i}p_i$. -The $E(F_p)$ curve, points on the curve and the addition operation are defined in the BLS12-381 Curve Specification section. +The $E(F_p)$ curve, points on the curve, multiplication on -1, and the addition operation are defined in the BLS12-381 Curve Specification section. Note: we take as input any points on the curve, not only from $G_1$ -***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. ***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. @@ -479,6 +483,10 @@ Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain - Empty input - Generate points on the curve and check that the result doesn’t depend on permutation - Generate points and cross-test the result with multiexp function. +- Correct input with negative signs +- Incorrect sign value (not 0 or 1) +- Correct input with negative signs for points with $y > \frac{p}{2}$ +- Sum of the two equal points with opposite sign ***Tests References:*** @@ -486,21 +494,22 @@ We can use all the tests for addition for Ethereum([^47], [^48]) to check the ca ***Error cases:*** -- The input length is not divided by 96 +- The input length is not divided by 97 - The input is empty - Too much memory is used - Field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve +- The sign value is not 0 or 1 ***Annotation:*** ```rust -/// Computes sum for elements on BLS12-381 curve -/// \sum_i p_i should be the equal result. +/// Computes sum for signed elements on BLS12-381 curve +/// \sum_i (-1)^{s_i} p_i should be the equal result. /// /// # Arguments /// -/// * `value` - sequence of pi points(x:Fp, y:Fp) on BLS-381 curve +/// * `value` - sequence of (pi, si) where pi is point(x:Fp, y:Fp) on BLS-381 curve and si is sign (0 for +, and 1 for -) /// BLS12-381 is Y^2 = X^3 + 4 curve over Fp. /// /// `value` is encoded as packed, big-endian @@ -511,7 +520,7 @@ We can use all the tests for addition for Ethereum([^47], [^48]) to check the ca /// If `value_len + value_ptr` points outside the memory or the registers /// use more memory than the limit, the function returns `MemoryAccessViolation`. /// -/// If point coordinates are not on curve or `value.len()%96 != 0`, +/// If (1) point coordinates are not on curve or (2) `value.len()%97 != 0` or (3) value of sign is not 0 or 1 /// the function returns `BLS12381InvalidInput`. /// /// # Cost @@ -528,13 +537,13 @@ pub fn bls12381_g1_sum(&mut self, ***Description:*** -The function computes the sum of the elements of the BLS12-381 curve. The input is an arbitrary number of points $p_i \in E'(F_{p^2})$, and the output is one point from $E'(F_{p^2})$ equal to $\sum p_i$. +The function computes the sum of the signed elements of the BLS12-381 curve. The input is an arbitrary number of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is point on elliptic curve and $s_i \in \textbraceleft 0, 1 \textbraceright$ is the point sign. The output is one point from $E'(F_{p^2})$ equal to $\sum (-1)^{s_i}p_i$. -The $E'(F_{p^2})$ curve, points on the curve and the addition operation are defined in the BLS12-381 Curve Specification section. +The $E'(F_{p^2})$ curve, points on the curve, multiplication on -1, and the addition operation are defined in the BLS12-381 Curve Specification section. -Note: we take as input any points on the curve, not only from $G_2$ +Note: we take as input any points on the curve, not only from $G_2$ -***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$. Expected `192*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. ***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. @@ -561,32 +570,33 @@ We can use all the tests for addition for Ethereum[^47][^48] to check the case w ***Error cases:*** -- The input length is not divided by 192 +- The input length is not divided by 193 - The input is empty - Too much memory is used - Extension field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve +- The sign value is not 0 or 1 ***Annotation:*** ```rust -/// Computes sum for elements on BLS12-381 curve -/// \sum_i p_i should be the equal result. +/// Computes sum for signed elements on BLS12-381 curve +/// \sum_i (-1)^{s_i} p_i should be the equal result. /// /// # Arguments /// -/// * `value` - sequence of pi points(x:Fp^2, y:Fp^2) on BLS-381 curve +/// * `value` - sequence of (pi, si), where pi is point(x:Fp^2, y:Fp^2) on BLS-381 curve and si is sign (0 for +, 1 for -) /// BLS12-381 is Y^2 = X^3 + 4(i + 1) curve over Fp^2. /// /// `value` is encoded as packed, big-endian -/// `[([u8; 96], [u8; 96])]` slice. +/// `[(([u8; 96], [u8; 96]), u8)]` slice. /// /// # Errors /// /// If `value_len + value_ptr` points outside the memory or the registers /// use more memory than the limit, the function returns `MemoryAccessViolation`. /// -/// If point coordinates are not on curve or `value.len()%192 != 0`, +/// If (1) point coordinates are not on curve or (2) `value.len()%193 != 0` or (3) sign is not 0 or 1, /// the function returns `BLS12381InvalidInput`. /// /// # Cost @@ -1227,7 +1237,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^7]: Specification of pairing friendly curves with a list of applications in the table: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-) [^8]: Specification of pairing friendly curves, the security level for BLS12-381: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1) [^9]: BN2005: [https://eprint.iacr.org/2005/133](https://eprint.iacr.org/2005/133) -[^10]: NEP-98 for BN254 precompile on NEAR: https://github.com/near/NEPs/issues/98 +[^10]: NEP-98 for BN254 precompile on NEAR: [https://github.com/near/NEPs/issues/98](https://github.com/near/NEPs/issues/98) [^11]: BLS12-381 for the Rest of Us: [https://hackmd.io/@benjaminion/bls12-381](https://hackmd.io/@benjaminion/bls12-381) [^12]: BN254 for the Rest of Us: [https://hackmd.io/@jpw/bn254](https://hackmd.io/@jpw/bn254) [^13]: Some analytics of different curve security: [https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security](https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security) From 55f9d993a7913c57b84c2657ccfcc549022d6a89 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 3 Oct 2023 10:27:05 +0300 Subject: [PATCH 035/163] no error on empty input --- neps/nep-0488.md | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 3b7727c2f..b22a2c14e 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -451,7 +451,7 @@ Note: we take as input any points on the curve, not only from $G_1$ ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. -***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. +***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). ***Gas Estimation:*** @@ -495,7 +495,6 @@ We can use all the tests for addition for Ethereum([^47], [^48]) to check the ca ***Error cases:*** - The input length is not divided by 97 -- The input is empty - Too much memory is used - Field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve @@ -545,7 +544,7 @@ Note: we take as input any points on the curve, not only from $G_2$ ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. -***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. +***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). ***Gas Estimation:*** @@ -571,7 +570,6 @@ We can use all the tests for addition for Ethereum[^47][^48] to check the case w ***Error cases:*** - The input length is not divided by 193 -- The input is empty - Too much memory is used - Extension field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve @@ -630,7 +628,7 @@ Note: ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. -***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. +***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). ***Gas Estimation:*** @@ -665,7 +663,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Error cases:*** - The input length is not divided by 128 -- The input is empty - Too much memory is used - Field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve @@ -732,7 +729,7 @@ Note: Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. -***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. +***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). ***Gas Estimation:*** @@ -758,7 +755,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Error cases:*** - The input length is not divided by 224 -- The input is empty - Too much memory is used - Field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve @@ -934,14 +930,14 @@ We need this function to verify BLS signature. This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$ and check: $$ -\sum e(p_i, q_i) = 1 +\prod e(p_i, q_i) = 1 $$ We don’t calculate the pairing function itself: the result will be in the huge field, and in all known applications only such a check is necessary. ***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $G_1 \subset E(F_p)$ — `96 bytes` and point from $G_2 \subset E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. -***Output:*** returns `bool` — the result of the pairing check. The `true` value means that the pairing result is equal to multiplicative identity and `false` otherwise. +***Output:*** returns `bool` — the result of the pairing check. The `true` value means that the pairing result is equal to multiplicative identity and `false` otherwise. For empty input it returns `true`. ***Gas Estimation:*** @@ -966,13 +962,13 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - The points not on the curve - Some points = 0 - The field elements are encoded incorrectly +- Empty input ***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47][^48]. ***Error cases:*** - The input length is not divided by 288 -- The input is empty - Too much memory is used - Field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve @@ -982,7 +978,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. ```rust /// Computes pairing check on BLS12-381 curve. -/// \sum_i e(g_{1 i}, g_{2 i}) should be equal one (in additive notation), e(g1, g2) is pairing +/// \prod_i e(g_{1 i}, g_{2 i}) should be equal one, e(g1, g2) is pairing /// /// # Arguments /// @@ -1049,7 +1045,6 @@ A and B are constants calculated empirically. ***Error cases:*** - The input length is not divided by 48 -- The input is empty - Too much memory is used - Field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve @@ -1124,7 +1119,6 @@ A and B are constants calculated empirically. ***Error cases:*** - The input length is not divided by 96 -- The input is empty - Too much memory is used - Field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve From a24a22671abe312f867d284ee7a390149a22e070 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 12:16:15 +0300 Subject: [PATCH 036/163] Map to curve specification --- neps/nep-0488.md | 257 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 255 insertions(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b22a2c14e..b698936c2 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -302,6 +302,255 @@ x = -0xd201000000010000 All parameters were taken from[^15][^51] and [^14], all of them consistent between sources. +### Map to curve specification +In this section we explain how to map the element $a \in F_p$ to the $G_1 \subset E(F_p)$ and how to map $b \in F_{p^2}$ to the $G_2 \subset E'(F_{p^2})$. +This section will explain how functions `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` work. +It mostly duplicates the correspondent section in EIP-2537[^49]. + +#### Mapping algorithm +The general elliptic curve equation is $y^2 = x^3 + A \cdot x + B$. In our case $A \cdot B = 0$, so the mapping algorithm +will consist of the following steps: +1. Field element($F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ +2. Points from this curve will map to the target curve($E(F_p)$ or $E'(F_{p^2})$) by isomorphism +3. For mapping points to subgroup($G_1$ or $G_2$) the cofactor will be cleared + +First, we will describe the general algorithm and in the next section, we will provide the concrete parameters. + +***Step 1: Map field element to the curve with AB != 0*** +In this section we will describe `map_to_curve_simple_swu(u)` function. +It is simplification of the Shallue-van de Woestijne-Ulas mapping described by Brier et al.[^56], which they call the “simplified SWU” map. +Wahby and Boneh[^57] generalize and optimize this mapping. + +A Weierstrass curve is $y^2 = g(x) = x^3 + A \cdot x + B$, where $A \ne 0$ and $B \ne 0$. + +Constants, which we will define in the following sections: +* $A$, $B$ -- the parameters of Weierstress curve +* $Z$ the element of the field $F$ (in our case $F_p$ or $F_{p^2}$), which meeting the below criteria: + * Z is non-square in F + * $Z \ne -1$ in F + * The polynomial $g(x) - Z$ is irreducible over F + * $g(\frac{B}{Z \cdot A})$ is square in $F$. + +For points $u$ and $-u$ we will get the same $x$-coordinate. We will define the $y$ sign the same as $u$ sign(see the definition of sign in sections `Compressed points on curve $E(F_p)$` and `Compressed points on curve $E'(F_{p^2})$`). + +The case when $Z^2 \cdot u^4 + Z \cdot u^2 = 0$ should be handled separately. In that case set $x_1 = \frac{B}{X \cdot A}$, +which guarantees that $g(x_1)$ is square by the condition on Z given above. + +The algorithm: +``` +fn map_to_curve_simple_swu(u) { + let tv1 = 1 / (Z^2 * u^4 + Z * u^2); + let x1 = (-B / A) * (1 + tv1); + if tv1 == 0 { + x1 = B/(Z*A); + } + + let gx1 = x1^3 + A*x1 + B; + let x2 = Z * u^2 + x1; + let gx2 = x2^3 + A*x2 + B; + let (x, y) = if is_squere(gx1) { + (x1, sqrt(gx1)); + } else { + (x2, sqrt(gx2)); + } + + if sign(u) != sign(y) { + y = -y; + } + + return (x, y); +} + +``` + +***Step 2: Map to target curve*** + +The function `iso_map(x_inner, y_inner)` map the points from isogenous curve E_inner with no-zero coefficients to our +target elliptic curve E. + +Wahby and Boneh[^57] show how to adopt the algorithm for case when elliptic curve have zero A or B. The idea: map +the F element to isogenous elliptic curve E_inner by the method from previous section, and then transform E_inner curve +to our target curve E by knowing isogeny. + +$E_inner$ curve with isogeny will be defined in the "Parameters" section. + +Note that `iso_map` is a group homomorphism. This mean $iso_map(p) + iso_map(q) = iso_map(p + q)$. So, the correspondent optimization can be applied. + +If any denominator in rational functions used in `iso_map` function equal to zero, the `iso_map` function +must return identity point on E. + +***Step 3: Map to subgroup(cofactor cleaning)*** + +In this section we will describe the function `clear_cofactor((x, y))`. This function transfer a point from $E(F_p)$ or $E'(F_{p^2})$ +into a point in $G_1 \subset E(F_p)$ or $G_2 \subset E'(F_{p^2})$ respectively. + +To do that, we should multiply the point on the curve by effective cofactor $h_eff$. Multiplication on $h_eff$ gives the +results in the same subset as multiplication on cofactor, but can be executed must faster. The value of $h_eff$ will be given in +the following sections. + +``` +fn clear_cofactor(P) { + h_eff * P +} + +``` + +***Full algorithm*** + +In this section, the pseudocode for the full mapping algorithm is shown. All the functions are described in the sections above. + +``` +1. (x_inner, y_inner) = map_to_curve_simple_swu(u) # (x_inner, y_inner) is on E_inner - the helper elliptic curve with AB != 0 +2. (x, y) = iso_map(x_inner, y_inner) # (x, y) is on E +3. (x, y) = clear_cofactor((x, y)) # clears cofactor for point (x, y) on E +4. return (x, y) +``` + +#### Parameters + +***Fp-to-G1 mapping*** + +**Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: +* A = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d +* B = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0 +* Z = 11 + +**Step 2:** Isogeny from $E_{inner}$ to curve $E(F_p)$: + +Let's we have the point on $E_{inner}$ with coordinates $(x_{inner}, y_{inner})$ and +we would like to calculate the correspondent coordinates $(x, y) \in E(F_p)$. + +* $x = \frac{x_{num}}{x_{den}}$ where + * $x_{num} = \sum_{i = 0}^{11} k_{1, i} \cdot x_{inner}^i$ + * $x_{den} = x_{inner}^10 + \sum_{i=0}^{9} k_{2, i} \cdot x_{inner}^i$ +* $y = y_{inner} \cdot \frac{y_num}{y_den}$: + * $y_{num} = \sum_{i = 0}^{15} k_{3, i} \cdot x_{inner}^i$ + * $y_{den} = x_{inner}^{15} + \sum_{i = 0}^{14} k_{4, i} \cdot x_{inner}^i$ + +The constants to compute $x_{num}$: +``` +k_(1,0) = 0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7 +k_(1,1) = 0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb +k_(1,2) = 0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0 +k_(1,3) = 0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861 +k_(1,4) = 0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9 +k_(1,5) = 0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983 +k_(1,6) = 0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84 +k_(1,7) = 0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e +k_(1,8) = 0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317 +k_(1,9) = 0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e +k_(1,10) = 0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b +k_(1,11) = 0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229 +``` + +The constants to compute $x_{den}$: +``` +k_(2,0) = 0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c +k_(2,1) = 0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff +k_(2,2) = 0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19 +k_(2,3) = 0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8 +k_(2,4) = 0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e +k_(2,5) = 0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5 +k_(2,6) = 0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a +k_(2,7) = 0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e +k_(2,8) = 0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641 +k_(2,9) = 0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a +``` + +The constants used to compute $y_{num}$: +``` +k_(3,0) = 0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33 +k_(3,1) = 0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696 +k_(3,2) = 0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6 +k_(3,3) = 0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb +k_(3,4) = 0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb +k_(3,5) = 0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0 +k_(3,6) = 0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2 +k_(3,7) = 0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29 +k_(3,8) = 0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587 +k_(3,9) = 0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30 +k_(3,10) = 0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132 +k_(3,11) = 0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e +k_(3,12) = 0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8 +k_(3,13) = 0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133 +k_(3,14) = 0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b +k_(3,15) = 0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604 +``` + +The constants to compute $y_{den}$: +``` +k_(4,0) = 0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1 +k_(4,1) = 0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d +k_(4,2) = 0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2 +k_(4,3) = 0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416 +k_(4,4) = 0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d +k_(4,5) = 0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac +k_(4,6) = 0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c +k_(4,7) = 0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9 +k_(4,8) = 0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a +k_(4,9) = 0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55 +k_(4,10) = 0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8 +k_(4,11) = 0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092 +k_(4,12) = 0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc +k_(4,13) = 0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7 +k_(4,14) = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f +``` + +**Step 3:** Effective cofactor: + * h_eff = 0xd201000000010001 + +***Fp2-to-G2 mapping*** +**Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: +* A = $240 \cdot I$ +* B = $1012 \cdot (1 + I)$ +* Z = $-(2 + I)$ + +Note: $I$ means a non-residue used to make an extension field $F_{p^2}$ + +**Step 2:** Isogeny from $E_{inner}$ to curve $E'(F_{p^2})$: + +Let's we have the point on $E_{inner}$ with coordinates $(x_{inner}, y_{inner})$ and +we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2})$. + +* $x = \frac{x_{num}}{x_{den}}$ where + * $x_{num} = \sum_{i = 0}^{3} k_{1, i} \cdot x_{inner}^i$ + * $x_{den} = x_{inner}^2 + \sum_{i=0}^{1} k_{2, i} \cdot x_{inner}^i$ +* $y = y_{inner} \cdot \frac{y_num}{y_den}$: + * $y_{num} = \sum_{i = 0}^{3} k_{3, i} \cdot x_{inner}^i$ + * $y_{den} = x_{inner}^{3} + \sum_{i = 0}^{2} k_{4, i} \cdot x_{inner}^i$ + +The constants used to compute $x_{num}$ are as follows: +``` +k_(1,0) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 + 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 * I +k_(1,1) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a * I +k_(1,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d * I +k_(1,3) = 0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1 +``` + +The constants used to compute $x_{den}$ are as follows: +``` +k_(2,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63 * I +k_(2,1) = 0xc + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f * I +``` + +The constants used to compute $y_{num}$ are as follows: +``` +k_(3,0) = 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 + 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 * I +k_(3,1) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be * I +k_(3,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f * I +k_(3,3) = 0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10 +``` + +The constants used to compute $y_{den}$ are as follows: +``` +k_(4,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb * I +k_(4,1) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3 * I +k_(4,2) = 0x12 + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99 * I +``` + +**Step 3:** Effective cofactor: +* h_eff = 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551 + ### Curve points encoding #### Bool as output @@ -802,7 +1051,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]. 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 section "Map to curve specification". 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. @@ -859,7 +1108,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]. 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 section "Map to curve specification". 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. @@ -1277,3 +1526,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^53]: Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) [^54]: Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 [^55]: Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) +[^56]: Eric Brier, Jean-Sébastien Coron, Thomas Icart, David Madore, Hugues Randriam, and Mehdi Tibouchi. Efficient indifferentiable hashing into ordinary +elliptic curves. In Tal Rabin, editor, CRYPTO 2010, volume 6223 of LNCS, +pages 237–254. Springer, Heidelberg, August 2010. [https://link.springer.com/chapter/10.1007/978-3-642-14623-7_13](https://link.springer.com/chapter/10.1007/978-3-642-14623-7_13) +[^57]: Wahby, Riad S., and Dan Boneh. "Fast and simple constant-time hashing to the BLS12-381 elliptic curve." Cryptology ePrint Archive (2019). [https://eprint.iacr.org/2019/403](https://eprint.iacr.org/2019/403) From f505f9962973c9ec732f89934265f93d28e7431d Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 12:32:19 +0300 Subject: [PATCH 037/163] clean up --- neps/nep-0488.md | 51 +++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b698936c2..e35291f18 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -310,11 +310,11 @@ It mostly duplicates the correspondent section in EIP-2537[^49]. #### Mapping algorithm The general elliptic curve equation is $y^2 = x^3 + A \cdot x + B$. In our case $A \cdot B = 0$, so the mapping algorithm will consist of the following steps: -1. Field element($F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ +1. Field element(from $F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ 2. Points from this curve will map to the target curve($E(F_p)$ or $E'(F_{p^2})$) by isomorphism 3. For mapping points to subgroup($G_1$ or $G_2$) the cofactor will be cleared -First, we will describe the general algorithm and in the next section, we will provide the concrete parameters. +First, we will describe the general algorithm and, next, we will provide the concrete parameters. ***Step 1: Map field element to the curve with AB != 0*** In this section we will describe `map_to_curve_simple_swu(u)` function. @@ -331,7 +331,7 @@ Constants, which we will define in the following sections: * The polynomial $g(x) - Z$ is irreducible over F * $g(\frac{B}{Z \cdot A})$ is square in $F$. -For points $u$ and $-u$ we will get the same $x$-coordinate. We will define the $y$ sign the same as $u$ sign(see the definition of sign in sections `Compressed points on curve $E(F_p)$` and `Compressed points on curve $E'(F_{p^2})$`). +For points $u$ and $-u$ we will get the same $x$-coordinate. We will define the $y$ sign the same as $u$ sign(see the definition of sign in sections "Compressed points on curve $E(F_p)$" and "Compressed points on curve $E'(F_{p^2})$`)". The case when $Z^2 \cdot u^4 + Z \cdot u^2 = 0$ should be handled separately. In that case set $x_1 = \frac{B}{X \cdot A}$, which guarantees that $g(x_1)$ is square by the condition on Z given above. @@ -372,9 +372,9 @@ Wahby and Boneh[^57] show how to adopt the algorithm for case when elliptic curv the F element to isogenous elliptic curve E_inner by the method from previous section, and then transform E_inner curve to our target curve E by knowing isogeny. -$E_inner$ curve with isogeny will be defined in the "Parameters" section. +E_inner curve with isogeny will be defined in the "Parameters" section. -Note that `iso_map` is a group homomorphism. This mean $iso_map(p) + iso_map(q) = iso_map(p + q)$. So, the correspondent optimization can be applied. +Note that `iso_map` is a group homomorphism. This mean `iso_map(p) + iso_map(q) = iso_map(p + q)`. So, the correspondent optimization can be applied. If any denominator in rational functions used in `iso_map` function equal to zero, the `iso_map` function must return identity point on E. @@ -384,8 +384,8 @@ must return identity point on E. In this section we will describe the function `clear_cofactor((x, y))`. This function transfer a point from $E(F_p)$ or $E'(F_{p^2})$ into a point in $G_1 \subset E(F_p)$ or $G_2 \subset E'(F_{p^2})$ respectively. -To do that, we should multiply the point on the curve by effective cofactor $h_eff$. Multiplication on $h_eff$ gives the -results in the same subset as multiplication on cofactor, but can be executed must faster. The value of $h_eff$ will be given in +To do that, we should multiply the point on the curve by effective cofactor `h_eff`. Multiplication on `h_eff` gives the +results in the same subset as multiplication on cofactor, but can be executed must faster. The value of `h_eff` will be given in the following sections. ``` @@ -415,17 +415,22 @@ In this section, the pseudocode for the full mapping algorithm is shown. All the * B = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0 * Z = 11 -**Step 2:** Isogeny from $E_{inner}$ to curve $E(F_p)$: +**Step 2:** Isogeny from E_inner to curve $E(F_p)$: -Let's we have the point on $E_{inner}$ with coordinates $(x_{inner}, y_{inner})$ and +Let's we have the point on E_inner with coordinates $(x_{inner}, y_{inner})$ and we would like to calculate the correspondent coordinates $(x, y) \in E(F_p)$. * $x = \frac{x_{num}}{x_{den}}$ where - * $x_{num} = \sum_{i = 0}^{11} k_{1, i} \cdot x_{inner}^i$ - * $x_{den} = x_{inner}^10 + \sum_{i=0}^{9} k_{2, i} \cdot x_{inner}^i$ -* $y = y_{inner} \cdot \frac{y_num}{y_den}$: - * $y_{num} = \sum_{i = 0}^{15} k_{3, i} \cdot x_{inner}^i$ - * $y_{den} = x_{inner}^{15} + \sum_{i = 0}^{14} k_{4, i} \cdot x_{inner}^i$ + + * $x_{num} = \Sum_{i = 0}^{11} k_{(1, i)} \cdot x_{inner}^i$ + + * $x_{den} = x_{inner}^{10} + \sum_{i=0}^{9} k_{(2, i)} \cdot x_{inner}^i$ + +* $y = y_{inner} \cdot \frac{y_{num}}{y_{den}}$: + + * $y_{num} = \Sum_{i = 0}^{15} k_{(3, i)} \cdot x_{inner}^i$ + + * $y_{den} = x_{inner}^{15} + \Sum_{i = 0}^{14} k_{(4, i)} \cdot x_{inner}^i$ The constants to compute $x_{num}$: ``` @@ -500,6 +505,7 @@ k_(4,14) = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2 * h_eff = 0xd201000000010001 ***Fp2-to-G2 mapping*** + **Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: * A = $240 \cdot I$ * B = $1012 \cdot (1 + I)$ @@ -507,17 +513,22 @@ k_(4,14) = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2 Note: $I$ means a non-residue used to make an extension field $F_{p^2}$ -**Step 2:** Isogeny from $E_{inner}$ to curve $E'(F_{p^2})$: +**Step 2:** Isogeny from E_inner to curve $E'(F_{p^2})$: -Let's we have the point on $E_{inner}$ with coordinates $(x_{inner}, y_{inner})$ and +Let's we have the point on E_inner with coordinates $(x_{inner}, y_{inner})$ and we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2})$. * $x = \frac{x_{num}}{x_{den}}$ where - * $x_{num} = \sum_{i = 0}^{3} k_{1, i} \cdot x_{inner}^i$ - * $x_{den} = x_{inner}^2 + \sum_{i=0}^{1} k_{2, i} \cdot x_{inner}^i$ + + * $x_{num} = \Sum_{i = 0}^{3} k_{1, i} \cdot x_{inner}^i$ + + * $x_{den} = x_{inner}^2 + \Sum_{i=0}^{1} k_{2, i} \cdot x_{inner}^i$ + * $y = y_{inner} \cdot \frac{y_num}{y_den}$: - * $y_{num} = \sum_{i = 0}^{3} k_{3, i} \cdot x_{inner}^i$ - * $y_{den} = x_{inner}^{3} + \sum_{i = 0}^{2} k_{4, i} \cdot x_{inner}^i$ + + * $y_{num} = \Sum_{i = 0}^{3} k_{3, i} \cdot x_{inner}^i$ + + * $y_{den} = x_{inner}^{3} + \Sum_{i = 0}^{2} k_{4, i} \cdot x_{inner}^i$ The constants used to compute $x_{num}$ are as follows: ``` From 1bdcdd5c8fbdf8d5a035c91052ea6187c0b57a52 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 12:44:22 +0300 Subject: [PATCH 038/163] clean up --- neps/nep-0488.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index e35291f18..56e54fd06 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -311,7 +311,7 @@ It mostly duplicates the correspondent section in EIP-2537[^49]. The general elliptic curve equation is $y^2 = x^3 + A \cdot x + B$. In our case $A \cdot B = 0$, so the mapping algorithm will consist of the following steps: 1. Field element(from $F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ -2. Points from this curve will map to the target curve($E(F_p)$ or $E'(F_{p^2})$) by isomorphism +2. Points from this curve will map to the target curve($E(F_p)$ or $ E'(F_{p^2}) $) by isomorphism 3. For mapping points to subgroup($G_1$ or $G_2$) the cofactor will be cleared First, we will describe the general algorithm and, next, we will provide the concrete parameters. @@ -331,7 +331,7 @@ Constants, which we will define in the following sections: * The polynomial $g(x) - Z$ is irreducible over F * $g(\frac{B}{Z \cdot A})$ is square in $F$. -For points $u$ and $-u$ we will get the same $x$-coordinate. We will define the $y$ sign the same as $u$ sign(see the definition of sign in sections "Compressed points on curve $E(F_p)$" and "Compressed points on curve $E'(F_{p^2})$`)". +For points $u$ and $-u$ we will get the same $x$-coordinate. We will define the $y$ sign the same as $u$ sign(see the definition of sign in sections "Compressed points on curve $E(F_p)$" and "Compressed points on curve $E'(F_{p^2})$)". The case when $Z^2 \cdot u^4 + Z \cdot u^2 = 0$ should be handled separately. In that case set $x_1 = \frac{B}{X \cdot A}$, which guarantees that $g(x_1)$ is square by the condition on Z given above. @@ -422,15 +422,15 @@ we would like to calculate the correspondent coordinates $(x, y) \in E(F_p)$. * $x = \frac{x_{num}}{x_{den}}$ where - * $x_{num} = \Sum_{i = 0}^{11} k_{(1, i)} \cdot x_{inner}^i$ + * $$x_{num} = \sum_{i=0}^{11} k_{(1, i)} \cdot x_{inner}^i$$ - * $x_{den} = x_{inner}^{10} + \sum_{i=0}^{9} k_{(2, i)} \cdot x_{inner}^i$ + * $$x_{den} = x_{inner}^{10} + \sum_{i=0}^{9} k_{(2, i)} \cdot x_{inner}^i$$ * $y = y_{inner} \cdot \frac{y_{num}}{y_{den}}$: - * $y_{num} = \Sum_{i = 0}^{15} k_{(3, i)} \cdot x_{inner}^i$ + * $$y_{num} = \sum_{i=0}^{15} k_{(3, i)} \cdot x_{inner}^i$$ - * $y_{den} = x_{inner}^{15} + \Sum_{i = 0}^{14} k_{(4, i)} \cdot x_{inner}^i$ + * $$y_{den} = x_{inner}^{15} + \sum_{i=0}^{14} k_{(4, i)} \cdot x_{inner}^i$$ The constants to compute $x_{num}$: ``` @@ -520,15 +520,15 @@ we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2}) * $x = \frac{x_{num}}{x_{den}}$ where - * $x_{num} = \Sum_{i = 0}^{3} k_{1, i} \cdot x_{inner}^i$ + * $$x_{num} = \sum_{i = 0}^{3} k_{1, i} \cdot x_{inner}^i$$ - * $x_{den} = x_{inner}^2 + \Sum_{i=0}^{1} k_{2, i} \cdot x_{inner}^i$ + * $$x_{den} = x_{inner}^2 + \sum_{i=0}^{1} k_{2, i} \cdot x_{inner}^i$$ * $y = y_{inner} \cdot \frac{y_num}{y_den}$: - * $y_{num} = \Sum_{i = 0}^{3} k_{3, i} \cdot x_{inner}^i$ + * $$y_{num} = \sum_{i = 0}^{3} k_{3, i} \cdot x_{inner}^i$$ - * $y_{den} = x_{inner}^{3} + \Sum_{i = 0}^{2} k_{4, i} \cdot x_{inner}^i$ + * $$y_{den} = x_{inner}^{3} + \sum_{i = 0}^{2} k_{4, i} \cdot x_{inner}^i$$ The constants used to compute $x_{num}$ are as follows: ``` From 12814238f7d46cc8a9d297c4ba041c4eb866fd83 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 12:51:22 +0300 Subject: [PATCH 039/163] clean up --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 56e54fd06..1d1271c0b 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -311,7 +311,7 @@ It mostly duplicates the correspondent section in EIP-2537[^49]. The general elliptic curve equation is $y^2 = x^3 + A \cdot x + B$. In our case $A \cdot B = 0$, so the mapping algorithm will consist of the following steps: 1. Field element(from $F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ -2. Points from this curve will map to the target curve($E(F_p)$ or $ E'(F_{p^2}) $) by isomorphism +2. Points from this curve will map to the target curve ($E(F_p) or E'(F_{p^2})$) by isomorphism 3. For mapping points to subgroup($G_1$ or $G_2$) the cofactor will be cleared First, we will describe the general algorithm and, next, we will provide the concrete parameters. From c7d9757aa5ea696912497738c485eb54014d7334 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 12:58:14 +0300 Subject: [PATCH 040/163] clean up --- neps/nep-0488.md | 64 ++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 1d1271c0b..c014fd323 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -303,13 +303,16 @@ x = -0xd201000000010000 All parameters were taken from[^15][^51] and [^14], all of them consistent between sources. ### Map to curve specification + In this section we explain how to map the element $a \in F_p$ to the $G_1 \subset E(F_p)$ and how to map $b \in F_{p^2}$ to the $G_2 \subset E'(F_{p^2})$. This section will explain how functions `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` work. It mostly duplicates the correspondent section in EIP-2537[^49]. #### Mapping algorithm + The general elliptic curve equation is $y^2 = x^3 + A \cdot x + B$. In our case $A \cdot B = 0$, so the mapping algorithm will consist of the following steps: + 1. Field element(from $F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ 2. Points from this curve will map to the target curve ($E(F_p) or E'(F_{p^2})$) by isomorphism 3. For mapping points to subgroup($G_1$ or $G_2$) the cofactor will be cleared @@ -324,12 +327,12 @@ Wahby and Boneh[^57] generalize and optimize this mapping. A Weierstrass curve is $y^2 = g(x) = x^3 + A \cdot x + B$, where $A \ne 0$ and $B \ne 0$. Constants, which we will define in the following sections: -* $A$, $B$ -- the parameters of Weierstress curve -* $Z$ the element of the field $F$ (in our case $F_p$ or $F_{p^2}$), which meeting the below criteria: - * Z is non-square in F - * $Z \ne -1$ in F - * The polynomial $g(x) - Z$ is irreducible over F - * $g(\frac{B}{Z \cdot A})$ is square in $F$. +- $A$, $B$ -- the parameters of Weierstress curve +- $Z$ the element of the field $F$ (in our case $F_p$ or $F_{p^2}$), which meeting the below criteria: + - Z is non-square in F + - $Z \ne -1$ in F + - The polynomial $g(x) - Z$ is irreducible over F + - $g(\frac{B}{Z \cdot A})$ is square in $F$. For points $u$ and $-u$ we will get the same $x$-coordinate. We will define the $y$ sign the same as $u$ sign(see the definition of sign in sections "Compressed points on curve $E(F_p)$" and "Compressed points on curve $E'(F_{p^2})$)". @@ -337,6 +340,7 @@ The case when $Z^2 \cdot u^4 + Z \cdot u^2 = 0$ should be handled separately. In which guarantees that $g(x_1)$ is square by the condition on Z given above. The algorithm: + ``` fn map_to_curve_simple_swu(u) { let tv1 = 1 / (Z^2 * u^4 + Z * u^2); @@ -411,28 +415,29 @@ In this section, the pseudocode for the full mapping algorithm is shown. All the ***Fp-to-G1 mapping*** **Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: -* A = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d -* B = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0 -* Z = 11 +- A = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d +- B = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0 +- Z = 11 **Step 2:** Isogeny from E_inner to curve $E(F_p)$: Let's we have the point on E_inner with coordinates $(x_{inner}, y_{inner})$ and we would like to calculate the correspondent coordinates $(x, y) \in E(F_p)$. -* $x = \frac{x_{num}}{x_{den}}$ where +- $x = \frac{x_{num}}{x_{den}}$ where - * $$x_{num} = \sum_{i=0}^{11} k_{(1, i)} \cdot x_{inner}^i$$ + $$x_{num} = \sum_{i=0}^{11} k_{(1, i)} \cdot x_{inner}^i$$ - * $$x_{den} = x_{inner}^{10} + \sum_{i=0}^{9} k_{(2, i)} \cdot x_{inner}^i$$ + $$x_{den} = x_{inner}^{10} + \sum_{i=0}^{9} k_{(2, i)} \cdot x_{inner}^i$$ -* $y = y_{inner} \cdot \frac{y_{num}}{y_{den}}$: +- $y = y_{inner} \cdot \frac{y_{num}}{y_{den}}$: - * $$y_{num} = \sum_{i=0}^{15} k_{(3, i)} \cdot x_{inner}^i$$ + $$y_{num} = \sum_{i=0}^{15} k_{(3, i)} \cdot x_{inner}^i$$ - * $$y_{den} = x_{inner}^{15} + \sum_{i=0}^{14} k_{(4, i)} \cdot x_{inner}^i$$ + $$y_{den} = x_{inner}^{15} + \sum_{i=0}^{14} k_{(4, i)} \cdot x_{inner}^i$$ The constants to compute $x_{num}$: + ``` k_(1,0) = 0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7 k_(1,1) = 0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb @@ -449,6 +454,7 @@ k_(1,11) = 0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b ``` The constants to compute $x_{den}$: + ``` k_(2,0) = 0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c k_(2,1) = 0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff @@ -463,6 +469,7 @@ k_(2,9) = 0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174 ``` The constants used to compute $y_{num}$: + ``` k_(3,0) = 0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33 k_(3,1) = 0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696 @@ -483,6 +490,7 @@ k_(3,15) = 0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b66 ``` The constants to compute $y_{den}$: + ``` k_(4,0) = 0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1 k_(4,1) = 0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d @@ -502,14 +510,14 @@ k_(4,14) = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2 ``` **Step 3:** Effective cofactor: - * h_eff = 0xd201000000010001 +- h_eff = 0xd201000000010001 ***Fp2-to-G2 mapping*** **Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: -* A = $240 \cdot I$ -* B = $1012 \cdot (1 + I)$ -* Z = $-(2 + I)$ +- A = $240 \cdot I$ +- B = $1012 \cdot (1 + I)$ +- Z = $-(2 + I)$ Note: $I$ means a non-residue used to make an extension field $F_{p^2}$ @@ -518,19 +526,20 @@ Note: $I$ means a non-residue used to make an extension field $F_{p^2}$ Let's we have the point on E_inner with coordinates $(x_{inner}, y_{inner})$ and we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2})$. -* $x = \frac{x_{num}}{x_{den}}$ where +- $x = \frac{x_{num}}{x_{den}}$ where - * $$x_{num} = \sum_{i = 0}^{3} k_{1, i} \cdot x_{inner}^i$$ + $$x_{num} = \sum_{i = 0}^{3} k_{1, i} \cdot x_{inner}^i$$ - * $$x_{den} = x_{inner}^2 + \sum_{i=0}^{1} k_{2, i} \cdot x_{inner}^i$$ + $$x_{den} = x_{inner}^2 + \sum_{i=0}^{1} k_{2, i} \cdot x_{inner}^i$$ -* $y = y_{inner} \cdot \frac{y_num}{y_den}$: +- $y = y_{inner} \cdot \frac{y_num}{y_den}$: - * $$y_{num} = \sum_{i = 0}^{3} k_{3, i} \cdot x_{inner}^i$$ + $$y_{num} = \sum_{i = 0}^{3} k_{3, i} \cdot x_{inner}^i$$ - * $$y_{den} = x_{inner}^{3} + \sum_{i = 0}^{2} k_{4, i} \cdot x_{inner}^i$$ + $$y_{den} = x_{inner}^{3} + \sum_{i = 0}^{2} k_{4, i} \cdot x_{inner}^i$$ The constants used to compute $x_{num}$ are as follows: + ``` k_(1,0) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 + 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 * I k_(1,1) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a * I @@ -539,12 +548,14 @@ k_(1,3) = 0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098 ``` The constants used to compute $x_{den}$ are as follows: + ``` k_(2,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63 * I k_(2,1) = 0xc + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f * I ``` The constants used to compute $y_{num}$ are as follows: + ``` k_(3,0) = 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 + 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 * I k_(3,1) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be * I @@ -553,6 +564,7 @@ k_(3,3) = 0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79 ``` The constants used to compute $y_{den}$ are as follows: + ``` k_(4,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb * I k_(4,1) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3 * I @@ -560,7 +572,7 @@ k_(4,2) = 0x12 + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f ``` **Step 3:** Effective cofactor: -* h_eff = 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551 +- h_eff = 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551 ### Curve points encoding From 8e091ddda8b543fe83e9332103b126cbae7838ca Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 13:02:17 +0300 Subject: [PATCH 041/163] clean up --- neps/nep-0488.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index c014fd323..7ba8e252c 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -327,6 +327,7 @@ Wahby and Boneh[^57] generalize and optimize this mapping. A Weierstrass curve is $y^2 = g(x) = x^3 + A \cdot x + B$, where $A \ne 0$ and $B \ne 0$. Constants, which we will define in the following sections: + - $A$, $B$ -- the parameters of Weierstress curve - $Z$ the element of the field $F$ (in our case $F_p$ or $F_{p^2}$), which meeting the below criteria: - Z is non-square in F @@ -341,7 +342,7 @@ which guarantees that $g(x_1)$ is square by the condition on Z given above. The algorithm: -``` +```text fn map_to_curve_simple_swu(u) { let tv1 = 1 / (Z^2 * u^4 + Z * u^2); let x1 = (-B / A) * (1 + tv1); @@ -392,7 +393,7 @@ To do that, we should multiply the point on the curve by effective cofactor `h_e results in the same subset as multiplication on cofactor, but can be executed must faster. The value of `h_eff` will be given in the following sections. -``` +```text fn clear_cofactor(P) { h_eff * P } @@ -403,7 +404,7 @@ fn clear_cofactor(P) { In this section, the pseudocode for the full mapping algorithm is shown. All the functions are described in the sections above. -``` +```text 1. (x_inner, y_inner) = map_to_curve_simple_swu(u) # (x_inner, y_inner) is on E_inner - the helper elliptic curve with AB != 0 2. (x, y) = iso_map(x_inner, y_inner) # (x, y) is on E 3. (x, y) = clear_cofactor((x, y)) # clears cofactor for point (x, y) on E @@ -438,7 +439,7 @@ we would like to calculate the correspondent coordinates $(x, y) \in E(F_p)$. The constants to compute $x_{num}$: -``` +```text k_(1,0) = 0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7 k_(1,1) = 0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb k_(1,2) = 0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0 @@ -455,7 +456,7 @@ k_(1,11) = 0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b The constants to compute $x_{den}$: -``` +```text k_(2,0) = 0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c k_(2,1) = 0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff k_(2,2) = 0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19 @@ -470,7 +471,7 @@ k_(2,9) = 0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174 The constants used to compute $y_{num}$: -``` +```text k_(3,0) = 0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33 k_(3,1) = 0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696 k_(3,2) = 0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6 @@ -491,7 +492,7 @@ k_(3,15) = 0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b66 The constants to compute $y_{den}$: -``` +```text k_(4,0) = 0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1 k_(4,1) = 0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d k_(4,2) = 0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2 @@ -510,11 +511,13 @@ k_(4,14) = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2 ``` **Step 3:** Effective cofactor: + - h_eff = 0xd201000000010001 ***Fp2-to-G2 mapping*** **Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: + - A = $240 \cdot I$ - B = $1012 \cdot (1 + I)$ - Z = $-(2 + I)$ @@ -540,7 +543,7 @@ we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2}) The constants used to compute $x_{num}$ are as follows: -``` +```text k_(1,0) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 + 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 * I k_(1,1) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a * I k_(1,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d * I @@ -549,14 +552,14 @@ k_(1,3) = 0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098 The constants used to compute $x_{den}$ are as follows: -``` +```text k_(2,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63 * I k_(2,1) = 0xc + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f * I ``` The constants used to compute $y_{num}$ are as follows: -``` +```text k_(3,0) = 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 + 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 * I k_(3,1) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be * I k_(3,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f * I @@ -565,13 +568,14 @@ k_(3,3) = 0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79 The constants used to compute $y_{den}$ are as follows: -``` +```text k_(4,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb * I k_(4,1) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3 * I k_(4,2) = 0x12 + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99 * I ``` **Step 3:** Effective cofactor: + - h_eff = 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551 ### Curve points encoding From c914a0f18a275cb12d932b6bff8bc955010cc8b9 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 13:05:09 +0300 Subject: [PATCH 042/163] clean up --- neps/nep-0488.md | 1 + 1 file changed, 1 insertion(+) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 7ba8e252c..1ec67bb73 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -416,6 +416,7 @@ In this section, the pseudocode for the full mapping algorithm is shown. All the ***Fp-to-G1 mapping*** **Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: + - A = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d - B = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0 - Z = 11 From 0e9b7b9efaccc3036af44e8eaebb5278db1447c7 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 22:17:03 +0300 Subject: [PATCH 043/163] fix code and math formating --- neps/nep-0488.md | 265 ++++++++++++++++++++--------------------------- 1 file changed, 112 insertions(+), 153 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 1ec67bb73..2bb2ed625 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -63,11 +63,9 @@ In the case of BLS12-381 equation is $y^2 \equiv x^3 + 4 \mod p$[^15][^51][^14][ **Parameters for our case:** -```rust -A = 0 -B = 4 -p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab -``` +- $A = 0$ +- $B = 4$ +- $p = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787$ **Definition:** Let’s $P \in E(F_q)$ have coordinates (x, y), define $-P$ as a point on a curve with coordinates (x, -y). @@ -100,13 +98,11 @@ Notation: $H \subseteq G$ 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 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][^51]: -```rust -Main subgroup order r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 -``` +- $r = 52435875175126190479447740508185965837690552500527637822603658699938581184513$ #### Field extension @@ -175,24 +171,21 @@ 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][^51]: -```rust -G1: -X = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb -Y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1 -``` +$G_1$: +- $x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507$ +- $y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569$ For $(x', y') \in G_2 \subset E'(F_{p^2}):$ $$x' = x_0 + x_1u$$ $$y' = y_0 + y_1u$$ -```rust -G2: -x0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8 -x1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e -y0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801 -y1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be -``` +$G_2$: +- $x_0 = 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160$ +- $x_1 = 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758$ +- $y_0 = 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905$ +- $y_1 = 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582$ + **Definition:** ***Cofactor*** is the ratio of the size of the whole group G to the size of subgroup H: @@ -202,15 +195,11 @@ $$ Cofactor $G_1\colon h = |E(F_p)|/r$[^51] -```rust -h = 0x396c8c005555e1568c00aaab0000aaab -``` +$$h = 76329603384216526031706109802092473003$$ Cofactor $G_2\colon h' = |E'(F_{p^2})|/r$[^51] -```rust -h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 -``` +$$h' = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109$$ #### Pairing @@ -223,9 +212,7 @@ The main pairing properties is: For calculating this function we will need the algorithm, called Miller Loop, and to effectively perform this algorithm we will need to know the key parameter for BLS curve $x$ -```rust -x = -0xd201000000010000 -``` +$$ x = -15132376222941642752$$ You can find this parameter in: @@ -238,9 +225,7 @@ You can find this parameter in: The parameters for the BLS12-381: -```rust -Base field modulus p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab -``` +Base field modulus $p = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787$ $$ E\colon y^2 \equiv x^3 + 4 @@ -250,9 +235,7 @@ $$ E'\colon y^2 \equiv x^3 + 4(u + 1) $$ -```rust -Main subgroup order r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 -``` +Main subgroup order $r = 52435875175126190479447740508185965837690552500527637822603658699938581184513$ $$ F_{p^2} = F_p[u] / (u^2 + 1) @@ -268,37 +251,25 @@ $$ Generator for G1: -```rust -X = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb -Y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1 -``` +- $x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507$ +- $y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569$ Generator for G2: -```rust -x0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8 -x1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e -y0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801 -y1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be -``` +- $x_0 = 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160$ +- $x_1 = 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758$ +- $y_0 = 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905$ +- $y_1 = 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582$ -Cofactor for G1: -```rust -h = 0x396c8c005555e1568c00aaab0000aaab -``` +Cofactor for G1: +$$h = 76329603384216526031706109802092473003$$ Cofactor for G2: - -```rust -h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5 -``` +$$h' = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109$$ Key BLS12-381 parameter used in Miller Loop: - -```rust -x = -0xd201000000010000 -``` +$$x = -15132376222941642752$$ All parameters were taken from[^15][^51] and [^14], all of them consistent between sources. @@ -313,13 +284,14 @@ It mostly duplicates the correspondent section in EIP-2537[^49]. The general elliptic curve equation is $y^2 = x^3 + A \cdot x + B$. In our case $A \cdot B = 0$, so the mapping algorithm will consist of the following steps: -1. Field element(from $F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ -2. Points from this curve will map to the target curve ($E(F_p) or E'(F_{p^2})$) by isomorphism -3. For mapping points to subgroup($G_1$ or $G_2$) the cofactor will be cleared +1. Field element (from $F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ +2. Points from this curve will map to the target curve ($E(F_p)$ or $E'(F_{p^2})$) by isomorphism +3. For mapping points to subgroup ($G_1$ or $G_2$) the cofactor will be cleared First, we will describe the general algorithm and, next, we will provide the concrete parameters. ***Step 1: Map field element to the curve with AB != 0*** + In this section we will describe `map_to_curve_simple_swu(u)` function. It is simplification of the Shallue-van de Woestijne-Ulas mapping described by Brier et al.[^56], which they call the “simplified SWU” map. Wahby and Boneh[^57] generalize and optimize this mapping. @@ -417,8 +389,8 @@ In this section, the pseudocode for the full mapping algorithm is shown. All the **Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: -- A = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d -- B = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0 +- $A = 12190336318893619529228877361869031420615612348429846051986726275283378313155663745811710833465465981901188123677$ +- $B = 2906670324641927570491258158026293881577086121416628140204402091718288198173574630967936031029026176254968826637280$ - Z = 11 **Step 2:** Isogeny from E_inner to curve $E(F_p)$: @@ -440,80 +412,74 @@ we would like to calculate the correspondent coordinates $(x, y) \in E(F_p)$. The constants to compute $x_{num}$: -```text -k_(1,0) = 0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7 -k_(1,1) = 0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb -k_(1,2) = 0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0 -k_(1,3) = 0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861 -k_(1,4) = 0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9 -k_(1,5) = 0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983 -k_(1,6) = 0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84 -k_(1,7) = 0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e -k_(1,8) = 0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317 -k_(1,9) = 0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e -k_(1,10) = 0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b -k_(1,11) = 0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229 -``` +- $k_{(1,0)} = 2712959285290305970661081772124144179193819192423276218370281158706191519995889425075952244140278856085036081760695$ +- $k_{(1,1)} = 3564859427549639835253027846704205725951033235539816243131874237388832081954622352624080767121604606753339903542203$ +- $k_{(1,2)} = 2051387046688339481714726479723076305756384619135044672831882917686431912682625619320120082313093891743187631791280$ +- $k_{(1,3)} = 3612713941521031012780325893181011392520079402153354595775735142359240110423346445050803899623018402874731133626465$ +- $k_{(1,4)} = 2247053637822768981792833880270996398470828564809439728372634811976089874056583714987807553397615562273407692740057$ +- $k_{(1,5)} = 3415427104483187489859740871640064348492611444552862448295571438270821994900526625562705192993481400731539293415811$ +- $k_{(1,6)} = 2067521456483432583860405634125513059912765526223015704616050604591207046392807563217109432457129564962571408764292$ +- $k_{(1,7)} = 3650721292069012982822225637849018828271936405382082649291891245623305084633066170122780668657208923883092359301262$ +- $k_{(1,8)} = 1239271775787030039269460763652455868148971086016832054354147730155061349388626624328773377658494412538595239256855$ +- $k_{(1,9)} = 3479374185711034293956731583912244564891370843071137483962415222733470401948838363051960066766720884717833231600798$ +- $k_{(1,10)} = 2492756312273161536685660027440158956721981129429869601638362407515627529461742974364729223659746272460004902959995$ +- $k_{(1,11)} = 1058488477413994682556770863004536636444795456512795473806825292198091015005841418695586811009326456605062948114985$ The constants to compute $x_{den}$: -```text -k_(2,0) = 0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c -k_(2,1) = 0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff -k_(2,2) = 0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19 -k_(2,3) = 0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8 -k_(2,4) = 0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e -k_(2,5) = 0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5 -k_(2,6) = 0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a -k_(2,7) = 0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e -k_(2,8) = 0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641 -k_(2,9) = 0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a -``` +- $k_{(2,0)} = 1353092447850172218905095041059784486169131709710991428415161466575141675351394082965234118340787683181925558786844$ +- $k_{(2,1)} = 2822220997908397120956501031591772354860004534930174057793539372552395729721474912921980407622851861692773516917759$ +- $k_{(2,2)} = 1717937747208385987946072944131378949849282930538642983149296304709633281382731764122371874602115081850953846504985$ +- $k_{(2,3)} = 501624051089734157816582944025690868317536915684467868346388760435016044027032505306995281054569109955275640941784$ +- $k_{(2,4)} = 3025903087998593826923738290305187197829899948335370692927241015584233559365859980023579293766193297662657497834014$ +- $k_{(2,5)} = 2224140216975189437834161136818943039444741035168992629437640302964164227138031844090123490881551522278632040105125$ +- $k_{(2,6)} = 1146414465848284837484508420047674663876992808692209238763293935905506532411661921697047880549716175045414621825594$ +- $k_{(2,7)} = 3179090966864399634396993677377903383656908036827452986467581478509513058347781039562481806409014718357094150199902$ +- $k_{(2,8)} = 1549317016540628014674302140786462938410429359529923207442151939696344988707002602944342203885692366490121021806145$ +- $k_{(2,9)} = 1442797143427491432630626390066422021593505165588630398337491100088557278058060064930663878153124164818522816175370$ + The constants used to compute $y_{num}$: -```text -k_(3,0) = 0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33 -k_(3,1) = 0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696 -k_(3,2) = 0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6 -k_(3,3) = 0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb -k_(3,4) = 0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb -k_(3,5) = 0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0 -k_(3,6) = 0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2 -k_(3,7) = 0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29 -k_(3,8) = 0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587 -k_(3,9) = 0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30 -k_(3,10) = 0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132 -k_(3,11) = 0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e -k_(3,12) = 0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8 -k_(3,13) = 0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133 -k_(3,14) = 0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b -k_(3,15) = 0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604 -``` +- $k_{(3,0)} = 1393399195776646641963150658816615410692049723305861307490980409834842911816308830479576739332720113414154429643571$ +- $k_{(3,1)} = 2968610969752762946134106091152102846225411740689724909058016729455736597929366401532929068084731548131227395540630$ +- $k_{(3,2)} = 122933100683284845219599644396874530871261396084070222155796123161881094323788483360414289333111221370374027338230$ +- $k_{(3,3)} = 303251954782077855462083823228569901064301365507057490567314302006681283228886645653148231378803311079384246777035$ +- $k_{(3,4)} = 1353972356724735644398279028378555627591260676383150667237975415318226973994509601413730187583692624416197017403099$ +- $k_{(3,5)} = 3443977503653895028417260979421240655844034880950251104724609885224259484262346958661845148165419691583810082940400$ +- $k_{(3,6)} = 718493410301850496156792713845282235942975872282052335612908458061560958159410402177452633054233549648465863759602$ +- $k_{(3,7)} = 1466864076415884313141727877156167508644960317046160398342634861648153052436926062434809922037623519108138661903145$ +- $k_{(3,8)} = 1536886493137106337339531461344158973554574987550750910027365237255347020572858445054025958480906372033954157667719$ +- $k_{(3,9)} = 2171468288973248519912068884667133903101171670397991979582205855298465414047741472281361964966463442016062407908400$ +- $k_{(3,10)} = 3915937073730221072189646057898966011292434045388986394373682715266664498392389619761133407846638689998746172899634$ +- $k_{(3,11)} = 3802409194827407598156407709510350851173404795262202653149767739163117554648574333789388883640862266596657730112910$ +- $k_{(3,12)} = 1707589313757812493102695021134258021969283151093981498394095062397393499601961942449581422761005023512037430861560$ +- $k_{(3,13)} = 349697005987545415860583335313370109325490073856352967581197273584891698473628451945217286148025358795756956811571$ +- $k_{(3,14)} = 885704436476567581377743161796735879083481447641210566405057346859953524538988296201011389016649354976986251207243$ +- $k_{(3,15)} = 3370924952219000111210625390420697640496067348723987858345031683392215988129398381698161406651860675722373763741188$ + The constants to compute $y_{den}$: -```text -k_(4,0) = 0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1 -k_(4,1) = 0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d -k_(4,2) = 0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2 -k_(4,3) = 0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416 -k_(4,4) = 0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d -k_(4,5) = 0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac -k_(4,6) = 0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c -k_(4,7) = 0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9 -k_(4,8) = 0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a -k_(4,9) = 0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55 -k_(4,10) = 0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8 -k_(4,11) = 0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092 -k_(4,12) = 0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc -k_(4,13) = 0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7 -k_(4,14) = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f -``` +- $k_{(4,0)} = 3396434800020507717552209507749485772788165484415495716688989613875369612529138640646200921379825018840894888371137$ +- $k_{(4,1)} = 3907278185868397906991868466757978732688957419873771881240086730384895060595583602347317992689443299391009456758845$ +- $k_{(4,2)} = 854914566454823955479427412036002165304466268547334760894270240966182605542146252771872707010378658178126128834546$ +- $k_{(4,3)} = 3496628876382137961119423566187258795236027183112131017519536056628828830323846696121917502443333849318934945158166$ +- $k_{(4,4)} = 1828256966233331991927609917644344011503610008134915752990581590799656305331275863706710232159635159092657073225757$ +- $k_{(4,5)} = 1362317127649143894542621413133849052553333099883364300946623208643344298804722863920546222860227051989127113848748$ +- $k_{(4,6)} = 3443845896188810583748698342858554856823966611538932245284665132724280883115455093457486044009395063504744802318172$ +- $k_{(4,7)} = 3484671274283470572728732863557945897902920439975203610275006103818288159899345245633896492713412187296754791689945$ +- $k_{(4,8)} = 3755735109429418587065437067067640634211015783636675372165599470771975919172394156249639331555277748466603540045130$ +- $k_{(4,9)} = 3459661102222301807083870307127272890283709299202626530836335779816726101522661683404130556379097384249447658110805$ +- $k_{(4,10)} = 742483168411032072323733249644347333168432665415341249073150659015707795549260947228694495111018381111866512337576$ +- $k_{(4,11)} = 1662231279858095762833829698537304807741442669992646287950513237989158777254081548205552083108208170765474149568658$ +- $k_{(4,12)} = 1668238650112823419388205992952852912407572045257706138925379268508860023191233729074751042562151098884528280913356$ +- $k_{(4,13)} = 369162719928976119195087327055926326601627748362769544198813069133429557026740823593067700396825489145575282378487$ +- $k_{(4,14)} = 2164195715141237148945939585099633032390257748382945597506236650132835917087090097395995817229686247227784224263055$ **Step 3:** Effective cofactor: -- h_eff = 0xd201000000010001 +$$h_{eff} = 15132376222941642753$$ ***Fp2-to-G2 mapping*** @@ -544,40 +510,33 @@ we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2}) The constants used to compute $x_{num}$ are as follows: -```text -k_(1,0) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 + 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 * I -k_(1,1) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a * I -k_(1,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d * I -k_(1,3) = 0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1 -``` + +- $k_(1,0) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 + 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 \cdot I$ +- $k_(1,1) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522 \cdot I$ +- $k_(1,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261 \cdot I$ +- $k_(1,3) = 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033$ The constants used to compute $x_{den}$ are as follows: -```text -k_(2,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63 * I -k_(2,1) = 0xc + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f * I -``` +- $k_(2,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715 \cdot I$ +- $k_(2,1) = 12 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775 \cdot I$ The constants used to compute $y_{num}$ are as follows: -```text -k_(3,0) = 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 + 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 * I -k_(3,1) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be * I -k_(3,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f * I -k_(3,3) = 0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10 -``` +- $k_(3,0) = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 + 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I$ +- $k_(3,1) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$ +- $k_(3,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263 \cdot I$ +- $k_(3,3) = 2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776$ The constants used to compute $y_{den}$ are as follows: -```text -k_(4,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb * I -k_(4,1) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3 * I -k_(4,2) = 0x12 + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99 * I -``` +- $k_(4,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 \cdot I$ +- $k_(4,1) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571 \cdot I$ +- $k_(4,2) = 18 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769 \cdot I$ **Step 3:** Effective cofactor: -- h_eff = 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551 +- $h_{eff} = 209869847837335686905080341498658477663839067235703451875306851526599783796572738804459333109033834234622528588876978987822447936461846631641690358257586228683615991308971558879306463436166481$ ### Curve points encoding @@ -593,13 +552,13 @@ The sign of the point on the elliptic curve is encoded as `u8` type in Rust with 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$ +#### Fields elements Fp 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], with implementation in milagro lib[^29]. -#### Extension fields elements $F_{p^2}$ +#### Extension fields elements Fp2 The $q \in F_{p^{2}}$ could be written as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$ The element from $F_{p^2}$ encoded in `[u8; 96]` as a bytes’ concatenation of $c_1$ and $c_0$. The $c_1$ and $c_0$ are encoded by the rule described in the previous section. @@ -610,7 +569,7 @@ $q \in F_{p^2}$, $q = c_0 + c_1 v$ encoded as `[u8; 96]`: The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. -#### Uncompressed points on curve $E(F_p)$ +#### Uncompressed points on curve E(Fp) The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ encoded in `[u8; 96]` as bytes’ concatenation of `x` and `y` point coordinates, where $x, y \in F_p$. The $x, y$ are encoded according to the rules described in the section “Fields elements $F_p$” . @@ -630,7 +589,7 @@ x[0] = x[0] | 0x40; The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. -#### Compressed points on curve $E(F_p)$ +#### Compressed points on curve E(Fp) The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ in compressed form are encoded in `[u8; 48]` as *big-endian* encoded $x \in F_p$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. @@ -660,7 +619,7 @@ x[0] = x[0] | 0x40; 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})$ +#### Uncompressed points on twisted curve E'(Fp2) The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ encoded in `[u8; 192]` as bytes’ concatenation of `x` and `y` point coordinates, where $x, y \in F_{p^2}$. The $x, y$ are encoded according to the rules described in the section “Extension fields elements $F_{p^2}$” . @@ -684,7 +643,7 @@ x[0] = x[0] | 0x40; The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. -#### Compressed points on twisted curve $E'(F_{p2})$ +#### Compressed points on twisted curve E'(Fp2) The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ in compressed form are encoded in `[u8; 96]` as *big-endian* encoded $x \in F_{p^2}$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. From e29997830e595c55dc5b0e4656fc3dd78989aec3 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 22:19:44 +0300 Subject: [PATCH 044/163] clean up --- neps/nep-0488.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 2bb2ed625..5f376842e 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -172,6 +172,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][^51]: $G_1$: + - $x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507$ - $y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569$ @@ -181,6 +182,7 @@ $$x' = x_0 + x_1u$$ $$y' = y_0 + y_1u$$ $G_2$: + - $x_0 = 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160$ - $x_1 = 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758$ - $y_0 = 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905$ From cb8f1840c2ea4aac4606e78b4d570e9d23a81c66 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 22:31:49 +0300 Subject: [PATCH 045/163] try fix formating --- neps/nep-0488.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 5f376842e..3eb276a57 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -268,7 +268,8 @@ Cofactor for G1: $$h = 76329603384216526031706109802092473003$$ Cofactor for G2: -$$h' = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109$$ +$$h' = 30550233393126834420099975319312150421446601925418814266766403298226760418297188402650742735925997784783227283904\\ +1616661285803823378372096355777062779109$$ Key BLS12-381 parameter used in Miller Loop: $$x = -15132376222941642752$$ @@ -287,7 +288,7 @@ The general elliptic curve equation is $y^2 = x^3 + A \cdot x + B$. In our case will consist of the following steps: 1. Field element (from $F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ -2. Points from this curve will map to the target curve ($E(F_p)$ or $E'(F_{p^2})$) by isomorphism +2. Points from this curve will map to the target curve (E(Fp) or E'(Fp2)) by isomorphism 3. For mapping points to subgroup ($G_1$ or $G_2$) the cofactor will be cleared First, we will describe the general algorithm and, next, we will provide the concrete parameters. @@ -309,7 +310,7 @@ Constants, which we will define in the following sections: - The polynomial $g(x) - Z$ is irreducible over F - $g(\frac{B}{Z \cdot A})$ is square in $F$. -For points $u$ and $-u$ we will get the same $x$-coordinate. We will define the $y$ sign the same as $u$ sign(see the definition of sign in sections "Compressed points on curve $E(F_p)$" and "Compressed points on curve $E'(F_{p^2})$)". +For points $u$ and $-u$ we will get the same $x$-coordinate. We will define the $y$ sign the same as $u$ sign(see the definition of sign in sections "Compressed points on curve E(Fp)" and "Compressed points on curve E'(Fp2))". The case when $Z^2 \cdot u^4 + Z \cdot u^2 = 0$ should be handled separately. In that case set $x_1 = \frac{B}{X \cdot A}$, which guarantees that $g(x_1)$ is square by the condition on Z given above. @@ -513,9 +514,11 @@ we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2}) The constants used to compute $x_{num}$ are as follows: -- $k_(1,0) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 + 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 \cdot I$ +- $k_(1,0) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 +\\ + 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 \cdot I$ - $k_(1,1) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522 \cdot I$ -- $k_(1,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261 \cdot I$ +- $k_(1,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 +\\ + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261 \cdot I$ - $k_(1,3) = 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033$ The constants used to compute $x_{den}$ are as follows: @@ -525,20 +528,24 @@ The constants used to compute $x_{den}$ are as follows: The constants used to compute $y_{num}$ are as follows: -- $k_(3,0) = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 + 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I$ +- $k_(3,0) = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 +\\ + 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I$ - $k_(3,1) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$ -- $k_(3,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263 \cdot I$ +- $k_(3,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 +\\ + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263 \cdot I$ - $k_(3,3) = 2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776$ The constants used to compute $y_{den}$ are as follows: -- $k_(4,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 \cdot I$ +- $k_(4,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 +\\ + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 \cdot I$ - $k_(4,1) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571 \cdot I$ - $k_(4,2) = 18 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769 \cdot I$ **Step 3:** Effective cofactor: -- $h_{eff} = 209869847837335686905080341498658477663839067235703451875306851526599783796572738804459333109033834234622528588876978987822447936461846631641690358257586228683615991308971558879306463436166481$ +- $h_{eff} = 2098698478373356869050803414986584776638390672357034518753068515265997837965727388044593331090338342346225\\ + 28588876978987822447936461846631641690358257586228683615991308971558879306463436166481$ ### Curve points encoding From 776f427aa3ad260bff8ea7505bd6e19afe2c92d1 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 22:35:24 +0300 Subject: [PATCH 046/163] try fix formating --- neps/nep-0488.md | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 3eb276a57..c6f4e8e8a 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -513,39 +513,37 @@ we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2}) The constants used to compute $x_{num}$ are as follows: - -- $k_(1,0) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 +\\ - 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 \cdot I$ -- $k_(1,1) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522 \cdot I$ -- $k_(1,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 +\\ - 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261 \cdot I$ -- $k_(1,3) = 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033$ +$$k_(1,0) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 + + 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 \cdot I$$ +$$k_(1,1) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522 \cdot I$$ +$$k_(1,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 + + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261 \cdot I$$ +$$k_(1,3) = 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033$$ The constants used to compute $x_{den}$ are as follows: -- $k_(2,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715 \cdot I$ -- $k_(2,1) = 12 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775 \cdot I$ +$$k_(2,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715 \cdot I$$ +$$k_(2,1) = 12 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775 \cdot I$$ The constants used to compute $y_{num}$ are as follows: -- $k_(3,0) = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 +\\ - 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I$ -- $k_(3,1) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$ -- $k_(3,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 +\\ - 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263 \cdot I$ -- $k_(3,3) = 2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776$ +$$k_(3,0) = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 + + 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I$$ +$$k_(3,1) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$$ +$$k_(3,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 + + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263 \cdot I$$ +$$k_(3,3) = 2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776$$ The constants used to compute $y_{den}$ are as follows: -- $k_(4,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 +\\ - 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 \cdot I$ -- $k_(4,1) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571 \cdot I$ -- $k_(4,2) = 18 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769 \cdot I$ +$$k_(4,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 + + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 \cdot I$$ +$$k_(4,1) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571 \cdot I$$ +$$k_(4,2) = 18 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769 \cdot I$$ **Step 3:** Effective cofactor: -- $h_{eff} = 2098698478373356869050803414986584776638390672357034518753068515265997837965727388044593331090338342346225\\ - 28588876978987822447936461846631641690358257586228683615991308971558879306463436166481$ +$$h_{eff} = 209869847837335686905080341498658477663839067235703451875306851526599783796572738804459333109033834234622528588876978987822447936461846631641690358257586228683615991308971558879306463436166481$$ ### Curve points encoding From aae20140633d61ace6dcf674d82b9f34c62e0427 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 22:38:45 +0300 Subject: [PATCH 047/163] try fix formating --- neps/nep-0488.md | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index c6f4e8e8a..d0d342c9a 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -513,33 +513,42 @@ we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2}) The constants used to compute $x_{num}$ are as follows: -$$k_(1,0) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 + +$$k_{(1,0)} = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 + 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 \cdot I$$ -$$k_(1,1) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522 \cdot I$$ -$$k_(1,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 + + +$$k_{(1,1)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522 \cdot I$$ + +$$k_{(1,2)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261 \cdot I$$ -$$k_(1,3) = 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033$$ + +$$k_{(1,3)} = 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033$$ The constants used to compute $x_{den}$ are as follows: -$$k_(2,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715 \cdot I$$ -$$k_(2,1) = 12 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775 \cdot I$$ +$$k_{(2,0)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715 \cdot I$$ + +$$k_{(2,1)} = 12 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775 \cdot I$$ The constants used to compute $y_{num}$ are as follows: -$$k_(3,0) = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 + +$$k_{(3,0)} = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 + 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I$$ -$$k_(3,1) = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$$ -$$k_(3,2) = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 + + +$$k_{(3,1)} = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$$ + +$$k_{(3,2)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263 \cdot I$$ -$$k_(3,3) = 2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776$$ + +$$k_{(3,3)} = 2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776$$ The constants used to compute $y_{den}$ are as follows: -$$k_(4,0) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 + +$$k_{(4,0)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 \cdot I$$ -$$k_(4,1) = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571 \cdot I$$ -$$k_(4,2) = 18 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769 \cdot I$$ + +$$k_{(4,1)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571 \cdot I$$ + +$$k_{(4,2)} = 18 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769 \cdot I$$ **Step 3:** Effective cofactor: From e287b0ed7ae031c7cc4f77fa31f6130b2ce39372 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 22:42:40 +0300 Subject: [PATCH 048/163] try fix formating --- neps/nep-0488.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index d0d342c9a..706619059 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -513,42 +513,42 @@ we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2}) The constants used to compute $x_{num}$ are as follows: -$$k_{(1,0)} = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 + +- $$k_{(1,0)} = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 + 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 \cdot I$$ -$$k_{(1,1)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522 \cdot I$$ +- $$k_{(1,1)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522 \cdot I$$ -$$k_{(1,2)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 + +- $$k_{(1,2)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261 \cdot I$$ -$$k_{(1,3)} = 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033$$ +- $$k_{(1,3)} = 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033$$ The constants used to compute $x_{den}$ are as follows: -$$k_{(2,0)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715 \cdot I$$ +- $$k_{(2,0)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715 \cdot I$$ -$$k_{(2,1)} = 12 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775 \cdot I$$ +- $$k_{(2,1)} = 12 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775 \cdot I$$ The constants used to compute $y_{num}$ are as follows: -$$k_{(3,0)} = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 + - 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I$$ +- $$\begin{aligned} k_{(3,0)} = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 +\\ + 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I \end{aligned}$$ -$$k_{(3,1)} = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$$ +- $$k_{(3,1)} = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$$ -$$k_{(3,2)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 + +- $$k_{(3,2)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 + 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263 \cdot I$$ -$$k_{(3,3)} = 2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776$$ +- $$k_{(3,3)} = 2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776$$ The constants used to compute $y_{den}$ are as follows: -$$k_{(4,0)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 + +- $$k_{(4,0)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 \cdot I$$ -$$k_{(4,1)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571 \cdot I$$ +- $$k_{(4,1)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571 \cdot I$$ -$$k_{(4,2)} = 18 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769 \cdot I$$ +- $$k_{(4,2)} = 18 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769 \cdot I$$ **Step 3:** Effective cofactor: From 450b471e863e9d6208b3a3b9ab583c930486d036 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 5 Oct 2023 22:44:23 +0300 Subject: [PATCH 049/163] try fix formating --- neps/nep-0488.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 706619059..55b6279e6 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -531,8 +531,8 @@ The constants used to compute $x_{den}$ are as follows: The constants used to compute $y_{num}$ are as follows: -- $$\begin{aligned} k_{(3,0)} = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 +\\ - 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I \end{aligned}$$ +- $$k_{(3,0)} = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 +\\ + 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I$$ - $$k_{(3,1)} = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$$ @@ -552,7 +552,7 @@ The constants used to compute $y_{den}$ are as follows: **Step 3:** Effective cofactor: -$$h_{eff} = 209869847837335686905080341498658477663839067235703451875306851526599783796572738804459333109033834234622528588876978987822447936461846631641690358257586228683615991308971558879306463436166481$$ +- $$h_{eff} = 209869847837335686905080341498658477663839067235703451875306851526599783796572738804459333109033834234622528588876978987822447936461846631641690358257586228683615991308971558879306463436166481$$ ### Curve points encoding From 910d27080a59d7689ef81a143f84edec8f1d82ed Mon Sep 17 00:00:00 2001 From: Slava Karkunov Date: Mon, 9 Oct 2023 21:48:58 +0100 Subject: [PATCH 050/163] Edit Summary, Motivation and headers --- neps/nep-0488.md | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 55b6279e6..36d4ea176 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1,45 +1,51 @@ --- NEP: 488 -Title: Precompile for BLS12-381 curve operations +Title: Host Functions for BLS12-381 Curve Operations Authors: Olga Kuniavskaia Status: Draft DiscussionsTo: https://github.com/nearprotocol/neps/pull/488 Type: Runtime Spec Version: 0.0.1 Created: 2023-07-17 -LastUpdated: 2023-07-17 +LastUpdated: 2023-10-09 --- ## Summary -A pre-compiled NEAR runtime functions for operations on BLS12-381 curve. It is a necessary set to efficiently perform operations such as BLS signature and zkSNARKs verifications. +Native NEAR runtime functions for operations on BLS12-381 curve. This NEP introduces a minimal set of functions to efficiently verify BLS signatures and zkSNARKs. ## Motivation -The BLS12-381([^1],[^11],[^52]) is a wildly -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 BLS12-381[^1][^11][^52] is a widely used[^2][^3][^4][^5][^6][^7] elliptic curve with 120+ bits security level[^8], which supports *the pairing operation*. It is an alternative for BN254 elliptic curve[^9][^12], which also supports the aggregation, and has been already implemented on NEAR as host functions[^10]. Recent research shows that BN254 security level is lower than 100-bit[^13]. Also, there is a tendency to switch from BN254 to BLS12-381 in the industry – ZCash[^14], Ethereum[^15][^3], Tezos[^16][^5] or just use it – Filecoin[^6]. -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. +The host functions implementation for the BLS12-381 curve operations from this NEP will allow to efficiently verify the BLS signature and zkSNARKs. At the moment, BLS signature verification for BLS12-381 is impossible due to the 300 TGas gas limit per one transaction on 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. +As we have seen above, other blockchains are using the BLS12-381 signature. In the context of cross-chain interactions we want to have a possibility to verify transactions from these blockchains on Near. Usually, it is done by implementing the on-chain client on Near, which will verify the corresponding BLS signatures. It is especially important for the Rainbow Bridge[^17] to send trustless transfers from Ethereum to Near. -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. +zkSNARKs are useful to work with the user's private information[^18],[^19]. Zeropool[^20] is a project, which 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 are also used in Rollups[^21][^22][^23] scaling solution. -This proposal is based on a similar proposal for Ethereum: EIP-2537[^15]. +This proposal is based on a similar proposal for Ethereum: EIP-2537[^15], so you will find similar functions there. +The closest analogues on Near are functions available for BN254 curve, also known as Alt-BN128[^10]. -In this NEP we propose to add the following functions as precompile: +In this NEP we propose to add the following functions as host functions: -- ***bls12381_g1_sum —*** the function which adds the signed 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 signed 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]. 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]. -- ***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] and in EIP-2537[^15]. +- ***bls12381_g1_sum —*** adds an array of the signed points from $G_1$ on an elliptic curve. This function is useful for the aggregation of private keys in BLS Signature. Can be used for simple addition in $G_1$. Separate from the multiexp function due to the gas cost. +- ***bls12381_g2_sum —*** adds an array of the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. Can be used for simple addition in $G_2$. Separate from the multiexp function due to the 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 to multiply a group element by a scalar. +- ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. Can be used to multiply a group element by a scalar. +- ***bls12381_g1_map_to_curve —*** maps base field element into the $G_1$ point. Doesn’t perform mapping of the byte string into field elements. Transfer field element into a curve. It is necessary for signature schemes. +- ***bls12381_g2_map_to_curve —*** maps extension field element into the $G_2$ point. Doesn’t perform mapping of the byte string into extension field elements. +- ***bls12381_g1_decompress —*** decompresses the points from $G_1$ provided in the compressed form. +- ***bls12381_g2_decompress —*** decompresses the points from $G_2$ provided in the compressed 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$. Used to verify BLS-signatures or zkSNARKs. + +Please note that some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. That is why we've decided to move it into the separate functions. +All the other functions in this NEP accept only decompressed points to be simple and to have optimized gas consumption. + +*multiexp* functions are useful to do zkSNARKs verification. They also could be optimized by using Pippenger algorithm[^25]. + +By using the functions introduced above, we can reproduce all functionality from EIP-2537[^15]. Which is useful for Aurora[^24] 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 From 71caeb45690c9796226ca48439e91e2c40bab4b2 Mon Sep 17 00:00:00 2001 From: Slava Karkunov Date: Tue, 10 Oct 2023 12:33:54 +0100 Subject: [PATCH 051/163] Fix vocabulary, inconsistent use of names, incorrect terminology --- neps/nep-0488.md | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 36d4ea176..cc7eecb34 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -22,7 +22,7 @@ The host functions implementation for the BLS12-381 curve operations from this N As we have seen above, other blockchains are using the BLS12-381 signature. In the context of cross-chain interactions we want to have a possibility to verify transactions from these blockchains on Near. Usually, it is done by implementing the on-chain client on Near, which will verify the corresponding BLS signatures. It is especially important for the Rainbow Bridge[^17] to send trustless transfers from Ethereum to Near. -zkSNARKs are useful to work with the user's private information[^18],[^19]. Zeropool[^20] is a project, which 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 are also used in Rollups[^21][^22][^23] scaling solution. +zkSNARKs are useful to work with the user's private information[^18],[^19]. Zeropool[^20] is a project, which implements zkSNARKs verifier on Near and is currently based on Alt-BN128. Implementation of the host functions for BLS12-381 can make the projects like that more secure. zkSNARKs are also used in Rollups[^21][^22][^23] scaling solution. This proposal is based on a similar proposal for Ethereum: EIP-2537[^15], so you will find similar functions there. The closest analogues on Near are functions available for BN254 curve, also known as Alt-BN128[^10]. @@ -55,8 +55,6 @@ By using the functions introduced above, we can reproduce all functionality from **Definition:** The field $F_p$ for some *prime* $p$ is a set of integer elements $\textbraceleft 0, 1, \ldots, p - 1 \textbraceright$ with two operations: multiplication $\cdot$ and addition $+$. These operations are performed as multiplication/addition for integers number and then taking the remainder modulo $p$. - - **Definition:** The elliptic curve $E(F_p)$ is a set of all pairs $(x, y) \in F_p$: $$ @@ -564,7 +562,7 @@ The constants used to compute $y_{den}$ are as follows: #### Bool as output -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]. +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]. #### Sign @@ -572,7 +570,7 @@ The sign of the point on the elliptic curve is encoded as `u8` type in Rust with #### 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], but `big-endian` encoding is used instead of `little-endian` as in EIP-2537[^15]. +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 Fp @@ -695,7 +693,7 @@ x[0] = x[0] | 0x40; The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. -### Precompile functions +### Host functions #### bls12381_g1_sum @@ -890,7 +888,7 @@ Note: ***Gas Estimation:*** -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]. +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 the host function for `Alt-BN128`[^10]. ```rust let k = (input_bytes+item_size-1)/item_size; @@ -980,18 +978,18 @@ The $E'(F_{p^2})$ curve, points on the curve and the addition operation are def Note: -- We take as input any points on the curve, not only from $G_2$. +- We take as input any points on the curve, not only from $G_2$. - The scalar is an arbitrary unsigned integer and can be bigger than the group order. ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. -***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). +***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). ***Gas Estimation:*** -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]. +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 the host function for `Alt-BN128`[^10]. ```rust let k = (input_bytes+item_size-1)/item_size; @@ -1270,8 +1268,6 @@ pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Resu ***Description:*** Function decompress compressed points from $E(F_p)$. The input is an arbitrary number of points $p_i \in E(F_p)$ in compressed format, and the output is the same number of points from $E(F_p)$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. - - ***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in compressed form. Expected `48*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E(F_p)$. More details are in the Curve Points Encoding section. ***Output:*** the sequence of point $p_i \in E(F_p)$, each point encoded in decompressed form. Expected `96*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E(F_p)$. `k` the same as in input. More details are in the Curve Points Encoding section. @@ -1426,7 +1422,7 @@ First of all, for integration with nearcore, we are interested in libraries in t 6. ***FileCoin implementation*** [^35] 7. ***zkCrypto*** [^36] -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. +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 host functions 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: @@ -1437,23 +1433,23 @@ In addition, there are implementations in other languages that are not so intere 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]. This implementation is based on blst library[^30]. This library one of the fastest[^45] and audited[^55]. +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 the most audited[^55]. ## Security Implications The implementation security relies on the security of the chosen library, which supports operations with BLS curves. -In this NEP, we do not require a constant execution time for all operations. This is not a problem if you use precompiles to verify the BLS signature. These precompiles should not be used if you need a constant-time algorithm. +In this NEP, we do not require a constant execution time for all operations. This is not a problem if you use host functions to verify the BLS signature. These host functions should not be used if you need a constant-time algorithm. The BLS12-381 has more security bits than the already existing pairing-friendly curve BN254, as a result, the security of the projects which need the pairing-friendly curve will improve. ## Alternatives -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. +In the nearcore the host functions 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 the 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 Ethereun it is BLS12-381[^3] nowadays. 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]. 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. +Another alternative is to create one simple host function 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 G1 subgroup for the public keys, and others – G2; (3) the specification for Ethereum 2.0 continue to be in the draft and details can change, (4) we have one big function instead of a more diverse and flexible set of functions (inspired by EIP-2537's precompiles). -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. +The next alternative is to execute BLS12-381 operations off-chain. In that case, the applications which are using the BLS curve will not be trustless anymore. ## Future possibilities @@ -1463,8 +1459,8 @@ In the future, it is possible to support work with other curves, not only BLS12- ### Positive -- Projects, which used BN254 will be able to switch on BLS12-381 curve, and it will improve security. -- The trustless cross-chain interactions with blockchains that use BLS12-381 in protocols(such as Ethereum 2) will become possible. +- Projects, which are using BN254 will be able to switch on BLS12-381 curve, and it will improve their security. +- The trustless cross-chain interactions with blockchains using BLS12-381 in protocols (such as Ethereum 2.0) will become possible. ### Neutral @@ -1489,7 +1485,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^7]: Specification of pairing friendly curves with a list of applications in the table: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#name-adoption-status-of-pairing-) [^8]: Specification of pairing friendly curves, the security level for BLS12-381: [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-09#section-4.2.1) [^9]: BN2005: [https://eprint.iacr.org/2005/133](https://eprint.iacr.org/2005/133) -[^10]: NEP-98 for BN254 precompile on NEAR: [https://github.com/near/NEPs/issues/98](https://github.com/near/NEPs/issues/98) +[^10]: NEP-98 for BN254 host functions on NEAR: [https://github.com/near/NEPs/issues/98](https://github.com/near/NEPs/issues/98) [^11]: BLS12-381 for the Rest of Us: [https://hackmd.io/@benjaminion/bls12-381](https://hackmd.io/@benjaminion/bls12-381) [^12]: BN254 for the Rest of Us: [https://hackmd.io/@jpw/bn254](https://hackmd.io/@jpw/bn254) [^13]: Some analytics of different curve security: [https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security](https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security) @@ -1505,7 +1501,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^23]: Ledger post about Roll Ups: [https://www.ledger.com/academy/what-are-blockchain-rollups](https://www.ledger.com/academy/what-are-blockchain-rollups) [^24]: Precompiles on Aurora: [https://doc.aurora.dev/evm/precompiles/](https://doc.aurora.dev/evm/precompiles/) [^25]: Pippenger Algorithm: [https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf) -[^26]: NEP-446 proposal for BLS-signature verification precompile: [https://github.com/nearprotocol/neps/pull/446](https://github.com/nearprotocol/neps/pull/446) +[^26]: NEP-446 proposal for BLS-signature verification: [https://github.com/nearprotocol/neps/pull/446](https://github.com/nearprotocol/neps/pull/446) [^27]: EIP-1962 EC arithmetic and pairings with runtime definitions: [https://eips.ethereum.org/EIPS/eip-1962](https://eips.ethereum.org/EIPS/eip-1962) [^28]: Drawbacks of NEP-446: [https://github.com/near/NEPs/pull/446#pullrequestreview-1314601508](https://github.com/near/NEPs/pull/446#pullrequestreview-1314601508) [^29]: BLS12-381 Milagro: [https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474](https://github.com/sigp/incubator-milagro-crypto-rust/tree/057d238936c0cbbe3a59dfae6f2405db1090f474) From 079e156d7339b63819ac7798a71334ae93d15df1 Mon Sep 17 00:00:00 2001 From: Slava Karkunov Date: Tue, 10 Oct 2023 13:59:02 +0100 Subject: [PATCH 052/163] Remove comma between footnotes --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index cc7eecb34..18760fb23 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -22,7 +22,7 @@ The host functions implementation for the BLS12-381 curve operations from this N As we have seen above, other blockchains are using the BLS12-381 signature. In the context of cross-chain interactions we want to have a possibility to verify transactions from these blockchains on Near. Usually, it is done by implementing the on-chain client on Near, which will verify the corresponding BLS signatures. It is especially important for the Rainbow Bridge[^17] to send trustless transfers from Ethereum to Near. -zkSNARKs are useful to work with the user's private information[^18],[^19]. Zeropool[^20] is a project, which implements zkSNARKs verifier on Near and is currently based on Alt-BN128. Implementation of the host functions for BLS12-381 can make the projects like that more secure. zkSNARKs are also used in Rollups[^21][^22][^23] scaling solution. +zkSNARKs are useful to work with the user's private information[^18][^19]. Zeropool[^20] is a project, which implements zkSNARKs verifier on Near and is currently based on Alt-BN128. Implementation of the host functions for BLS12-381 can make the projects like that more secure. zkSNARKs are also used in Rollups[^21][^22][^23] scaling solution. This proposal is based on a similar proposal for Ethereum: EIP-2537[^15], so you will find similar functions there. The closest analogues on Near are functions available for BN254 curve, also known as Alt-BN128[^10]. From d124617958d9b6d6c2c529ec70f019ab6b096988 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 11 Oct 2023 12:57:41 +0300 Subject: [PATCH 053/163] alt-bn128 -> bn254 --- neps/nep-0488.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 18760fb23..9c0da0521 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -22,7 +22,7 @@ The host functions implementation for the BLS12-381 curve operations from this N As we have seen above, other blockchains are using the BLS12-381 signature. In the context of cross-chain interactions we want to have a possibility to verify transactions from these blockchains on Near. Usually, it is done by implementing the on-chain client on Near, which will verify the corresponding BLS signatures. It is especially important for the Rainbow Bridge[^17] to send trustless transfers from Ethereum to Near. -zkSNARKs are useful to work with the user's private information[^18][^19]. Zeropool[^20] is a project, which implements zkSNARKs verifier on Near and is currently based on Alt-BN128. Implementation of the host functions for BLS12-381 can make the projects like that more secure. zkSNARKs are also used in Rollups[^21][^22][^23] scaling solution. +zkSNARKs are useful to work with the user's private information[^18][^19]. Zeropool[^20] is a project, which implements zkSNARKs verifier on Near and is currently based on BN254. Implementation of the host functions for BLS12-381 can make the projects like that more secure. zkSNARKs are also used in Rollups[^21][^22][^23] scaling solution. This proposal is based on a similar proposal for Ethereum: EIP-2537[^15], so you will find similar functions there. The closest analogues on Near are functions available for BN254 curve, also known as Alt-BN128[^10]. @@ -562,7 +562,7 @@ The constants used to compute $y_{den}$ are as follows: #### Bool as output -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]. +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 BN254 implementation in nearcore[^50]. #### Sign @@ -570,7 +570,7 @@ The sign of the point on the elliptic curve is encoded as `u8` type in Rust with #### 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], but `big-endian` encoding is used instead of `little-endian` as in EIP-2537[^15]. +The scalar value is encoded as a big-endian `[u8;32]`. All possible bytes combination is allowed. Encoding is similar with BN254 implementation in nearcore[^50], but `big-endian` encoding is used instead of `little-endian` as in EIP-2537[^15]. #### Fields elements Fp @@ -888,7 +888,7 @@ Note: ***Gas Estimation:*** -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 the host function 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 the host function for `BN254`[^10]. ```rust let k = (input_bytes+item_size-1)/item_size; @@ -989,7 +989,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]. 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 the host function 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 the host function for `BN254`[^10]. ```rust let k = (input_bytes+item_size-1)/item_size; @@ -1445,7 +1445,7 @@ The BLS12-381 has more security bits than the already existing pairing-friendly ## Alternatives -In the nearcore the host functions 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 the 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 Ethereun it is BLS12-381[^3] nowadays. As a result, there is no alternative to using another pairing-friendly curve. +In the nearcore the host functions for another pairing-friendly curve BN254 are already implemented[^10]. For some projects[^20] the alternative is just to use the supported curve. However, according to the 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 Ethereun it is BLS12-381[^3] nowadays. As a result, there is no alternative to using another pairing-friendly curve. Another alternative is to create one simple host function 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 G1 subgroup for the public keys, and others – G2; (3) the specification for Ethereum 2.0 continue to be in the draft and details can change, (4) we have one big function instead of a more diverse and flexible set of functions (inspired by EIP-2537's precompiles). From 65a8df87473cc8652f707013236499994cd827de Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 11 Oct 2023 12:59:37 +0300 Subject: [PATCH 054/163] fix typo --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 9c0da0521..a638fb548 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1445,7 +1445,7 @@ The BLS12-381 has more security bits than the already existing pairing-friendly ## Alternatives -In the nearcore the host functions for another pairing-friendly curve BN254 are already implemented[^10]. For some projects[^20] the alternative is just to use the supported curve. However, according to the 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 Ethereun it is BLS12-381[^3] nowadays. As a result, there is no alternative to using another pairing-friendly curve. +In the nearcore the host functions for another pairing-friendly curve BN254 are already implemented[^10]. For some projects[^20] the alternative is just to use the supported curve. However, according to the 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 Ethereum it is BLS12-381[^3] nowadays. As a result, there is no alternative to using another pairing-friendly curve. Another alternative is to create one simple host function 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 G1 subgroup for the public keys, and others – G2; (3) the specification for Ethereum 2.0 continue to be in the draft and details can change, (4) we have one big function instead of a more diverse and flexible set of functions (inspired by EIP-2537's precompiles). From fc6e46bd2ae28618f8c1c7992155ea077b8dd577 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 11 Oct 2023 13:01:07 +0300 Subject: [PATCH 055/163] fix typo --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a638fb548..14900302c 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -29,7 +29,7 @@ The closest analogues on Near are functions available for BN254 curve, also know In this NEP we propose to add the following functions as host functions: -- ***bls12381_g1_sum —*** adds an array of the signed points from $G_1$ on an elliptic curve. This function is useful for the aggregation of private keys in BLS Signature. Can be used for simple addition in $G_1$. Separate from the multiexp function due to the gas cost. +- ***bls12381_g1_sum —*** adds an array of the signed points from $G_1$ on an elliptic curve. This function is useful for the aggregation of public keys in BLS Signature. Can be used for simple addition in $G_1$. Separate from the multiexp function due to the gas cost. - ***bls12381_g2_sum —*** adds an array of the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. Can be used for simple addition in $G_2$. Separate from the multiexp function due to the 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 to multiply a group element by a scalar. - ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. Can be used to multiply a group element by a scalar. From bd1c469aa0341db132bd808dacb19fe349816bef Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 11 Oct 2023 13:12:14 +0300 Subject: [PATCH 056/163] fix naming --- neps/nep-0488.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 14900302c..6934bd2d0 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -7,7 +7,7 @@ DiscussionsTo: https://github.com/nearprotocol/neps/pull/488 Type: Runtime Spec Version: 0.0.1 Created: 2023-07-17 -LastUpdated: 2023-10-09 +LastUpdated: 2023-11-09 --- ## Summary @@ -33,11 +33,11 @@ In this NEP we propose to add the following functions as host functions: - ***bls12381_g2_sum —*** adds an array of the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. Can be used for simple addition in $G_2$. Separate from the multiexp function due to the 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 to multiply a group element by a scalar. - ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. Can be used to multiply a group element by a scalar. -- ***bls12381_g1_map_to_curve —*** maps base field element into the $G_1$ point. Doesn’t perform mapping of the byte string into field elements. Transfer field element into a curve. It is necessary for signature schemes. -- ***bls12381_g2_map_to_curve —*** maps extension field element into the $G_2$ point. Doesn’t perform mapping of the byte string into extension field elements. -- ***bls12381_g1_decompress —*** decompresses the points from $G_1$ provided in the compressed form. -- ***bls12381_g2_decompress —*** decompresses the points from $G_2$ provided in the compressed 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$. Used to verify BLS-signatures or zkSNARKs. +- ***bls12381_map_fp_to_g1 —*** maps base field element into the $G_1$ point. Doesn’t perform mapping of the byte string into field elements. Transfer field element into a curve. It is necessary for signature schemes. +- ***bls12381_map_fp2_to_g2 —*** maps extension field element into the $G_2$ point. Doesn’t perform mapping of the byte string into extension field elements. +- ***bls12381_decompress_g1 —*** decompresses the points from $G_1$ provided in the compressed form. +- ***bls12381_decompress_g2 —*** decompresses the points from $G_2$ provided in the compressed form. +- ***bls12381_pairing_check —*** 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$. Used to verify BLS-signatures or zkSNARKs. Please note that some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. That is why we've decided to move it into the separate functions. All the other functions in this NEP accept only decompressed points to be simple and to have optimized gas consumption. @@ -1260,7 +1260,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. /// # Cost /// /// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_pairing_base + bls12381_pairing_element * num_elements` +/// bls12381_pairing_check_base + bls12381_pairing_check_element * num_elements` pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Result { ``` @@ -1329,7 +1329,7 @@ A and B are constants calculated empirically. /// # Cost /// /// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_g1_decompress_base + bls12381_g1_decompress_element * num_elements` +/// bls12381_decompress_g1_base + bls12381_decompress_g1_element * num_elements` pub fn bls12381_decompress_g1(&mut self, value_len: u64, value_ptr: u64, @@ -1403,7 +1403,7 @@ A and B are constants calculated empirically. /// # Cost /// /// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_g2_decompress_base + bls12381_g2_decompress_element * num_elements` +/// bls12381_decompress_g2_base + bls12381_decompress_g2_element * num_elements` pub fn bls12381_decompress_g2(&mut self, value_len: u64, value_ptr: u64, From f1a65d4866f4f21c9fcf6d2f2ebe515a634f11d9 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 11 Oct 2023 14:13:17 +0300 Subject: [PATCH 057/163] minor fix --- neps/nep-0488.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 6934bd2d0..d1c23eff5 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -205,7 +205,8 @@ $$h = 76329603384216526031706109802092473003$$ Cofactor $G_2\colon h' = |E'(F_{p^2})|/r$[^51] -$$h' = 305502333931268344200999753193121504214466019254188142667664032982267604182971884026507427359259977847832272839041616661285803823378372096355777062779109$$ +$$h' = 30550233393126834420099975319312150421446601925418814266766403298226760418297188402650742735925997784783227283904\\ +1616661285803823378372096355777062779109$$ #### Pairing @@ -746,7 +747,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain ***Tests References:*** -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. +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:*** @@ -768,7 +769,7 @@ We can use all the tests for addition for Ethereum([^47], [^48]) to check the ca /// BLS12-381 is Y^2 = X^3 + 4 curve over Fp. /// /// `value` is encoded as packed, big-endian -/// `[([u8; 48], [u8; 48])]` slice. +/// `[(([u8; 48], [u8; 48]), u8)]` slice. /// /// # Errors /// From 3b76fd4cf6ea2b577c5ba25e57bd353e3daedaa2 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 11 Oct 2023 14:53:55 +0300 Subject: [PATCH 058/163] add separation for links --- neps/nep-0488.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index d1c23eff5..a08d29602 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -16,13 +16,13 @@ Native NEAR runtime functions for operations on BLS12-381 curve. This NEP introd ## Motivation -The BLS12-381[^1][^11][^52] is a widely used[^2][^3][^4][^5][^6][^7] elliptic curve with 120+ bits security level[^8], which supports *the pairing operation*. It is an alternative for BN254 elliptic curve[^9][^12], which also supports the aggregation, and has been already implemented on NEAR as host functions[^10]. Recent research shows that BN254 security level is lower than 100-bit[^13]. Also, there is a tendency to switch from BN254 to BLS12-381 in the industry – ZCash[^14], Ethereum[^15][^3], Tezos[^16][^5] or just use it – Filecoin[^6]. +The BLS12-381[^1],[^11],[^52] is a widely used[^2],[^3],[^4],[^5],[^6],[^7] elliptic curve with 120+ bits security level[^8], which supports *the pairing operation*. It is an alternative for BN254 elliptic curve[^9],[^12], which also supports the aggregation, and has been already implemented on NEAR as host functions[^10]. Recent research shows that BN254 security level is lower than 100-bit[^13]. Also, there is a tendency to switch from BN254 to BLS12-381 in the industry – ZCash[^14], Ethereum[^15],[^3], Tezos[^16],[^5] or just use it – Filecoin[^6]. The host functions implementation for the BLS12-381 curve operations from this NEP will allow to efficiently verify the BLS signature and zkSNARKs. At the moment, BLS signature verification for BLS12-381 is impossible due to the 300 TGas gas limit per one transaction on Near. As we have seen above, other blockchains are using the BLS12-381 signature. In the context of cross-chain interactions we want to have a possibility to verify transactions from these blockchains on Near. Usually, it is done by implementing the on-chain client on Near, which will verify the corresponding BLS signatures. It is especially important for the Rainbow Bridge[^17] to send trustless transfers from Ethereum to Near. -zkSNARKs are useful to work with the user's private information[^18][^19]. Zeropool[^20] is a project, which implements zkSNARKs verifier on Near and is currently based on BN254. Implementation of the host functions for BLS12-381 can make the projects like that more secure. zkSNARKs are also used in Rollups[^21][^22][^23] scaling solution. +zkSNARKs are useful to work with the user's private information[^18],[^19]. Zeropool[^20] is a project, which implements zkSNARKs verifier on Near and is currently based on BN254. Implementation of the host functions for BLS12-381 can make the projects like that more secure. zkSNARKs are also used in Rollups[^21],[^22],[^23] scaling solution. This proposal is based on a similar proposal for Ethereum: EIP-2537[^15], so you will find similar functions there. The closest analogues on Near are functions available for BN254 curve, also known as Alt-BN128[^10]. @@ -63,7 +63,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][^51][^14][^11] +In the case of BLS12-381 equation is $y^2 \equiv x^3 + 4 \mod p$[^15],[^51],[^14],[^11] **Parameters for our case:** @@ -104,7 +104,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][^51]: +For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$[^15],[^51]: - $r = 52435875175126190479447740508185965837690552500527637822603658699938581184513$ @@ -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][^51]: +$G_1$ and $G_2$ are cyclic subgroups with the following generators[^15],[^51]: $G_1$: @@ -279,7 +279,7 @@ $$h' = 3055023339312683442009997531931215042144660192541881426676640329822676041 Key BLS12-381 parameter used in Miller Loop: $$x = -15132376222941642752$$ -All parameters were taken from[^15][^51] and [^14], all of them consistent between sources. +All parameters were taken from[^15],[^51] and [^14], all of them consistent between sources. ### Map to curve specification @@ -747,7 +747,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain ***Tests References:*** -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. +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:*** @@ -822,7 +822,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][^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. +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:*** @@ -915,7 +915,7 @@ Addition test cases: ***Tests References:*** -The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47][^48]. +The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. ***Error cases:*** @@ -1007,7 +1007,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][^48]. +The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. ***Error cases:*** @@ -1076,7 +1076,7 @@ The gas consumption is a constant calculated empirically. - $a \ge p$ - 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][^48]. +***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. ***Error cases:*** @@ -1133,7 +1133,7 @@ The gas consumption is a constant calculated empirically. - One of the `a` value $\ge p$ - 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][^48]. +***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. ***Error cases:*** @@ -1221,7 +1221,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - The field elements are encoded incorrectly - Empty input -***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47][^48]. +***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. ***Error cases:*** @@ -1294,7 +1294,7 @@ A and B are constants calculated empirically. ***Tests References:*** -- Take the correct points on the curve from Ethereum tests[^47][^48] 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:*** @@ -1368,7 +1368,7 @@ A and B are constants calculated empirically. ***Tests References:*** -- Take the correct points on the curve from Ethereum tests[^47][^48] 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:*** From cead29ef8a8d0c043d2c7c899a193dabe76eaaa9 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 11 Oct 2023 15:10:30 +0300 Subject: [PATCH 059/163] add space before ( --- neps/nep-0488.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a08d29602..458275352 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -708,7 +708,7 @@ Note: we take as input any points on the curve, not only from $G_1$ ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. -***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). +***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). ***Gas Estimation:*** @@ -885,7 +885,7 @@ Note: ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. -***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). +***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). ***Gas Estimation:*** From 23bd63a8131b2cc3f5000fb919ce2675c8e6279a Mon Sep 17 00:00:00 2001 From: Slava Karkunov Date: Wed, 11 Oct 2023 15:13:25 +0100 Subject: [PATCH 060/163] Grammar, spelling fixes --- neps/nep-0488.md | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 458275352..5c7f2e17d 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -12,40 +12,39 @@ LastUpdated: 2023-11-09 ## Summary -Native NEAR runtime functions for operations on BLS12-381 curve. This NEP introduces a minimal set of functions to efficiently verify BLS signatures and zkSNARKs. +Native NEAR runtime functions for operations on the BLS12-381 curve. This NEP introduces a minimal set of functions to efficiently verify BLS signatures and zkSNARKs. ## Motivation -The BLS12-381[^1],[^11],[^52] is a widely used[^2],[^3],[^4],[^5],[^6],[^7] elliptic curve with 120+ bits security level[^8], which supports *the pairing operation*. It is an alternative for BN254 elliptic curve[^9],[^12], which also supports the aggregation, and has been already implemented on NEAR as host functions[^10]. Recent research shows that BN254 security level is lower than 100-bit[^13]. Also, there is a tendency to switch from BN254 to BLS12-381 in the industry – ZCash[^14], Ethereum[^15],[^3], Tezos[^16],[^5] or just use it – Filecoin[^6]. +The BLS12-381[^1],[^11],[^52] is a widely used[^2],[^3],[^4],[^5],[^6],[^7] elliptic curve with 120+ bits security level[^8], which supports *the pairing operation*. It is an alternative for the BN254 elliptic curve[^9],[^12], which also supports the aggregation and has already been implemented on NEAR as host functions[^10]. Recent research shows that the BN254 security level is lower than 100-bit[^13]. Also, there is a tendency to switch from BN254 to BLS12-381 in the industry – ZCash[^14], Ethereum[^15],[^3], Tezos[^16],[^5] or just use it – Filecoin[^6]. -The host functions implementation for the BLS12-381 curve operations from this NEP will allow to efficiently verify the BLS signature and zkSNARKs. At the moment, BLS signature verification for BLS12-381 is impossible due to the 300 TGas gas limit per one transaction on Near. +The host functions implementation for the BLS12-381 curve operations from this NEP will allow for efficient verification of the BLS signature and zkSNARKs. Currently, BLS signature verification for BLS12-381 is impossible due to the 300 TGas gas limit per one transaction on Near. -As we have seen above, other blockchains are using the BLS12-381 signature. In the context of cross-chain interactions we want to have a possibility to verify transactions from these blockchains on Near. Usually, it is done by implementing the on-chain client on Near, which will verify the corresponding BLS signatures. It is especially important for the Rainbow Bridge[^17] to send trustless transfers from Ethereum to Near. +As we have seen above, other blockchains are using the BLS12-381 signature. In the context of cross-chain interactions, we want to have the possibility to verify transactions from these blockchains on Near. Usually, it is done by implementing the on-chain client on Near, which will verify the corresponding BLS signatures. It is especially important for the Rainbow Bridge[^17] to send trustless transfers from Ethereum to Near. -zkSNARKs are useful to work with the user's private information[^18],[^19]. Zeropool[^20] is a project, which implements zkSNARKs verifier on Near and is currently based on BN254. Implementation of the host functions for BLS12-381 can make the projects like that more secure. zkSNARKs are also used in Rollups[^21],[^22],[^23] scaling solution. +zkSNARKs are useful to work with the user's private information[^18],[^19]. Zeropool[^20] is a project that implements the zkSNARKs verifier on Near and is currently based on BN254. Having the host functions for BLS12-381 can make projects like that more secure. zkSNARKs are also used in Rollups[^21],[^22],[^23] scaling solution. This proposal is based on a similar proposal for Ethereum: EIP-2537[^15], so you will find similar functions there. -The closest analogues on Near are functions available for BN254 curve, also known as Alt-BN128[^10]. +The closest analogs on Near are functions available for the BN254 curve, also known as Alt-BN128[^10]. -In this NEP we propose to add the following functions as host functions: +In this NEP, we propose to add the following functions as host functions: -- ***bls12381_g1_sum —*** adds an array of the signed points from $G_1$ on an elliptic curve. This function is useful for the aggregation of public keys in BLS Signature. Can be used for simple addition in $G_1$. Separate from the multiexp function due to the gas cost. -- ***bls12381_g2_sum —*** adds an array of the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. Can be used for simple addition in $G_2$. Separate from the multiexp function due to the 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 to multiply a group element by a scalar. -- ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. Can be used to multiply a group element by a scalar. -- ***bls12381_map_fp_to_g1 —*** maps base field element into the $G_1$ point. Doesn’t perform mapping of the byte string into field elements. Transfer field element into a curve. It is necessary for signature schemes. -- ***bls12381_map_fp2_to_g2 —*** maps extension field element into the $G_2$ point. Doesn’t perform mapping of the byte string into extension field elements. +- ***bls12381_g1_sum —*** adds an array of the signed points from $G_1$ on an elliptic curve. This function is useful for the aggregation of public keys in BLS Signature. It can be used for simple addition in $G_1$. Separate from the multiexp function due to the gas cost. +- ***bls12381_g2_sum —*** adds an array of the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. It can be used for simple addition in $G_2$. Separate from the multiexp function due to the gas cost. +- ***bls12381_g1_multiexp —*** for points $g_i \in G_1$ and scalars $s_i$ calculate $\sum g_i s_i$. It can be used to multiply a group element by a scalar. +- ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. It can be used to multiply a group element by a scalar. +- ***bls12381_map_fp_to_g1 —*** maps base field element into the $G_1$ point. It does not perform mapping of the byte string into field elements. Transfers field element into a curve. It is necessary for signature schemes. +- ***bls12381_map_fp2_to_g2 —*** maps extension field element into the $G_2$ point. It does not perform mapping of the byte string into extension field elements. - ***bls12381_decompress_g1 —*** decompresses the points from $G_1$ provided in the compressed form. - ***bls12381_decompress_g2 —*** decompresses the points from $G_2$ provided in the compressed form. -- ***bls12381_pairing_check —*** 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$. Used to verify BLS-signatures or zkSNARKs. +- ***bls12381_pairing_check —*** 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$. Used to verify BLS signatures or zkSNARKs. -Please note that some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. That is why we've decided to move it into the separate functions. +Please note that some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. That is why we have decided to move it into separate functions. All the other functions in this NEP accept only decompressed points to be simple and to have optimized gas consumption. -*multiexp* functions are useful to do zkSNARKs verification. They also could be optimized by using Pippenger algorithm[^25]. - -By using the functions introduced above, we can reproduce all functionality from EIP-2537[^15]. Which is useful for Aurora[^24] to support Ethereum functionality on Near. +*multiexp* functions are helpful in doing zkSNARKs verification. They also could be optimized by using the Pippenger algorithm[^25]. +Using the functions introduced above, we can reproduce all functionality from EIP-2537[^15], which is useful for Aurora[^24] to support Ethereum functionality on Near. ## Specification From 4003d702842af4c9608a576ad84d59177a9c1cf1 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 10:39:58 +0200 Subject: [PATCH 061/163] return ERROR_CODE --- neps/nep-0488.md | 147 ++++++++++++++++++++++++++++++----------------- 1 file changed, 93 insertions(+), 54 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 5c7f2e17d..2a639b3bc 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -560,10 +560,6 @@ The constants used to compute $y_{den}$ are as follows: ### Curve points encoding -#### Bool as output - -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 BN254 implementation in nearcore[^50]. - #### Sign The sign of the point on the elliptic curve is encoded as `u8` type in Rust with two possible values: `0` and `1`. `0` for positive sign, and `1` for negative sign. All other value of `u8` is not allowed and should be interpreted as incorrect. @@ -693,6 +689,24 @@ x[0] = x[0] | 0x40; The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. +#### ERROR_CODE + +Verifying the correctness of the input for the host-functions inside the contract can be gas-consuming. +For example, checking that the point is an element of the subgroup. If the near host function returns an error, +the whole execution is reverted. To avoid it, if the input is difficult to verify, the host function will finish +the work successfully but will return the ERROR_CODE. This solution will provide the opportunity for the user +to handle error cases by himself. Note: the host functions can finish with an error if the error were easy to avoid +(for example, if the input size is incorrect). + +The ERROR_CODE encoded as a little-endian u64 and can take the following values: +- 0 -- no error, execution was successful +- 1 -- incorrect encoding (the bit compress/decompress format set incorrectly, coordinate >= p etc) +- 2 -- point not on the curve +- 3 -- point not in expected subgroup +- 5 -- the pairing result is not equal to multiplicative identity + +ERROR_CODEs consistent with blst errors[^58]. + ### Host functions #### bls12381_g1_sum @@ -707,7 +721,10 @@ Note: we take as input any points on the curve, not only from $G_1$ ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. -***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +***Output:*** the ERROR_CODE is returned. +- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +- If the field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty +- If point not on the curve: ERROR_CODE = 2, the output is empty ***Gas Estimation:*** @@ -752,8 +769,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case - The input length is not divided by 97 - Too much memory is used -- Field elements encoded incorrectly (see Curve points encoded section) -- Any points not on the curve - The sign value is not 0 or 1 ***Annotation:*** @@ -775,7 +790,7 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case /// If `value_len + value_ptr` points outside the memory or the registers /// use more memory than the limit, the function returns `MemoryAccessViolation`. /// -/// If (1) point coordinates are not on curve or (2) `value.len()%97 != 0` or (3) value of sign is not 0 or 1 +/// If (1) `value.len()%97 != 0` or (2) value of sign is not 0 or 1 /// the function returns `BLS12381InvalidInput`. /// /// # Cost @@ -785,7 +800,7 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case pub fn bls12381_g1_sum(&mut self, value_len: u64, value_ptr: u64, - register_id: u64) -> Result<()>; + register_id: u64) -> Result; ``` #### bls12381_g2_sum @@ -800,7 +815,12 @@ Note: we take as input any points on the curve, not only from $G_2$ ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. -***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). +***Output:*** +the ERROR_CODE is returned. +- If the input is correct: ERROR_CODE = 0, the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). +- If extension field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty +- If point not on the curve: ERROR_CODE = 2, the output is empty + ***Gas Estimation:*** @@ -827,8 +847,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case - The input length is not divided by 193 - Too much memory is used -- Extension field elements encoded incorrectly (see Curve points encoded section) -- Any points not on the curve - The sign value is not 0 or 1 ***Annotation:*** @@ -850,7 +868,7 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case /// If `value_len + value_ptr` points outside the memory or the registers /// use more memory than the limit, the function returns `MemoryAccessViolation`. /// -/// If (1) point coordinates are not on curve or (2) `value.len()%193 != 0` or (3) sign is not 0 or 1, +/// If (1) `value.len()%193 != 0` or (2) sign is not 0 or 1, /// the function returns `BLS12381InvalidInput`. /// /// # Cost @@ -860,7 +878,7 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case pub fn bls12381_g2_sum(&mut self, value_len: u64, value_ptr: u64, - register_id: u64) -> Result<()>; + register_id: u64) -> Result; ``` #### ***bls12381_g1_multiexp*** @@ -884,7 +902,11 @@ Note: ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. -***Output:*** the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +***Output:*** +the ERROR_CODE is returned. +- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty +- If point not on the curve: ERROR_CODE = 2, the output is empty ***Gas Estimation:*** @@ -920,8 +942,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether - The input length is not divided by 128 - Too much memory is used -- Field elements encoded incorrectly (see Curve points encoded section) -- Any points not on the curve ***Annotation:*** @@ -944,9 +964,7 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether /// use more memory than the limit, the function returns /// `MemoryAccessViolation`. /// -/// If point coordinates are not on curve, point is not in the subgroup, -/// scalar is not in the field or `value.len()%128!=0`, the function returns -/// `BLS12381InvalidInput`. +/// If `value.len()%128!=0`, the function returns `BLS12381InvalidInput`. /// /// # Cost /// @@ -959,7 +977,7 @@ pub fn bls12381_g1_multiexp( value_len: u64, value_ptr: u64, register_id: u64, -) -> Result<()>; +) -> Result; ``` #### ***bls12381_g2_multiexp*** @@ -985,7 +1003,14 @@ Note: Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. -***Output:*** the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). +***Output:*** + +the ERROR_CODE is returned. +- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty +- If point not on the curve: ERROR_CODE = 2, the output is empty + +the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). ***Gas Estimation:*** @@ -1036,9 +1061,7 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether /// use more memory than the limit, the function returns /// `MemoryAccessViolation`. /// -/// If point coordinates are not on curve, point is not in the subgroup, -/// scalar is not in the field or `value.len()%224!=0`, the function returns -/// `BLS12381InvalidInput`. +/// If `value.len()%224!=0`, the function returns `BLS12381InvalidInput`. /// /// # Cost /// @@ -1051,7 +1074,7 @@ pub fn bls12381_g2_multiexp( value_len: u64, value_ptr: u64, register_id: u64, -) -> Result<()>; +) -> Result; ``` #### bls12381_map_fp_to_g1 @@ -1062,7 +1085,13 @@ The function takes the element $a \in F_p$ and maps it to the $G_1 \subset E(F_p ***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. -***Output:*** the output is `96 bytes` — one point $\in G_1 \subset E(F_p)$ in decompressed format. More details are in the Curve Points Encoding section. +***Output:*** + +the ERROR_CODE is returned. +* If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +* $a \ge p$: ERROR_CODE = 1, the output is empty + +the output is `96 bytes` — one point $\in G_1 \subset E(F_p)$ in decompressed format. More details are in the Curve Points Encoding section. ***Gas Estimation:*** @@ -1080,7 +1109,6 @@ The gas consumption is a constant calculated empirically. ***Error cases:*** - Incorrect input length -- $a \ge p$ ***Annotation:*** @@ -1097,7 +1125,7 @@ The gas consumption is a constant calculated empirically. /// use more memory than the limit, the function returns /// `MemoryAccessViolation`. /// -/// If value_len != 48 or the value >= p the function return `BLS12381InvalidInput`. +/// If value_len != 48 the function return `BLS12381InvalidInput`. /// /// # Cost /// @@ -1108,7 +1136,7 @@ pub fn bls12381_map_fp_to_g1( value_len: u64, value_ptr: u64, register_id: u64, -) -> Result<()>; +) -> Result; ``` #### bls12381_map_fp2_to_g2 @@ -1119,7 +1147,13 @@ The function takes the element $a \in F_{p^2}$ and maps it to the $G_2 \subset E ***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. -***Output:*** the output is `192 bytes` — one point $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. +***Output:*** + +the ERROR_CODE is returned. +- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +- If value is not a valid extension field $F_{p^2}$ element: ERROR_CODE = 1, the output is empty + +the output is `192 bytes` — one point $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. ***Gas Estimation:*** @@ -1137,7 +1171,6 @@ The gas consumption is a constant calculated empirically. ***Error cases:*** - Incorrect input length -- Value is not a valid extension field $F_{p^2}$ element ***Annotation:*** @@ -1154,7 +1187,7 @@ The gas consumption is a constant calculated empirically. /// use more memory than the limit, the function returns /// `MemoryAccessViolation`. /// -/// If value_len != 96 or the value is not correct Fp2 element the function return `BLS12381InvalidInput`. +/// If value_len != 96 the function return `BLS12381InvalidInput`. /// /// # Cost /// @@ -1165,7 +1198,7 @@ pub fn bls12381_map_fp2_to_g2( value_len: u64, value_ptr: u64, register_id: u64, -) -> Result<()>; +) -> Result; ``` #### bls12381_pairing_check @@ -1193,7 +1226,15 @@ We don’t calculate the pairing function itself: the result will be in the huge ***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $G_1 \subset E(F_p)$ — `96 bytes` and point from $G_2 \subset E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. -***Output:*** returns `bool` — the result of the pairing check. The `true` value means that the pairing result is equal to multiplicative identity and `false` otherwise. For empty input it returns `true`. +***Output:*** +the ERROR_CODE is returned. +- If the input is correct and the pairing result is equal to multiplicative identity : ERROR_CODE = 0 +- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1 +- If point not on the curve: ERROR_CODE = 2 +- If point not in $G_1/G_2$: ERROR_CODE = 3 +- If the input is correct and the pairing result is not equal to multiplicative identity : ERROR_CODE = 5 + +For empty input it returns ERROR_CODE = 0. ***Gas Estimation:*** @@ -1226,9 +1267,6 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - The input length is not divided by 288 - Too much memory is used -- Field elements encoded incorrectly (see Curve points encoded section) -- Any points not on the curve -- Any points not in $G_1/G_2$ ***Annotation:*** @@ -1253,9 +1291,8 @@ Here you can find benchmark test vectors for EIP-2537[^46]. /// If `value_len + value_ptr` points outside the memory than /// the function returns `MemoryAccessViolation`. /// -/// If point coordinates are not on curve, point is not in the subgroup -// or data are wrong serialized, for example, -/// `value.len()%288!=0`, the function returns `BLS12381InvalidInput`. +/// If point coordinates are not on curve `value.len()%288!=0`, +/// the function returns `BLS12381InvalidInput`. /// /// # Cost /// @@ -1270,7 +1307,11 @@ pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Resu ***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in compressed form. Expected `48*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E(F_p)$. More details are in the Curve Points Encoding section. -***Output:*** the sequence of point $p_i \in E(F_p)$, each point encoded in decompressed form. Expected `96*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E(F_p)$. `k` the same as in input. More details are in the Curve Points Encoding section. +***Output:*** +the ERROR_CODE is returned. +- If the input is correct: ERROR_CODE = 0, the output is the sequence of point $p_i \in E(F_p)$, each point encoded in decompressed form. Expected `96*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E(F_p)$. `k` the same as in input. More details are in the Curve Points Encoding section. +- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty +- If point not on the curve: ERROR_CODE = 2, the output is empty ***Gas Estimation:*** The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula @@ -1300,8 +1341,6 @@ A and B are constants calculated empirically. - The input length is not divided by 48 - Too much memory is used -- Field elements encoded incorrectly (see Curve points encoded section) -- Any points not on the curve ***Annotation:*** @@ -1323,8 +1362,7 @@ A and B are constants calculated empirically. /// If `value_len + value_ptr` points outside the memory or the registers /// use more memory than the limit, the function returns `MemoryAccessViolation`. /// -/// If point coordinates are not on curve or `value.len()%48 != 0`, -/// the function returns `BLS12381InvalidInput`. +/// If `value.len()%48 != 0` the function returns `BLS12381InvalidInput`. /// /// # Cost /// @@ -1333,18 +1371,20 @@ A and B are constants calculated empirically. pub fn bls12381_decompress_g1(&mut self, value_len: u64, value_ptr: u64, - register_id: u64) -> Result<()>; + register_id: u64) -> Result; ``` #### bls12381_decompress_g2 ***Description:*** Function decompress compressed points from $E'(F_{p^2})$. The input is an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format, and the output is the same number of points from $E'(F_{p^2})$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. - - ***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in compressed form. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. -***Output:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in decompressed form. Expected `192*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E'(F_{p^2})$. `k` the same as in input. More details are in the Curve Points Encoding section. +***Output:*** +the ERROR_CODE is returned. +- If the input is correct: ERROR_CODE = 0, the output is the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in decompressed form. Expected `192*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E'(F_{p^2})$. `k` the same as in input. More details are in the Curve Points Encoding section. +- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty +- If point not on the curve: ERROR_CODE = 2, the output is empty ***Gas Estimation:*** The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula @@ -1374,8 +1414,6 @@ A and B are constants calculated empirically. - The input length is not divided by 96 - Too much memory is used -- Field elements encoded incorrectly (see Curve points encoded section) -- Any points not on the curve ***Annotation:*** @@ -1397,7 +1435,7 @@ A and B are constants calculated empirically. /// If `value_len + value_ptr` points outside the memory or the registers /// use more memory than the limit, the function returns `MemoryAccessViolation`. /// -/// If point coordinates are not on curve or `value.len()%96 != 0`, +/// If `value.len()%96 != 0`, /// the function returns `BLS12381InvalidInput`. /// /// # Cost @@ -1407,7 +1445,7 @@ A and B are constants calculated empirically. pub fn bls12381_decompress_g2(&mut self, value_len: u64, value_ptr: u64, - register_id: u64) -> Result<()>; + register_id: u64) -> Result; ``` ## Reference Implementation @@ -1535,3 +1573,4 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] elliptic curves. In Tal Rabin, editor, CRYPTO 2010, volume 6223 of LNCS, pages 237–254. Springer, Heidelberg, August 2010. [https://link.springer.com/chapter/10.1007/978-3-642-14623-7_13](https://link.springer.com/chapter/10.1007/978-3-642-14623-7_13) [^57]: Wahby, Riad S., and Dan Boneh. "Fast and simple constant-time hashing to the BLS12-381 elliptic curve." Cryptology ePrint Archive (2019). [https://eprint.iacr.org/2019/403](https://eprint.iacr.org/2019/403) +[^58]: BLST errors list. [https://github.com/supranational/blst/blob/v0.3.11/src/errors.h](https://github.com/supranational/blst/blob/v0.3.11/src/errors.h) From 7c5cb3b4c8ffea0d13f0a0ec6127923f288fc9dc Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 12:10:47 +0200 Subject: [PATCH 062/163] scalar encoding --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 2a639b3bc..47ddaa000 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -566,7 +566,7 @@ The sign of the point on the elliptic curve is encoded as `u8` type in Rust with #### Scalar -The scalar value is encoded as a big-endian `[u8;32]`. All possible bytes combination is allowed. Encoding is similar with BN254 implementation in nearcore[^50], but `big-endian` encoding is used instead of `little-endian` as in EIP-2537[^15]. +The scalar value is encoded as a little-endian `[u8;32]`. All possible bytes combination is allowed. #### Fields elements Fp From b2a315a0f567252d07e47071c62dd6d121ccf724 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 12:12:33 +0200 Subject: [PATCH 063/163] fix formating --- neps/nep-0488.md | 1 + 1 file changed, 1 insertion(+) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 47ddaa000..bdda5006b 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -699,6 +699,7 @@ to handle error cases by himself. Note: the host functions can finish with an er (for example, if the input size is incorrect). The ERROR_CODE encoded as a little-endian u64 and can take the following values: + - 0 -- no error, execution was successful - 1 -- incorrect encoding (the bit compress/decompress format set incorrectly, coordinate >= p etc) - 2 -- point not on the curve From 90cb55f4a0dbd07f7ff794939197cddd3e36c5b6 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 12:32:07 +0200 Subject: [PATCH 064/163] encoding of inf --- neps/nep-0488.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index bdda5006b..f10245eb8 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -595,6 +595,7 @@ $E(F_p)$ is encoded as `[u8; 96]`: - $y \in F_p$ `[u8; 48]` *The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. +If the second bit is set to 1, all others bits should be set to 0. Other encoding should throw an error. Encoding point on infinity: @@ -612,6 +613,7 @@ The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The e *The first bit* should be set as 1. This bit indicates that point is encoded in compressed form. *The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. +If the second bit is set to 1, all others except first two bits should be set to 0. Other encoding should throw an error. To represent the sign of the $y$ *the third bit* of x encoding is used. If the first bit = 0 the $y$ is positive, if the first bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y = p - y$. @@ -648,7 +650,8 @@ $E'(F_{p^2})$ is encoded as `[u8; 192]`: - $c_1 \in F_p$ `[u8; 48]` - $c_0 \in F_p$ `[u8; 48]` -*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. +*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. +If the second bit is set to 1, all others bits should be set to 0. Other encoding should throw an error. Encoding point on infinity: @@ -666,6 +669,7 @@ The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The *The first bit* should be set as 1. This bit indicates that point is encoded in compressed form. *The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. +If the second bit is set to 1, all others except first two bits should be set to 0. Other encoding should throw an error. To represent the sign of the $y$ *the third bit* of x encoding is used. If the first bit = 0 the $y$ is positive, if the first bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y$: first compare $c_1$ and second $c_0$. From e47f922cb2e3aba75ea74f23a6c3ad1674db33e5 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 12:35:03 +0200 Subject: [PATCH 065/163] fix formating --- neps/nep-0488.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index f10245eb8..52d525f3b 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -727,6 +727,7 @@ Note: we take as input any points on the curve, not only from $G_1$ ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. + - If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). - If the field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty - If point not on the curve: ERROR_CODE = 2, the output is empty @@ -822,6 +823,7 @@ Note: we take as input any points on the curve, not only from $G_2$ ***Output:*** the ERROR_CODE is returned. + - If the input is correct: ERROR_CODE = 0, the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). - If extension field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty - If point not on the curve: ERROR_CODE = 2, the output is empty @@ -909,6 +911,7 @@ Note: ***Output:*** the ERROR_CODE is returned. + - If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). - If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty - If point not on the curve: ERROR_CODE = 2, the output is empty @@ -1011,6 +1014,7 @@ Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ ***Output:*** the ERROR_CODE is returned. + - If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). - If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty - If point not on the curve: ERROR_CODE = 2, the output is empty @@ -1093,8 +1097,9 @@ The function takes the element $a \in F_p$ and maps it to the $G_1 \subset E(F_p ***Output:*** the ERROR_CODE is returned. -* If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). -* $a \ge p$: ERROR_CODE = 1, the output is empty + +- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +- $a \ge p$: ERROR_CODE = 1, the output is empty the output is `96 bytes` — one point $\in G_1 \subset E(F_p)$ in decompressed format. More details are in the Curve Points Encoding section. @@ -1155,6 +1160,7 @@ The function takes the element $a \in F_{p^2}$ and maps it to the $G_2 \subset E ***Output:*** the ERROR_CODE is returned. + - If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). - If value is not a valid extension field $F_{p^2}$ element: ERROR_CODE = 1, the output is empty @@ -1232,7 +1238,9 @@ We don’t calculate the pairing function itself: the result will be in the huge ***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $G_1 \subset E(F_p)$ — `96 bytes` and point from $G_2 \subset E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. ***Output:*** + the ERROR_CODE is returned. + - If the input is correct and the pairing result is equal to multiplicative identity : ERROR_CODE = 0 - If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1 - If point not on the curve: ERROR_CODE = 2 @@ -1313,7 +1321,9 @@ pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Resu ***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in compressed form. Expected `48*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E(F_p)$. More details are in the Curve Points Encoding section. ***Output:*** + the ERROR_CODE is returned. + - If the input is correct: ERROR_CODE = 0, the output is the sequence of point $p_i \in E(F_p)$, each point encoded in decompressed form. Expected `96*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E(F_p)$. `k` the same as in input. More details are in the Curve Points Encoding section. - If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty - If point not on the curve: ERROR_CODE = 2, the output is empty @@ -1386,7 +1396,9 @@ pub fn bls12381_decompress_g1(&mut self, ***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in compressed form. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. ***Output:*** + the ERROR_CODE is returned. + - If the input is correct: ERROR_CODE = 0, the output is the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in decompressed form. Expected `192*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E'(F_{p^2})$. `k` the same as in input. More details are in the Curve Points Encoding section. - If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty - If point not on the curve: ERROR_CODE = 2, the output is empty From d9b039a05f6552e8005ebd4102c032def6cf4226 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 14:35:52 +0200 Subject: [PATCH 066/163] change point, sign order --- neps/nep-0488.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 52d525f3b..decd4eea4 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -718,13 +718,13 @@ ERROR_CODEs consistent with blst errors[^58]. ***Description:*** -The function computes the sum of the signed elements of the BLS12-381 curve. The input is an arbitrary number of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is point on elliptic curve and $s_i \in \textbraceleft 0, 1 \textbraceright$ is the point sign. The output is one point from $E(F_p)$ equal to $\sum (-1)^{s_i}p_i$. +The function computes the sum of the signed elements of the BLS12-381 curve. The input is an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ is point on elliptic curve and $s_i \in \textbraceleft 0, 1 \textbraceright$ is the point sign. The output is one point from $E(F_p)$ equal to $\sum (-1)^{s_i}p_i$. The $E(F_p)$ curve, points on the curve, multiplication on -1, and the addition operation are defined in the BLS12-381 Curve Specification section. Note: we take as input any points on the curve, not only from $G_1$ -***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. @@ -785,11 +785,11 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case /// /// # Arguments /// -/// * `value` - sequence of (pi, si) where pi is point(x:Fp, y:Fp) on BLS-381 curve and si is sign (0 for +, and 1 for -) +/// * `value` - sequence of (si, pi) where pi is point(x:Fp, y:Fp) on BLS-381 curve and si is sign (0 for +, and 1 for -) /// BLS12-381 is Y^2 = X^3 + 4 curve over Fp. /// /// `value` is encoded as packed, big-endian -/// `[(([u8; 48], [u8; 48]), u8)]` slice. +/// `[(u8, ([u8; 48], [u8; 48]))]` slice. /// /// # Errors /// @@ -813,13 +813,13 @@ pub fn bls12381_g1_sum(&mut self, ***Description:*** -The function computes the sum of the signed elements of the BLS12-381 curve. The input is an arbitrary number of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is point on elliptic curve and $s_i \in \textbraceleft 0, 1 \textbraceright$ is the point sign. The output is one point from $E'(F_{p^2})$ equal to $\sum (-1)^{s_i}p_i$. +The function computes the sum of the signed elements of the BLS12-381 curve. The input is an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point on elliptic curve and $s_i \in \textbraceleft 0, 1 \textbraceright$ is the point sign. The output is one point from $E'(F_{p^2})$ equal to $\sum (-1)^{s_i}p_i$. The $E'(F_{p^2})$ curve, points on the curve, multiplication on -1, and the addition operation are defined in the BLS12-381 Curve Specification section. Note: we take as input any points on the curve, not only from $G_2$ -***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. @@ -864,11 +864,11 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case /// /// # Arguments /// -/// * `value` - sequence of (pi, si), where pi is point(x:Fp^2, y:Fp^2) on BLS-381 curve and si is sign (0 for +, 1 for -) +/// * `value` - sequence of (si, pi), where pi is point(x:Fp^2, y:Fp^2) on BLS-381 curve and si is sign (0 for +, 1 for -) /// BLS12-381 is Y^2 = X^3 + 4(i + 1) curve over Fp^2. /// /// `value` is encoded as packed, big-endian -/// `[(([u8; 96], [u8; 96]), u8)]` slice. +/// `[(u8, ([u8; 96], [u8; 96]))]` slice. /// /// # Errors /// From b737d0b80918b055c07ea9d12094e893e5ad5dcc Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 15:10:15 +0200 Subject: [PATCH 067/163] simplify gas estimation --- neps/nep-0488.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index decd4eea4..d580d0356 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -737,7 +737,7 @@ Note: we take as input any points on the curve, not only from $G_1$ The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula ```rust -let k = (input_bytes + item_size - 1)/item_size +let k = input_bytes / item_size let gas_consumed = A + B * k ``` @@ -834,7 +834,7 @@ the ERROR_CODE is returned. The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula ```rust -let k = (input_bytes + item_size - 1)/item_size +let k = input_bytes / item_size let gas_consumed = A + B * k ``` @@ -921,7 +921,7 @@ the ERROR_CODE is returned. 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 the host function for `BN254`[^10]. ```rust -let k = (input_bytes+item_size-1)/item_size; +let k = input_bytes / item_size; let gas_consumed = A + B*k + C * if k > 1 {k / (k as f32).log2().floor()} else {k}; ``` @@ -1026,7 +1026,7 @@ the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form 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 the host function for `BN254`[^10]. ```rust -let k = (input_bytes+item_size-1)/item_size; +let k = input_bytes / item_size; let gas_consumed = A + B*k + C * if k > 1 {k / (k as f32).log2().floor()} else {k}; ``` @@ -1254,7 +1254,7 @@ For empty input it returns ERROR_CODE = 0. The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula ```rust -let k = (input_bytes + item_size - 1)/item_size +let k = input_bytes / item_size let gas_consumed = A + B * k ``` @@ -1331,7 +1331,7 @@ the ERROR_CODE is returned. ***Gas Estimation:*** The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula ```rust -let k = (input_bytes + item_size - 1)/item_size +let k = input_bytes / item_size let gas_consumed = A + B * k ``` From 80adcc7167832afd653386381d621b77a01d1f4f Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 15:40:38 +0200 Subject: [PATCH 068/163] simplify multiexp function --- neps/nep-0488.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index d580d0356..5efff47b1 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -918,16 +918,16 @@ the ERROR_CODE is returned. ***Gas Estimation:*** -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 the host function for `BN254`[^10]. +For simplicity, we will use the linear formula for gas calculation: ```rust -let k = input_bytes / item_size; -let gas_consumed = A + B*k + C * if k > 1 {k / (k as f32).log2().floor()} else {k}; +let k = input_bytes / item_size +let gas_consumed = A + B * k ``` -A, B and C are constants calculated empirically. +A and B are constants calculated empirically. -For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[^46]. +To improve gas costs Pippenger’s algorithm[^25] can be used. For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[^46]. ***Test cases:*** @@ -978,8 +978,7 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether /// /// `base + write_register_base + write_register_byte * num_bytes + /// bls12381_g1_multiexp_base + -/// bls12381_g1_multiexp_element * num_elements + -/// bls12381_g1_multiexp_element_div_log * num_elements/max(1, log(num_elements))` +/// bls12381_g1_multiexp_element * num_elements pub fn bls12381_g1_multiexp( &mut self, value_len: u64, @@ -1023,16 +1022,16 @@ the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form ***Gas Estimation:*** -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 the host function for `BN254`[^10]. +For simplicity, we will use the linear formula for gas calculation: ```rust -let k = input_bytes / item_size; -let gas_consumed = A + B*k + C * if k > 1 {k / (k as f32).log2().floor()} else {k}; +let k = input_bytes / item_size +let gas_consumed = A + B * k ``` -A, B and C are constants calculated empirically. +A and B are constants calculated empirically. -For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[^46]. +To improve gas costs Pippenger’s algorithm[^25] can be used. For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[^46]. ***Test cases:*** @@ -1076,8 +1075,7 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether /// /// `base + write_register_base + write_register_byte * num_bytes + /// bls12381_g2_multiexp_base + -/// bls12381_g2_multiexp_element * num_elements + -/// bls12381_g2_multiexp_element_div_log * num_elements/max(1, log(num_elements))` +/// bls12381_g2_multiexp_element * num_elements pub fn bls12381_g2_multiexp( &mut self, value_len: u64, From cc448df84cb9d3a3d4dd73b14097b9ef011f2d6d Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 15:48:33 +0200 Subject: [PATCH 069/163] remove comments in annotation --- neps/nep-0488.md | 208 +---------------------------------------------- 1 file changed, 1 insertion(+), 207 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 5efff47b1..b49df2244 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -780,29 +780,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Annotation:*** ```rust -/// Computes sum for signed elements on BLS12-381 curve -/// \sum_i (-1)^{s_i} p_i should be the equal result. -/// -/// # Arguments -/// -/// * `value` - sequence of (si, pi) where pi is point(x:Fp, y:Fp) on BLS-381 curve and si is sign (0 for +, and 1 for -) -/// BLS12-381 is Y^2 = X^3 + 4 curve over Fp. -/// -/// `value` is encoded as packed, big-endian -/// `[(u8, ([u8; 48], [u8; 48]))]` slice. -/// -/// # Errors -/// -/// If `value_len + value_ptr` points outside the memory or the registers -/// use more memory than the limit, the function returns `MemoryAccessViolation`. -/// -/// If (1) `value.len()%97 != 0` or (2) value of sign is not 0 or 1 -/// the function returns `BLS12381InvalidInput`. -/// -/// # Cost -/// -/// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_g1_sum_base + bls12381_g1_sum_element * num_elements` pub fn bls12381_g1_sum(&mut self, value_len: u64, value_ptr: u64, @@ -859,29 +836,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Annotation:*** ```rust -/// Computes sum for signed elements on BLS12-381 curve -/// \sum_i (-1)^{s_i} p_i should be the equal result. -/// -/// # Arguments -/// -/// * `value` - sequence of (si, pi), where pi is point(x:Fp^2, y:Fp^2) on BLS-381 curve and si is sign (0 for +, 1 for -) -/// BLS12-381 is Y^2 = X^3 + 4(i + 1) curve over Fp^2. -/// -/// `value` is encoded as packed, big-endian -/// `[(u8, ([u8; 96], [u8; 96]))]` slice. -/// -/// # Errors -/// -/// If `value_len + value_ptr` points outside the memory or the registers -/// use more memory than the limit, the function returns `MemoryAccessViolation`. -/// -/// If (1) `value.len()%193 != 0` or (2) sign is not 0 or 1, -/// the function returns `BLS12381InvalidInput`. -/// -/// # Cost -/// -/// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_g2_sum_base + bls12381_g2_sum_element * num_elements` pub fn bls12381_g2_sum(&mut self, value_len: u64, value_ptr: u64, @@ -954,31 +908,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Annotation:*** ```rust -/// Computes multiexp on BLS12-381 curve using Pippenger's algorithm -///\sum_i si*pi should be equal result. -/// -/// # Arguments -/// -/// * `value` - sequence of (pi, si), where -/// pi is point (x:Fp, y:Fp) on BLS12-381, and si is u256. -/// BLS12-381 is Y^2 = X^3 + 4 curve over Fp. -/// -/// `value` is encoded as packed, big-endian -/// `[(([u8; 48], [u8; 48]), u256)]` slice. -/// -/// # Errors -/// -/// If `value_len + value_ptr` points outside the memory or the registers -/// use more memory than the limit, the function returns -/// `MemoryAccessViolation`. -/// -/// If `value.len()%128!=0`, the function returns `BLS12381InvalidInput`. -/// -/// # Cost -/// -/// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_g1_multiexp_base + -/// bls12381_g1_multiexp_element * num_elements pub fn bls12381_g1_multiexp( &mut self, value_len: u64, @@ -1051,31 +980,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Annotation:*** ```rust -/// Computes multiexp on BLS12-381 curve using Pippenger's algorithm -///\sum_i si*pi should be equal result. -/// -/// # Arguments -/// -/// * `value` - sequence of (pi, si), where -/// pi is point (x:Fp^2, y:Fp^2) on BLS12-381, and si is u256. -/// BLS12-381 is Y^2 = X^3 + 4(i + 1) curve over Fp^2. -/// -/// `value` is encoded as packed, big-endian -/// `[(([u8; 96], [u8; 96]), u256)]` slice. -/// -/// # Errors -/// -/// If `value_len + value_ptr` points outside the memory or the registers -/// use more memory than the limit, the function returns -/// `MemoryAccessViolation`. -/// -/// If `value.len()%224!=0`, the function returns `BLS12381InvalidInput`. -/// -/// # Cost -/// -/// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_g2_multiexp_base + -/// bls12381_g2_multiexp_element * num_elements pub fn bls12381_g2_multiexp( &mut self, value_len: u64, @@ -1121,24 +1025,6 @@ The gas consumption is a constant calculated empirically. ***Annotation:*** ```rust -/// Map elements from Fp to G1 subset of BLS12-381 curve -/// -/// # Arguments -/// -/// * `value` - 48 bytes, the element from Fp -- unsigned integer < p -/// -/// # Errors -/// -/// If `value_len + value_ptr` points outside the memory or the registers -/// use more memory than the limit, the function returns -/// `MemoryAccessViolation`. -/// -/// If value_len != 48 the function return `BLS12381InvalidInput`. -/// -/// # Cost -/// -/// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_map_fp_to_g1_base` pub fn bls12381_map_fp_to_g1( &mut self, value_len: u64, @@ -1184,24 +1070,6 @@ The gas consumption is a constant calculated empirically. ***Annotation:*** ```rust -/// Map elements from Fp2 to G2 subset of E'(Fp2) BLS12-381 curve -/// -/// # Arguments -/// -/// * `value` - 96 bytes, the element from Fp2 -- two unsigned integer < p -/// -/// # Errors -/// -/// If `value_len + value_ptr` points outside the memory or the registers -/// use more memory than the limit, the function returns -/// `MemoryAccessViolation`. -/// -/// If value_len != 96 the function return `BLS12381InvalidInput`. -/// -/// # Cost -/// -/// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_map_fp2_to_g2_base` pub fn bls12381_map_fp2_to_g2( &mut self, value_len: u64, @@ -1282,34 +1150,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. ***Annotation:*** ```rust -/// Computes pairing check on BLS12-381 curve. -/// \prod_i e(g_{1 i}, g_{2 i}) should be equal one, e(g1, g2) is pairing -/// -/// # Arguments -/// -/// * `value` - sequence of (g1:G1, g2:G2), where -/// G2 is subgroup point (x:Fp2, y:Fp2) on BLS12-381 twist, -/// BLS12-381 twist is Y^2 = X^3 + 4(i + 1) curve over Fp2 -/// Fp2 is complex field element (re: Fp, im: Fp) -/// G1 is point (x:Fp, y:Fp) on BLS12-381, -/// BLS12-381 is Y^2 = X^3 + 4 curve over Fp -/// -/// `value` is encoded a as packed, big-endian -/// `[(([u8; 48], [u8; 48]), ([u8; 96], [u8; 96]))]` slice. -/// -/// # Errors -/// -/// If `value_len + value_ptr` points outside the memory than -/// the function returns `MemoryAccessViolation`. -/// -/// If point coordinates are not on curve `value.len()%288!=0`, -/// the function returns `BLS12381InvalidInput`. -/// -/// # Cost -/// -/// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_pairing_check_base + bls12381_pairing_check_element * num_elements` -pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Result { +pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Result; ``` #### bls12381_decompress_g1 @@ -1358,29 +1199,6 @@ A and B are constants calculated empirically. ***Annotation:*** ```rust -/// Decompress points on BLS12-381 curve. -/// -/// # Arguments -/// -/// * `value` - sequence of pi points (x:Fp) on BLS-381 curve -/// BLS12-381 is Y^2 = X^3 + 4 curve over Fp. -/// -/// `value` is encoded as packed `[[u8; 48]]` slice. -/// -/// # Output -/// sequence of pi points (x: Fp; y: Fp) in decompress format: [([u8; 48], [u8; 48])] -/// -/// # Errors -/// -/// If `value_len + value_ptr` points outside the memory or the registers -/// use more memory than the limit, the function returns `MemoryAccessViolation`. -/// -/// If `value.len()%48 != 0` the function returns `BLS12381InvalidInput`. -/// -/// # Cost -/// -/// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_decompress_g1_base + bls12381_decompress_g1_element * num_elements` pub fn bls12381_decompress_g1(&mut self, value_len: u64, value_ptr: u64, @@ -1433,30 +1251,6 @@ A and B are constants calculated empirically. ***Annotation:*** ```rust -/// Decompress points on twisted BLS12-381 curve. -/// -/// # Arguments -/// -/// * `value` - sequence of pi points (x:Fp2) on twisted BLS-381 curve -/// BLS12-381 is Y^2 = X^3 + (4 + i) curve over Fp2. -/// -/// `value` is encoded as packed `[[u8; 96]]` slice. -/// -/// # Output -/// sequence of pi points (x: Fp2; y: Fp2) in decompress format: [([u8; 96], [u8; 96])] -/// -/// # Errors -/// -/// If `value_len + value_ptr` points outside the memory or the registers -/// use more memory than the limit, the function returns `MemoryAccessViolation`. -/// -/// If `value.len()%96 != 0`, -/// the function returns `BLS12381InvalidInput`. -/// -/// # Cost -/// -/// `base + write_register_base + write_register_byte * num_bytes + -/// bls12381_decompress_g2_base + bls12381_decompress_g2_element * num_elements` pub fn bls12381_decompress_g2(&mut self, value_len: u64, value_ptr: u64, From ab83571435ef6aafd1284d3c2ea31b63e2c2b41d Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 17:10:34 +0200 Subject: [PATCH 070/163] input parsing description --- neps/nep-0488.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b49df2244..dd5cd869f 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -779,6 +779,13 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Annotation:*** +The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, +if the `value_len` is `u64::MAX` the input will be obtained from register. + +The output data will be written to register with `register_id` id. + +The ERROR_CODE is returned. + ```rust pub fn bls12381_g1_sum(&mut self, value_len: u64, @@ -835,6 +842,13 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Annotation:*** +The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, +if the `value_len` is `u64::MAX` the input will be obtained from register. + +The output data will be written to register with `register_id` id. + +The ERROR_CODE is returned. + ```rust pub fn bls12381_g2_sum(&mut self, value_len: u64, @@ -907,6 +921,13 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Annotation:*** +The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, +if the `value_len` is `u64::MAX` the input will be obtained from register. + +The output data will be written to register with `register_id` id. + +The ERROR_CODE is returned. + ```rust pub fn bls12381_g1_multiexp( &mut self, @@ -979,6 +1000,13 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Annotation:*** +The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, +if the `value_len` is `u64::MAX` the input will be obtained from register. + +The output data will be written to register with `register_id` id. + +The ERROR_CODE is returned. + ```rust pub fn bls12381_g2_multiexp( &mut self, @@ -1024,6 +1052,13 @@ The gas consumption is a constant calculated empirically. ***Annotation:*** +The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, +if the `value_len` is `u64::MAX` the input will be obtained from register. + +The output data will be written to register with `register_id` id. + +The ERROR_CODE is returned. + ```rust pub fn bls12381_map_fp_to_g1( &mut self, @@ -1069,6 +1104,13 @@ The gas consumption is a constant calculated empirically. ***Annotation:*** +The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, +if the `value_len` is `u64::MAX` the input will be obtained from register. + +The output data will be written to register with `register_id` id. + +The ERROR_CODE is returned. + ```rust pub fn bls12381_map_fp2_to_g2( &mut self, @@ -1149,6 +1191,11 @@ Here you can find benchmark test vectors for EIP-2537[^46]. ***Annotation:*** +The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, +if the `value_len` is `u64::MAX` the input will be obtained from register. + +The ERROR_CODE is returned. + ```rust pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Result; ``` @@ -1198,6 +1245,13 @@ A and B are constants calculated empirically. ***Annotation:*** +The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, +if the `value_len` is `u64::MAX` the input will be obtained from register. + +The output data will be written to register with `register_id` id. + +The ERROR_CODE is returned. + ```rust pub fn bls12381_decompress_g1(&mut self, value_len: u64, @@ -1250,6 +1304,13 @@ A and B are constants calculated empirically. ***Annotation:*** +The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, +if the `value_len` is `u64::MAX` the input will be obtained from register. + +The output data will be written to register with `register_id` id. + +The ERROR_CODE is returned. + ```rust pub fn bls12381_decompress_g2(&mut self, value_len: u64, From 1526529bc7559a75030f3b62a0d3bc73419f7b7c Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 17:43:03 +0200 Subject: [PATCH 071/163] rewrite sentence about library --- neps/nep-0488.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index dd5cd869f..30aaa2b35 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1341,7 +1341,8 @@ In addition, there are implementations in other languages that are not so intere 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]. This implementation is based on *blst* library[^30]. This library one of the fastest[^45] and the most audited[^55]. +One of the possible libraries to use is *blst* library[^30]. This library shows a good performance[^45] and passed some audits[^55]. +The draft implementation in nearcore, which is based on this library, you can find by this link[^54]. ## Security Implications From 6e9c7b0728791b93fea92fb18ea13f54c6acc496 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 18:13:23 +0200 Subject: [PATCH 072/163] add negative factor --- neps/nep-0488.md | 1 + 1 file changed, 1 insertion(+) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 30aaa2b35..3c184a3ce 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1376,6 +1376,7 @@ In the future, it is possible to support work with other curves, not only BLS12- ### Negative - The appearance of dependence on the library which supports BLS12-381 curves operations. +- We will need to maintain operations with BLS12-381 curve forever, even if vulnerabilities are found and it is no longer safe to use. ### Backward Compatibility From fe0151d0d5c1eac934cc7d7777fb5ad12ffe73bb Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Fri, 17 Nov 2023 21:00:41 +0200 Subject: [PATCH 073/163] extra motivation --- neps/nep-0488.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 3c184a3ce..4faa5c1e5 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -16,7 +16,7 @@ Native NEAR runtime functions for operations on the BLS12-381 curve. This NEP in ## Motivation -The BLS12-381[^1],[^11],[^52] is a widely used[^2],[^3],[^4],[^5],[^6],[^7] elliptic curve with 120+ bits security level[^8], which supports *the pairing operation*. It is an alternative for the BN254 elliptic curve[^9],[^12], which also supports the aggregation and has already been implemented on NEAR as host functions[^10]. Recent research shows that the BN254 security level is lower than 100-bit[^13]. Also, there is a tendency to switch from BN254 to BLS12-381 in the industry – ZCash[^14], Ethereum[^15],[^3], Tezos[^16],[^5] or just use it – Filecoin[^6]. +The BLS12-381[^1],[^11],[^52] is a widely used[^2],[^3],[^4],[^5],[^6],[^7] elliptic curve with 120+ bits security level[^8], which supports *the pairing operation*. It is an alternative for the BN254 elliptic curve[^9],[^12], which also supports the aggregation and has already been partly implemented on NEAR as host functions[^10]. Recent research shows that the BN254 security level is lower than 100-bit[^13]. Also, there is a tendency to switch from BN254 to BLS12-381 in the industry – ZCash[^14], Ethereum[^15],[^3], Tezos[^16],[^5] or just use it – Filecoin[^6]. The host functions implementation for the BLS12-381 curve operations from this NEP will allow for efficient verification of the BLS signature and zkSNARKs. Currently, BLS signature verification for BLS12-381 is impossible due to the 300 TGas gas limit per one transaction on Near. @@ -42,6 +42,10 @@ In this NEP, we propose to add the following functions as host functions: Please note that some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. That is why we have decided to move it into separate functions. All the other functions in this NEP accept only decompressed points to be simple and to have optimized gas consumption. +Currently, Near supports only BN254 operations needed for verifying zkSNARKs, and it is not enough for verifying BLS-signatures. +For BLS-signature verification we introduced the `bls12381_map_fp2_to_g2` which allows the mapping of the message to the element of the group. +Also, we include all functions for both G1 and G2 groups. + *multiexp* functions are helpful in doing zkSNARKs verification. They also could be optimized by using the Pippenger algorithm[^25]. Using the functions introduced above, we can reproduce all functionality from EIP-2537[^15], which is useful for Aurora[^24] to support Ethereum functionality on Near. From 8609d5bc057f33a7f63af688e86797a1bca13c68 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 20 Nov 2023 10:33:09 +0200 Subject: [PATCH 074/163] clarify the bit order --- neps/nep-0488.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 4faa5c1e5..0cd8acd7a 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -598,8 +598,8 @@ $E(F_p)$ is encoded as `[u8; 96]`: - $x \in F_p$ `[u8; 48]` - $y \in F_p$ `[u8; 48]` -*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. -If the second bit is set to 1, all others bits should be set to 0. Other encoding should throw an error. +*The second-highest bit* is used to mark a point on infinity, if the second-highest bit is set to 1 — it is an infinity point. +If the second-highest bit is set to 1, all others bits should be set to 0. Other encoding should throw an error. Encoding point on infinity: @@ -614,12 +614,12 @@ The rule of encoding is consistent with zkcrypto[^53] and with implementation in The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ in compressed form are encoded in `[u8; 48]` as *big-endian* encoded $x \in F_p$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. -*The first bit* should be set as 1. This bit indicates that point is encoded in compressed form. +*The highest bit* should be set as 1. This bit indicates that point is encoded in compressed form. -*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. -If the second bit is set to 1, all others except first two bits should be set to 0. Other encoding should throw an error. +*The second-highest bit* is used to mark a point on infinity, if the second-highest bit is set to 1 — it is an infinity point. +If the second-highest bit is set to 1, all others except first two bits should be set to 0. Other encoding should throw an error. -To represent the sign of the $y$ *the third bit* of x encoding is used. If the first bit = 0 the $y$ is positive, if the first bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y = p - y$. +To represent the sign of the $y$ *the third-highest bit* of x encoding is used. If the first bit = 0 the $y$ is positive, if the first bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y = p - y$. The $x \in F_p$ encoded as `[u8; 48]` bytes according to the rules from section “Extension fields elements $F_{p}$” . @@ -654,8 +654,8 @@ $E'(F_{p^2})$ is encoded as `[u8; 192]`: - $c_1 \in F_p$ `[u8; 48]` - $c_0 \in F_p$ `[u8; 48]` -*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. -If the second bit is set to 1, all others bits should be set to 0. Other encoding should throw an error. +*The second-highest bit* is used to mark a point on infinity, if the second-highest bit is set to 1 — it is an infinity point. +If the second-highest bit is set to 1, all others bits should be set to 0. Other encoding should throw an error. Encoding point on infinity: @@ -670,12 +670,12 @@ The rule of encoding is consistent with zkcrypto[^53] and with implementation in The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ in compressed form are encoded in `[u8; 96]` as *big-endian* encoded $x \in F_{p^2}$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. -*The first bit* should be set as 1. This bit indicates that point is encoded in compressed form. +*The highest bit* should be set as 1. This bit indicates that point is encoded in compressed form. -*The second bit* is used to mark a point on infinity, if the second bit is set to 1 — it is an infinity point. -If the second bit is set to 1, all others except first two bits should be set to 0. Other encoding should throw an error. +*The second-highest bit* is used to mark a point on infinity, if the second-highest bit is set to 1 — it is an infinity point. +If the second-highest bit is set to 1, all others except first two bits should be set to 0. Other encoding should throw an error. -To represent the sign of the $y$ *the third bit* of x encoding is used. If the first bit = 0 the $y$ is positive, if the first bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y$: first compare $c_1$ and second $c_0$. +To represent the sign of the $y$ *the third-highest bit* of x encoding is used. If the bit = 0 the $y$ is positive, if the bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y$: first compare $c_1$ and second $c_0$. The $x \in F_{p^2}$ encoded as `[u8; 96]` bytes according to the rules from section “Extension fields elements $F_{p^2}$” . From 7bcb52f4fe0513adb154dd3bcf7c359522619655 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 20 Nov 2023 11:44:53 +0200 Subject: [PATCH 075/163] fix formula --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 0cd8acd7a..101d81689 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -668,7 +668,7 @@ The rule of encoding is consistent with zkcrypto[^53] and with implementation in #### Compressed points on twisted curve E'(Fp2) -The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ in compressed form are encoded in `[u8; 96]` as *big-endian* encoded $x \in F_{p^2}$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. +The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ in compressed form are encoded in `[u8; 96]` as *big-endian* encoded $x \in F_{p^2}$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4(u + 1)}$. *The highest bit* should be set as 1. This bit indicates that point is encoded in compressed form. From 4b225f0fd19c45de88e5e7cff272bd6452994b9f Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 20 Nov 2023 12:09:08 +0200 Subject: [PATCH 076/163] fix typo --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 101d81689..15c58afc9 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -105,7 +105,7 @@ Notation: $H \subseteq G$ 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 some technical reason (for `pairing` operation which we will define later), we will work not with the whole $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],[^51]: From 22529fbffb0a61604a401133ef7803eaca86a0b1 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 20 Nov 2023 17:58:27 +0200 Subject: [PATCH 077/163] hard limit --- neps/nep-0488.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 15c58afc9..7ab15f9c2 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -728,7 +728,7 @@ The $E(F_p)$ curve, points on the curve, multiplication on -1, and the additio Note: we take as input any points on the curve, not only from $G_1$ -***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. @@ -761,7 +761,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain - The coding of field elements is incorrect, but by modulo p it is a correct element on the curve - The coding of field elements is incorrect, an incorrect extra bit, which shows that it is decompressed encoding. - Sum with the maximum number of elements -- Too many points for sum +- Number of points more than 1000 - Incorrect len of input - Empty input - Generate points on the curve and check that the result doesn’t depend on permutation @@ -778,6 +778,7 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Error cases:*** - The input length is not divided by 97 +- Number of points more than 1000 - Too much memory is used - The sign value is not 0 or 1 @@ -807,7 +808,7 @@ The $E'(F_{p^2})$ curve, points on the curve, multiplication on -1, and the add Note: we take as input any points on the curve, not only from $G_2$ -***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. @@ -842,6 +843,7 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case - The input length is not divided by 193 - Too much memory is used +- Number of points more than 1000 - The sign value is not 0 or 1 ***Annotation:*** @@ -879,7 +881,7 @@ Note: - We take as input any points on the curve, not only from $G_1$. - The scalar is an arbitrary unsigned integer and can be bigger than the group order. -***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. @@ -922,6 +924,7 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether - The input length is not divided by 128 - Too much memory is used +- Number of points more than 1000 ***Annotation:*** @@ -962,7 +965,7 @@ Note: ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. -Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. +Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** @@ -1001,6 +1004,7 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether - Too much memory is used - Field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve +- Number of points more than 1000 ***Annotation:*** @@ -1147,7 +1151,7 @@ $$ We don’t calculate the pairing function itself: the result will be in the huge field, and in all known applications only such a check is necessary. -***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $G_1 \subset E(F_p)$ — `96 bytes` and point from $G_2 \subset E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the concatenation of uncompressed point from $G_1 \subset E(F_p)$ — `96 bytes` and point from $G_2 \subset E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. ***Output:*** @@ -1192,6 +1196,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - The input length is not divided by 288 - Too much memory is used +- Number of pairs more than 1000 ***Annotation:*** @@ -1208,7 +1213,7 @@ pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Resu ***Description:*** Function decompress compressed points from $E(F_p)$. The input is an arbitrary number of points $p_i \in E(F_p)$ in compressed format, and the output is the same number of points from $E(F_p)$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. -***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in compressed form. Expected `48*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E(F_p)$. More details are in the Curve Points Encoding section. +***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in compressed form. Expected `48*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the compressed point from $E(F_p)$. More details are in the Curve Points Encoding section. ***Output:*** @@ -1246,6 +1251,7 @@ A and B are constants calculated empirically. - The input length is not divided by 48 - Too much memory is used +- Number of points more than 1000 ***Annotation:*** @@ -1267,7 +1273,7 @@ pub fn bls12381_decompress_g1(&mut self, ***Description:*** Function decompress compressed points from $E'(F_{p^2})$. The input is an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format, and the output is the same number of points from $E'(F_{p^2})$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. -***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in compressed form. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. +***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in compressed form. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the compressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. ***Output:*** @@ -1305,6 +1311,7 @@ A and B are constants calculated empirically. - The input length is not divided by 96 - Too much memory is used +- Number of points more than 1000 ***Annotation:*** From 7588008b7141290215401eb30df296682c3516db Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 21 Nov 2023 14:48:11 +0200 Subject: [PATCH 078/163] improve test case for sum --- neps/nep-0488.md | 73 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 7ab15f9c2..ebd938696 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -751,25 +751,70 @@ Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain ***Test cases:*** -- Correct points in G1 group -- One of the points is 0 -- One of the points is not in G1 group but on the curve -- The result is 0 -- Correct addition with one point -- Point not on the curve +_Tests for the sum of two points_ + +In this section, I would like to test that the sum of two correct elements on the curve works correctly. +We can use the following methods: + +- Take the points on the curve with known answer and compare results. For example, we can use tests for EIP-2537 +- Generate the random points on the curve and check the P + Q = Q + P +- Generate the random points from G1 and check that sum also in G1 +- Use the implementation from another library, generate the random points on curve and compare results + +Edge cases: + +- Points not from G1 +- 0 + 0 = 0 +- P + 0 = 0 + P = P +- P + (-P) = (-P) + P = 0 +- P + P (tangent to the curve) +- (-(P + P)) + P (no third point of intersection with a curve) + + +_Tests for inversion_ + +In this section, I would like to check that point inverse works correctly. + +- Generate random points on the curve and check P - P = -P + P = 0 +- Generate random points on the curve and check -(-P) = P +- Generate random points from G1 and check -P also from G1 +- Use the implementation from another library, generate the random points on curve and compare results + +Edge cases: + +- Point not from G1 +- -0 + + +_Tests for incorrect data_ + +In this section, I would like to check that incorrect input data is handled properly + +- Incorrect len of input +- Incorrect sign value (not 0 or 1) - The coding of field elements is incorrect, but if take only the suffix it will be the correct point on the curve - The coding of field elements is incorrect, but by modulo p it is a correct element on the curve - The coding of field elements is incorrect, an incorrect extra bit, which shows that it is decompressed encoding. -- Sum with the maximum number of elements +- Point not on the curve +- The point on infinity encoded incorrectly - Number of points more than 1000 -- Incorrect len of input -- Empty input -- Generate points on the curve and check that the result doesn’t depend on permutation + + +_Tests for the sum of an arbitrary amount of points_ + +In this section, we are checking that the sum of an arbitrary amount of points works properly + +- Generate random points on the curve and check that sum of random permutation is the same +- Use the implementation from another library, generate the random points on curve and compare results - Generate points and cross-test the result with multiexp function. -- Correct input with negative signs -- Incorrect sign value (not 0 or 1) -- Correct input with negative signs for points with $y > \frac{p}{2}$ -- Sum of the two equal points with opposite sign +- Generate a random points from G1 and check that sum also from G1 + +Edge cases: + +- Empty input +- Sum with the maximum number of elements +- One point + ***Tests References:*** From 43a7b3fceb941e46d90d2030ae17d16f42d60890 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 21 Nov 2023 16:31:11 +0200 Subject: [PATCH 079/163] dec to hex --- neps/nep-0488.md | 198 +++++++++++++++++++++++------------------------ 1 file changed, 97 insertions(+), 101 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index ebd938696..dc656ea08 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -72,7 +72,7 @@ In the case of BLS12-381 equation is $y^2 \equiv x^3 + 4 \mod p$[^15],[^51],[^14 - $A = 0$ - $B = 4$ -- $p = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787$ +- $p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab$ **Definition:** Let’s $P \in E(F_q)$ have coordinates (x, y), define $-P$ as a point on a curve with coordinates (x, -y). @@ -109,7 +109,7 @@ For some technical reason (for `pairing` operation which we will define later), For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$[^15],[^51]: -- $r = 52435875175126190479447740508185965837690552500527637822603658699938581184513$ +- $r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001$ #### Field extension @@ -174,14 +174,12 @@ In most cases we will work with points from $G_2' \subset E'(F_{p^2})$ and use f **Definition:** if in the group $G$ exists element g, such as $\textbraceleft g, 2g, 3g, \ldots, |G|g \textbraceright = G$, the group G called ***cyclic group*** and g called ***generator*** - - $G_1$ and $G_2$ are cyclic subgroups with the following generators[^15],[^51]: $G_1$: -- $x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507$ -- $y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569$ +- $x = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb$ +- $y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1$ For $(x', y') \in G_2 \subset E'(F_{p^2}):$ $$x' = x_0 + x_1u$$ @@ -190,10 +188,10 @@ $$y' = y_0 + y_1u$$ $G_2$: -- $x_0 = 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160$ -- $x_1 = 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758$ -- $y_0 = 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905$ -- $y_1 = 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582$ +- $x_0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8$ +- $x_1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e$ +- $y_0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801$ +- $y_1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be$ **Definition:** ***Cofactor*** is the ratio of the size of the whole group G to the size of subgroup H: @@ -204,12 +202,11 @@ $$ Cofactor $G_1\colon h = |E(F_p)|/r$[^51] -$$h = 76329603384216526031706109802092473003$$ +$$h = 0x396c8c005555e1568c00aaab0000aaab$$ Cofactor $G_2\colon h' = |E'(F_{p^2})|/r$[^51] -$$h' = 30550233393126834420099975319312150421446601925418814266766403298226760418297188402650742735925997784783227283904\\ -1616661285803823378372096355777062779109$$ +$$h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5$$ #### Pairing @@ -222,7 +219,7 @@ The main pairing properties is: For calculating this function we will need the algorithm, called Miller Loop, and to effectively perform this algorithm we will need to know the key parameter for BLS curve $x$ -$$ x = -15132376222941642752$$ +$$ x = -0xd201000000010000$$ You can find this parameter in: @@ -235,7 +232,7 @@ You can find this parameter in: The parameters for the BLS12-381: -Base field modulus $p = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787$ +Base field modulus $p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab$ $$ E\colon y^2 \equiv x^3 + 4 @@ -245,7 +242,7 @@ $$ E'\colon y^2 \equiv x^3 + 4(u + 1) $$ -Main subgroup order $r = 52435875175126190479447740508185965837690552500527637822603658699938581184513$ +Main subgroup order $r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001$ $$ F_{p^2} = F_p[u] / (u^2 + 1) @@ -261,26 +258,25 @@ $$ Generator for G1: -- $x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507$ -- $y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569$ +- $x = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb$ +- $y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1$ Generator for G2: -- $x_0 = 352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160$ -- $x_1 = 3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758$ -- $y_0 = 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905$ -- $y_1 = 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582$ +- $x_0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8$ +- $x_1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e$ +- $y_0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801$ +- $y_1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be$ Cofactor for G1: -$$h = 76329603384216526031706109802092473003$$ +$$h = 0x396c8c005555e1568c00aaab0000aaab$$ Cofactor for G2: -$$h' = 30550233393126834420099975319312150421446601925418814266766403298226760418297188402650742735925997784783227283904\\ -1616661285803823378372096355777062779109$$ +$$h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5$$ Key BLS12-381 parameter used in Miller Loop: -$$x = -15132376222941642752$$ +$$x = -0xd201000000010000$$ All parameters were taken from[^15],[^51] and [^14], all of them consistent between sources. @@ -400,8 +396,8 @@ In this section, the pseudocode for the full mapping algorithm is shown. All the **Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: -- $A = 12190336318893619529228877361869031420615612348429846051986726275283378313155663745811710833465465981901188123677$ -- $B = 2906670324641927570491258158026293881577086121416628140204402091718288198173574630967936031029026176254968826637280$ +- $A = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d$ +- $B = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0$ - Z = 11 **Step 2:** Isogeny from E_inner to curve $E(F_p)$: @@ -423,74 +419,74 @@ we would like to calculate the correspondent coordinates $(x, y) \in E(F_p)$. The constants to compute $x_{num}$: -- $k_{(1,0)} = 2712959285290305970661081772124144179193819192423276218370281158706191519995889425075952244140278856085036081760695$ -- $k_{(1,1)} = 3564859427549639835253027846704205725951033235539816243131874237388832081954622352624080767121604606753339903542203$ -- $k_{(1,2)} = 2051387046688339481714726479723076305756384619135044672831882917686431912682625619320120082313093891743187631791280$ -- $k_{(1,3)} = 3612713941521031012780325893181011392520079402153354595775735142359240110423346445050803899623018402874731133626465$ -- $k_{(1,4)} = 2247053637822768981792833880270996398470828564809439728372634811976089874056583714987807553397615562273407692740057$ -- $k_{(1,5)} = 3415427104483187489859740871640064348492611444552862448295571438270821994900526625562705192993481400731539293415811$ -- $k_{(1,6)} = 2067521456483432583860405634125513059912765526223015704616050604591207046392807563217109432457129564962571408764292$ -- $k_{(1,7)} = 3650721292069012982822225637849018828271936405382082649291891245623305084633066170122780668657208923883092359301262$ -- $k_{(1,8)} = 1239271775787030039269460763652455868148971086016832054354147730155061349388626624328773377658494412538595239256855$ -- $k_{(1,9)} = 3479374185711034293956731583912244564891370843071137483962415222733470401948838363051960066766720884717833231600798$ -- $k_{(1,10)} = 2492756312273161536685660027440158956721981129429869601638362407515627529461742974364729223659746272460004902959995$ -- $k_{(1,11)} = 1058488477413994682556770863004536636444795456512795473806825292198091015005841418695586811009326456605062948114985$ +- $k_{(1,0)} = 0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7$ +- $k_{(1,1)} = 0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb$ +- $k_{(1,2)} = 0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0$ +- $k_{(1,3)} = 0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861$ +- $k_{(1,4)} = 0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9$ +- $k_{(1,5)} = 0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983$ +- $k_{(1,6)} = 0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84$ +- $k_{(1,7)} = 0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e$ +- $k_{(1,8)} = 0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317$ +- $k_{(1,9)} = 0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e$ +- $k_{(1,10)} = 0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b$ +- $k_{(1,11)} = 0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229$ The constants to compute $x_{den}$: -- $k_{(2,0)} = 1353092447850172218905095041059784486169131709710991428415161466575141675351394082965234118340787683181925558786844$ -- $k_{(2,1)} = 2822220997908397120956501031591772354860004534930174057793539372552395729721474912921980407622851861692773516917759$ -- $k_{(2,2)} = 1717937747208385987946072944131378949849282930538642983149296304709633281382731764122371874602115081850953846504985$ -- $k_{(2,3)} = 501624051089734157816582944025690868317536915684467868346388760435016044027032505306995281054569109955275640941784$ -- $k_{(2,4)} = 3025903087998593826923738290305187197829899948335370692927241015584233559365859980023579293766193297662657497834014$ -- $k_{(2,5)} = 2224140216975189437834161136818943039444741035168992629437640302964164227138031844090123490881551522278632040105125$ -- $k_{(2,6)} = 1146414465848284837484508420047674663876992808692209238763293935905506532411661921697047880549716175045414621825594$ -- $k_{(2,7)} = 3179090966864399634396993677377903383656908036827452986467581478509513058347781039562481806409014718357094150199902$ -- $k_{(2,8)} = 1549317016540628014674302140786462938410429359529923207442151939696344988707002602944342203885692366490121021806145$ -- $k_{(2,9)} = 1442797143427491432630626390066422021593505165588630398337491100088557278058060064930663878153124164818522816175370$ +- $k_{(2,0)} = 0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c$ +- $k_{(2,1)} = 0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff$ +- $k_{(2,2)} = 0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19$ +- $k_{(2,3)} = 0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8$ +- $k_{(2,4)} = 0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e$ +- $k_{(2,5)} = 0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5$ +- $k_{(2,6)} = 0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a$ +- $k_{(2,7)} = 0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e$ +- $k_{(2,8)} = 0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641$ +- $k_{(2,9)} = 0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a$ The constants used to compute $y_{num}$: -- $k_{(3,0)} = 1393399195776646641963150658816615410692049723305861307490980409834842911816308830479576739332720113414154429643571$ -- $k_{(3,1)} = 2968610969752762946134106091152102846225411740689724909058016729455736597929366401532929068084731548131227395540630$ -- $k_{(3,2)} = 122933100683284845219599644396874530871261396084070222155796123161881094323788483360414289333111221370374027338230$ -- $k_{(3,3)} = 303251954782077855462083823228569901064301365507057490567314302006681283228886645653148231378803311079384246777035$ -- $k_{(3,4)} = 1353972356724735644398279028378555627591260676383150667237975415318226973994509601413730187583692624416197017403099$ -- $k_{(3,5)} = 3443977503653895028417260979421240655844034880950251104724609885224259484262346958661845148165419691583810082940400$ -- $k_{(3,6)} = 718493410301850496156792713845282235942975872282052335612908458061560958159410402177452633054233549648465863759602$ -- $k_{(3,7)} = 1466864076415884313141727877156167508644960317046160398342634861648153052436926062434809922037623519108138661903145$ -- $k_{(3,8)} = 1536886493137106337339531461344158973554574987550750910027365237255347020572858445054025958480906372033954157667719$ -- $k_{(3,9)} = 2171468288973248519912068884667133903101171670397991979582205855298465414047741472281361964966463442016062407908400$ -- $k_{(3,10)} = 3915937073730221072189646057898966011292434045388986394373682715266664498392389619761133407846638689998746172899634$ -- $k_{(3,11)} = 3802409194827407598156407709510350851173404795262202653149767739163117554648574333789388883640862266596657730112910$ -- $k_{(3,12)} = 1707589313757812493102695021134258021969283151093981498394095062397393499601961942449581422761005023512037430861560$ -- $k_{(3,13)} = 349697005987545415860583335313370109325490073856352967581197273584891698473628451945217286148025358795756956811571$ -- $k_{(3,14)} = 885704436476567581377743161796735879083481447641210566405057346859953524538988296201011389016649354976986251207243$ -- $k_{(3,15)} = 3370924952219000111210625390420697640496067348723987858345031683392215988129398381698161406651860675722373763741188$ +- $k_{(3,0)} = 0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33$ +- $k_{(3,1)} = 0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696$ +- $k_{(3,2)} = 0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6$ +- $k_{(3,3)} = 0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb$ +- $k_{(3,4)} = 0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb$ +- $k_{(3,5)} = 0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0$ +- $k_{(3,6)} = 0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2$ +- $k_{(3,7)} = 0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29$ +- $k_{(3,8)} = 0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587$ +- $k_{(3,9)} = 0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30$ +- $k_{(3,10)} = 0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132$ +- $k_{(3,11)} = 0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e$ +- $k_{(3,12)} = 0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8$ +- $k_{(3,13)} = 0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133$ +- $k_{(3,14)} = 0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b$ +- $k_{(3,15)} = 0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604$ The constants to compute $y_{den}$: -- $k_{(4,0)} = 3396434800020507717552209507749485772788165484415495716688989613875369612529138640646200921379825018840894888371137$ -- $k_{(4,1)} = 3907278185868397906991868466757978732688957419873771881240086730384895060595583602347317992689443299391009456758845$ -- $k_{(4,2)} = 854914566454823955479427412036002165304466268547334760894270240966182605542146252771872707010378658178126128834546$ -- $k_{(4,3)} = 3496628876382137961119423566187258795236027183112131017519536056628828830323846696121917502443333849318934945158166$ -- $k_{(4,4)} = 1828256966233331991927609917644344011503610008134915752990581590799656305331275863706710232159635159092657073225757$ -- $k_{(4,5)} = 1362317127649143894542621413133849052553333099883364300946623208643344298804722863920546222860227051989127113848748$ -- $k_{(4,6)} = 3443845896188810583748698342858554856823966611538932245284665132724280883115455093457486044009395063504744802318172$ -- $k_{(4,7)} = 3484671274283470572728732863557945897902920439975203610275006103818288159899345245633896492713412187296754791689945$ -- $k_{(4,8)} = 3755735109429418587065437067067640634211015783636675372165599470771975919172394156249639331555277748466603540045130$ -- $k_{(4,9)} = 3459661102222301807083870307127272890283709299202626530836335779816726101522661683404130556379097384249447658110805$ -- $k_{(4,10)} = 742483168411032072323733249644347333168432665415341249073150659015707795549260947228694495111018381111866512337576$ -- $k_{(4,11)} = 1662231279858095762833829698537304807741442669992646287950513237989158777254081548205552083108208170765474149568658$ -- $k_{(4,12)} = 1668238650112823419388205992952852912407572045257706138925379268508860023191233729074751042562151098884528280913356$ -- $k_{(4,13)} = 369162719928976119195087327055926326601627748362769544198813069133429557026740823593067700396825489145575282378487$ -- $k_{(4,14)} = 2164195715141237148945939585099633032390257748382945597506236650132835917087090097395995817229686247227784224263055$ +- $k_{(4,0)} = 0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1$ +- $k_{(4,1)} = 0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d$ +- $k_{(4,2)} = 0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2$ +- $k_{(4,3)} = 0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416$ +- $k_{(4,4)} = 0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d$ +- $k_{(4,5)} = 0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac$ +- $k_{(4,6)} = 0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c$ +- $k_{(4,7)} = 0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9$ +- $k_{(4,8)} = 0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a$ +- $k_{(4,9)} = 0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55$ +- $k_{(4,10)} = 0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8$ +- $k_{(4,11)} = 0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092$ +- $k_{(4,12)} = 0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc$ +- $k_{(4,13)} = 0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7$ +- $k_{(4,14)} = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f$ **Step 3:** Effective cofactor: -$$h_{eff} = 15132376222941642753$$ +$$h_{eff} = 0xd201000000010001$$ ***Fp2-to-G2 mapping*** @@ -521,46 +517,46 @@ we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2}) The constants used to compute $x_{num}$ are as follows: -- $$k_{(1,0)} = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 + - 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235542 \cdot I$$ +- $$k_{(1,0)} = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 + + 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 \cdot I$$ -- $$k_{(1,1)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706522 \cdot I$$ +- $$k_{(1,1)} = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a \cdot I$$ -- $$k_{(1,2)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706526 + - 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853261 \cdot I$$ +- $$k_{(1,2)} = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e + + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d \cdot I$$ -- $$k_{(1,3)} = 3557697382419259905260257622876359250272784728834673675850718343221361467102966990615722337003569479144794908942033$$ +- $$k_{(1,3)} = 0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1$$ The constants used to compute $x_{den}$ are as follows: -- $$k_{(2,0)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559715 \cdot I$$ +- $$k_{(2,0)} = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63 \cdot I$$ -- $$k_{(2,1)} = 12 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559775 \cdot I$$ +- $$k_{(2,1)} = 0xc + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f \cdot I$$ The constants used to compute $y_{num}$ are as follows: -- $$k_{(3,0)} = 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 +\\ - 3261222600550988246488569487636662646083386001431784202863158481286248011511053074731078808919938689216061999863558 \cdot I$$ +- $$k_{(3,0)} = 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 +\\ + 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 \cdot I$$ -- $$k_{(3,1)} = 889424345604814976315064405719089812568196182208668418962679585805340366775741747653930584250892369786198727235518 \cdot I$$ +- $$k_{(3,1)} = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be \cdot I$$ -- $$k_{(3,2)} = 2668273036814444928945193217157269437704588546626005256888038757416021100327225242961791752752677109358596181706524 + - 1334136518407222464472596608578634718852294273313002628444019378708010550163612621480895876376338554679298090853263 \cdot I$$ +- $$k_{(3,2)} = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c + + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f \cdot I$$ -- $$k_{(3,3)} = 2816510427748580758331037284777117739799287910327449993381818688383577828123182200904113516794492504322962636245776$$ +- $$k_{(3,3)} = 0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10$$ The constants used to compute $y_{den}$ are as follows: -- $$k_{(4,0)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 + - 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559355 \cdot I$$ +- $$k_{(4,0)} = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb + + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb \cdot I$$ -- $$k_{(4,1)} = 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559571 \cdot I$$ +- $$k_{(4,1)} = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3 \cdot I$$ -- $$k_{(4,2)} = 18 + 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559769 \cdot I$$ +- $$k_{(4,2)} = 0x12 + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99 \cdot I$$ **Step 3:** Effective cofactor: -- $$h_{eff} = 209869847837335686905080341498658477663839067235703451875306851526599783796572738804459333109033834234622528588876978987822447936461846631641690358257586228683615991308971558879306463436166481$$ +- $$h_{eff} = 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551$$ ### Curve points encoding From dc1b001ced30b14bbd3f99c2df9a2139ba974b12 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 21 Nov 2023 18:30:40 +0200 Subject: [PATCH 080/163] clean up --- neps/nep-0488.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index dc656ea08..455a28755 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -7,12 +7,12 @@ DiscussionsTo: https://github.com/nearprotocol/neps/pull/488 Type: Runtime Spec Version: 0.0.1 Created: 2023-07-17 -LastUpdated: 2023-11-09 +LastUpdated: 2023-11-21 --- ## Summary -Native NEAR runtime functions for operations on the BLS12-381 curve. This NEP introduces a minimal set of functions to efficiently verify BLS signatures and zkSNARKs. +This NEP introduces host functions to perform operations on the BLS12-381 elliptic curve. It is a minimal set of functions needed to efficiently verify BLS signatures and zkSNARKs. ## Motivation @@ -56,9 +56,9 @@ Using the functions introduced above, we can reproduce all functionality from EI #### Elliptic Curve -**Definition:** The field $F_p$ for some *prime* $p$ is a set of integer elements $\textbraceleft 0, 1, \ldots, p - 1 \textbraceright$ with two operations: multiplication $\cdot$ and addition $+$. These operations are performed as multiplication/addition for integers number and then taking the remainder modulo $p$. +**The field $F_p$** for some *prime* $p$ is a set of integer elements $\textbraceleft 0, 1, \ldots, p - 1 \textbraceright$ with two operations: multiplication $\cdot$ and addition $+$. These operations are performed as multiplication/addition for integers number and then taking the remainder modulo $p$. -**Definition:** The elliptic curve $E(F_p)$ is a set of all pairs $(x, y) \in F_p$: +**The elliptic curve $E(F_p)$** is a set of all pairs $(x, y) \in F_p$: $$ y^2 \equiv x^3 + Ax + B \mod p @@ -74,9 +74,9 @@ In the case of BLS12-381 equation is $y^2 \equiv x^3 + 4 \mod p$[^15],[^51],[^14 - $B = 4$ - $p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab$ -**Definition:** Let’s $P \in E(F_q)$ have coordinates (x, y), define $-P$ as a point on a curve with coordinates (x, -y). +Let’s $P \in E(F_q)$ have coordinates (x, y), define **$-P$** as a point on a curve with coordinates (x, -y). -**Definition:** The addition operation for Elliptic Curve is a function $+\colon E(F_p) \times E(F_p) \rightarrow E(F_p)$ defined with following rules: let’s P and Q $\in E(F_p)$ +**The addition operation for Elliptic Curve** is a function $+\colon E(F_p) \times E(F_p) \rightarrow E(F_p)$ defined with following rules: let’s P and Q $\in E(F_p)$ - if $P \ne Q$ and $P \ne -Q$ - draw a line passing through P and Q. This line intersects the curve at a third point R @@ -93,7 +93,7 @@ With the addition operation, Elliptic Curve forms a **group**. #### Subgroups -**Definition:** Subgroup H is a subset of the group G with the following properties: +**Subgroup** H is a subset of the group G with the following properties: - $\forall h_1, h_2 \in H\colon h_1 + h_2 \in H$ - $0 \in H$ @@ -101,7 +101,7 @@ With the addition operation, Elliptic Curve forms a **group**. Notation: $H \subseteq G$ -**Definition:** group/subgroup **order** is the number of elements in group/subgroup. +Group/subgroup **order** is the number of elements in group/subgroup. Notation: |G| or #G, where G is group @@ -113,7 +113,7 @@ For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$[^15],[^51]: #### Field extension -**Definition:** The field extension $F_{p^k}$ is a set of all polynomials with degree < k and coefficients from $F_p$ and defined operations $\cdot$ , $+$ +**The field extension $F_{p^k}$** is a set of all polynomials with degree < k and coefficients from $F_p$ and defined operations $\cdot$ , $+$ $$ a_{k - 1}x^{k - 1} + \ldots + a_1x + a_0 = A(x) \in F_{p^k} \vert a_i \in F_p @@ -172,7 +172,7 @@ In most cases we will work with points from $G_2' \subset E'(F_{p^2})$ and use f #### Generators -**Definition:** if in the group $G$ exists element g, such as $\textbraceleft g, 2g, 3g, \ldots, |G|g \textbraceright = G$, the group G called ***cyclic group*** and g called ***generator*** +If in the group $G$ exists element g, such as $\textbraceleft g, 2g, 3g, \ldots, |G|g \textbraceright = G$, the group G called ***cyclic group*** and g called ***generator*** $G_1$ and $G_2$ are cyclic subgroups with the following generators[^15],[^51]: @@ -194,7 +194,7 @@ $G_2$: - $y_1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be$ -**Definition:** ***Cofactor*** is the ratio of the size of the whole group G to the size of subgroup H: +**Cofactor** is the ratio of the size of the whole group G to the size of subgroup H: $$ |G|/|H| @@ -1428,7 +1428,7 @@ In the future, it is possible to support work with other curves, not only BLS12- ### Negative - The appearance of dependence on the library which supports BLS12-381 curves operations. -- We will need to maintain operations with BLS12-381 curve forever, even if vulnerabilities are found and it is no longer safe to use. +- We will need to maintain operations with BLS12-381 curve forever, even if vulnerabilities are found, and it is no longer safe to use. ### Backward Compatibility From c9ee9404d5ab4775620204b1ccf772c6d40f1ae5 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 21 Nov 2023 20:22:29 +0200 Subject: [PATCH 081/163] update motivation --- neps/nep-0488.md | 59 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 455a28755..d3e56a48b 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -16,18 +16,26 @@ This NEP introduces host functions to perform operations on the BLS12-381 ellipt ## Motivation -The BLS12-381[^1],[^11],[^52] is a widely used[^2],[^3],[^4],[^5],[^6],[^7] elliptic curve with 120+ bits security level[^8], which supports *the pairing operation*. It is an alternative for the BN254 elliptic curve[^9],[^12], which also supports the aggregation and has already been partly implemented on NEAR as host functions[^10]. Recent research shows that the BN254 security level is lower than 100-bit[^13]. Also, there is a tendency to switch from BN254 to BLS12-381 in the industry – ZCash[^14], Ethereum[^15],[^3], Tezos[^16],[^5] or just use it – Filecoin[^6]. - -The host functions implementation for the BLS12-381 curve operations from this NEP will allow for efficient verification of the BLS signature and zkSNARKs. Currently, BLS signature verification for BLS12-381 is impossible due to the 300 TGas gas limit per one transaction on Near. - -As we have seen above, other blockchains are using the BLS12-381 signature. In the context of cross-chain interactions, we want to have the possibility to verify transactions from these blockchains on Near. Usually, it is done by implementing the on-chain client on Near, which will verify the corresponding BLS signatures. It is especially important for the Rainbow Bridge[^17] to send trustless transfers from Ethereum to Near. - -zkSNARKs are useful to work with the user's private information[^18],[^19]. Zeropool[^20] is a project that implements the zkSNARKs verifier on Near and is currently based on BN254. Having the host functions for BLS12-381 can make projects like that more secure. zkSNARKs are also used in Rollups[^21],[^22],[^23] scaling solution. - -This proposal is based on a similar proposal for Ethereum: EIP-2537[^15], so you will find similar functions there. -The closest analogs on Near are functions available for the BN254 curve, also known as Alt-BN128[^10]. - -In this NEP, we propose to add the following functions as host functions: +The primary aim of this NEP is to enable fast and efficient verification of BLS signatures and zkSNARKs based on +BLS12-381[^1],[^11],[^52] elliptic curve on NEAR. + +To efficiently verify zkSNARKs[^19], host functions for operations on the BN254 +elliptic curve(also known as Alt-BN128)[^9], [^12] have already been implemented on NEAR[^10]. +For instance, the Zeropool[^20] project utilizes these host functions for verifying zkSNARKs on NEAR. +However, recent research shows that the BN254 security level is lower than 100-bit[^13] and it is not recommended for use. +BLS12-381, on the other hand, offers over 120 bits of security[^8] and is widely used[^2],[^3],[^4],[^5],[^6],[^7] as a robust alternative. +Supporting operations for BLS12-381 elliptic curve will significantly enhance the security of projects similar to Zeropool. + +Another crucial objective is the verification of BLS signatures. +Initially, host functions for BN254 in NEAR were designed for zkSNARK verification and +are insufficient for BLS signature verifications. +However, even if they were sufficient, it wouldn't work for us. +Projects such as ZCash[^2], Ethereum[^3], Tezos[^5], and Filecoin[^6] incorporate BLS12-381 specifically within their protocols. +If we aim for compatibility with these projects, we must also utilize this elliptic curve. +For instance, to create a trustless bridge[^17] between Ethereum and NEAR, +we must efficiently verify BLS signatures based on BLS12-381, as these are the signatures employed within Ethereum's protocol. + +In this NEP, we propose to add the following host functions: - ***bls12381_g1_sum —*** adds an array of the signed points from $G_1$ on an elliptic curve. This function is useful for the aggregation of public keys in BLS Signature. It can be used for simple addition in $G_1$. Separate from the multiexp function due to the gas cost. - ***bls12381_g2_sum —*** adds an array of the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. It can be used for simple addition in $G_2$. Separate from the multiexp function due to the gas cost. @@ -39,16 +47,27 @@ In this NEP, we propose to add the following functions as host functions: - ***bls12381_decompress_g2 —*** decompresses the points from $G_2$ provided in the compressed form. - ***bls12381_pairing_check —*** 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$. Used to verify BLS signatures or zkSNARKs. -Please note that some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. That is why we have decided to move it into separate functions. -All the other functions in this NEP accept only decompressed points to be simple and to have optimized gas consumption. +Functions required for verifying BLS signatures[^59]: + +- bls12381_g1_sum +- bls12381_g2_sum +- bls12381_map_fp2_to_g2 -- we need this function to map message to the element of the group. We don't implement hash_to_field[^60] function, because it can be done inside a contract and different hashing algorithms can be used. +- bls12381_decompress_g1 -- some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. All the other functions in this NEP accept only decompressed points to be simple and to have optimized gas consumption. +- bls12381_decompress_g2 +- bls12381_pairing_check + +Functions required for verifying zkSNARKs: -Currently, Near supports only BN254 operations needed for verifying zkSNARKs, and it is not enough for verifying BLS-signatures. -For BLS-signature verification we introduced the `bls12381_map_fp2_to_g2` which allows the mapping of the message to the element of the group. -Also, we include all functions for both G1 and G2 groups. +- bls12381_g1_sum +- bls12381_g1_multiexp +- bls12381_pairing_check -*multiexp* functions are helpful in doing zkSNARKs verification. They also could be optimized by using the Pippenger algorithm[^25]. +Both zkSNARKs and BLS signatures can be implemented alternatively by swapping G1 and G2. +Therefore, all functions have been implemented for both G1 and G2. -Using the functions introduced above, we can reproduce all functionality from EIP-2537[^15], which is useful for Aurora[^24] to support Ethereum functionality on Near. +An analogous proposal, EIP-2537[^15], exists in Ethereum. +The functions here have been designed considering compatibility with Ethereum's proposal. +This design approach aims to ensure future ease in supporting corresponding precompiles for Aurora[^24]. ## Specification @@ -1498,3 +1517,5 @@ elliptic curves. In Tal Rabin, editor, CRYPTO 2010, volume 6223 of LNCS, pages 237–254. Springer, Heidelberg, August 2010. [https://link.springer.com/chapter/10.1007/978-3-642-14623-7_13](https://link.springer.com/chapter/10.1007/978-3-642-14623-7_13) [^57]: Wahby, Riad S., and Dan Boneh. "Fast and simple constant-time hashing to the BLS12-381 elliptic curve." Cryptology ePrint Archive (2019). [https://eprint.iacr.org/2019/403](https://eprint.iacr.org/2019/403) [^58]: BLST errors list. [https://github.com/supranational/blst/blob/v0.3.11/src/errors.h](https://github.com/supranational/blst/blob/v0.3.11/src/errors.h) +[^59]: Implementation of BLS-signature based on these host functions: [https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs](https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs) +[^60]: hash_to_field specification: [https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio](https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio) \ No newline at end of file From dd43b9fef6bda9bfbe471ef24f5688613d0306b9 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 21 Nov 2023 20:44:29 +0200 Subject: [PATCH 082/163] update motivation --- neps/nep-0488.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index d3e56a48b..dbdcd43bf 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -41,9 +41,9 @@ In this NEP, we propose to add the following host functions: - ***bls12381_g2_sum —*** adds an array of the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. It can be used for simple addition in $G_2$. Separate from the multiexp function due to the gas cost. - ***bls12381_g1_multiexp —*** for points $g_i \in G_1$ and scalars $s_i$ calculate $\sum g_i s_i$. It can be used to multiply a group element by a scalar. - ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. It can be used to multiply a group element by a scalar. -- ***bls12381_map_fp_to_g1 —*** maps base field element into the $G_1$ point. It does not perform mapping of the byte string into field elements. Transfers field element into a curve. It is necessary for signature schemes. -- ***bls12381_map_fp2_to_g2 —*** maps extension field element into the $G_2$ point. It does not perform mapping of the byte string into extension field elements. -- ***bls12381_decompress_g1 —*** decompresses the points from $G_1$ provided in the compressed form. +- ***bls12381_map_fp_to_g1 —*** maps base field element into the $G_1$ point. It does not perform mapping of the byte string into field elements. +- ***bls12381_map_fp2_to_g2 —*** maps extension field element into the $G_2$ point. It does not perform mapping of the byte string into extension field elements. We require this function to efficiently map a message into a group element. We don't implement hash_to_field[^60] function, because it can be done inside a contract and different hashing algorithms can be used. +- ***bls12381_decompress_g1 —*** decompresses the points from $G_1$ provided in the compressed form. Some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. All the other functions in this NEP accept only decompressed points to be simple and to have optimized gas consumption. - ***bls12381_decompress_g2 —*** decompresses the points from $G_2$ provided in the compressed form. - ***bls12381_pairing_check —*** 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$. Used to verify BLS signatures or zkSNARKs. @@ -51,8 +51,8 @@ Functions required for verifying BLS signatures[^59]: - bls12381_g1_sum - bls12381_g2_sum -- bls12381_map_fp2_to_g2 -- we need this function to map message to the element of the group. We don't implement hash_to_field[^60] function, because it can be done inside a contract and different hashing algorithms can be used. -- bls12381_decompress_g1 -- some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. All the other functions in this NEP accept only decompressed points to be simple and to have optimized gas consumption. +- bls12381_map_fp2_to_g2 +- bls12381_decompress_g1 - bls12381_decompress_g2 - bls12381_pairing_check From 67842d4085ad297783aae78b1343cbbe13635b9b Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 21 Nov 2023 20:47:14 +0200 Subject: [PATCH 083/163] update motivation --- neps/nep-0488.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index dbdcd43bf..1295b312e 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -37,8 +37,8 @@ we must efficiently verify BLS signatures based on BLS12-381, as these are the s In this NEP, we propose to add the following host functions: -- ***bls12381_g1_sum —*** adds an array of the signed points from $G_1$ on an elliptic curve. This function is useful for the aggregation of public keys in BLS Signature. It can be used for simple addition in $G_1$. Separate from the multiexp function due to the gas cost. -- ***bls12381_g2_sum —*** adds an array of the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. It can be used for simple addition in $G_2$. Separate from the multiexp function due to the gas cost. +- ***bls12381_g1_sum —*** sum the signed points from $G_1$ on an elliptic curve. This function is useful for the aggregation of public keys in BLS Signature. It can be used for simple addition in $G_1$. Separate from the multiexp function due to the gas cost. +- ***bls12381_g2_sum —*** sum the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. It can be used for simple addition in $G_2$. Separate from the multiexp function due to the gas cost. - ***bls12381_g1_multiexp —*** for points $g_i \in G_1$ and scalars $s_i$ calculate $\sum g_i s_i$. It can be used to multiply a group element by a scalar. - ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. It can be used to multiply a group element by a scalar. - ***bls12381_map_fp_to_g1 —*** maps base field element into the $G_1$ point. It does not perform mapping of the byte string into field elements. From cbce9e3322243c0bb38e946c548c32e4e731b389 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 21 Nov 2023 21:04:19 +0200 Subject: [PATCH 084/163] fix tests case --- neps/nep-0488.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 1295b312e..e52216024 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -766,7 +766,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain ***Test cases:*** -_Tests for the sum of two points_ +Tests for the sum of two points In this section, I would like to test that the sum of two correct elements on the curve works correctly. We can use the following methods: @@ -783,10 +783,10 @@ Edge cases: - P + 0 = 0 + P = P - P + (-P) = (-P) + P = 0 - P + P (tangent to the curve) -- (-(P + P)) + P (no third point of intersection with a curve) +- The sum of two points P and (-(P + P)). (tangent to the curve in point P) -_Tests for inversion_ +Tests for inversion In this section, I would like to check that point inverse works correctly. @@ -801,7 +801,7 @@ Edge cases: - -0 -_Tests for incorrect data_ +Tests for incorrect data In this section, I would like to check that incorrect input data is handled properly @@ -815,7 +815,7 @@ In this section, I would like to check that incorrect input data is handled prop - Number of points more than 1000 -_Tests for the sum of an arbitrary amount of points_ +Tests for the sum of an arbitrary amount of points In this section, we are checking that the sum of an arbitrary amount of points works properly From 225352d58879392a916364673eca8c763e6c7a4c Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 11:38:24 +0200 Subject: [PATCH 085/163] test cases for point decompression --- neps/nep-0488.md | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index e52216024..15a0b7530 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1294,13 +1294,31 @@ A and B are constants calculated empirically. ***Test cases:*** -- the correct input with different length -- the input with incorrect size -- the points with the negative `y` coordinate -- 0 points -- points not on the curve -- incorrectly encoded points -- very long input +Tests for one point decompression + +- generate random points on the curve from G1 and not from G1: + - check that the uncompressed point lies on the curve + - compare the result with another library +- generate random points with negative y: + - take inverse and compare y + - compare the result with another library +- decompress point on infinity + +Tests for decompression of arbitrary amount of points + +- empty input +- maximum amount of points +- generate the random amount of the random points on curve and compare the result with another library + +Tests for error cases + +- the input length is not divided by 48 +- input length exceeds memory limit +- 1001 points on input +- point not on the curve +- incorrect decompression bit +- incorrectly encoded infinity point +- point with coordinate bigger then p ***Tests References:*** From 966290a3fcb53b71776321c0561d5f164bceb930 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 13:26:30 +0200 Subject: [PATCH 086/163] map_fp_to_g1 tests --- neps/nep-0488.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 15a0b7530..7e00f338a 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1107,10 +1107,27 @@ The gas consumption is a constant calculated empirically. ***Test cases:*** -- Correct $F_p$ element +Tests for general cases + +- validate the results for known answers. Tests for same function in EIP-2537 +- generate random point $a$ from Fp: + - check the result with another library + - check that result point on curve in G1 + - compare results for $a$ and $-a$, it should be the same x coordinates and opposite y. + +Edge cases: + - $a = 0$ -- $a \ge p$ -- Edge cases for inner algorithms for mapping[^49] +- $a = p - 1$ + +Tests for error cases + +- input length not equal to 48 bytes: + - empty input + - 96 bytes + - out of memory input length +- $a = p$ +- random number $\ge p$ ***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. From aede25dbed5646a9a9889accb54e44eb0e36b2fe Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 15:17:46 +0200 Subject: [PATCH 087/163] pairing tests --- neps/nep-0488.md | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 7e00f338a..a2d9b603e 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1257,15 +1257,48 @@ Here you can find benchmark test vectors for EIP-2537[^46]. ***Test cases:*** -- The correct input with different lengths with results true -- The correct input with different lengths with results false +Tests for one pair + +- generate random $P \in G_1$: check $e(P, 0) = 1$ +- generate random $Q \in G_2$: check $e(0, Q) = 1$ +- generate random $P \ne 0 \in G_1$ and $Q \ne 0 \in G_2$: check $e(P, Q) \ne 1$ + +Tests for two pairs + +- generate random points $P \in G_1$, $Q \in G_2$ and random scalars $s_1, s_2$: + - $e(P, Q) \cdot e(P, -Q) = 1$ + - $e(P, Q) \cdot e(-P, Q) = 1$ + - $e(s_1P, s_2Q) \cdot e(-s_2P, s_1Q) = 1$ + - $e(s_1P, s_2Q) \cdot e(s_2P, -s_1Q) = 1$ + +- $g_1 \in G_1$, $g_2 \in G_2$ -- generators defined in section 'BLS12-381 Curve Specification', r -- order of $G_1$ and $G_2$, and $p_1, p_2, q_1, q_2$ randomly generated scalars: + - if $p_1 \cdot q_1 + p_2 \cdot q_2 \ne \equiv 0 (mod r)$, check $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) \ne 1$ + - if $p_1 \cdot q_1 + p_2 \cdot q_2 \equiv 0 (mod r)$, check $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) = 1$ + +Tests for arbitrary amount of pairs + +- empty input +- test with maximum available amount of pairs +- tests with known answers from EIP-2537 +- random pairs numbers, random scalars $p_1 \cdots p_n$ and $q_1 \cdots q_n$ such as $\sum \p_i \cdot q_i \ne \equiv 0 (mod r)$: + - check $\prod e(p_i g_1, q_i g_2) \ne 1$ +- random pairs numbers, random scalars $p_1 \cdots p_{n - 1}$ and $q_1 \cdots q_{n - 1}$: + - check $(\prod e(p_i g_1, q_i g_2)) \cdot e(-(\sum p_i q_i) g_1, g_2) = 1$ + - check $(\prod e(p_i g_1, q_i g_2)) \cdot e(g_1, -(\sum p_i q_i) g_2) = 1$ + +Tests for error cases + - The first point on the curve but not in G1 - The second point on the curve but not in G2 -- The input with incorrect length -- The points not on the curve -- Some points = 0 -- The field elements are encoded incorrectly -- Empty input +- The input length not divided by 288 +- The first point not on the curve +- The second point not on the curve +- Number of point more than 1000 +- Input length exceeds memory limit +- The incorrect 0 point encoding +- Incorrect encoding of curve point: + - wrong decompression bit + - coordinates bigger or equal than p ***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. From f671725fb9d33524b8ef6984e1d13eaae5f2bffb Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 16:49:17 +0200 Subject: [PATCH 088/163] test cases for multiexp function --- neps/nep-0488.md | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a2d9b603e..93fc6d8ab 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -965,9 +965,17 @@ To improve gas costs Pippenger’s algorithm[^25] can be used. For gas estimatio ***Test cases:*** -The same test cases as for the bls12381_g1_sum section. +Tests for multiplication + +- tests with known answer for multiplication from EIP-2537 +- random small scalar n and point P: + - check with sum function results: `P + P + P .. + P = n*P` + - check with result from another library +- random scalar n and point P: + - check with result from another library + - implement multiplication by using sum function and double-and-add algorithm[^61] -Addition test cases: +Edge cases: - `group_order * P = 0` - `(scalar + groupt_order) * P = scalar * P` @@ -976,6 +984,29 @@ Addition test cases: - `1 * P = P` - Scalar is a MAX_INT +Tests for sum of two points +The same test cases as for the bls12381_g1_sum section. + +- random points P and Q, compare results with sum function + +Tests for the sum of an arbitrary amount of points + +- random points number amount, random points, compare results with sum function +- empty input +- input of maximum size + +Tests for the multiexp of an arbitrary amount of points + +- tests with known answers from EIP-2537 +- random number of points, scalars, points: + - check with results from another library + - check with raw implementation based on sum function and double-and-add algorithm +- empty input +- maximum input with MAX_INT scalars and random points + +Tests for error cases +The same test cases as for the bls12381_g1_sum section. + ***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. @@ -1586,4 +1617,5 @@ pages 237–254. Springer, Heidelberg, August 2010. [https://link.springer.com/c [^57]: Wahby, Riad S., and Dan Boneh. "Fast and simple constant-time hashing to the BLS12-381 elliptic curve." Cryptology ePrint Archive (2019). [https://eprint.iacr.org/2019/403](https://eprint.iacr.org/2019/403) [^58]: BLST errors list. [https://github.com/supranational/blst/blob/v0.3.11/src/errors.h](https://github.com/supranational/blst/blob/v0.3.11/src/errors.h) [^59]: Implementation of BLS-signature based on these host functions: [https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs](https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs) -[^60]: hash_to_field specification: [https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio](https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio) \ No newline at end of file +[^60]: hash_to_field specification: [https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio](https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio) +[^61]: double-and-add algorithm: [https://en.wikipedia.org/wiki/Exponentiation_by_squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring) \ No newline at end of file From 020a6b3d16ddd7d040570c82de9c723fd645eb6b Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 16:57:36 +0200 Subject: [PATCH 089/163] tests for fp2 to g2 --- neps/nep-0488.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 93fc6d8ab..d66814d24 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1207,10 +1207,29 @@ The gas consumption is a constant calculated empirically. ***Test cases:*** -- Correct $F_{p^2}$ element -- $a = 0$ -- One of the `a` value $\ge p$ -- Edge cases for inner algorithms for mapping[^49] +Tests for general cases + +- validate the results for known answers. Tests for same function in EIP-2537 +- generate random point $a$ from $F_{p^2}$: + - check the result with another library + - check that result point on curve in G2 + - compare results for $a$ and $-a$, it should be the same x coordinates and opposite y. + +Edge cases: + +- $a = (0, 0)$ +- $a = (p - 1, p - 1)$ + +Tests for error cases + +- input length not equal to 96 bytes: + - empty input + - 192 bytes + - out of memory input length +- $a = (0, p)$ +- $a = (p, 0)$ +- (random number $\ge p$, 0) +- (0, random number $\ge p$) ***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. From b40119fcc792cdb39878e21679b8b7f4ba2d00b0 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 17:19:23 +0200 Subject: [PATCH 090/163] fix tests from decompression --- neps/nep-0488.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index d66814d24..8c45b3fec 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1472,13 +1472,7 @@ A and B are constants calculated empirically. ***Test cases:*** -- the correct input with different length -- the input with incorrect size -- the points with the negative `y` coordinate -- 0 points -- points not on the curve -- incorrectly encoded points -- very long input +The same test cases as for `bls12381_decompress_g1` but with points from $G_2$ and the input length should be divided by 96. ***Tests References:*** From cbab082546bd76a473f41c9e977e65bcc3fc2e1a Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 17:23:51 +0200 Subject: [PATCH 091/163] fix tests formating --- neps/nep-0488.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 8c45b3fec..243ba2e45 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1322,15 +1322,15 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - $e(s_1P, s_2Q) \cdot e(s_2P, -s_1Q) = 1$ - $g_1 \in G_1$, $g_2 \in G_2$ -- generators defined in section 'BLS12-381 Curve Specification', r -- order of $G_1$ and $G_2$, and $p_1, p_2, q_1, q_2$ randomly generated scalars: - - if $p_1 \cdot q_1 + p_2 \cdot q_2 \ne \equiv 0 (mod r)$, check $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) \ne 1$ - - if $p_1 \cdot q_1 + p_2 \cdot q_2 \equiv 0 (mod r)$, check $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) = 1$ + - if $p_1 \cdot q_1 + p_2 \cdot q_2 \not \equiv 0 (\mod r)$, check $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) \ne 1$ + - if $p_1 \cdot q_1 + p_2 \cdot q_2 \equiv 0 (\mod r)$, check $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) = 1$ Tests for arbitrary amount of pairs - empty input - test with maximum available amount of pairs - tests with known answers from EIP-2537 -- random pairs numbers, random scalars $p_1 \cdots p_n$ and $q_1 \cdots q_n$ such as $\sum \p_i \cdot q_i \ne \equiv 0 (mod r)$: +- random pairs numbers, random scalars $p_1 \cdots p_n$ and $q_1 \cdots q_n$ such as $\sum \p_i \cdot q_i \not \equiv 0 (\mod r)$: - check $\prod e(p_i g_1, q_i g_2) \ne 1$ - random pairs numbers, random scalars $p_1 \cdots p_{n - 1}$ and $q_1 \cdots q_{n - 1}$: - check $(\prod e(p_i g_1, q_i g_2)) \cdot e(-(\sum p_i q_i) g_1, g_2) = 1$ From c4e91ae165d41412b6765ac73627d6119fdf90a5 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 17:26:36 +0200 Subject: [PATCH 092/163] fix tests formating --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 243ba2e45..05831d0c3 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1330,7 +1330,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - empty input - test with maximum available amount of pairs - tests with known answers from EIP-2537 -- random pairs numbers, random scalars $p_1 \cdots p_n$ and $q_1 \cdots q_n$ such as $\sum \p_i \cdot q_i \not \equiv 0 (\mod r)$: +- random pairs numbers, random scalars $p_1 \cdots p_n$ and $q_1 \cdots q_n$ such as $\sum p_i \cdot q_i \not \equiv 0 (\mod r)$: - check $\prod e(p_i g_1, q_i g_2) \ne 1$ - random pairs numbers, random scalars $p_1 \cdots p_{n - 1}$ and $q_1 \cdots q_{n - 1}$: - check $(\prod e(p_i g_1, q_i g_2)) \cdot e(-(\sum p_i q_i) g_1, g_2) = 1$ From f1e919ea0159c24aab65c5e4843ba64ce04adca1 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 18:21:18 +0200 Subject: [PATCH 093/163] simplify map to curve specification --- neps/nep-0488.md | 287 +++-------------------------------------------- 1 file changed, 17 insertions(+), 270 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 05831d0c3..5aaa92ce9 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -301,281 +301,24 @@ All parameters were taken from[^15],[^51] and [^14], all of them consistent betw ### Map to curve specification -In this section we explain how to map the element $a \in F_p$ to the $G_1 \subset E(F_p)$ and how to map $b \in F_{p^2}$ to the $G_2 \subset E'(F_{p^2})$. -This section will explain how functions `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` work. -It mostly duplicates the correspondent section in EIP-2537[^49]. +This section explains the functionality of the `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` functions. +They operate based on the specification RFC9380 "Hashing to Elliptic Curves"[^62]. -#### Mapping algorithm - -The general elliptic curve equation is $y^2 = x^3 + A \cdot x + B$. In our case $A \cdot B = 0$, so the mapping algorithm -will consist of the following steps: - -1. Field element (from $F_p$ or $F_{p^2}$) will map to some curve with $A \cdot B \ne 0$ -2. Points from this curve will map to the target curve (E(Fp) or E'(Fp2)) by isomorphism -3. For mapping points to subgroup ($G_1$ or $G_2$) the cofactor will be cleared - -First, we will describe the general algorithm and, next, we will provide the concrete parameters. - -***Step 1: Map field element to the curve with AB != 0*** - -In this section we will describe `map_to_curve_simple_swu(u)` function. -It is simplification of the Shallue-van de Woestijne-Ulas mapping described by Brier et al.[^56], which they call the “simplified SWU” map. -Wahby and Boneh[^57] generalize and optimize this mapping. - -A Weierstrass curve is $y^2 = g(x) = x^3 + A \cdot x + B$, where $A \ne 0$ and $B \ne 0$. - -Constants, which we will define in the following sections: - -- $A$, $B$ -- the parameters of Weierstress curve -- $Z$ the element of the field $F$ (in our case $F_p$ or $F_{p^2}$), which meeting the below criteria: - - Z is non-square in F - - $Z \ne -1$ in F - - The polynomial $g(x) - Z$ is irreducible over F - - $g(\frac{B}{Z \cdot A})$ is square in $F$. - -For points $u$ and $-u$ we will get the same $x$-coordinate. We will define the $y$ sign the same as $u$ sign(see the definition of sign in sections "Compressed points on curve E(Fp)" and "Compressed points on curve E'(Fp2))". - -The case when $Z^2 \cdot u^4 + Z \cdot u^2 = 0$ should be handled separately. In that case set $x_1 = \frac{B}{X \cdot A}$, -which guarantees that $g(x_1)$ is square by the condition on Z given above. - -The algorithm: - -```text -fn map_to_curve_simple_swu(u) { - let tv1 = 1 / (Z^2 * u^4 + Z * u^2); - let x1 = (-B / A) * (1 + tv1); - if tv1 == 0 { - x1 = B/(Z*A); - } - - let gx1 = x1^3 + A*x1 + B; - let x2 = Z * u^2 + x1; - let gx2 = x2^3 + A*x2 + B; - let (x, y) = if is_squere(gx1) { - (x1, sqrt(gx1)); - } else { - (x2, sqrt(gx2)); - } - - if sign(u) != sign(y) { - y = -y; - } - - return (x, y); -} - -``` - -***Step 2: Map to target curve*** - -The function `iso_map(x_inner, y_inner)` map the points from isogenous curve E_inner with no-zero coefficients to our -target elliptic curve E. - -Wahby and Boneh[^57] show how to adopt the algorithm for case when elliptic curve have zero A or B. The idea: map -the F element to isogenous elliptic curve E_inner by the method from previous section, and then transform E_inner curve -to our target curve E by knowing isogeny. - -E_inner curve with isogeny will be defined in the "Parameters" section. - -Note that `iso_map` is a group homomorphism. This mean `iso_map(p) + iso_map(q) = iso_map(p + q)`. So, the correspondent optimization can be applied. - -If any denominator in rational functions used in `iso_map` function equal to zero, the `iso_map` function -must return identity point on E. - -***Step 3: Map to subgroup(cofactor cleaning)*** - -In this section we will describe the function `clear_cofactor((x, y))`. This function transfer a point from $E(F_p)$ or $E'(F_{p^2})$ -into a point in $G_1 \subset E(F_p)$ or $G_2 \subset E'(F_{p^2})$ respectively. - -To do that, we should multiply the point on the curve by effective cofactor `h_eff`. Multiplication on `h_eff` gives the -results in the same subset as multiplication on cofactor, but can be executed must faster. The value of `h_eff` will be given in -the following sections. - -```text -fn clear_cofactor(P) { - h_eff * P -} - -``` - -***Full algorithm*** - -In this section, the pseudocode for the full mapping algorithm is shown. All the functions are described in the sections above. +This functions maps the field element($F_p$ or $F_{p^2}$) to the subgroup of elliptic curve($G_1 \subset E(F_p)$ or $G_2 \subset E'(F_{p^2})$). +`bls12381_map_fp_to_g1`/`bls12381_map_fp2_to_g2` combine functions `map_to_curve` and `clear_cofactor` from RFC9380[^63]. ```text -1. (x_inner, y_inner) = map_to_curve_simple_swu(u) # (x_inner, y_inner) is on E_inner - the helper elliptic curve with AB != 0 -2. (x, y) = iso_map(x_inner, y_inner) # (x, y) is on E -3. (x, y) = clear_cofactor((x, y)) # clears cofactor for point (x, y) on E -4. return (x, y) +fn bls12381_map_fp_to_g1(u): + let Q = map_to_curve(u); + return clear_cofactor(Q); ``` -#### Parameters - -***Fp-to-G1 mapping*** - -**Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: - -- $A = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d$ -- $B = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0$ -- Z = 11 - -**Step 2:** Isogeny from E_inner to curve $E(F_p)$: - -Let's we have the point on E_inner with coordinates $(x_{inner}, y_{inner})$ and -we would like to calculate the correspondent coordinates $(x, y) \in E(F_p)$. - -- $x = \frac{x_{num}}{x_{den}}$ where - - $$x_{num} = \sum_{i=0}^{11} k_{(1, i)} \cdot x_{inner}^i$$ - - $$x_{den} = x_{inner}^{10} + \sum_{i=0}^{9} k_{(2, i)} \cdot x_{inner}^i$$ - -- $y = y_{inner} \cdot \frac{y_{num}}{y_{den}}$: - - $$y_{num} = \sum_{i=0}^{15} k_{(3, i)} \cdot x_{inner}^i$$ - - $$y_{den} = x_{inner}^{15} + \sum_{i=0}^{14} k_{(4, i)} \cdot x_{inner}^i$$ - -The constants to compute $x_{num}$: - -- $k_{(1,0)} = 0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7$ -- $k_{(1,1)} = 0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb$ -- $k_{(1,2)} = 0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0$ -- $k_{(1,3)} = 0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861$ -- $k_{(1,4)} = 0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9$ -- $k_{(1,5)} = 0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983$ -- $k_{(1,6)} = 0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84$ -- $k_{(1,7)} = 0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e$ -- $k_{(1,8)} = 0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317$ -- $k_{(1,9)} = 0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e$ -- $k_{(1,10)} = 0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b$ -- $k_{(1,11)} = 0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229$ - -The constants to compute $x_{den}$: - -- $k_{(2,0)} = 0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c$ -- $k_{(2,1)} = 0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff$ -- $k_{(2,2)} = 0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19$ -- $k_{(2,3)} = 0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8$ -- $k_{(2,4)} = 0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e$ -- $k_{(2,5)} = 0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5$ -- $k_{(2,6)} = 0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a$ -- $k_{(2,7)} = 0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e$ -- $k_{(2,8)} = 0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641$ -- $k_{(2,9)} = 0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a$ - - -The constants used to compute $y_{num}$: - -- $k_{(3,0)} = 0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33$ -- $k_{(3,1)} = 0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696$ -- $k_{(3,2)} = 0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6$ -- $k_{(3,3)} = 0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb$ -- $k_{(3,4)} = 0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb$ -- $k_{(3,5)} = 0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0$ -- $k_{(3,6)} = 0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2$ -- $k_{(3,7)} = 0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29$ -- $k_{(3,8)} = 0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587$ -- $k_{(3,9)} = 0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30$ -- $k_{(3,10)} = 0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132$ -- $k_{(3,11)} = 0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e$ -- $k_{(3,12)} = 0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8$ -- $k_{(3,13)} = 0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133$ -- $k_{(3,14)} = 0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b$ -- $k_{(3,15)} = 0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604$ - - -The constants to compute $y_{den}$: - -- $k_{(4,0)} = 0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1$ -- $k_{(4,1)} = 0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d$ -- $k_{(4,2)} = 0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2$ -- $k_{(4,3)} = 0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416$ -- $k_{(4,4)} = 0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d$ -- $k_{(4,5)} = 0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac$ -- $k_{(4,6)} = 0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c$ -- $k_{(4,7)} = 0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9$ -- $k_{(4,8)} = 0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a$ -- $k_{(4,9)} = 0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55$ -- $k_{(4,10)} = 0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8$ -- $k_{(4,11)} = 0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092$ -- $k_{(4,12)} = 0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc$ -- $k_{(4,13)} = 0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7$ -- $k_{(4,14)} = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f$ - -**Step 3:** Effective cofactor: - -$$h_{eff} = 0xd201000000010001$$ - -***Fp2-to-G2 mapping*** - -**Step 1:** E_inner: $y^2 = x^3 + A \cdot x + B$ parameters: - -- A = $240 \cdot I$ -- B = $1012 \cdot (1 + I)$ -- Z = $-(2 + I)$ - -Note: $I$ means a non-residue used to make an extension field $F_{p^2}$ - -**Step 2:** Isogeny from E_inner to curve $E'(F_{p^2})$: - -Let's we have the point on E_inner with coordinates $(x_{inner}, y_{inner})$ and -we would like to calculate the correspondent coordinates $(x, y) \in E'(F_{p^2})$. - -- $x = \frac{x_{num}}{x_{den}}$ where - - $$x_{num} = \sum_{i = 0}^{3} k_{1, i} \cdot x_{inner}^i$$ - - $$x_{den} = x_{inner}^2 + \sum_{i=0}^{1} k_{2, i} \cdot x_{inner}^i$$ - -- $y = y_{inner} \cdot \frac{y_num}{y_den}$: - - $$y_{num} = \sum_{i = 0}^{3} k_{3, i} \cdot x_{inner}^i$$ - - $$y_{den} = x_{inner}^{3} + \sum_{i = 0}^{2} k_{4, i} \cdot x_{inner}^i$$ - -The constants used to compute $x_{num}$ are as follows: - -- $$k_{(1,0)} = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 + - 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 \cdot I$$ - -- $$k_{(1,1)} = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a \cdot I$$ - -- $$k_{(1,2)} = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e + - 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d \cdot I$$ - -- $$k_{(1,3)} = 0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1$$ - -The constants used to compute $x_{den}$ are as follows: - -- $$k_{(2,0)} = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63 \cdot I$$ - -- $$k_{(2,1)} = 0xc + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f \cdot I$$ - -The constants used to compute $y_{num}$ are as follows: - -- $$k_{(3,0)} = 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 +\\ - 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 \cdot I$$ - -- $$k_{(3,1)} = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be \cdot I$$ - -- $$k_{(3,2)} = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c + - 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f \cdot I$$ - -- $$k_{(3,3)} = 0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10$$ - -The constants used to compute $y_{den}$ are as follows: - -- $$k_{(4,0)} = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb + - 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb \cdot I$$ - -- $$k_{(4,1)} = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3 \cdot I$$ - -- $$k_{(4,2)} = 0x12 + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99 \cdot I$$ - -**Step 3:** Effective cofactor: +We won't be implementing `hash_to_field` function as a host function because hashing can be performed through +various methods, and this part is most likely subject to change. Additionally, executing this function within +the contract consumes approximately 2 TGas, which is acceptable for our goals. -- $$h_{eff} = 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551$$ +Specific parameters for implementing `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` you can find in RFC9380 in +sections 8.8.1[^64] and 8.8.2[^65] respectively. ### Curve points encoding @@ -1631,4 +1374,8 @@ pages 237–254. Springer, Heidelberg, August 2010. [https://link.springer.com/c [^58]: BLST errors list. [https://github.com/supranational/blst/blob/v0.3.11/src/errors.h](https://github.com/supranational/blst/blob/v0.3.11/src/errors.h) [^59]: Implementation of BLS-signature based on these host functions: [https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs](https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs) [^60]: hash_to_field specification: [https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio](https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio) -[^61]: double-and-add algorithm: [https://en.wikipedia.org/wiki/Exponentiation_by_squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring) \ No newline at end of file +[^61]: double-and-add algorithm: [https://en.wikipedia.org/wiki/Exponentiation_by_squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring) +[^62]: RFC 9380 Hashing to Elliptic Curves specification: [https://www.rfc-editor.org/rfc/rfc9380](https://www.rfc-editor.org/rfc/rfc9380) +[^63]: map_to_curve and clear_cofactor functions: [https://datatracker.ietf.org/doc/html/rfc9380#name-encoding-byte-strings-to-el](https://datatracker.ietf.org/doc/html/rfc9380#name-encoding-byte-strings-to-el) +[^64]: Specification of parameters for BLS12-381 G1: [https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g1](https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g1) +[^65]: Specification of parameters for BLS12-381 G2: [https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g2](https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g2) \ No newline at end of file From 60a4a8099e1c89c25343bcd656fba575ad51a422 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 20:25:52 +0200 Subject: [PATCH 094/163] improve english --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 5aaa92ce9..c3e79050d 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -304,7 +304,7 @@ All parameters were taken from[^15],[^51] and [^14], all of them consistent betw This section explains the functionality of the `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` functions. They operate based on the specification RFC9380 "Hashing to Elliptic Curves"[^62]. -This functions maps the field element($F_p$ or $F_{p^2}$) to the subgroup of elliptic curve($G_1 \subset E(F_p)$ or $G_2 \subset E'(F_{p^2})$). +These functions map the field element in $F_p$ or $F_{p^2}$ to the corresponding subgroup $G_1 \subset E(F_p)$ or $G_2 \subset E'(F_{p^2})$. `bls12381_map_fp_to_g1`/`bls12381_map_fp2_to_g2` combine functions `map_to_curve` and `clear_cofactor` from RFC9380[^63]. ```text From 5911703b1eacb82f8279de6cc4fcd6230040a927 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 22 Nov 2023 21:13:24 +0200 Subject: [PATCH 095/163] remove unused links --- neps/nep-0488.md | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index c3e79050d..9d8ab96f0 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1327,14 +1327,9 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^13]: Some analytics of different curve security: [https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security](https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-02.html#name-for-100-bits-of-security) [^14]: ZCash Transfer from bn254 to bls12-381: [https://electriccoin.co/blog/new-snark-curve/](https://electriccoin.co/blog/new-snark-curve/) [^15]: EIP-2537 Precompiles for Ethereum for BLS12-381: [https://eips.ethereum.org/EIPS/eip-2537](https://eips.ethereum.org/EIPS/eip-2537) -[^16]: The article, where Tezos announce the support of BLS12-381 [https://medium.com/metastatedev/meanwhile-at-cryptium-labs-2-part-2-adding-the-pairing-equipped-elliptic-curve-bls12-381-to-tezos-cfce907e4be3](https://medium.com/metastatedev/meanwhile-at-cryptium-labs-2-part-2-adding-the-pairing-equipped-elliptic-curve-bls12-381-to-tezos-cfce907e4be3) [^17]: Article about Rainbow Bridge [https://near.org/blog/eth-near-rainbow-bridge](https://near.org/blog/eth-near-rainbow-bridge) -[^18]: EIP-196. Precompiles for BN254: [https://eips.ethereum.org/EIPS/eip-196](https://eips.ethereum.org/EIPS/eip-196) [^19]: Intro into zkSNARKs: [https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b](https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b) [^20]: Zeropool project: [https://zeropool.network/](https://zeropool.network/) -[^21]: Motivation for EIP-2537: [https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders](https://www.youtube.com/watch?v=al4YpfDVmS4&ab_channel=EthereumCatHerders) -[^22]: NEAR blog post about Roll Ups: [https://near.org/blog/layer-2](https://near.org/blog/layer-2) -[^23]: Ledger post about Roll Ups: [https://www.ledger.com/academy/what-are-blockchain-rollups](https://www.ledger.com/academy/what-are-blockchain-rollups) [^24]: Precompiles on Aurora: [https://doc.aurora.dev/evm/precompiles/](https://doc.aurora.dev/evm/precompiles/) [^25]: Pippenger Algorithm: [https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf) [^26]: NEP-446 proposal for BLS-signature verification: [https://github.com/nearprotocol/neps/pull/446](https://github.com/nearprotocol/neps/pull/446) @@ -1360,17 +1355,11 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^46]: Bench vectors from EIP2537: [https://eips.ethereum.org/assets/eip-2537/bench_vectors](https://eips.ethereum.org/assets/eip-2537/bench_vectors) [^47]: Metter Labs tests for EIP2537: [https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537) [^48]: Tests from Go Ethereum implementation: [https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles) -[^49]: EIP-2537 Map To Curve specification: [https://eips.ethereum.org/assets/eip-2537/field_to_curve](https://eips.ethereum.org/assets/eip-2537/field_to_curve) -[^50]: The current implementation of BN254: [https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs](https://github.com/near/nearcore/blob/master/runtime/near-vm-runner/src/logic/logic.rs) [^51]: draft-irtf-cfrg-pairing-friendly-curves-11 [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-) *(*[https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md) → [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04) → this ref*)* [^52]: Paper with BLS12-381: [https://eprint.iacr.org/2019/403.pdf](https://eprint.iacr.org/2019/403.pdf) [^53]: Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) [^54]: Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 [^55]: Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) -[^56]: Eric Brier, Jean-Sébastien Coron, Thomas Icart, David Madore, Hugues Randriam, and Mehdi Tibouchi. Efficient indifferentiable hashing into ordinary -elliptic curves. In Tal Rabin, editor, CRYPTO 2010, volume 6223 of LNCS, -pages 237–254. Springer, Heidelberg, August 2010. [https://link.springer.com/chapter/10.1007/978-3-642-14623-7_13](https://link.springer.com/chapter/10.1007/978-3-642-14623-7_13) -[^57]: Wahby, Riad S., and Dan Boneh. "Fast and simple constant-time hashing to the BLS12-381 elliptic curve." Cryptology ePrint Archive (2019). [https://eprint.iacr.org/2019/403](https://eprint.iacr.org/2019/403) [^58]: BLST errors list. [https://github.com/supranational/blst/blob/v0.3.11/src/errors.h](https://github.com/supranational/blst/blob/v0.3.11/src/errors.h) [^59]: Implementation of BLS-signature based on these host functions: [https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs](https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs) [^60]: hash_to_field specification: [https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio](https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio) @@ -1378,4 +1367,4 @@ pages 237–254. Springer, Heidelberg, August 2010. [https://link.springer.com/c [^62]: RFC 9380 Hashing to Elliptic Curves specification: [https://www.rfc-editor.org/rfc/rfc9380](https://www.rfc-editor.org/rfc/rfc9380) [^63]: map_to_curve and clear_cofactor functions: [https://datatracker.ietf.org/doc/html/rfc9380#name-encoding-byte-strings-to-el](https://datatracker.ietf.org/doc/html/rfc9380#name-encoding-byte-strings-to-el) [^64]: Specification of parameters for BLS12-381 G1: [https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g1](https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g1) -[^65]: Specification of parameters for BLS12-381 G2: [https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g2](https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g2) \ No newline at end of file +[^65]: Specification of parameters for BLS12-381 G2: [https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g2](https://datatracker.ietf.org/doc/html/rfc9380#name-bls12-381-g2) From 5c87153b82b55a74b4789588d5ed655b7ea58132 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 23 Nov 2023 12:00:24 +0200 Subject: [PATCH 096/163] remove the hard limits --- neps/nep-0488.md | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 9d8ab96f0..a0ecbf5b9 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -486,7 +486,7 @@ The $E(F_p)$ curve, points on the curve, multiplication on -1, and the additio Note: we take as input any points on the curve, not only from $G_1$ -***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. @@ -555,7 +555,7 @@ In this section, I would like to check that incorrect input data is handled prop - The coding of field elements is incorrect, an incorrect extra bit, which shows that it is decompressed encoding. - Point not on the curve - The point on infinity encoded incorrectly -- Number of points more than 1000 +- Input length exceeds memory limit Tests for the sum of an arbitrary amount of points @@ -581,7 +581,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Error cases:*** - The input length is not divided by 97 -- Number of points more than 1000 - Too much memory is used - The sign value is not 0 or 1 @@ -611,7 +610,7 @@ The $E'(F_{p^2})$ curve, points on the curve, multiplication on -1, and the add Note: we take as input any points on the curve, not only from $G_2$ -***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. @@ -646,7 +645,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case - The input length is not divided by 193 - Too much memory is used -- Number of points more than 1000 - The sign value is not 0 or 1 ***Annotation:*** @@ -684,7 +682,7 @@ Note: - We take as input any points on the curve, not only from $G_1$. - The scalar is an arbitrary unsigned integer and can be bigger than the group order. -***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. @@ -758,7 +756,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether - The input length is not divided by 128 - Too much memory is used -- Number of points more than 1000 ***Annotation:*** @@ -799,7 +796,7 @@ Note: ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. -Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. +Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** @@ -838,7 +835,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether - Too much memory is used - Field elements encoded incorrectly (see Curve points encoded section) - Any points not on the curve -- Number of points more than 1000 ***Annotation:*** @@ -1021,7 +1017,7 @@ $$ We don’t calculate the pairing function itself: the result will be in the huge field, and in all known applications only such a check is necessary. -***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the concatenation of uncompressed point from $G_1 \subset E(F_p)$ — `96 bytes` and point from $G_2 \subset E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $G_1 \subset E(F_p)$ — `96 bytes` and point from $G_2 \subset E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. ***Output:*** @@ -1086,7 +1082,6 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - The input length not divided by 288 - The first point not on the curve - The second point not on the curve -- Number of point more than 1000 - Input length exceeds memory limit - The incorrect 0 point encoding - Incorrect encoding of curve point: @@ -1099,7 +1094,6 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - The input length is not divided by 288 - Too much memory is used -- Number of pairs more than 1000 ***Annotation:*** @@ -1116,7 +1110,7 @@ pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Resu ***Description:*** Function decompress compressed points from $E(F_p)$. The input is an arbitrary number of points $p_i \in E(F_p)$ in compressed format, and the output is the same number of points from $E(F_p)$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. -***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in compressed form. Expected `48*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the compressed point from $E(F_p)$. More details are in the Curve Points Encoding section. +***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in compressed form. Expected `48*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E(F_p)$. More details are in the Curve Points Encoding section. ***Output:*** @@ -1157,7 +1151,6 @@ A and B are constants calculated empirically. - the input length is not divided by 48 - input length exceeds memory limit -- 1001 points on input - point not on the curve - incorrect decompression bit - incorrectly encoded infinity point @@ -1172,7 +1165,6 @@ A and B are constants calculated empirically. - The input length is not divided by 48 - Too much memory is used -- Number of points more than 1000 ***Annotation:*** @@ -1194,7 +1186,7 @@ pub fn bls12381_decompress_g1(&mut self, ***Description:*** Function decompress compressed points from $E'(F_{p^2})$. The input is an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format, and the output is the same number of points from $E'(F_{p^2})$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. -***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in compressed form. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices ($k \le 1000$), each slice is the compressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. +***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in compressed form. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. ***Output:*** @@ -1226,7 +1218,6 @@ The same test cases as for `bls12381_decompress_g1` but with points from $G_2$ a - The input length is not divided by 96 - Too much memory is used -- Number of points more than 1000 ***Annotation:*** From dbdb08a6aafb1b4aa47b8992ca8f191dd2413c00 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 10:19:54 +0200 Subject: [PATCH 097/163] fix ERROR_CODE --- neps/nep-0488.md | 96 +++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a0ecbf5b9..1a4d3d1a1 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -467,12 +467,10 @@ to handle error cases by himself. Note: the host functions can finish with an er The ERROR_CODE encoded as a little-endian u64 and can take the following values: - 0 -- no error, execution was successful -- 1 -- incorrect encoding (the bit compress/decompress format set incorrectly, coordinate >= p etc) -- 2 -- point not on the curve -- 3 -- point not in expected subgroup -- 5 -- the pairing result is not equal to multiplicative identity - -ERROR_CODEs consistent with blst errors[^58]. +- 1 -- execution finish with error: + - incorrect encoding (the bit compress/decompress format set incorrectly, coordinate >= p etc) + - a point not on the curve (where it is applicable) + - a point not in the expected subgroup (where it is applicable) ### Host functions @@ -482,7 +480,7 @@ ERROR_CODEs consistent with blst errors[^58]. The function computes the sum of the signed elements of the BLS12-381 curve. The input is an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ is point on elliptic curve and $s_i \in \textbraceleft 0, 1 \textbraceright$ is the point sign. The output is one point from $E(F_p)$ equal to $\sum (-1)^{s_i}p_i$. -The $E(F_p)$ curve, points on the curve, multiplication on -1, and the addition operation are defined in the BLS12-381 Curve Specification section. +The $E(F_p)$ curve, points on the curve, multiplication on -1, and the addition operation are defined in the BLS12-381 Curve Specification section. Note: we take as input any points on the curve, not only from $G_1$ @@ -490,9 +488,11 @@ Note: we take as input any points on the curve, not only from $G_1$ ***Output:*** the ERROR_CODE is returned. -- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). -- If the field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty -- If point not on the curve: ERROR_CODE = 2, the output is empty +- ERROR_CODE = 0: the input is correct + - Output: is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +- ERROR_CODE = 1: + - points or signs encoded incorrectly (see Curve points encoded section) + - points not on the curve ***Gas Estimation:*** @@ -582,7 +582,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case - The input length is not divided by 97 - Too much memory is used -- The sign value is not 0 or 1 ***Annotation:*** @@ -615,10 +614,11 @@ Note: we take as input any points on the curve, not only from $G_2$ ***Output:*** the ERROR_CODE is returned. -- If the input is correct: ERROR_CODE = 0, the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). -- If extension field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty -- If point not on the curve: ERROR_CODE = 2, the output is empty - +- ERROR_CODE = 0: the input is correct + - Output: 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). +- ERROR_CODE = 1: + - points or signs encoded incorrectly (see Curve points encoded section) + - points not on the curve ***Gas Estimation:*** @@ -645,7 +645,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case - The input length is not divided by 193 - Too much memory is used -- The sign value is not 0 or 1 ***Annotation:*** @@ -687,9 +686,11 @@ Note: ***Output:*** the ERROR_CODE is returned. -- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). -- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty -- If point not on the curve: ERROR_CODE = 2, the output is empty +- ERROR_CODE = 0: the input is correct + - Output: 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). +- ERROR_CODE = 1: + - points encoded incorrectly (see Curve points encoded section) + - point not on the curve ***Gas Estimation:*** @@ -802,11 +803,11 @@ Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ the ERROR_CODE is returned. -- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). -- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty -- If point not on the curve: ERROR_CODE = 2, the output is empty - -the output is 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). +- ERROR_CODE = 0: the input is correct + - Output: 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). +- ERROR_CODE = 1: + - points encoded incorrectly (see Curve points encoded section) + - point not on the curve ***Gas Estimation:*** @@ -833,8 +834,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether - The input length is not divided by 224 - Too much memory is used -- Field elements encoded incorrectly (see Curve points encoded section) -- Any points not on the curve ***Annotation:*** @@ -866,10 +865,9 @@ The function takes the element $a \in F_p$ and maps it to the $G_1 \subset E(F_p the ERROR_CODE is returned. -- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). -- $a \ge p$: ERROR_CODE = 1, the output is empty - -the output is `96 bytes` — one point $\in G_1 \subset E(F_p)$ in decompressed format. More details are in the Curve Points Encoding section. +- ERROR_CODE = 0: the input is correct + - Output: `96 bytes` — one point $\in G_1 \subset E(F_p)$ in decompressed format. More details are in the Curve Points Encoding section. +- ERROR_CODE = 1: $a \ge p$. ***Gas Estimation:*** @@ -935,10 +933,9 @@ The function takes the element $a \in F_{p^2}$ and maps it to the $G_2 \subset E the ERROR_CODE is returned. -- If the input is correct: ERROR_CODE = 0, the output is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). -- If value is not a valid extension field $F_{p^2}$ element: ERROR_CODE = 1, the output is empty - -the output is `192 bytes` — one point $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. +- ERROR_CODE = 0: the input is correct + - Output: `192 bytes` — one point $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. +- ERROR_CODE = 1: value is not a valid extension field $F_{p^2}$ element ***Gas Estimation:*** @@ -1023,11 +1020,12 @@ We don’t calculate the pairing function itself: the result will be in the huge the ERROR_CODE is returned. -- If the input is correct and the pairing result is equal to multiplicative identity : ERROR_CODE = 0 -- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1 -- If point not on the curve: ERROR_CODE = 2 -- If point not in $G_1/G_2$: ERROR_CODE = 3 -- If the input is correct and the pairing result is not equal to multiplicative identity : ERROR_CODE = 5 +- ERROR_CODE = 0: the input is correct + - Output: 1 byte with two possible values: 1 if the pairing result is equal to multiplicative identity and 0 -- otherwise. +- ERROR_CODE = 1: + - points encoded incorrectly (see Curve points encoded section) + - point not on the curve + - point not in $G_1/G_2$ For empty input it returns ERROR_CODE = 0. @@ -1100,10 +1098,12 @@ Here you can find benchmark test vectors for EIP-2537[^46]. The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. +The output data will be written to register with `register_id` id. + The ERROR_CODE is returned. ```rust -pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Result; +pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; ``` #### bls12381_decompress_g1 @@ -1116,9 +1116,11 @@ pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64) -> Resu the ERROR_CODE is returned. -- If the input is correct: ERROR_CODE = 0, the output is the sequence of point $p_i \in E(F_p)$, each point encoded in decompressed form. Expected `96*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E(F_p)$. `k` the same as in input. More details are in the Curve Points Encoding section. -- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty -- If point not on the curve: ERROR_CODE = 2, the output is empty +- ERROR_CODE = 0: the input is correct + - Output: the sequence of point $p_i \in E(F_p)$, each point encoded in decompressed form. Expected `96*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E(F_p)$. `k` the same as in input. More details are in the Curve Points Encoding section. +- ERROR_CODE = 1: + - points encoded incorrectly (see Curve points encoded section) + - point not on the curve ***Gas Estimation:*** The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula @@ -1192,9 +1194,11 @@ pub fn bls12381_decompress_g1(&mut self, the ERROR_CODE is returned. -- If the input is correct: ERROR_CODE = 0, the output is the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in decompressed form. Expected `192*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E'(F_{p^2})$. `k` the same as in input. More details are in the Curve Points Encoding section. -- If field elements encoded incorrectly (see Curve points encoded section): ERROR_CODE = 1, the output is empty -- If point not on the curve: ERROR_CODE = 2, the output is empty +- ERROR_CODE = 0: the input is correct + - Output: the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in decompressed form. Expected `192*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E'(F_{p^2})$. `k` the same as in input. More details are in the Curve Points Encoding section. +- ERROR_CODE = 1: + - points encoded incorrectly (see Curve points encoded section) + - point not on the curve ***Gas Estimation:*** The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula From 034ae11e6d702a44b6f23ef8fb64e7d279ade262 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 10:43:36 +0200 Subject: [PATCH 098/163] remove redundant definition --- neps/nep-0488.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 1a4d3d1a1..eea0dcd8f 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -681,7 +681,7 @@ Note: - We take as input any points on the curve, not only from $G_1$. - The scalar is an arbitrary unsigned integer and can be bigger than the group order. -***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Each point is encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** the ERROR_CODE is returned. @@ -797,7 +797,7 @@ Note: ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. -Each point is encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and a scalar has a type `u256` and BigEndian encoded in 32 bytes. Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. +Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** From 3cb0c57c698804057c159a33f20634bee986e6d1 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 12:00:26 +0200 Subject: [PATCH 099/163] implicit Error cases comments --- neps/nep-0488.md | 72 ++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index eea0dcd8f..00aa523c6 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -578,7 +578,7 @@ Edge cases: 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:*** +***Error cases (execution is terminated):*** - The input length is not divided by 97 - Too much memory is used @@ -588,9 +588,11 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. -The output data will be written to register with `register_id` id. +Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. +Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. -The ERROR_CODE is returned. +If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, +otherwise, nothing will be written to the register. ```rust pub fn bls12381_g1_sum(&mut self, @@ -641,7 +643,7 @@ The same as for **`bls12381_g1_sum`** only change points from $G_1$ and $E(F_p)$ 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:*** +***Error cases (execution is terminated):*** - The input length is not divided by 193 - Too much memory is used @@ -651,9 +653,11 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. -The output data will be written to register with `register_id` id. +Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. +Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. -The ERROR_CODE is returned. +If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, +otherwise, nothing will be written to the register. ```rust pub fn bls12381_g2_sum(&mut self, @@ -753,7 +757,7 @@ The same test cases as for the bls12381_g1_sum section. The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. -***Error cases:*** +***Error cases (execution is terminated):*** - The input length is not divided by 128 - Too much memory is used @@ -763,9 +767,11 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. -The output data will be written to register with `register_id` id. +Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. +Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. -The ERROR_CODE is returned. +If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, +otherwise, nothing will be written to the register. ```rust pub fn bls12381_g1_multiexp( @@ -830,7 +836,7 @@ The same as for **`bls12381_g1_multiexp`** only change points from $G_1$ and $E( The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. -***Error cases:*** +***Error cases (execution is terminated):*** - The input length is not divided by 224 - Too much memory is used @@ -840,9 +846,11 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. -The output data will be written to register with `register_id` id. +Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. +Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. -The ERROR_CODE is returned. +If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, +otherwise, nothing will be written to the register. ```rust pub fn bls12381_g2_multiexp( @@ -899,7 +907,7 @@ Edge cases: ***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. -***Error cases:*** +***Error cases (execution is terminated):*** - Incorrect input length @@ -908,9 +916,11 @@ Edge cases: The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. -The output data will be written to register with `register_id` id. +Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. +Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. -The ERROR_CODE is returned. +If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, +otherwise, nothing will be written to the register. ```rust pub fn bls12381_map_fp_to_g1( @@ -969,7 +979,7 @@ Edge cases: ***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. -***Error cases:*** +***Error cases (execution is terminated):*** - Incorrect input length @@ -978,9 +988,11 @@ Edge cases: The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. -The output data will be written to register with `register_id` id. +Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. +Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. -The ERROR_CODE is returned. +If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, +otherwise, nothing will be written to the register. ```rust pub fn bls12381_map_fp2_to_g2( @@ -1088,7 +1100,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. ***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. -***Error cases:*** +***Error cases (execution is terminated):*** - The input length is not divided by 288 - Too much memory is used @@ -1098,9 +1110,11 @@ Here you can find benchmark test vectors for EIP-2537[^46]. The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. -The output data will be written to register with `register_id` id. +Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. +Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. -The ERROR_CODE is returned. +If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, +otherwise, nothing will be written to the register. ```rust pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; @@ -1163,7 +1177,7 @@ A and B are constants calculated empirically. - 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:*** +***Error cases (execution is terminated):*** - The input length is not divided by 48 - Too much memory is used @@ -1173,9 +1187,11 @@ A and B are constants calculated empirically. The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. -The output data will be written to register with `register_id` id. +Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. +Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. -The ERROR_CODE is returned. +If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, +otherwise, nothing will be written to the register. ```rust pub fn bls12381_decompress_g1(&mut self, @@ -1218,7 +1234,7 @@ The same test cases as for `bls12381_decompress_g1` but with points from $G_2$ a - 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:*** +***Error cases (execution is terminated):*** - The input length is not divided by 96 - Too much memory is used @@ -1228,9 +1244,11 @@ The same test cases as for `bls12381_decompress_g1` but with points from $G_2$ a The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, if the `value_len` is `u64::MAX` the input will be obtained from register. -The output data will be written to register with `register_id` id. +Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. +Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. -The ERROR_CODE is returned. +If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, +otherwise, nothing will be written to the register. ```rust pub fn bls12381_decompress_g2(&mut self, From c895d70af4493c27f8955ace6395b10d349e0abd Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 12:24:13 +0200 Subject: [PATCH 100/163] fix error case --- neps/nep-0488.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 00aa523c6..47a75ddd2 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -581,7 +581,7 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Error cases (execution is terminated):*** - The input length is not divided by 97 -- Too much memory is used +- The input out of memory bounds ***Annotation:*** @@ -646,7 +646,7 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Error cases (execution is terminated):*** - The input length is not divided by 193 -- Too much memory is used +- The input out of memory bounds ***Annotation:*** @@ -760,7 +760,7 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Error cases (execution is terminated):*** - The input length is not divided by 128 -- Too much memory is used +- The input out of memory bounds ***Annotation:*** @@ -839,7 +839,7 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Error cases (execution is terminated):*** - The input length is not divided by 224 -- Too much memory is used +- The input out of memory bounds ***Annotation:*** @@ -1103,7 +1103,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. ***Error cases (execution is terminated):*** - The input length is not divided by 288 -- Too much memory is used +- The input out of memory bounds ***Annotation:*** @@ -1180,7 +1180,7 @@ A and B are constants calculated empirically. ***Error cases (execution is terminated):*** - The input length is not divided by 48 -- Too much memory is used +- The input out of memory bounds ***Annotation:*** @@ -1237,7 +1237,7 @@ The same test cases as for `bls12381_decompress_g1` but with points from $G_2$ a ***Error cases (execution is terminated):*** - The input length is not divided by 96 -- Too much memory is used +- The input out of memory bounds ***Annotation:*** From 749b0cc88747c30c7aa49277bbfcd305354b827f Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 12:38:23 +0200 Subject: [PATCH 101/163] remove unses link --- neps/nep-0488.md | 1 - 1 file changed, 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 47a75ddd2..a159d04a4 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1373,7 +1373,6 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^53]: Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) [^54]: Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 [^55]: Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) -[^58]: BLST errors list. [https://github.com/supranational/blst/blob/v0.3.11/src/errors.h](https://github.com/supranational/blst/blob/v0.3.11/src/errors.h) [^59]: Implementation of BLS-signature based on these host functions: [https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs](https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs) [^60]: hash_to_field specification: [https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio](https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio) [^61]: double-and-add algorithm: [https://en.wikipedia.org/wiki/Exponentiation_by_squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring) From 7ca6c1a4d6772b4ef4aee1b1e07ef8c3bb94f793 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 13:34:56 +0200 Subject: [PATCH 102/163] fix grammer for Consequences, Future possibilities and alternatives --- neps/nep-0488.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a159d04a4..8a0c00820 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1293,29 +1293,33 @@ The BLS12-381 has more security bits than the already existing pairing-friendly ## Alternatives -In the nearcore the host functions for another pairing-friendly curve BN254 are already implemented[^10]. For some projects[^20] the alternative is just to use the supported curve. However, according to the 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 Ethereum it is BLS12-381[^3] nowadays. As a result, there is no alternative to using another pairing-friendly curve. +In nearcore, host functions for another pairing-friendly curve, BN254, have already been implemented[^10]. Some projects[^20] might consider utilizing the supported curve as an alternative. However, recent research indicates that this curve provides less than 100 bits of security and is not recommended for use[^13]. Furthermore, projects involved in cross-chain interactions, like Rainbow Bridge, are mandated to employ the same curve as the target protocol, which, in the case of Ethereum, is currently BLS12-381[^3]. Consequently, there is no viable alternative to employing a different pairing-friendly curve. -Another alternative is to create one simple host function 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 G1 subgroup for the public keys, and others – G2; (3) the specification for Ethereum 2.0 continue to be in the draft and details can change, (4) we have one big function instead of a more diverse and flexible set of functions (inspired by EIP-2537's precompiles). +An alternative approach involves creating a single straightforward host function in nearcore for BLS signature verification. This was the initially proposed solution[^26]. However, this solution lacks flexibility[^28] for several reasons: (1) projects may utilize different hash functions; (2) some projects might employ the G1 subgroup for public keys, while others use G2; (3) the specifications for Ethereum 2.0 remain in draft, subject to potential changes; (4) instead of a more varied and adaptable set of functions (inspired by EIP-2537's precompiles), we are left with a single large function; (5) there will be no support for zkSNARKs verification. -The next alternative is to execute BLS12-381 operations off-chain. In that case, the applications which are using the BLS curve will not be trustless anymore. +Another alternative is to perform BLS12-381 operations off-chain. In this scenario, applications utilizing the BLS curve will no longer maintain trustlessness. ## Future possibilities -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. +In the future, there might be support for working with various curves beyond just BLS12-381. In Ethereum, prior to EIP-2537[^15], there was a proposal, EIP-1962[^27], to introduce pairing-friendly elliptic curves in a versatile format, accommodating not only BLS curves but numerous others as well. However, this proposal wasn't adopted due to its extensive scope and complexity. Implementing every conceivable curve might not be practical, but it remains a potential extension worth considering. + +Another potential extension could involve supporting hash_to_field or hash_to_curve operations[^58]. Enabling their support would optimize gas usage for encoding messages into elements on the curve, which could benefit BLS signatures. However, implementing the hash_to_field operation requires supporting multiple hashing algorithms simultaneously and doesn't demand a significant amount of gas for implementation within the contract. Therefore, these functions exceed the scope of this proposal. + +Additionally, a potential expansion might encompass supporting not only affine coordinates but also other coordinate systems, such as homogeneous or Jacobian projective coordinates. ## Consequences ### Positive -- Projects, which are using BN254 will be able to switch on BLS12-381 curve, and it will improve their security. -- The trustless cross-chain interactions with blockchains using BLS12-381 in protocols (such as Ethereum 2.0) will become possible. +- Projects currently utilizing BN254 will have the capability to transition to the BLS12-381 curve, thereby enhancing their security. +- Trustless cross-chain interactions with blockchains employing BLS12-381 in protocols (like Ethereum 2.0) will become feasible. ### Neutral ### Negative -- The appearance of dependence on the library which supports BLS12-381 curves operations. -- We will need to maintain operations with BLS12-381 curve forever, even if vulnerabilities are found, and it is no longer safe to use. +- There emerges a dependency on a library that supports operations with BLS12-381 curves. +- We'll have to continually maintain operations with BLS12-381 curves, even if vulnerabilities are discovered, and it becomes unsafe to use these curves. ### Backward Compatibility @@ -1373,6 +1377,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^53]: Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) [^54]: Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 [^55]: Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) +[^58]: hash_to_curve and hash_to_field function: [https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio](https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio) [^59]: Implementation of BLS-signature based on these host functions: [https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs](https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs) [^60]: hash_to_field specification: [https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio](https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio) [^61]: double-and-add algorithm: [https://en.wikipedia.org/wiki/Exponentiation_by_squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring) From fa332ddee577b30bdf016dc158a3eb744122c372 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 16:05:02 +0200 Subject: [PATCH 103/163] fix grammer in Reference Implementation section --- neps/nep-0488.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 8a0c00820..eea98a17e 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1259,7 +1259,7 @@ pub fn bls12381_decompress_g2(&mut self, ## Reference Implementation -First of all, for integration with nearcore, we are interested in libraries in the Rust language. The existing BLS12-381 implementations on Rust: +Primarily, concerning integration with nearcore, our interest lies in Rust language libraries. The current implementations of BLS12-381 in Rust are: 1. ***Milagro Library*** [^29]. 2. ***BLST*** [^30][^31]. @@ -1269,9 +1269,9 @@ First of all, for integration with nearcore, we are interested in libraries in t 6. ***FileCoin implementation*** [^35] 7. ***zkCrypto*** [^36] -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 host functions from that NEP we will need to modify any of that libraries. +To compile the list, we used links from EIP-2537[^43], the pairing-curves specification[^44], and an article containing benchmarks[^45]. This list might be incomplete, but it should encompass the primary BLS12-381 implementations. -In addition, there are implementations in other languages that are not so interesting to us in this context, but can be used as references: +In addition, there are implementations in other languages that are less relevant to us in this context but can serve as references. 1. C++, ETH2.0 Client, ***Chia library***[^37] 2. Haskell, ***Adjoint Lib***[^38] @@ -1280,16 +1280,17 @@ In addition, there are implementations in other languages that are not so intere 5. Go, ***Matter Labs Go EIP-1962 implementation***[^41] 6. C++, ***Matter Labs Go EIP-1962 implementation***[^42] -One of the possible libraries to use is *blst* library[^30]. This library shows a good performance[^45] and passed some audits[^55]. -The draft implementation in nearcore, which is based on this library, you can find by this link[^54]. +One of the possible libraries to use is the blst library[^30]. +This library exhibits good performance[^45] and has undergone several audits[^55]. +You can find the draft implementation in nearcore, which is based on this library, through this link[^54]. ## Security Implications -The implementation security relies on the security of the chosen library, which supports operations with BLS curves. +The implementation's security depends on the chosen library's security, supporting operations with BLS curves. -In this NEP, we do not require a constant execution time for all operations. This is not a problem if you use host functions to verify the BLS signature. These host functions should not be used if you need a constant-time algorithm. +Within this NEP, a constant execution time for all operations isn't mandated. This isn't an issue when employing host functions for BLS signature/zkSNARKs verification. However, refrain from using these host functions if a constant-time algorithm is necessary. -The BLS12-381 has more security bits than the already existing pairing-friendly curve BN254, as a result, the security of the projects which need the pairing-friendly curve will improve. +BLS12-381 offers more security bits compared to the already existing pairing-friendly curve BN254. Consequently, the security of projects requiring the pairing-friendly curve will be enhanced. ## Alternatives From 9a70bdebe8a80392f64910b71f4914ca8d9909cc Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 16:26:30 +0200 Subject: [PATCH 104/163] separate common parts --- neps/nep-0488.md | 95 +++++++----------------------------------------- 1 file changed, 14 insertions(+), 81 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index eea98a17e..c0fdaf5b6 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -585,15 +585,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Annotation:*** -The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, -if the `value_len` is `u64::MAX` the input will be obtained from register. - -Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. -Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. - -If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, -otherwise, nothing will be written to the register. - ```rust pub fn bls12381_g1_sum(&mut self, value_len: u64, @@ -650,15 +641,6 @@ We can use all the tests for addition for Ethereum[^47],[^48] to check the case ***Annotation:*** -The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, -if the `value_len` is `u64::MAX` the input will be obtained from register. - -Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. -Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. - -If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, -otherwise, nothing will be written to the register. - ```rust pub fn bls12381_g2_sum(&mut self, value_len: u64, @@ -764,15 +746,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Annotation:*** -The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, -if the `value_len` is `u64::MAX` the input will be obtained from register. - -Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. -Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. - -If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, -otherwise, nothing will be written to the register. - ```rust pub fn bls12381_g1_multiexp( &mut self, @@ -843,15 +816,6 @@ The EIP-2537 contains the same function, so we can reuse test vectors from Ether ***Annotation:*** -The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, -if the `value_len` is `u64::MAX` the input will be obtained from register. - -Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. -Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. - -If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, -otherwise, nothing will be written to the register. - ```rust pub fn bls12381_g2_multiexp( &mut self, @@ -913,15 +877,6 @@ Edge cases: ***Annotation:*** -The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, -if the `value_len` is `u64::MAX` the input will be obtained from register. - -Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. -Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. - -If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, -otherwise, nothing will be written to the register. - ```rust pub fn bls12381_map_fp_to_g1( &mut self, @@ -985,15 +940,6 @@ Edge cases: ***Annotation:*** -The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, -if the `value_len` is `u64::MAX` the input will be obtained from register. - -Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. -Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. - -If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, -otherwise, nothing will be written to the register. - ```rust pub fn bls12381_map_fp2_to_g2( &mut self, @@ -1107,15 +1053,6 @@ Here you can find benchmark test vectors for EIP-2537[^46]. ***Annotation:*** -The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, -if the `value_len` is `u64::MAX` the input will be obtained from register. - -Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. -Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. - -If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, -otherwise, nothing will be written to the register. - ```rust pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; ``` @@ -1184,15 +1121,6 @@ A and B are constants calculated empirically. ***Annotation:*** -The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, -if the `value_len` is `u64::MAX` the input will be obtained from register. - -Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. -Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. - -If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, -otherwise, nothing will be written to the register. - ```rust pub fn bls12381_decompress_g1(&mut self, value_len: u64, @@ -1241,15 +1169,6 @@ The same test cases as for `bls12381_decompress_g1` but with points from $G_2$ a ***Annotation:*** -The input is obtained from memory started from `value_ptr` to `value_ptr + value_len`, -if the `value_len` is `u64::MAX` the input will be obtained from register. - -Execution is terminated only in case of incorrect input length or reaching of memory or gas limits. -Otherwise, the execution will finish successfully and the ERROR_CODE will be returned. - -If the ERROR_CODE = 0 the output data will be written to register with `register_id` id, -otherwise, nothing will be written to the register. - ```rust pub fn bls12381_decompress_g2(&mut self, value_len: u64, @@ -1257,6 +1176,20 @@ pub fn bls12381_decompress_g2(&mut self, register_id: u64) -> Result; ``` +#### General comments for all functions + +In all functions, input is fetched from memory, beginning at `value_ptr` and extending to `value_ptr + value_len`. +If `value_len` is `u64::MAX`, input will come from the register. + +Execution ends only if there's an incorrect input length, +input extends beyond memory bounds, or gas limits are reached. +Otherwise, execution completes successfully, providing the `ERROR_CODE`. + +If the `ERROR_CODE` equals 0, the output data will be written to +the register with the `register_id` identifier. +Otherwise, nothing will be written to the register. + + ## Reference Implementation Primarily, concerning integration with nearcore, our interest lies in Rust language libraries. The current implementations of BLS12-381 in Rust are: From 65bbd1f1ba3a3ed33722737b5ce9f8b822060116 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 16:39:57 +0200 Subject: [PATCH 105/163] remove test reference section --- neps/nep-0488.md | 43 +++++-------------------------------------- 1 file changed, 5 insertions(+), 38 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index c0fdaf5b6..83ea0375e 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -514,7 +514,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain In this section, I would like to test that the sum of two correct elements on the curve works correctly. We can use the following methods: -- Take the points on the curve with known answer and compare results. For example, we can use tests for EIP-2537 +- Take the points on the curve with known answer and compare results. For example, we can use tests for EIP-2537[^47],[^48] - Generate the random points on the curve and check the P + Q = Q + P - Generate the random points from G1 and check that sum also in G1 - Use the implementation from another library, generate the random points on curve and compare results @@ -573,11 +573,6 @@ Edge cases: - Sum with the maximum number of elements - One point - -***Tests References:*** - -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 (execution is terminated):*** - The input length is not divided by 97 @@ -630,10 +625,6 @@ Here you can find benchmark test vectors for EIP-2537[^46]. It doesn’t contain The same as for **`bls12381_g1_sum`** only change points from $G_1$ and $E(F_p)$ into $G_2$ and $E'(F_{p^2})$. -***Tests References:*** - -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 (execution is terminated):*** - The input length is not divided by 193 @@ -725,7 +716,7 @@ The same test cases as for the bls12381_g1_sum section. Tests for the multiexp of an arbitrary amount of points -- tests with known answers from EIP-2537 +- tests with known answers from EIP-2537[^47],[^48] - random number of points, scalars, points: - check with results from another library - check with raw implementation based on sum function and double-and-add algorithm @@ -735,10 +726,6 @@ The same test cases as for the bls12381_g1_sum section. Tests for error cases The same test cases as for the bls12381_g1_sum section. -***Tests References:*** - -The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. - ***Error cases (execution is terminated):*** - The input length is not divided by 128 @@ -805,10 +792,6 @@ To improve gas costs Pippenger’s algorithm[^25] can be used. For gas estimatio The same as for **`bls12381_g1_multiexp`** only change points from $G_1$ and $E(F_p)$ into $G_2$ and $E'(F_{p^2})$. -***Tests References:*** - -The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. - ***Error cases (execution is terminated):*** - The input length is not divided by 224 @@ -849,7 +832,7 @@ The gas consumption is a constant calculated empirically. Tests for general cases -- validate the results for known answers. Tests for same function in EIP-2537 +- validate the results for known answers. Tests for same function in EIP-2537[^47],[^48] - generate random point $a$ from Fp: - check the result with another library - check that result point on curve in G1 @@ -869,8 +852,6 @@ Edge cases: - $a = p$ - random number $\ge p$ -***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. - ***Error cases (execution is terminated):*** - Incorrect input length @@ -910,7 +891,7 @@ The gas consumption is a constant calculated empirically. Tests for general cases -- validate the results for known answers. Tests for same function in EIP-2537 +- validate the results for known answers. Tests for same function in EIP-2537[^47],[^48] - generate random point $a$ from $F_{p^2}$: - check the result with another library - check that result point on curve in G2 @@ -932,8 +913,6 @@ Edge cases: - (random number $\ge p$, 0) - (0, random number $\ge p$) -***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. - ***Error cases (execution is terminated):*** - Incorrect input length @@ -1024,7 +1003,7 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - empty input - test with maximum available amount of pairs -- tests with known answers from EIP-2537 +- tests with known answers from EIP-2537[^47],[^48] - random pairs numbers, random scalars $p_1 \cdots p_n$ and $q_1 \cdots q_n$ such as $\sum p_i \cdot q_i \not \equiv 0 (\mod r)$: - check $\prod e(p_i g_1, q_i g_2) \ne 1$ - random pairs numbers, random scalars $p_1 \cdots p_{n - 1}$ and $q_1 \cdots q_{n - 1}$: @@ -1044,8 +1023,6 @@ Here you can find benchmark test vectors for EIP-2537[^46]. - wrong decompression bit - coordinates bigger or equal than p -***Tests References:*** The EIP-2537 contains the same function, so we can reuse test vectors from Ethereum[^47],[^48]. - ***Error cases (execution is terminated):*** - The input length is not divided by 288 @@ -1109,11 +1086,6 @@ A and B are constants calculated empirically. - incorrectly encoded infinity point - point with coordinate bigger then p -***Tests References:*** - -- 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 (execution is terminated):*** - The input length is not divided by 48 @@ -1157,11 +1129,6 @@ A and B are constants calculated empirically. The same test cases as for `bls12381_decompress_g1` but with points from $G_2$ and the input length should be divided by 96. -***Tests References:*** - -- 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 (execution is terminated):*** - The input length is not divided by 96 From 01912b75c13f85a8a4e19d90eab4d79cf01a48f3 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 17:04:41 +0200 Subject: [PATCH 106/163] fix bls12381_decompress_g2 section --- neps/nep-0488.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 83ea0375e..f9e637c23 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1102,37 +1102,39 @@ pub fn bls12381_decompress_g1(&mut self, #### bls12381_decompress_g2 -***Description:*** Function decompress compressed points from $E'(F_{p^2})$. The input is an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format, and the output is the same number of points from $E'(F_{p^2})$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. +***Description:*** The function decompresses compressed points from $E'(F_{p^2})$. It takes an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format as input and outputs the same number of points from $E'(F_{p^2})$ in decompressed format. For more information about the decompressed and compressed formats, refer to the Curve Points Encoding section. -***Input:*** the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in compressed form. Expected `96*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E'(F_{p^2})$. More details are in the Curve Points Encoding section. +***Input:*** Sequence of points $p_i \in E'(F_{p^2})$, with each point encoded in compressed form. The expected input size is 96*k bytes, interpreted as the byte concatenation of k slices. Each slice represents the compressed point from $E'(F_{p^2})$. Additional details are available in the Curve Points Encoding section. ***Output:*** -the ERROR_CODE is returned. +The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: the sequence of point $p_i \in E'(F_{p^2})$, each point encoded in decompressed form. Expected `192*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E'(F_{p^2})$. `k` the same as in input. More details are in the Curve Points Encoding section. + - Output: the sequence of point $p_i \in E'(F_{p^2})$, with each point encoded in decompressed form. The expected output is 192*k bytes, interpreted as the byte concatenation of k slices. `k` corresponds to the value specified in the input section. Each slice represents the decompressed point from $E'(F_{p^2})$. For more details, refer to the Curve Points Encoding section. - ERROR_CODE = 1: - - points encoded incorrectly (see Curve points encoded section) - - point not on the curve + - Points are incorrectly encoded (refer to Curve points encoded section). + - Point is not on the curve. -***Gas Estimation:*** The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula +***Gas Estimation:*** + +The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: ```rust -let k = (input_bytes + item_size - 1)/item_size +let k = input_bytes/item_size let gas_consumed = A + B * k ``` -A and B are constants calculated empirically. +Here, A and B represent empirically calculated constants. ***Test cases:*** -The same test cases as for `bls12381_decompress_g1` but with points from $G_2$ and the input length should be divided by 96. +The same test cases as `bls12381_decompress_g1`, but with points from $G_2$, and the input length should be divisible by 96. ***Error cases (execution is terminated):*** -- The input length is not divided by 96 -- The input out of memory bounds +- The input length is not divisible by 96. +- The input is beyond memory bounds. ***Annotation:*** From 43f20268cfd8e5338f1d8b492fa0a119fd8ec968 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 17:25:35 +0200 Subject: [PATCH 107/163] fix bls12381_decompress_g1 section --- neps/nep-0488.md | 62 +++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index f9e637c23..b126fb151 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1036,60 +1036,62 @@ pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64, registe #### bls12381_decompress_g1 -***Description:*** Function decompress compressed points from $E(F_p)$. The input is an arbitrary number of points $p_i \in E(F_p)$ in compressed format, and the output is the same number of points from $E(F_p)$ in decompressed format. More about the decompressed and compressed formats you can read in the Curve Points Encoding section. +***Description:*** The function decompresses compressed points from $E(F_p)$. It takes an arbitrary number of points $p_i \in E(F_p)$ in compressed format as input and outputs the same number of points from $E(F_p)$ in decompressed format. Further details about the decompressed and compressed formats are available in the Curve Points Encoding section. -***Input:*** the sequence of point $p_i \in E(F_p)$, each point encoded in compressed form. Expected `48*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the compressed point from $E(F_p)$. More details are in the Curve Points Encoding section. +***Input:*** A sequence of points $p_i \in E(F_p)$, with each point encoded in compressed form. An expected input size of 48*k bytes is anticipated, interpreted as the byte concatenation of k slices. Each slice represents the compressed point from $E(F_p)$. Additional details can be found in the Curve Points Encoding section. ***Output:*** -the ERROR_CODE is returned. +The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: the sequence of point $p_i \in E(F_p)$, each point encoded in decompressed form. Expected `96*k` bytes as an output that is interpreted as byte concatenation of `k` slices, each slice is the decompressed point from $E(F_p)$. `k` the same as in input. More details are in the Curve Points Encoding section. + - Output: The sequence of points $p_i \in E(F_p)$, with each point encoded in decompressed form. An expected output of 96*k bytes, interpreted as the byte concatenation of k slices. Each slice represents the decompressed point from $E(F_p)$. k is the same as in the input. More details are available in the Curve Points Encoding section. - ERROR_CODE = 1: - - points encoded incorrectly (see Curve points encoded section) - - point not on the curve + - Points are incorrectly encoded (refer to the Curve points encoded section). + - Point is not on the curve. + +***Gas Estimation:*** -***Gas Estimation:*** The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula +The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: ```rust -let k = input_bytes / item_size +let k = input_bytes/item_size let gas_consumed = A + B * k ``` -A and B are constants calculated empirically. +Here, A and B represent empirically calculated constants. ***Test cases:*** -Tests for one point decompression +Tests for decompressing a single point -- generate random points on the curve from G1 and not from G1: - - check that the uncompressed point lies on the curve - - compare the result with another library -- generate random points with negative y: - - take inverse and compare y - - compare the result with another library -- decompress point on infinity +- Generate random points on the curve from G1 and not from G1: + - Check that the uncompressed point lies on the curve. + - Compare the result with another library. +- Generate random points with a negative y: + - Take the inverse and compare the y-coordinate. + - Compare the result with another library. +- Decompress a point on infinity. -Tests for decompression of arbitrary amount of points +Tests for decompression of an arbitrary number of points -- empty input -- maximum amount of points -- generate the random amount of the random points on curve and compare the result with another library +- Empty input. +- Maximum number of points. +- Generate a random number of points on the curve and compare the result with another library. Tests for error cases -- the input length is not divided by 48 -- input length exceeds memory limit -- point not on the curve -- incorrect decompression bit -- incorrectly encoded infinity point -- point with coordinate bigger then p +- The input length is not divisible by 48. +- The input is beyond memory bounds. +- Point is not on the curve. +- Incorrect decompression bit. +- Incorrectly encoded infinity point. +- Point with a coordinate larger than 'p'. ***Error cases (execution is terminated):*** -- The input length is not divided by 48 -- The input out of memory bounds +- The input length is not divisible by 48. +- The input is beyond memory bounds. ***Annotation:*** @@ -1104,7 +1106,7 @@ pub fn bls12381_decompress_g1(&mut self, ***Description:*** The function decompresses compressed points from $E'(F_{p^2})$. It takes an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format as input and outputs the same number of points from $E'(F_{p^2})$ in decompressed format. For more information about the decompressed and compressed formats, refer to the Curve Points Encoding section. -***Input:*** Sequence of points $p_i \in E'(F_{p^2})$, with each point encoded in compressed form. The expected input size is 96*k bytes, interpreted as the byte concatenation of k slices. Each slice represents the compressed point from $E'(F_{p^2})$. Additional details are available in the Curve Points Encoding section. +***Input:*** A sequence of points $p_i \in E'(F_{p^2})$, with each point encoded in compressed form. The expected input size is 96*k bytes, interpreted as the byte concatenation of k slices. Each slice represents the compressed point from $E'(F_{p^2})$. Additional details are available in the Curve Points Encoding section. ***Output:*** From 4adcbf154c9349d52f20df12a6383d7c77561aa8 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 18:49:09 +0200 Subject: [PATCH 108/163] fix pairing check --- neps/nep-0488.md | 91 +++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b126fb151..38e63c703 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -932,50 +932,50 @@ pub fn bls12381_map_fp2_to_g2( ***Description:*** -The pairing function $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{q^{12}}$. The pairing function has the following properties: +The pairing function $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{q^{12}}$, exhibits the following properties: - $e(P, Q + R) = e(P, Q) \cdot e(P, R)$ - $e(P + S, R) = e(P, R)\cdot e(S, R)$ -The consequence: +Consequently: $e([a]P, [b]Q) = e(P, Q)^{ab} = e([b]P, [a]Q)$ -We need this function to verify BLS signature. +This function is necessary to verify BLS signatures/zkSNARKs. -This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$ and check: +This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$ and validate: $$ \prod e(p_i, q_i) = 1 $$ -We don’t calculate the pairing function itself: the result will be in the huge field, and in all known applications only such a check is necessary. +We don’t calculate the pairing function itself: the result will be in the huge field, and in all known applications only this validation check is necessary. -***Input:*** the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. Expected `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $G_1 \subset E(F_p)$ — `96 bytes` and point from $G_2 \subset E'(F_{p^2})$ — `192 bytes`. More details are in the Curve Points Encoding section. +***Input:*** A sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. An expected input size of 288*k bytes is anticipated, interpreted as byte concatenation of k slices. Each slice comprises the concatenation of an uncompressed point from $G_1 \subset E(F_p)$ (occupying 96 bytes) and a point from $G_2 \subset E'(F_{p^2})$ (occupying 192 bytes). Additional details can be found in the Curve Points Encoding section. ***Output:*** -the ERROR_CODE is returned. +The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 1 byte with two possible values: 1 if the pairing result is equal to multiplicative identity and 0 -- otherwise. + - Output: 1 byte with two possible values: 1 if the pairing result equals the multiplicative identity, and 0 otherwise. - ERROR_CODE = 1: - - points encoded incorrectly (see Curve points encoded section) - - point not on the curve - - point not in $G_1/G_2$ + - Points encoded incorrectly (refer to the Curve Points Encoded section). + - Point not on the curve. + - Point not in $G_1/G_2$. -For empty input it returns ERROR_CODE = 0. +For an empty input, the function returns ERROR_CODE = 0. ***Gas Estimation:*** -The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula +The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: ```rust -let k = input_bytes / item_size +let k = input_bytes/item_size let gas_consumed = A + B * k ``` -A and B are constants calculated empirically. +Here, A and B represent empirically calculated constants. Here you can find benchmark test vectors for EIP-2537[^46]. @@ -983,55 +983,58 @@ Here you can find benchmark test vectors for EIP-2537[^46]. Tests for one pair -- generate random $P \in G_1$: check $e(P, 0) = 1$ -- generate random $Q \in G_2$: check $e(0, Q) = 1$ -- generate random $P \ne 0 \in G_1$ and $Q \ne 0 \in G_2$: check $e(P, Q) \ne 1$ +- Generate a random point $P \in G_1$: verify $e(P, 0) = 1$ +- Generate a random point $Q \in G_2$: verify $e(0, Q) = 1$ +- Generate random points $P \ne 0 \in G_1$ and $Q \ne 0 \in G_2$: verify $e(P, Q) \ne 1$ Tests for two pairs -- generate random points $P \in G_1$, $Q \in G_2$ and random scalars $s_1, s_2$: +- Generate random points $P \in G_1$, $Q \in G_2$ and random scalars $s_1, s_2$: - $e(P, Q) \cdot e(P, -Q) = 1$ - $e(P, Q) \cdot e(-P, Q) = 1$ - $e(s_1P, s_2Q) \cdot e(-s_2P, s_1Q) = 1$ - $e(s_1P, s_2Q) \cdot e(s_2P, -s_1Q) = 1$ -- $g_1 \in G_1$, $g_2 \in G_2$ -- generators defined in section 'BLS12-381 Curve Specification', r -- order of $G_1$ and $G_2$, and $p_1, p_2, q_1, q_2$ randomly generated scalars: - - if $p_1 \cdot q_1 + p_2 \cdot q_2 \not \equiv 0 (\mod r)$, check $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) \ne 1$ - - if $p_1 \cdot q_1 + p_2 \cdot q_2 \equiv 0 (\mod r)$, check $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) = 1$ +- $g_1 \in G_1$, $g_2 \in G_2$ are generators defined in section 'BLS12-381 Curve Specification', r is the order of $G_1$ and $G_2$, and $p_1, p_2, q_1, q_2$ are randomly generated scalars: + - if $p_1 \cdot q_1 + p_2 \cdot q_2 \not \equiv 0 (\mod r)$, verify $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) \ne 1$ + - if $p_1 \cdot q_1 + p_2 \cdot q_2 \equiv 0 (\mod r)$, verify $e(p_1 g_1, q_1 g_2) \cdot e(p_2 g_1, q_2 g_2) = 1$ -Tests for arbitrary amount of pairs +Tests for an arbitrary number of pairs -- empty input -- test with maximum available amount of pairs -- tests with known answers from EIP-2537[^47],[^48] -- random pairs numbers, random scalars $p_1 \cdots p_n$ and $q_1 \cdots q_n$ such as $\sum p_i \cdot q_i \not \equiv 0 (\mod r)$: - - check $\prod e(p_i g_1, q_i g_2) \ne 1$ -- random pairs numbers, random scalars $p_1 \cdots p_{n - 1}$ and $q_1 \cdots q_{n - 1}$: - - check $(\prod e(p_i g_1, q_i g_2)) \cdot e(-(\sum p_i q_i) g_1, g_2) = 1$ - - check $(\prod e(p_i g_1, q_i g_2)) \cdot e(g_1, -(\sum p_i q_i) g_2) = 1$ +- Empty input +- Test with the maximum number of pairs +- Tests using known answers from EIP-2537[^47],[^48] +- For all possible values of 'n', generate random scalars $p_1 \cdots p_n$ and $q_1 \cdots q_n$ such that $\sum p_i \cdot q_i \not \equiv 0 (\mod r)$: + - Verify $\prod e(p_i g_1, q_i g_2) \ne 1$ +- For all possible values of 'n', generate random scalars $p_1 \cdots p_{n - 1}$ and $q_1 \cdots q_{n - 1}$: + - Verify $(\prod e(p_i g_1, q_i g_2)) \cdot e(-(\sum p_i q_i) g_1, g_2) = 1$ + - Verify $(\prod e(p_i g_1, q_i g_2)) \cdot e(g_1, -(\sum p_i q_i) g_2) = 1$ Tests for error cases -- The first point on the curve but not in G1 -- The second point on the curve but not in G2 -- The input length not divided by 288 -- The first point not on the curve -- The second point not on the curve -- Input length exceeds memory limit -- The incorrect 0 point encoding -- Incorrect encoding of curve point: - - wrong decompression bit - - coordinates bigger or equal than p +- The first point is on the curve but not in G1. +- The second point is on the curve but not in G2. +- The input length is not divisible by 288. +- The first point is not on the curve. +- The second point is not on the curve. +- Input length exceeds the memory limit. +- Incorrect encoding of the infinity point. +- Incorrect encoding of a curve point: + - Incorrect decompression bit. + - Coordinates greater than or equal to 'p'. ***Error cases (execution is terminated):*** -- The input length is not divided by 288 -- The input out of memory bounds +- The input length is not divisible by 288. +- The input is beyond memory bounds. ***Annotation:*** ```rust -pub fn bls12381_pairing_check(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; +pub fn bls12381_pairing_check(&mut self, + value_len: u64, + value_ptr: u64, + register_id: u64) -> Result; ``` #### bls12381_decompress_g1 From 6ea39ba73938d75582d58d0d5dd0fd3c4ef946bd Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 19:07:49 +0200 Subject: [PATCH 109/163] map fp to g1 --- neps/nep-0488.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 38e63c703..ddf3fc5b0 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -871,17 +871,17 @@ 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 section "Map to curve specification". 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 $G_2 \subset E'(F_{p^2})$. You can find the mapping function's specifications in the "Map to Curve Specification" section. It's important to note that this function does NOT map the byte string into $F_{p^2}$. The implementation of this function may vary and can be effectively executed within 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. +***Input:*** the function takes as input `96 bytes` — the element from $F_{p^2}$ (two unsigned integers $< p$). Additional details can be found in the Curve Points Encoding section. ***Output:*** -the ERROR_CODE is returned. +The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: `192 bytes` — one point $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. -- ERROR_CODE = 1: value is not a valid extension field $F_{p^2}$ element + - Output: `192` bytes - represents a single point $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. +- ERROR_CODE = 1: the value is not a valid extension field $F_{p^2}$ element ***Gas Estimation:*** @@ -891,11 +891,11 @@ The gas consumption is a constant calculated empirically. Tests for general cases -- validate the results for known answers. Tests for same function in EIP-2537[^47],[^48] -- generate random point $a$ from $F_{p^2}$: - - check the result with another library - - check that result point on curve in G2 - - compare results for $a$ and $-a$, it should be the same x coordinates and opposite y. +- Validate the results for known answers from EIP-2537[^47],[^48] +- Generate a random point $a$ from $F_{p^2}$: + - Verify the result with another library. + - Check that result point on curve in G2. + - Compare results for $a$ and $-a$; they should have the same x-coordinates and opposite y-coordinates. Edge cases: @@ -904,10 +904,10 @@ Edge cases: Tests for error cases -- input length not equal to 96 bytes: - - empty input +- Input length not equal to 96 bytes:: + - Empty input - 192 bytes - - out of memory input length + - Input is beyond memory bounds. - $a = (0, p)$ - $a = (p, 0)$ - (random number $\ge p$, 0) From 63b7c2dbe5d9a62c24a8da534ef4939a99a14cd2 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 19:21:18 +0200 Subject: [PATCH 110/163] fix map fp to g2 --- neps/nep-0488.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index ddf3fc5b0..3f69e2445 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -812,16 +812,18 @@ 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 section "Map to curve specification". 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 $G_1 \subset E(F_p)$. You can find the specification of this mapping function in the section titled 'Map to curve specification.' Importantly, this function does NOT perform the mapping of the byte string into $F_p$. The implementation of this function may vary and can be effectively executed within the 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. +***Input:*** + +The function expects 48 bytes as input, representing an element from $F_p$ (a single unsigned integer $< p$). Additional information is available in the Curve Points Encoding section. ***Output:*** -the ERROR_CODE is returned. +The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: `96 bytes` — one point $\in G_1 \subset E(F_p)$ in decompressed format. More details are in the Curve Points Encoding section. + - Output: `96` bytes - represents a single point $\in G_1 \subset E(F_p)$ in decompressed format. Further information is available in the Curve Points Encoding section. - ERROR_CODE = 1: $a \ge p$. ***Gas Estimation:*** @@ -832,11 +834,11 @@ The gas consumption is a constant calculated empirically. Tests for general cases -- validate the results for known answers. Tests for same function in EIP-2537[^47],[^48] -- generate random point $a$ from Fp: - - check the result with another library - - check that result point on curve in G1 - - compare results for $a$ and $-a$, it should be the same x coordinates and opposite y. +- Validate the results for known answers from EIP-2537[^47],[^48]. +- Generate a random point $a$ from $F_p$: + - Verify the result using another library. + - Check that the resulting point lies on the curve in $G_1$. + - Compare the results for $a$ and $-a$; they should share the same x-coordinates and have opposite y-coordinates. Edge cases: @@ -845,12 +847,12 @@ Edge cases: Tests for error cases -- input length not equal to 48 bytes: - - empty input +- Input length not equal to 48 bytes: + - Empty input - 96 bytes - - out of memory input length + - Input is beyond memory bounds. - $a = p$ -- random number $\ge p$ +- Random number $\ge p$ ***Error cases (execution is terminated):*** From 702adc06613abf92cd511d69318e66f2f8a980f3 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 19:49:22 +0200 Subject: [PATCH 111/163] fix g2 multiexp --- neps/nep-0488.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 3f69e2445..fd2326a5d 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -746,20 +746,20 @@ pub fn bls12381_g1_multiexp( ***Description:*** -The function takes as input the list of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. The function calculates $\sum s_i \cdot p_i$. +The function takes a list of pairs $(p_i, s_i)$ as input, where $p_i \in E'(F_{p^2})$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ denotes a scalar. The function computes $\sum s_i \cdot p_i$. -The multiplication on the scalar is the addition of that point a scalar number of times: +This scalar multiplication operation involves adding the point $p$ to itself a specified number of times: $$ s \cdot p = \underbrace{p + p + \ldots + p}_{s} $$ -The $E'(F_{p^2})$ curve, points on the curve and the addition operation are defined in the BLS12-381 Curve Specification section. +The $E'(F_{p^2})$ curve, points on the curve, and the addition operation are defined in the BLS12-381 Curve Specification section. -Note: +Please note: -- We take as input any points on the curve, not only from $G_2$. -- The scalar is an arbitrary unsigned integer and can be bigger than the group order. +- Input points can be from any part of the curve, not limited to $G_2$. +- The scalar is an arbitrary unsigned integer and can exceed the group order. ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. @@ -767,13 +767,13 @@ Expected `224*k` bytes as an input that is interpreted as byte concatenation of ***Output:*** -the ERROR_CODE is returned. +The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). + - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - - points encoded incorrectly (see Curve points encoded section) - - point not on the curve + - Points are incorrectly encoded (refer to Curve points encoded section). + - Point is not on the curve. ***Gas Estimation:*** @@ -784,19 +784,19 @@ let k = input_bytes / item_size let gas_consumed = A + B * k ``` -A and B are constants calculated empirically. +Here, A and B represent empirically calculated constants. -To improve gas costs Pippenger’s algorithm[^25] can be used. For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[^46]. +Pippenger’s algorithm[^25] can be employed to enhance gas efficiency. For gas estimation, the benchmark vectors for addition and multiplication in EIP-2537[^46] can be utilized. ***Test cases:*** -The same as for **`bls12381_g1_multiexp`** only change points from $G_1$ and $E(F_p)$ into $G_2$ and $E'(F_{p^2})$. +The test cases are identical to those for `bls12381_g1_multiexp`, except that the points from $G_1$ and $E(F_p)$ are replaced with points from $G_2$ and $E'(F_{p^2})$ ***Error cases (execution is terminated):*** -- The input length is not divided by 224 -- The input out of memory bounds - +- The input length is not divisible by 224. +- The input is beyond memory bounds. + ***Annotation:*** ```rust From c616ec3a40069dcf267077b3de2acc498c210f81 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 20:22:51 +0200 Subject: [PATCH 112/163] fix g1 multiexp --- neps/nep-0488.md | 72 +++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index fd2326a5d..0d25db88b 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -643,31 +643,32 @@ pub fn bls12381_g2_sum(&mut self, ***Description:*** -The function takes as input the list of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. The function calculates $\sum s_i \cdot p_i$. +The function accepts a list of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ denotes a scalar. It calculates $\sum s_i \cdot p_i$. -The multiplication on the scalar is the addition of that point a scalar number of times: +The scalar multiplication operation signifies the addition of that point a scalar number of times: $$ s \cdot p = \underbrace{p + p + \ldots + p}_{s} $$ -The $E(F_p)$ curve, points on the curve and the addition operation are defined in the BLS12-381 Curve Specification section. +The $E(F_p)$ curve, points on the curve, and the addition operation are defined in the BLS12-381 Curve Specification section. -Note: +Please note: -- We take as input any points on the curve, not only from $G_1$. -- The scalar is an arbitrary unsigned integer and can be bigger than the group order. +- The function accepts any points on the curve, not solely from $G_1$. +- The scalar is an arbitrary unsigned integer and can exceed the group order. -***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. Expected `128*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E(F_p)$ — `96` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. +***Input:*** The sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ is a scalar. The expected input size is 128*k bytes, interpreted as byte concatenation of k slices. Each slice comprises the concatenation of an uncompressed point from $E(F_p)$— 96 bytes, along with a scalar— 32 bytes. Further details are available in the Curve Points Encoding section. ***Output:*** -the ERROR_CODE is returned. + +The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). + - Output: 96 bytes represent one point $\in E(F_p)$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - - points encoded incorrectly (see Curve points encoded section) - - point not on the curve + - Points are incorrectly encoded (refer to Curve points encoded section). + - Point is not on the curve. ***Gas Estimation:*** @@ -678,21 +679,21 @@ let k = input_bytes / item_size let gas_consumed = A + B * k ``` -A and B are constants calculated empirically. +Here, A and B represent empirically calculated constants. -To improve gas costs Pippenger’s algorithm[^25] can be used. For gas estimation, we can use the benchmark vectors for addition and multiplication for EIP-2537[^46]. +Pippenger’s algorithm[^25] can be employed to enhance gas efficiency. For gas estimation, the benchmark vectors for addition and multiplication in EIP-2537[^46] can be utilized. ***Test cases:*** Tests for multiplication -- tests with known answer for multiplication from EIP-2537 -- random small scalar n and point P: - - check with sum function results: `P + P + P .. + P = n*P` - - check with result from another library -- random scalar n and point P: - - check with result from another library - - implement multiplication by using sum function and double-and-add algorithm[^61] +- Tests with known answers for multiplication from EIP-2537[^47],[^48]. +- Random small scalar n and point P: + - Check results with the sum function: `P + P + P + .. + P = n*P`. + - Compare with results from another library. +- Random scalar n and point P: + - Verify against results from another library. + - Implement multiplication by using the sum function and the double-and-add algorithm[^61]. Edge cases: @@ -704,32 +705,33 @@ Edge cases: - Scalar is a MAX_INT Tests for sum of two points -The same test cases as for the bls12381_g1_sum section. -- random points P and Q, compare results with sum function +These are identical test cases to those in the `bls12381_g1_sum` section. + +- Generate random points P and Q, then compare the results with the sum function. Tests for the sum of an arbitrary amount of points -- random points number amount, random points, compare results with sum function -- empty input -- input of maximum size +- Random number of points, random point values; compare results with the sum function. +- Empty input. +- Input of maximum size. Tests for the multiexp of an arbitrary amount of points -- tests with known answers from EIP-2537[^47],[^48] -- random number of points, scalars, points: - - check with results from another library - - check with raw implementation based on sum function and double-and-add algorithm -- empty input -- maximum input with MAX_INT scalars and random points +- Tests with known answers from EIP-2537[^47],[^48] +- Random number of points, scalars, and points: + - Check with results from another library. + - Check with raw implementation based on the sum function and the double-and-add algorithm.- Empty input +- Maximum number of scalars and points. Tests for error cases -The same test cases as for the bls12381_g1_sum section. + +The same test cases as those in the `bls12381_g1_sum` section will be applied. ***Error cases (execution is terminated):*** -- The input length is not divided by 128 -- The input out of memory bounds +- The input length is not divisible by 128. +- The input is beyond memory bounds. ***Annotation:*** @@ -758,7 +760,7 @@ The $E'(F_{p^2})$ curve, points on the curve, and the addition operation are def Please note: -- Input points can be from any part of the curve, not limited to $G_2$. +- The function accepts any points on the curve, not solely from $G_2$. - The scalar is an arbitrary unsigned integer and can exceed the group order. ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. From 0744ff68926b27d39a69fb8ca475f8c266f2dcb4 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 28 Nov 2023 20:48:43 +0200 Subject: [PATCH 113/163] fix g2 sum --- neps/nep-0488.md | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 0d25db88b..7cb023a70 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -591,44 +591,50 @@ pub fn bls12381_g1_sum(&mut self, ***Description:*** -The function computes the sum of the signed elements of the BLS12-381 curve. The input is an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point on elliptic curve and $s_i \in \textbraceleft 0, 1 \textbraceright$ is the point sign. The output is one point from $E'(F_{p^2})$ equal to $\sum (-1)^{s_i}p_i$. +The function computes the sum of the signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ represents a point on the elliptic curve and $s_i \in {0, 1}$ is the point's sign. The output is a single point from $E'(F_{p^2})$ equal to $\sum (-1)^{s_i}p_i$. -The $E'(F_{p^2})$ curve, points on the curve, multiplication on -1, and the addition operation are defined in the BLS12-381 Curve Specification section. +The $E'(F_{p^2})$ curve, the points on the curve, the multiplication by -1, and the addition operation are all defined in the BLS12-381 Curve Specification section. -Note: we take as input any points on the curve, not only from $G_2$ +Note: The function accepts any points on the curve, not limited to $G_2$. -***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_{p^2}, y\colon F_{p^2})$ and sign encoded in one byte. Expected `193*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E'(F_{p^2})$ and the point sign. More details are in the Curve Points Encoding section. +***Input:*** + +The sequence of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ represents a sign. +Each point is encoded in decompressed form as $(x: F_{p^2}, y: F_{p^2})$, and the sign is encoded in one byte. The expected input size is 193*k bytes, interpreted as a byte concatenation of k slices, +each slice representing the point sign alongside the uncompressed point from $E'(F_{p^2})$. +More details are available in the Curve Points Encoding section. ***Output:*** -the ERROR_CODE is returned. + +The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 192 bytes — the one point $\in E'(F_{p^2})$ in decompressed form. For empty input it returns point on infinity(see Curve Points Encoding section). + - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - - points or signs encoded incorrectly (see Curve points encoded section) - - points not on the curve + - Points are incorrectly encoded (refer to Curve points encoded section). + - Point is not on the curve. ***Gas Estimation:*** -The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula +The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: ```rust -let k = input_bytes / item_size +let k = input_bytes/item_size let gas_consumed = A + B * k ``` -A and B are constants calculated empirically. +Here, A and B represent empirically calculated constants. -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. +Here, you can find benchmark test vectors for EIP-2537[^46]. Although it doesn't include a sum function, we can adapt the test vector for addition by duplicating it multiple times. ***Test cases:*** -The same as for **`bls12381_g1_sum`** only change points from $G_1$ and $E(F_p)$ into $G_2$ and $E'(F_{p^2})$. +The test cases are identical to those of `bls12381_g1_sum`, with the only alteration being the substitution of points from $G_1$ and $E(F_p)$ with points from $G_2$ and $E'(F_{p^2})$. ***Error cases (execution is terminated):*** -- The input length is not divided by 193 -- The input out of memory bounds +- The input length is not divisible by 193. +- The input is beyond memory bounds. ***Annotation:*** From 2442ab90439347a8b8b0d23ff0506a90e5bf0d73 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 09:56:45 +0200 Subject: [PATCH 114/163] fix bls12381_g1_sum --- neps/nep-0488.md | 102 ++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 7cb023a70..1281b2343 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -478,65 +478,68 @@ The ERROR_CODE encoded as a little-endian u64 and can take the following values: ***Description:*** -The function computes the sum of the signed elements of the BLS12-381 curve. The input is an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ is point on elliptic curve and $s_i \in \textbraceleft 0, 1 \textbraceright$ is the point sign. The output is one point from $E(F_p)$ equal to $\sum (-1)^{s_i}p_i$. +The function calculates the sum of signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ represents a point on the elliptic curve, and $s_i \in {0, 1}$ signifies the point's sign. The output is a single point from $E(F_p)$ equivalent to $\sum (-1)^{s_i}p_i$. -The $E(F_p)$ curve, points on the curve, multiplication on -1, and the addition operation are defined in the BLS12-381 Curve Specification section. +The operations, including the $E(F_p)$ curve, points on the curve, multiplication by -1, and the addition operation, are detailed in the BLS12-381 Curve Specification section. -Note: we take as input any points on the curve, not only from $G_1$ +Note: The function accepts points from the entire curve, not restricted to $G_1$. -***Input:*** the sequence of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ is sign, each point encoded in decompress form as $(x\colon F_p, y\colon F_p)$ and sign encoded in one byte with only two allowed values: 0, 1. Expected `97*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the uncompressed point from $E(F_p)$ and a bool value for point sign. More details are in the Curve Points Encoding section. +***Input:*** -***Output:*** the ERROR_CODE is returned. +The sequence of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ represents a point and $s_i \in {0, 1}$ denotes the sign. Each point is encoded in decompressed form as $(x\colon F_p, y\colon F_p)$, and the sign is encoded in one byte, taking only two allowed values: 0 or 1. Expect 97*k bytes as input, which are interpreted as byte concatenation of k slices, with each slice representing the point sign and the uncompressed point from $E(F_p)$. Further details are available in the Curve Points Encoding section. + +***Output:*** + +The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: is 96 bytes — the one point $\in E(F_p)$ in decompressed form. For empty input it returns point on infinity (see Curve Points Encoding section). + - Output: 96 bytes represent one point $\in E(F_p)$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - - points or signs encoded incorrectly (see Curve points encoded section) - - points not on the curve + - Points or signs are incorrectly encoded (refer to Curve points encoded section). + - Point is not on the curve. ***Gas Estimation:*** -The algorithm has a linear complexity of the number of elements. The gas can be calculated by the next formula +The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: ```rust -let k = input_bytes / item_size +let k = input_bytes/item_size let gas_consumed = A + B * k ``` -A and B are constants calculated empirically. +Here, A and B represent empirically calculated constants. -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. +Here, you can find benchmark test vectors for EIP-2537[^46]. Although it doesn't include a sum function, we can adapt the test vector for addition by duplicating it multiple times. ***Test cases:*** Tests for the sum of two points -In this section, I would like to test that the sum of two correct elements on the curve works correctly. -We can use the following methods: +This section aims to verify the correctness of summing two valid elements on the curve: -- Take the points on the curve with known answer and compare results. For example, we can use tests for EIP-2537[^47],[^48] -- Generate the random points on the curve and check the P + Q = Q + P -- Generate the random points from G1 and check that sum also in G1 -- Use the implementation from another library, generate the random points on curve and compare results +- Utilize points on the curve with known addition results for comparison, such as tests from EIP-2537[^47],[^48]. +- Generate random points on the curve and verify the commutative property: P + Q = Q + P. +- Validate that the sum of random points from G1 remains in G1. +- Generate random points on the curve and use another library to cross-check the results. Edge cases: -- Points not from G1 -- 0 + 0 = 0 -- P + 0 = 0 + P = P -- P + (-P) = (-P) + P = 0 -- P + P (tangent to the curve) -- The sum of two points P and (-(P + P)). (tangent to the curve in point P) +- Points not from G1. +- 0 + 0 = 0. +- P + 0 = 0 + P = P. +- P + (-P) = (-P) + P = 0. +- P + P (tangent to the curve). +- The sum of two points P and (-(P + P)) (tangent to the curve at point P). Tests for inversion -In this section, I would like to check that point inverse works correctly. - -- Generate random points on the curve and check P - P = -P + P = 0 -- Generate random points on the curve and check -(-P) = P -- Generate random points from G1 and check -P also from G1 -- Use the implementation from another library, generate the random points on curve and compare results +This section aims to validate the correctness of point inversion: + +- Generate random points on the curve and verify P - P = -P + P = 0. +- Generate random points on the curve and verify -(-P) = P. +- Generate random points from G1 and ensure that -P also belong to G1. +- Utilize an external implementation, generate random points on the curve, and compare results. Edge cases: @@ -546,37 +549,36 @@ Edge cases: Tests for incorrect data -In this section, I would like to check that incorrect input data is handled properly - -- Incorrect len of input -- Incorrect sign value (not 0 or 1) -- The coding of field elements is incorrect, but if take only the suffix it will be the correct point on the curve -- The coding of field elements is incorrect, but by modulo p it is a correct element on the curve -- The coding of field elements is incorrect, an incorrect extra bit, which shows that it is decompressed encoding. -- Point not on the curve -- The point on infinity encoded incorrectly -- Input length exceeds memory limit +This section aims to validate the handling of incorrect input data: +- Incorrect input length. +- Incorrect sign value (not 0 or 1). +- Erroneous coding of field elements, resulting in a correct point on the curve if only the suffix is considered. +- Erroneous coding of field elements resulting in a correct element on the curve modulo p. +- Erroneous coding of field elements with an incorrect extra bit in the decompressed encoding. +- Point not on the curve. +- Incorrect encoding of the point on infinity. +- Input is beyond memory bounds. Tests for the sum of an arbitrary amount of points -In this section, we are checking that the sum of an arbitrary amount of points works properly +This section focuses on validating the summation functionality with an arbitrary number of points: -- Generate random points on the curve and check that sum of random permutation is the same -- Use the implementation from another library, generate the random points on curve and compare results -- Generate points and cross-test the result with multiexp function. -- Generate a random points from G1 and check that sum also from G1 +- Generate random points on the curve and verify that the sum of the random permutation matches. +- Generate random points on the curve and utilize another library to validate results. +- Create points and cross-check the outcome with the multiexp function. +- Generate random points from $G_1$ and confirm that the sum is also from $G_1$. -Edge cases: +- Edge cases: - Empty input - Sum with the maximum number of elements -- One point +- A single point ***Error cases (execution is terminated):*** -- The input length is not divided by 97 -- The input out of memory bounds +- The input length is not divisible by 97. +- The input is beyond memory bounds. ***Annotation:*** @@ -611,7 +613,7 @@ The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - - Points are incorrectly encoded (refer to Curve points encoded section). + - Points or signs are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. ***Gas Estimation:*** From bf3e8d82e9d9e382d951d40fe16d78fd07bbadc1 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 10:20:22 +0200 Subject: [PATCH 115/163] fix ERROR_CODE --- neps/nep-0488.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 1281b2343..4b13db6a4 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -457,20 +457,22 @@ The rule of encoding is consistent with zkcrypto[^53] and with implementation in #### ERROR_CODE -Verifying the correctness of the input for the host-functions inside the contract can be gas-consuming. -For example, checking that the point is an element of the subgroup. If the near host function returns an error, -the whole execution is reverted. To avoid it, if the input is difficult to verify, the host function will finish -the work successfully but will return the ERROR_CODE. This solution will provide the opportunity for the user -to handle error cases by himself. Note: the host functions can finish with an error if the error were easy to avoid -(for example, if the input size is incorrect). - -The ERROR_CODE encoded as a little-endian u64 and can take the following values: - -- 0 -- no error, execution was successful -- 1 -- execution finish with error: - - incorrect encoding (the bit compress/decompress format set incorrectly, coordinate >= p etc) - - a point not on the curve (where it is applicable) - - a point not in the expected subgroup (where it is applicable) +Validating the input for the host functions within the contract can consume significant gas. +For instance, verifying if a point belongs to the subgroup is gas-consuming. +If an error is returned by the near host function, the entire execution is reverted. +To mitigate this, when the input verification is complex, the host function +will successfully complete its work but return an ERROR_CODE. +This enables users to handle error cases independently. It's important to note that host functions +might terminate with an error if it's straightforward to avoid (e.g., incorrect input size). + +The ERROR_CODE is encoded as a little-endian u64 and can hold the following values: + +- 0: No error, execution was successful. +- 1: Execution finished with error due to: + - Incorrect encoding (e.g., incorrectly set compression/decompression bit, coordinate >= p, etc.). + - A point not on the curve (where applicable). + - A point not in the expected subgroup (where applicable). + ### Host functions From 31209ee28828e33571b28a6299307703a9beee1d Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 10:45:52 +0200 Subject: [PATCH 116/163] fix compressed points on twisted curve --- neps/nep-0488.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 4b13db6a4..afa70c4fc 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -426,18 +426,20 @@ The rule of encoding is consistent with zkcrypto[^53] and with implementation in #### Compressed points on twisted curve E'(Fp2) -The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ in compressed form are encoded in `[u8; 96]` as *big-endian* encoded $x \in F_{p^2}$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4(u + 1)}$. +The points on the curve are represented by affine coordinates: $(x: F_{p^2}, y: F_{p^2})$. +Elements from $E'(F_{p^2})$ in compressed form are encoded as [u8; 96], +with big-endian encoded $x \in F_{p^2}$. +The $y$ coordinate is determined using the formula: $y = \pm \sqrt{x^3 + 4(u + 1)}$. -*The highest bit* should be set as 1. This bit indicates that point is encoded in compressed form. - -*The second-highest bit* is used to mark a point on infinity, if the second-highest bit is set to 1 — it is an infinity point. -If the second-highest bit is set to 1, all others except first two bits should be set to 0. Other encoding should throw an error. - -To represent the sign of the $y$ *the third-highest bit* of x encoding is used. If the bit = 0 the $y$ is positive, if the bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y$: first compare $c_1$ and second $c_0$. +- The highest bit indicates if the point is encoded in compressed form and should be set to 1. +- The second-highest bit marks a point as infinity (if set to 1). + - For infinity points, all bits except the first two should be set to 0; other encodings should throw an error. +- To represent the sign of $y$, the third-highest bit in the x encoding is utilized. + - If the bit is 0, $y$ is positive; if 1, $y$ is negative. We'll consider the number positive by taking the smallest value between $y$ and $-y$: first compare $c_1$, then $c_0$. -The $x \in F_{p^2}$ encoded as `[u8; 96]` bytes according to the rules from section “Extension fields elements $F_{p^2}$” . +The encoding of $x \in F_{p^2}$ as [u8; 96] bytes follows the rules from the section “Extension Fields Elements $F_{p^2}$”. -The point on $E'(F_{p^2})$ with negative $y$ coordinate encoded as `[u8; 96]` bytes: +Encoding a point on $E'(F_{p^2})$ with a negative $y$ coordinate: ```rust let x: [u8; 96] = encodeFp2(x); @@ -445,7 +447,7 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x20; ``` -Encoding point of infinity: +Encoding the point of infinity: ```rust let x: [u8; 96] = [0; 96]; @@ -453,7 +455,7 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x40; ``` -The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. +This encoding rule aligns with zkcrypto[^53] and the implementation in the milagro lib[^29]. #### ERROR_CODE From 7ac1467996aba64e31946f28a06de4eb89211b9a Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 11:04:40 +0200 Subject: [PATCH 117/163] fix Uncompressed points on twisted curve --- neps/nep-0488.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index afa70c4fc..1b0b7cd2a 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -397,32 +397,26 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x40; ``` -The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. +This encoding rule aligns with zkcrypto[^53] and the implementation in the milagro lib[^29]. #### Uncompressed points on twisted curve E'(Fp2) -The points on the curve represent by affine coordinates: `(x: Fp2, y: Fp2)`. The elements from $E'(F_{p^2})$ encoded in `[u8; 192]` as bytes’ concatenation of `x` and `y` point coordinates, where $x, y \in F_{p^2}$. The $x, y$ are encoded according to the rules described in the section “Extension fields elements $F_{p^2}$” . - -$E'(F_{p^2})$ is encoded as `[u8; 192]`: - -- $x \in F_{p^2}$ `[u8; 96]`: - - $c_1 \in F_p$ `[u8; 48]` - - $c_0 \in F_p$ `[u8; 48]` -- $y \in F_{p^2}$ `[u8; 96]`: - - $c_1 \in F_p$ `[u8; 48]` - - $c_0 \in F_p$ `[u8; 48]` +The points on the curve are represented by affine coordinates: $(x: F_{p^2}, y: F_{p^2})$. +Elements from $E'(F_{p^2})$ are encoded in [u8; 192] as a concatenation of bytes representing x and y coordinates, where $x, y \in F_{p^2}$. +The encoding for $x$ and $y$ follows the rules detailed in the "Extension Fields Elements $F_{p^2}$" section. -*The second-highest bit* is used to mark a point on infinity, if the second-highest bit is set to 1 — it is an infinity point. -If the second-highest bit is set to 1, all others bits should be set to 0. Other encoding should throw an error. +*The second-highest bit* within the encoding serves to signify a point at infinity. +When this bit is set to 1, it designates an infinity point. +In this case, all other bits should be set to 0. -Encoding point on infinity: +Encoding the point of infinity: ```bash let x: [u8; 192] = [0; 192]; x[0] = x[0] | 0x40; ``` -The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. +This encoding rule aligns with zkcrypto[^53] and the implementation in the milagro lib[^29]. #### Compressed points on twisted curve E'(Fp2) @@ -433,7 +427,7 @@ The $y$ coordinate is determined using the formula: $y = \pm \sqrt{x^3 + 4(u + 1 - The highest bit indicates if the point is encoded in compressed form and should be set to 1. - The second-highest bit marks a point as infinity (if set to 1). - - For infinity points, all bits except the first two should be set to 0; other encodings should throw an error. + - For infinity points, all bits except the first two should be set to 0; other encodings should be considered as incorrect. - To represent the sign of $y$, the third-highest bit in the x encoding is utilized. - If the bit is 0, $y$ is positive; if 1, $y$ is negative. We'll consider the number positive by taking the smallest value between $y$ and $-y$: first compare $c_1$, then $c_0$. From 6278d0ae1a8bd29427eb0abc8994085a9ed37bbc Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 11:16:16 +0200 Subject: [PATCH 118/163] separate common part --- neps/nep-0488.md | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 1b0b7cd2a..0aea437fd 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -334,8 +334,6 @@ The scalar value is encoded as a little-endian `[u8;32]`. All possible bytes com 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], with implementation in milagro lib[^29]. - #### Extension fields elements Fp2 The $q \in F_{p^{2}}$ could be written as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$ The element from $F_{p^2}$ encoded in `[u8; 96]` as a bytes’ concatenation of $c_1$ and $c_0$. The $c_1$ and $c_0$ are encoded by the rule described in the previous section. @@ -345,8 +343,6 @@ $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] and with implementation in milagro lib[^29]. - #### Uncompressed points on curve E(Fp) The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ encoded in `[u8; 96]` as bytes’ concatenation of `x` and `y` point coordinates, where $x, y \in F_p$. The $x, y$ are encoded according to the rules described in the section “Fields elements $F_p$” . @@ -366,8 +362,6 @@ let x: [u8; 96] = [0; 96]; x[0] = x[0] | 0x40; ``` -The rule of encoding is consistent with zkcrypto[^53] and with implementation in milagro lib[^29]. - #### Compressed points on curve E(Fp) The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ in compressed form are encoded in `[u8; 48]` as *big-endian* encoded $x \in F_p$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. @@ -389,7 +383,7 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x20; ``` -For encoding point of infinity: +Encoding the point of infinity: ```rust let x: [u8; 48] = [0; 48]; @@ -397,8 +391,6 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x40; ``` -This encoding rule aligns with zkcrypto[^53] and the implementation in the milagro lib[^29]. - #### Uncompressed points on twisted curve E'(Fp2) The points on the curve are represented by affine coordinates: $(x: F_{p^2}, y: F_{p^2})$. @@ -416,8 +408,6 @@ let x: [u8; 192] = [0; 192]; x[0] = x[0] | 0x40; ``` -This encoding rule aligns with zkcrypto[^53] and the implementation in the milagro lib[^29]. - #### Compressed points on twisted curve E'(Fp2) The points on the curve are represented by affine coordinates: $(x: F_{p^2}, y: F_{p^2})$. @@ -449,8 +439,6 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x40; ``` -This encoding rule aligns with zkcrypto[^53] and the implementation in the milagro lib[^29]. - #### ERROR_CODE Validating the input for the host functions within the contract can consume significant gas. @@ -469,6 +457,9 @@ The ERROR_CODE is encoded as a little-endian u64 and can hold the following valu - A point not on the curve (where applicable). - A point not in the expected subgroup (where applicable). +#### General comments + +The encoding rules for curve points and field elements align with the standards established in zkcrypto[^53] and the implementation in the milagro lib[^29]. ### Host functions From 39393a152284ef0cb5a08accdf00cc74d2f5cbc1 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 11:30:32 +0200 Subject: [PATCH 119/163] compressed points on curve --- neps/nep-0488.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 0aea437fd..f06852fd8 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -364,18 +364,20 @@ x[0] = x[0] | 0x40; #### Compressed points on curve E(Fp) -The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ in compressed form are encoded in `[u8; 48]` as *big-endian* encoded $x \in F_p$. The $y$ coordinate can be detected by the formula: $y = \pm \sqrt{x^3 + 4}$. +The points on the curve are represented by affine coordinates: $(x: F_p, y: F_p)$. +Elements from $E(F_p)$ in compressed form are encoded as `[u8; 48]`, +with big-endian encoded $x \in F_p$. +The $y$ coordinate is determined by the formula: $y = \pm \sqrt{x^3 + 4}$. -*The highest bit* should be set as 1. This bit indicates that point is encoded in compressed form. - -*The second-highest bit* is used to mark a point on infinity, if the second-highest bit is set to 1 — it is an infinity point. -If the second-highest bit is set to 1, all others except first two bits should be set to 0. Other encoding should throw an error. - -To represent the sign of the $y$ *the third-highest bit* of x encoding is used. If the first bit = 0 the $y$ is positive, if the first bit = 1 the $y$ is negative. We will consider the number positive the smallest between $y$ and $-y = p - y$. +- The highest bit indicates if the point is encoded in compressed form and should be set to 1. +- The second-highest bit marks a point as infinity (if set to 1). + - For infinity points, all bits except the first two should be set to 0; other encodings should be considered as incorrect. +- To represent the sign of $y$, the third-highest bit in the x encoding is utilized. + - If the bit is 0, $y$ is positive; if 1, $y$ is negative. We'll consider the number positive by taking the smallest value between $y$ and $-y$. -The $x \in F_p$ encoded as `[u8; 48]` bytes according to the rules from section “Extension fields elements $F_{p}$” . +The encoding for $x \in F_p$ as `[u8; 48]` bytes follows the rules described in the section "Extension fields elements $F_{p}$". -The point on $E(F_p)$ with negative $y$ coordinate encoded as `[u8; 48]` bytes: +Encoding a point on $E(F_p)$ with a negative $y$ coordinate: ```rust let x: [u8; 48] = encodeFp(x) From a287996fd6a3bddc5ca3c7cc47266281cce081c8 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 12:15:12 +0200 Subject: [PATCH 120/163] fix uncompressed points on curve --- neps/nep-0488.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index f06852fd8..d018107b1 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -345,15 +345,18 @@ $q \in F_{p^2}$, $q = c_0 + c_1 v$ encoded as `[u8; 96]`: #### Uncompressed points on curve E(Fp) -The points on the curve represent by affine coordinates: `(x: Fp, y: Fp)`. The elements from $E(F_p)$ encoded in `[u8; 96]` as bytes’ concatenation of `x` and `y` point coordinates, where $x, y \in F_p$. The $x, y$ are encoded according to the rules described in the section “Fields elements $F_p$” . +Points on the curve are represented by affine coordinates: $(x: F_p, y: F_p)$. +The elements from $E(F_p)$ are encoded in `[u8; 96]` as a byte concatenation of x and y point coordinates, where $x, y \in F_p$. +The encoding follows the rules outlined in the section “Fields elements $F_p$”. -$E(F_p)$ is encoded as `[u8; 96]`: +$E(F_p)$ is encoded as [u8; 96]: -- $x \in F_p$ `[u8; 48]` -- $y \in F_p$ `[u8; 48]` +- $x \in F_p$ is represented as [u8; 48] +- $y \in F_p$ is represented as [u8; 48] -*The second-highest bit* is used to mark a point on infinity, if the second-highest bit is set to 1 — it is an infinity point. -If the second-highest bit is set to 1, all others bits should be set to 0. Other encoding should throw an error. +*The second-highest bit* within the encoding serves to signify a point at infinity. +When this bit is set to 1, it designates an infinity point. +In this case, all other bits should be set to 0. Encoding point on infinity: From 4cff9591e1ca0c17a2e9d99b02a476be7623262c Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 12:31:19 +0200 Subject: [PATCH 121/163] fix extension Fp2 --- neps/nep-0488.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index d018107b1..2b0aad39c 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -336,12 +336,12 @@ The value from $F_p$ is encoded as a big-endian `[u8; 48]`. Only values less tha #### Extension fields elements Fp2 -The $q \in F_{p^{2}}$ could be written as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$ The element from $F_{p^2}$ encoded in `[u8; 96]` as a bytes’ concatenation of $c_1$ and $c_0$. The $c_1$ and $c_0$ are encoded by the rule described in the previous section. +An element $q \in F_{p^{2}}$ can be expressed as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$. The element from $F_{p^2}$ is encoded in [u8; 96] as a byte concatenation of $c_1$ and $c_0$. The encoding for $c_1$ and $c_0$ follows the rule described in the previous section. -$q \in F_{p^2}$, $q = c_0 + c_1 v$ encoded as `[u8; 96]`: +The representation of $q \in F_{p^2}$, with $q = c_0 + c_1 v$, is encoded as [u8; 96]: -- $c_1 \in F_p$ `[u8; 48]` -- $c_0 \in F_p$ `[u8; 48]` +- $c_1 \in F_p$ is represented as `[u8; 48]` +- $c_0 \in F_p$ is represented as `[u8; 48]` #### Uncompressed points on curve E(Fp) From 455bc5c24d5860db122ca280db2035758791fd51 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 12:35:31 +0200 Subject: [PATCH 122/163] fix Fp encdoing --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 2b0aad39c..f27fb8318 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -332,7 +332,7 @@ The scalar value is encoded as a little-endian `[u8;32]`. All possible bytes com #### Fields elements Fp -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. +Values from $F_p$ are encoded as big-endian [u8; 48]. Only values less than p are permitted. If the value is equal to or greater than p, an error should be returned. #### Extension fields elements Fp2 From b7843b16c28340def54131e4241004a3fd6abc32 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 12:42:05 +0200 Subject: [PATCH 123/163] fix scalar description --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index f27fb8318..e3bc3eb08 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -328,7 +328,7 @@ The sign of the point on the elliptic curve is encoded as `u8` type in Rust with #### Scalar -The scalar value is encoded as a little-endian `[u8;32]`. All possible bytes combination is allowed. +The scalar value is encoded as a little-endian [u8; 32]. All possible byte combinations are allowed. #### Fields elements Fp From 2a9b9489802311a5df7cbb0e103bc1bea9e8b714 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 12:46:16 +0200 Subject: [PATCH 124/163] fix sign --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index e3bc3eb08..b030590aa 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -324,7 +324,7 @@ sections 8.8.1[^64] and 8.8.2[^65] respectively. #### Sign -The sign of the point on the elliptic curve is encoded as `u8` type in Rust with two possible values: `0` and `1`. `0` for positive sign, and `1` for negative sign. All other value of `u8` is not allowed and should be interpreted as incorrect. +The sign of a point on the elliptic curve is represented as a u8 type in Rust, with two possible values: 0 for a positive sign and 1 for a negative sign. Any other u8 value is considered invalid and should be treated as incorrect. #### Scalar From f019ad7228c12260cd1b80c8e93cd5e44f7c5f27 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 12:59:28 +0200 Subject: [PATCH 125/163] map to curve specification --- neps/nep-0488.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b030590aa..f8d3765a0 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -301,11 +301,13 @@ All parameters were taken from[^15],[^51] and [^14], all of them consistent betw ### Map to curve specification -This section explains the functionality of the `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` functions. -They operate based on the specification RFC9380 "Hashing to Elliptic Curves"[^62]. +This section delineates the functionality of the `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` functions, +operating in accordance with the RFC9380 specification "Hashing to Elliptic Curves"[^62]. -These functions map the field element in $F_p$ or $F_{p^2}$ to the corresponding subgroup $G_1 \subset E(F_p)$ or $G_2 \subset E'(F_{p^2})$. -`bls12381_map_fp_to_g1`/`bls12381_map_fp2_to_g2` combine functions `map_to_curve` and `clear_cofactor` from RFC9380[^63]. +These functions map the field elements in $F_p$ or $F_{p^2}$ +to their corresponding subgroups: $G_1 \subset E(F_p)$ or $G_2 \subset E'(F_{p^2})$. +`bls12381_map_fp_to_g1`/`bls12381_map_fp2_to_g2` combine the functionalities +of map_to_curve and clear_cofactor from RFC9380[^63]. ```text fn bls12381_map_fp_to_g1(u): @@ -313,12 +315,11 @@ fn bls12381_map_fp_to_g1(u): return clear_cofactor(Q); ``` -We won't be implementing `hash_to_field` function as a host function because hashing can be performed through -various methods, and this part is most likely subject to change. Additionally, executing this function within -the contract consumes approximately 2 TGas, which is acceptable for our goals. +We choose not to implement the hash_to_field function as a host function due to potential changes in hashing methods. +Additionally, executing this function within the contract consumes approximately 2 TGas, which is acceptable for our goals. -Specific parameters for implementing `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` you can find in RFC9380 in -sections 8.8.1[^64] and 8.8.2[^65] respectively. +Specific implementation parameters for bls12381_map_fp_to_g1 and bls12381_map_fp2_to_g2 can be found in RFC9380 +under sections 8.8.1[^64] and 8.8.2[^65], respectively. ### Curve points encoding From c2cad64841078e2da4fb7fa827fd47e94f18cbd8 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 13:06:15 +0200 Subject: [PATCH 126/163] fix summary for BLS specification --- neps/nep-0488.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index f8d3765a0..af50d65cf 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -249,9 +249,9 @@ You can find this parameter in: #### Summary -The parameters for the BLS12-381: +The parameters for the BLS12-381 curve are as follows: -Base field modulus $p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab$ +Base field modulus: $p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab$ $$ E\colon y^2 \equiv x^3 + 4 @@ -261,7 +261,7 @@ $$ E'\colon y^2 \equiv x^3 + 4(u + 1) $$ -Main subgroup order $r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001$ +Main subgroup order: $r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001$ $$ F_{p^2} = F_p[u] / (u^2 + 1) @@ -297,7 +297,7 @@ $$h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb Key BLS12-381 parameter used in Miller Loop: $$x = -0xd201000000010000$$ -All parameters were taken from[^15],[^51] and [^14], all of them consistent between sources. +All parameters were sourced from [^15], [^51], and [^14], and they remain consistent across these sources. ### Map to curve specification From 7379f18a20bce17b3ee0fef08ffc8ba6ca26a2b0 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 13:15:08 +0200 Subject: [PATCH 127/163] Pairing section fix --- neps/nep-0488.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index af50d65cf..01390468d 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -229,18 +229,20 @@ $$h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb #### Pairing -Pairing is an operation, which we will need for digital signature verification. Pairing operation $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{p^{12}}$. +Pairing is an operation necessary for digital signatures and zkSNARKs verification. It performs the operation $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{p^{12}}$. -The main pairing properties is: +The main properties of the pairing operation are: - $e(P, Q + R) = e(P, Q) \cdot e(P, R)$ - $e(P + S, R) = e(P, R)\cdot e(S, R)$ -For calculating this function we will need the algorithm, called Miller Loop, and to effectively perform this algorithm we will need to know the key parameter for BLS curve $x$ +To compute this function, we utilize an algorithm called Miller Loop. +For effective implementation of this algorithm, +we require a key parameter for the BLS curve, denoted as $x$: $$ x = -0xd201000000010000$$ -You can find this parameter in: +This parameter can be found in the following sources: - [^15] section specification, pairing parameters, miller loop scalar - [^51] section 4.2.1 Parameter t From b0a0f935f893ed5fd4d22ac28134048da149b750 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 13:21:47 +0200 Subject: [PATCH 128/163] Generator section fix --- neps/nep-0488.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 01390468d..3ba1a6f03 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -191,7 +191,7 @@ In most cases we will work with points from $G_2' \subset E'(F_{p^2})$ and use f #### Generators -If in the group $G$ exists element g, such as $\textbraceleft g, 2g, 3g, \ldots, |G|g \textbraceright = G$, the group G called ***cyclic group*** and g called ***generator*** +If there exists an element g in the group G such that $\textbraceleft g, 2g, 3g, \ldots, |G|g \textbraceright = G$, the group G is called a ***cyclic group*** and g is termed a ***generator*** $G_1$ and $G_2$ are cyclic subgroups with the following generators[^15],[^51]: @@ -213,7 +213,7 @@ $G_2$: - $y_1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be$ -**Cofactor** is the ratio of the size of the whole group G to the size of subgroup H: +**Cofactor** is the ratio of the size of the entire group G to the size of the subgroup H: $$ |G|/|H| From 35df676fad922f012d2d57e1bef7b99066d71e7a Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 13:38:42 +0200 Subject: [PATCH 129/163] fix twist section --- neps/nep-0488.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 3ba1a6f03..bb76edf39 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -172,22 +172,25 @@ Our second subgroup of order r, which we will use, is a subgroup of the same Ell #### Twist -Store elements from $E(F_{p^{12}})$ takes a lot of memory. ***The twist*** operation transforms the origin curve $E(F_{p^{12}})$ into another curve under another space $E'(F_{p^2})$. It is important that the new curve also has a $G'_2$ subgroup with order r and we can easily transform it to origin $G_2$. +Storing elements from $E(F_{p^{12}})$ consumes a significant amount of memory. +The twist operation transforms the original curve $E(F_{p^{12}})$ into another curve within a different space, +denoted as $E'(F_{p^2})$. It is crucial that this new curve also includes a $G'_2$ subgroup with order 'r' +so that we can easily transform it back to the original $G_2$. We want to have $\psi \colon E'(F_{p^2}) \rightarrow E(F_{p^{12}})$, such as - $\forall a, b \in E'(F_{p^2}) \colon \psi(a + b) = \psi(a) + \psi(b)$ - $\forall a, b \in E'(F_{p^2}) \colon \psi(a) = \psi(b) \Rightarrow a = b$ -It is called injective group homomorphism. +This is referred to as an injective group homomorphism. -For BLS12-381 E’ is defined as[^51]: +For BLS12-381, E’ is defined as[^51]: $$ E'\colon y^2 = x^3 + 4(u + 1) $$ -In most cases we will work with points from $G_2' \subset E'(F_{p^2})$ and use for this subgroup just the notation $G_2$. +In most cases, we will be working with points from $G_2' \subset E'(F_{p^2})$ and will simply use the notation $G_2$ for this subgroup. #### Generators From 534cd49d1b46718b7aed257b9b08a8502671212f Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 13:55:21 +0200 Subject: [PATCH 130/163] fix field extension section --- neps/nep-0488.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index bb76edf39..fbdfdbded 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -132,13 +132,13 @@ For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$[^15],[^51]: #### Field extension -**The field extension $F_{p^k}$** is a set of all polynomials with degree < k and coefficients from $F_p$ and defined operations $\cdot$ , $+$ +**The field extension $F_{p^k}$** is a set comprising all polynomials with a degree < k and coefficients from $F_p$, along with defined operations of multiplication ($\cdot$) and addition ($+$). $$ a_{k - 1}x^{k - 1} + \ldots + a_1x + a_0 = A(x) \in F_{p^k} \vert a_i \in F_p $$ -The $+$ operation is defined as a regular addition for polynomials: +The addition operation ($+$) is defined as regular polynomial addition: $$ A(x) + B(x) = C(x) @@ -152,7 +152,9 @@ $$ c_i = (a_i + b_i) \mod p $$ -The multiplication $\cdot$ is defined as a regular polynomials’ multiplication by modulo M(x), where M(x) is an ***irreducible*** polynomial of degree k with coefficients from $F_p$ + +The multiplication $\cdot$ is defined as regular polynomial multiplication modulo $M(x)$, +where $M(x)$ is an irreducible polynomial of degree $k$ with coefficients from $F_p$. $$ C(x) = A(x) \cdot B(x)\mod M(x) @@ -160,15 +162,23 @@ $$ 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}$. +In BLS12-381, we will require $F_{p^{12}}$. +We'll construct this field not directly as an extension from $F_p$, +but rather through a stepwise process. First, we'll build $F_{p^2}$ +as a quadratic extension of the field $F_p$. +Second, we'll establish $F_{p^6}$ as a cubic extension of $F_{p^2}$. +Finally, we'll create $F_{p^{12}}$, a quadratic extension of the +field $F_{p^6}$. -For defining these fields, we will need to set up three $M(x)$ irreducible polynomials[^51]: +To define these fields, we'll need to set up three irreducible polynomials[^51]: - $F_{p^2} = F_p[u] / (u^2 + 1)$ - $F_{p^6} = F_{p^2}[v] / (v^3 - u - 1)$ - $F_{p^{12}} = F_{p^6}[w]/(w^2 - v)$ -Our second subgroup of order r, which we will use, is a subgroup of the same Elliptic Curve but with elements from $F_{p^{12}}$. $G_2 \subset E(F_{p^{12}})$, where $E: y^2 = x^3 + 4$ +The second subgroup we'll utilize has an order of r and +resides within the same elliptic curve but with elements from $F_{p^{12}}$. +Specifically, $G_2 \subset E(F_{p^{12}})$, where $E: y^2 = x^3 + 4$ #### Twist From 56325a4e860ad25d51a63dab6d40f1190181a342 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 14:08:02 +0200 Subject: [PATCH 131/163] fix subgroup section --- neps/nep-0488.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index fbdfdbded..e039f5384 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -122,11 +122,17 @@ Notation: $H \subseteq G$ Group/subgroup **order** is the number of elements in group/subgroup. -Notation: |G| or #G, where G is group +Notation: |G| or #G, where G represents the group. -For some technical reason (for `pairing` operation which we will define later), we will work not with the whole $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 some technical reason (for `pairing` operation which we will define later), +we will operate not with the entire $E(F_p)$, +but only with the two subgroups $G_1$ and $G_2$ +having the same **order** $r$. +$G_1$ is a subset of $E(F_p)$, +while $G_2$ is a subgroup of another group that we will define later. +The value of $r$ should be a prime number, and $G1 \ne G2$ -For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$[^15],[^51]: +For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$[^15],[^51] is given by: - $r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001$ From cdc7484dbec2f81d9fa042f6e6d6954409dcc3ed Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 14:17:16 +0200 Subject: [PATCH 132/163] fix Elliptic Curve section --- neps/nep-0488.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index e039f5384..e544d7ca6 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -75,7 +75,11 @@ This design approach aims to ensure future ease in supporting corresponding prec #### Elliptic Curve -**The field $F_p$** for some *prime* $p$ is a set of integer elements $\textbraceleft 0, 1, \ldots, p - 1 \textbraceright$ with two operations: multiplication $\cdot$ and addition $+$. These operations are performed as multiplication/addition for integers number and then taking the remainder modulo $p$. +**The field $F_p$** for some *prime* $p$ is a set of integer +elements $\textbraceleft 0, 1, \ldots, p - 1 \textbraceright$ with two +operations: multiplication $\cdot$ and addition $+$. +These operations involve standard integer multiplication and addition, +followed by taking the remainder modulo $p$. **The elliptic curve $E(F_p)$** is a set of all pairs $(x, y) \in F_p$: From 766759619f76748f066503d7505cc955aa1c14f8 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 29 Nov 2023 14:42:20 +0200 Subject: [PATCH 133/163] fix Motivation section --- neps/nep-0488.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index e544d7ca6..d8a6fea82 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -37,15 +37,15 @@ we must efficiently verify BLS signatures based on BLS12-381, as these are the s In this NEP, we propose to add the following host functions: -- ***bls12381_g1_sum —*** sum the signed points from $G_1$ on an elliptic curve. This function is useful for the aggregation of public keys in BLS Signature. It can be used for simple addition in $G_1$. Separate from the multiexp function due to the gas cost. -- ***bls12381_g2_sum —*** sum the signed points from $G_2$ on an elliptic curve. This function is useful for the aggregation of signatures in BLS Signature. It can be used for simple addition in $G_2$. Separate from the multiexp function due to the gas cost. -- ***bls12381_g1_multiexp —*** for points $g_i \in G_1$ and scalars $s_i$ calculate $\sum g_i s_i$. It can be used to multiply a group element by a scalar. -- ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. It can be used to multiply a group element by a scalar. -- ***bls12381_map_fp_to_g1 —*** maps base field element into the $G_1$ point. It does not perform mapping of the byte string into field elements. -- ***bls12381_map_fp2_to_g2 —*** maps extension field element into the $G_2$ point. It does not perform mapping of the byte string into extension field elements. We require this function to efficiently map a message into a group element. We don't implement hash_to_field[^60] function, because it can be done inside a contract and different hashing algorithms can be used. -- ***bls12381_decompress_g1 —*** decompresses the points from $G_1$ provided in the compressed form. Some protocols provide points on the curve in the compressed form (e.g., the light client updates in Ethereum 2.0), and decompressing is a time-consuming operation. All the other functions in this NEP accept only decompressed points to be simple and to have optimized gas consumption. +- ***bls12381_g1_sum —*** sum the signed points from $G_1$ on an elliptic curve. This function is useful for aggregating public keys in BLS Signature. It can be employed for simple addition in $G_1$. It is kept separate from the multiexp function due to gas cost considerations. +- ***bls12381_g2_sum —*** sum the signed points from $G_2$ on an elliptic curve. This function is useful for aggregating signatures in BLS Signature. +- ***bls12381_g1_multiexp —*** for points $g_i \in G_1$ and scalars $s_i$ calculate $\sum g_i s_i$. This operation can be utilized to multiply a group element by a scalar. +- ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. +- ***bls12381_map_fp_to_g1 —*** maps a base field element into the $G_1$ point. It does not perform the mapping of the byte string into field elements. +- ***bls12381_map_fp2_to_g2 —*** maps an extension field element into the $G_2$ point. It does not perform the mapping of the byte string into extension field elements. We need this function to efficiently map a message into a group element. We are not implementing the hash_to_field[^60] function because it can be executed within a contract and various hashing algorithms can be applied. +- ***bls12381_decompress_g1 —*** decompresses the points from $G_1$ provided in the compressed form. Certain protocols offer points on the curve in compressed form (e.g., the light client updates in Ethereum 2.0), and decompression is a time-consuming operation. All the other functions in this NEP only accept decompressed points for simplicity and optimized gas consumption. - ***bls12381_decompress_g2 —*** decompresses the points from $G_2$ provided in the compressed form. -- ***bls12381_pairing_check —*** 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$. Used to verify BLS signatures or zkSNARKs. +- ***bls12381_pairing_check —*** 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$. This function is used to verify BLS signatures or zkSNARKs. Functions required for verifying BLS signatures[^59]: @@ -66,8 +66,9 @@ Both zkSNARKs and BLS signatures can be implemented alternatively by swapping G1 Therefore, all functions have been implemented for both G1 and G2. An analogous proposal, EIP-2537[^15], exists in Ethereum. -The functions here have been designed considering compatibility with Ethereum's proposal. -This design approach aims to ensure future ease in supporting corresponding precompiles for Aurora[^24]. +The functions here have been designed with compatibility +with Ethereum's proposal in mind. This design approach aims +to ensure future ease in supporting corresponding precompiles for Aurora[^24]. ## Specification From e5b42f6115b8387b7ac806b73c47e47c786cc679 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 30 Nov 2023 12:47:54 +0200 Subject: [PATCH 134/163] map functions take as input arbitary number of elements --- neps/nep-0488.md | 72 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index d8a6fea82..5a625277a 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -41,8 +41,8 @@ In this NEP, we propose to add the following host functions: - ***bls12381_g2_sum —*** sum the signed points from $G_2$ on an elliptic curve. This function is useful for aggregating signatures in BLS Signature. - ***bls12381_g1_multiexp —*** for points $g_i \in G_1$ and scalars $s_i$ calculate $\sum g_i s_i$. This operation can be utilized to multiply a group element by a scalar. - ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. -- ***bls12381_map_fp_to_g1 —*** maps a base field element into the $G_1$ point. It does not perform the mapping of the byte string into field elements. -- ***bls12381_map_fp2_to_g2 —*** maps an extension field element into the $G_2$ point. It does not perform the mapping of the byte string into extension field elements. We need this function to efficiently map a message into a group element. We are not implementing the hash_to_field[^60] function because it can be executed within a contract and various hashing algorithms can be applied. +- ***bls12381_map_fp_to_g1 —*** maps a base field elements into the $G_1$ points. It does not perform the mapping of the byte string into field elements. +- ***bls12381_map_fp2_to_g2 —*** maps an extension field elements into the $G_2$ points. It does not perform the mapping of the byte string into extension field elements. We need this function to efficiently map a message into a group element. We are not implementing the hash_to_field[^60] function because it can be executed within a contract and various hashing algorithms can be applied. - ***bls12381_decompress_g1 —*** decompresses the points from $G_1$ provided in the compressed form. Certain protocols offer points on the curve in compressed form (e.g., the light client updates in Ethereum 2.0), and decompression is a time-consuming operation. All the other functions in this NEP only accept decompressed points for simplicity and optimized gas consumption. - ***bls12381_decompress_g2 —*** decompresses the points from $G_2$ provided in the compressed form. - ***bls12381_pairing_check —*** 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$. This function is used to verify BLS signatures or zkSNARKs. @@ -567,7 +567,6 @@ Edge cases: - Point not from G1 - -0 - Tests for incorrect data This section aims to validate the handling of incorrect input data: @@ -843,23 +842,33 @@ pub fn bls12381_g2_multiexp( ***Description:*** -The function takes the element $a \in F_p$ and maps it to $G_1 \subset E(F_p)$. You can find the specification of this mapping function in the section titled 'Map to curve specification.' Importantly, this function does NOT perform the mapping of the byte string into $F_p$. The implementation of this function may vary and can be effectively executed within the contract. +The function takes the list of field elements $a_i \in F_p$ and maps them to $G_1 \subset E(F_p)$. +You can find the specification of this mapping function in the section titled 'Map to curve specification.' +Importantly, this function does NOT perform the mapping of the byte string into $F_p$. +The implementation of this function may vary and can be effectively executed within the contract. ***Input:*** -The function expects 48 bytes as input, representing an element from $F_p$ (a single unsigned integer $< p$). Additional information is available in the Curve Points Encoding section. +The function expects `48*k` bytes as input, representing a list of element from $F_p$ (unsigned integer $< p$). Additional information is available in the Curve Points Encoding section. ***Output:*** The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: `96` bytes - represents a single point $\in G_1 \subset E(F_p)$ in decompressed format. Further information is available in the Curve Points Encoding section. -- ERROR_CODE = 1: $a \ge p$. + - Output: `96*k` bytes - represents a list of points $\in G_1 \subset E(F_p)$ in decompressed format. Further information is available in the Curve Points Encoding section. +- ERROR_CODE = 1: $a_i \ge p$. ***Gas Estimation:*** -The gas consumption is a constant calculated empirically. +The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: + +```rust +let k = input_bytes/item_size +let gas_consumed = A + B * k +``` + +Here, A and B represent empirically calculated constants. ***Test cases:*** @@ -876,18 +885,23 @@ Edge cases: - $a = 0$ - $a = p - 1$ +Tests for an arbitrary number of elements + +- Empty input +- Maximum number of points. +- Generate a random number of field elements and compare the result with another library. + Tests for error cases -- Input length not equal to 48 bytes: - - Empty input - - 96 bytes - - Input is beyond memory bounds. +- Input length is not divisible by 48: +- Input is beyond memory bounds. - $a = p$ - Random number $\ge p$ ***Error cases (execution is terminated):*** -- Incorrect input length +- The input length is not divisible by 48. +- The input is beyond memory bounds. ***Annotation:*** @@ -904,21 +918,28 @@ pub fn bls12381_map_fp_to_g1( ***Description:*** -The function takes the element $a \in F_{p^2}$ and maps it to $G_2 \subset E'(F_{p^2})$. You can find the mapping function's specifications in the "Map to Curve Specification" section. It's important to note that this function does NOT map the byte string into $F_{p^2}$. The implementation of this function may vary and can be effectively executed within the contract. +The function takes the list of elements $a_i \in F_{p^2}$ and maps them to $G_2 \subset E'(F_{p^2})$. You can find the mapping function's specifications in the "Map to Curve Specification" section. It's important to note that this function does NOT map the byte string into $F_{p^2}$. The implementation of this function may vary and can be effectively executed within the contract. -***Input:*** the function takes as input `96 bytes` — the element from $F_{p^2}$ (two unsigned integers $< p$). Additional details can be found in the Curve Points Encoding section. +***Input:*** the function takes as input `96*k` bytes — the elements from $F_{p^2}$ (two unsigned integers $< p$). Additional details can be found in the Curve Points Encoding section. ***Output:*** The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: `192` bytes - represents a single point $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. -- ERROR_CODE = 1: the value is not a valid extension field $F_{p^2}$ element + - Output: `192*k` bytes - represents a list of points $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. +- ERROR_CODE = 1: one of the values is not a valid extension field $F_{p^2}$ element ***Gas Estimation:*** -The gas consumption is a constant calculated empirically. +The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: + +```rust +let k = input_bytes/item_size +let gas_consumed = A + B * k +``` + +Here, A and B represent empirically calculated constants. ***Test cases:*** @@ -935,12 +956,16 @@ Edge cases: - $a = (0, 0)$ - $a = (p - 1, p - 1)$ +Tests for an arbitrary number of elements + +- Empty input +- Maximum number of points. +- Generate a random number of field elements and compare the result with another library. + Tests for error cases -- Input length not equal to 96 bytes:: - - Empty input - - 192 bytes - - Input is beyond memory bounds. +- Input length is not divisible by 96. +- Input is beyond memory bounds. - $a = (0, p)$ - $a = (p, 0)$ - (random number $\ge p$, 0) @@ -948,7 +973,8 @@ Edge cases: ***Error cases (execution is terminated):*** -- Incorrect input length +- The input length is not divisible by 96. +- The input is beyond memory bounds. ***Annotation:*** From 9aa61233b1dcb3a591c4299e66b42afdcf1cbf0c Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 30 Nov 2023 14:08:14 +0200 Subject: [PATCH 135/163] separate gas estimation section --- neps/nep-0488.md | 124 ++++++----------------------------------------- 1 file changed, 15 insertions(+), 109 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 5a625277a..a14bac787 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -519,19 +519,6 @@ The ERROR_CODE is returned. - Points or signs are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. -***Gas Estimation:*** - -The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: - -```rust -let k = input_bytes/item_size -let gas_consumed = A + B * k -``` - -Here, A and B represent empirically calculated constants. - -Here, you can find benchmark test vectors for EIP-2537[^46]. Although it doesn't include a sum function, we can adapt the test vector for addition by duplicating it multiple times. - ***Test cases:*** Tests for the sum of two points @@ -636,19 +623,6 @@ The ERROR_CODE is returned. - Points or signs are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. -***Gas Estimation:*** - -The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: - -```rust -let k = input_bytes/item_size -let gas_consumed = A + B * k -``` - -Here, A and B represent empirically calculated constants. - -Here, you can find benchmark test vectors for EIP-2537[^46]. Although it doesn't include a sum function, we can adapt the test vector for addition by duplicating it multiple times. - ***Test cases:*** The test cases are identical to those of `bls12381_g1_sum`, with the only alteration being the substitution of points from $G_1$ and $E(F_p)$ with points from $G_2$ and $E'(F_{p^2})$. @@ -685,6 +659,7 @@ Please note: - The function accepts any points on the curve, not solely from $G_1$. - The scalar is an arbitrary unsigned integer and can exceed the group order. +- To enhance gas efficiency, the Pippenger’s algorithm[^25] can be utilized. ***Input:*** The sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ is a scalar. The expected input size is 128*k bytes, interpreted as byte concatenation of k slices. Each slice comprises the concatenation of an uncompressed point from $E(F_p)$— 96 bytes, along with a scalar— 32 bytes. Further details are available in the Curve Points Encoding section. @@ -698,19 +673,6 @@ The ERROR_CODE is returned. - Points are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. -***Gas Estimation:*** - -For simplicity, we will use the linear formula for gas calculation: - -```rust -let k = input_bytes / item_size -let gas_consumed = A + B * k -``` - -Here, A and B represent empirically calculated constants. - -Pippenger’s algorithm[^25] can be employed to enhance gas efficiency. For gas estimation, the benchmark vectors for addition and multiplication in EIP-2537[^46] can be utilized. - ***Test cases:*** Tests for multiplication @@ -790,6 +752,7 @@ Please note: - The function accepts any points on the curve, not solely from $G_2$. - The scalar is an arbitrary unsigned integer and can exceed the group order. +- To enhance gas efficiency, the Pippenger’s algorithm[^25] can be utilized. ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. @@ -805,19 +768,6 @@ The ERROR_CODE is returned. - Points are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. -***Gas Estimation:*** - -For simplicity, we will use the linear formula for gas calculation: - -```rust -let k = input_bytes / item_size -let gas_consumed = A + B * k -``` - -Here, A and B represent empirically calculated constants. - -Pippenger’s algorithm[^25] can be employed to enhance gas efficiency. For gas estimation, the benchmark vectors for addition and multiplication in EIP-2537[^46] can be utilized. - ***Test cases:*** The test cases are identical to those for `bls12381_g1_multiexp`, except that the points from $G_1$ and $E(F_p)$ are replaced with points from $G_2$ and $E'(F_{p^2})$ @@ -859,17 +809,6 @@ The ERROR_CODE is returned. - Output: `96*k` bytes - represents a list of points $\in G_1 \subset E(F_p)$ in decompressed format. Further information is available in the Curve Points Encoding section. - ERROR_CODE = 1: $a_i \ge p$. -***Gas Estimation:*** - -The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: - -```rust -let k = input_bytes/item_size -let gas_consumed = A + B * k -``` - -Here, A and B represent empirically calculated constants. - ***Test cases:*** Tests for general cases @@ -930,17 +869,6 @@ The ERROR_CODE is returned. - Output: `192*k` bytes - represents a list of points $\in G_2 \subset E'(F_{p^2})$ in decompressed format. More details are in the Curve Points Encoding section. - ERROR_CODE = 1: one of the values is not a valid extension field $F_{p^2}$ element -***Gas Estimation:*** - -The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: - -```rust -let k = input_bytes/item_size -let gas_consumed = A + B * k -``` - -Here, A and B represent empirically calculated constants. - ***Test cases:*** Tests for general cases @@ -1025,19 +953,6 @@ The ERROR_CODE is returned. For an empty input, the function returns ERROR_CODE = 0. -***Gas Estimation:*** - -The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: - -```rust -let k = input_bytes/item_size -let gas_consumed = A + B * k -``` - -Here, A and B represent empirically calculated constants. - -Here you can find benchmark test vectors for EIP-2537[^46]. - ***Test cases:*** Tests for one pair @@ -1112,17 +1027,6 @@ The ERROR_CODE is returned. - Points are incorrectly encoded (refer to the Curve points encoded section). - Point is not on the curve. -***Gas Estimation:*** - -The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: - -```rust -let k = input_bytes/item_size -let gas_consumed = A + B * k -``` - -Here, A and B represent empirically calculated constants. - ***Test cases:*** Tests for decompressing a single point @@ -1180,17 +1084,6 @@ The ERROR_CODE is returned. - Points are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. -***Gas Estimation:*** - -The algorithm has linear complexity concerning the number of elements. The gas estimation can be calculated using the following formula: - -```rust -let k = input_bytes/item_size -let gas_consumed = A + B * k -``` - -Here, A and B represent empirically calculated constants. - ***Test cases:*** The same test cases as `bls12381_decompress_g1`, but with points from $G_2$, and the input length should be divisible by 96. @@ -1223,6 +1116,19 @@ the register with the `register_id` identifier. Otherwise, nothing will be written to the register. +***Gas Estimation:*** + +The algorithms described above exhibit linear complexity concerning the number of elements. Gas estimation can be calculated using the following formula: + +```rust +let k = input_bytes/item_size +let gas_consumed = A + B * k +``` + +Here, A and B denote empirically calculated constants unique to each algorithm. + +For gas estimation, the benchmark vectors outlined in EIP-2537[^46] can be used where applicable. + ## Reference Implementation Primarily, concerning integration with nearcore, our interest lies in Rust language libraries. The current implementations of BLS12-381 in Rust are: From 0fbd492381e4b161e8781095bd6def730544a6be Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 30 Nov 2023 14:18:18 +0200 Subject: [PATCH 136/163] separate error cases --- neps/nep-0488.md | 55 +++++++----------------------------------------- 1 file changed, 8 insertions(+), 47 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a14bac787..2fcc9c15c 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -582,11 +582,6 @@ This section focuses on validating the summation functionality with an arbitrary - Sum with the maximum number of elements - A single point -***Error cases (execution is terminated):*** - -- The input length is not divisible by 97. -- The input is beyond memory bounds. - ***Annotation:*** ```rust @@ -627,11 +622,6 @@ The ERROR_CODE is returned. The test cases are identical to those of `bls12381_g1_sum`, with the only alteration being the substitution of points from $G_1$ and $E(F_p)$ with points from $G_2$ and $E'(F_{p^2})$. -***Error cases (execution is terminated):*** - -- The input length is not divisible by 193. -- The input is beyond memory bounds. - ***Annotation:*** ```rust @@ -718,11 +708,6 @@ These are identical test cases to those in the `bls12381_g1_sum` section. The same test cases as those in the `bls12381_g1_sum` section will be applied. -***Error cases (execution is terminated):*** - -- The input length is not divisible by 128. -- The input is beyond memory bounds. - ***Annotation:*** ```rust @@ -772,11 +757,6 @@ The ERROR_CODE is returned. The test cases are identical to those for `bls12381_g1_multiexp`, except that the points from $G_1$ and $E(F_p)$ are replaced with points from $G_2$ and $E'(F_{p^2})$ -***Error cases (execution is terminated):*** - -- The input length is not divisible by 224. -- The input is beyond memory bounds. - ***Annotation:*** ```rust @@ -837,11 +817,6 @@ Edge cases: - $a = p$ - Random number $\ge p$ -***Error cases (execution is terminated):*** - -- The input length is not divisible by 48. -- The input is beyond memory bounds. - ***Annotation:*** ```rust @@ -899,11 +874,6 @@ Edge cases: - (random number $\ge p$, 0) - (0, random number $\ge p$) -***Error cases (execution is terminated):*** - -- The input length is not divisible by 96. -- The input is beyond memory bounds. - ***Annotation:*** ```rust @@ -997,11 +967,6 @@ For an empty input, the function returns ERROR_CODE = 0. - Incorrect decompression bit. - Coordinates greater than or equal to 'p'. -***Error cases (execution is terminated):*** - -- The input length is not divisible by 288. -- The input is beyond memory bounds. - ***Annotation:*** ```rust @@ -1054,11 +1019,6 @@ The ERROR_CODE is returned. - Incorrectly encoded infinity point. - Point with a coordinate larger than 'p'. -***Error cases (execution is terminated):*** - -- The input length is not divisible by 48. -- The input is beyond memory bounds. - ***Annotation:*** ```rust @@ -1072,7 +1032,7 @@ pub fn bls12381_decompress_g1(&mut self, ***Description:*** The function decompresses compressed points from $E'(F_{p^2})$. It takes an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format as input and outputs the same number of points from $E'(F_{p^2})$ in decompressed format. For more information about the decompressed and compressed formats, refer to the Curve Points Encoding section. -***Input:*** A sequence of points $p_i \in E'(F_{p^2})$, with each point encoded in compressed form. The expected input size is 96*k bytes, interpreted as the byte concatenation of k slices. Each slice represents the compressed point from $E'(F_{p^2})$. Additional details are available in the Curve Points Encoding section. +***Input:*** A sequence of points $p_i \in E'(F_{p^2})$, with each point encoded in compressed form. The expected input size is `96*k` bytes, interpreted as the byte concatenation of k slices. Each slice represents the compressed point from $E'(F_{p^2})$. Additional details are available in the Curve Points Encoding section. ***Output:*** @@ -1088,11 +1048,6 @@ The ERROR_CODE is returned. The same test cases as `bls12381_decompress_g1`, but with points from $G_2$, and the input length should be divisible by 96. -***Error cases (execution is terminated):*** - -- The input length is not divisible by 96. -- The input is beyond memory bounds. - ***Annotation:*** ```rust @@ -1115,7 +1070,6 @@ If the `ERROR_CODE` equals 0, the output data will be written to the register with the `register_id` identifier. Otherwise, nothing will be written to the register. - ***Gas Estimation:*** The algorithms described above exhibit linear complexity concerning the number of elements. Gas estimation can be calculated using the following formula: @@ -1129,6 +1083,13 @@ Here, A and B denote empirically calculated constants unique to each algorithm. For gas estimation, the benchmark vectors outlined in EIP-2537[^46] can be used where applicable. +***Error cases (execution is terminated):*** + +For all functions, execution will terminate in the following cases: + +- The input length is not divisible by `item_size`. +- The input is beyond memory bounds. + ## Reference Implementation Primarily, concerning integration with nearcore, our interest lies in Rust language libraries. The current implementations of BLS12-381 in Rust are: From 809dd198c741d89d2f08e058c4d16c8a8ec70024 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 30 Nov 2023 17:37:23 +0200 Subject: [PATCH 137/163] fix typo --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 2fcc9c15c..b60692407 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -576,7 +576,7 @@ This section focuses on validating the summation functionality with an arbitrary - Create points and cross-check the outcome with the multiexp function. - Generate random points from $G_1$ and confirm that the sum is also from $G_1$. -- Edge cases: +Edge cases: - Empty input - Sum with the maximum number of elements From 8e0feb93d371e4a951c49f1db020ebcf654ca770 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 6 Dec 2023 11:46:24 +0200 Subject: [PATCH 138/163] fix motivation grammer --- neps/nep-0488.md | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b60692407..70981daf7 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -16,36 +16,35 @@ This NEP introduces host functions to perform operations on the BLS12-381 ellipt ## Motivation -The primary aim of this NEP is to enable fast and efficient verification of BLS signatures and zkSNARKs based on -BLS12-381[^1],[^11],[^52] elliptic curve on NEAR. +The primary aim of this NEP is to enable fast and efficient verification of BLS signatures and zkSNARKs based on the BLS12-381[^1],[^11],[^52] elliptic curve on NEAR. To efficiently verify zkSNARKs[^19], host functions for operations on the BN254 -elliptic curve(also known as Alt-BN128)[^9], [^12] have already been implemented on NEAR[^10]. +elliptic curve (also known as Alt-BN128)[^9], [^12] have already been implemented on NEAR[^10]. For instance, the Zeropool[^20] project utilizes these host functions for verifying zkSNARKs on NEAR. However, recent research shows that the BN254 security level is lower than 100-bit[^13] and it is not recommended for use. BLS12-381, on the other hand, offers over 120 bits of security[^8] and is widely used[^2],[^3],[^4],[^5],[^6],[^7] as a robust alternative. Supporting operations for BLS12-381 elliptic curve will significantly enhance the security of projects similar to Zeropool. Another crucial objective is the verification of BLS signatures. -Initially, host functions for BN254 in NEAR were designed for zkSNARK verification and -are insufficient for BLS signature verifications. -However, even if they were sufficient, it wouldn't work for us. -Projects such as ZCash[^2], Ethereum[^3], Tezos[^5], and Filecoin[^6] incorporate BLS12-381 specifically within their protocols. +Initially, host functions for BN254 on NEAR were designed for zkSNARK verification and +are insufficient for BLS signature verification. +However, even if these host functions were sufficient for BLS signature verification on the BN254 elliptic curve, this would not be enough for compatibility with other projects. +In particular, projects such as ZCash[^2], Ethereum[^3], Tezos[^5], and Filecoin[^6] incorporate BLS12-381 specifically within their protocols. If we aim for compatibility with these projects, we must also utilize this elliptic curve. For instance, to create a trustless bridge[^17] between Ethereum and NEAR, we must efficiently verify BLS signatures based on BLS12-381, as these are the signatures employed within Ethereum's protocol. In this NEP, we propose to add the following host functions: -- ***bls12381_g1_sum —*** sum the signed points from $G_1$ on an elliptic curve. This function is useful for aggregating public keys in BLS Signature. It can be employed for simple addition in $G_1$. It is kept separate from the multiexp function due to gas cost considerations. -- ***bls12381_g2_sum —*** sum the signed points from $G_2$ on an elliptic curve. This function is useful for aggregating signatures in BLS Signature. -- ***bls12381_g1_multiexp —*** for points $g_i \in G_1$ and scalars $s_i$ calculate $\sum g_i s_i$. This operation can be utilized to multiply a group element by a scalar. -- ***bls12381_g2_multiexp —*** for points $g_i \in G_2$ and scalars $s_i$ calculate $\sum g_i s_i$. -- ***bls12381_map_fp_to_g1 —*** maps a base field elements into the $G_1$ points. It does not perform the mapping of the byte string into field elements. -- ***bls12381_map_fp2_to_g2 —*** maps an extension field elements into the $G_2$ points. It does not perform the mapping of the byte string into extension field elements. We need this function to efficiently map a message into a group element. We are not implementing the hash_to_field[^60] function because it can be executed within a contract and various hashing algorithms can be applied. -- ***bls12381_decompress_g1 —*** decompresses the points from $G_1$ provided in the compressed form. Certain protocols offer points on the curve in compressed form (e.g., the light client updates in Ethereum 2.0), and decompression is a time-consuming operation. All the other functions in this NEP only accept decompressed points for simplicity and optimized gas consumption. -- ***bls12381_decompress_g2 —*** decompresses the points from $G_2$ provided in the compressed form. -- ***bls12381_pairing_check —*** 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$. This function is used to verify BLS signatures or zkSNARKs. +- ***bls12381_g1_sum —*** computes the sum of signed points from $G_1$ on an elliptic curve. This function is useful for aggregating public keys in the BLS signature scheme. It can be employed for simple addition in $G_1$. It is kept separate from the `multiexp` function due to gas cost considerations. +- ***bls12381_g2_sum —*** computes the sum of signed points from $G_2$ on an elliptic curve. This function is useful for aggregating signatures in the BLS signature scheme. +- ***bls12381_g1_multiexp —*** calculates $\sum g_i s_i$ for points $g_i \in G_1$ and scalars $s_i$. This operation can be used to multiply a group element by a scalar. +- ***bls12381_g2_multiexp —*** calculates $\sum g_i s_i$ for points $g_i \in G_2$ and scalars $s_i$. +- ***bls12381_map_fp_to_g1 —*** maps base field elements into $G_1$ points. It does not perform the mapping of byte strings into field elements. +- ***bls12381_map_fp2_to_g2 —*** maps extension field elements into $G_2$ points. This function does not perform the mapping of byte strings into extension field elements, which would be needed to efficiently map a message into a group element. We are not implementing the `hash_to_field`[^60] function because the latter can be executed within a contract and various hashing algorithms can be used within this function. +- ***bls12381_decompress_g1 —*** decompresses points from $G_1$ provided in a compressed form. Certain protocols offer points on the curve in a compressed form (e.g., the light client updates in Ethereum 2.0), and decompression is a time-consuming operation. All the other functions in this NEP only accept decompressed points for simplicity and optimized gas consumption. +- ***bls12381_decompress_g2 —*** decompresses points from $G_2$ provided in a compressed form. +- ***bls12381_pairing_check —*** verifies 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$. This function is used to verify BLS signatures or zkSNARKs. Functions required for verifying BLS signatures[^59]: @@ -62,12 +61,12 @@ Functions required for verifying zkSNARKs: - bls12381_g1_multiexp - bls12381_pairing_check -Both zkSNARKs and BLS signatures can be implemented alternatively by swapping G1 and G2. -Therefore, all functions have been implemented for both G1 and G2. +Both zkSNARKs and BLS signatures can be implemented alternatively by swapping $G_1$ and $G_2$. +Therefore, all functions have been implemented for both $G_1$ and $G_2$. An analogous proposal, EIP-2537[^15], exists in Ethereum. The functions here have been designed with compatibility -with Ethereum's proposal in mind. This design approach aims +with that Ethereum's proposal in mind. This design approach aims to ensure future ease in supporting corresponding precompiles for Aurora[^24]. ## Specification @@ -185,7 +184,7 @@ To define these fields, we'll need to set up three irreducible polynomials[^51]: - $F_{p^2} = F_p[u] / (u^2 + 1)$ - $F_{p^6} = F_{p^2}[v] / (v^3 - u - 1)$ -- $F_{p^{12}} = F_{p^6}[w]/(w^2 - v)$ +- $F_{p^{12}} = F_{p^6}[w] / (w^2 - v)$ The second subgroup we'll utilize has an order of r and resides within the same elliptic curve but with elements from $F_{p^{12}}$. From 616fd038625914623677712abb0f047412f2b0d0 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 6 Dec 2023 13:51:24 +0200 Subject: [PATCH 139/163] fix bls12381 specification section --- neps/nep-0488.md | 124 +++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 70981daf7..768b75d66 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -79,15 +79,15 @@ to ensure future ease in supporting corresponding precompiles for Aurora[^24]. elements $\textbraceleft 0, 1, \ldots, p - 1 \textbraceright$ with two operations: multiplication $\cdot$ and addition $+$. These operations involve standard integer multiplication and addition, -followed by taking the remainder modulo $p$. +followed by computing the remainder modulo $p$. -**The elliptic curve $E(F_p)$** is a set of all pairs $(x, y) \in F_p$: +**The elliptic curve $E(F_p)$** is the set of all pairs $(x, y)$ with coordinates in $F_p$ satisfying: $$ y^2 \equiv x^3 + Ax + B \mod p $$ -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$ +together with an imaginary point at infinity $\mathcal{O}$, 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],[^51],[^14],[^11] @@ -95,22 +95,22 @@ In the case of BLS12-381 equation is $y^2 \equiv x^3 + 4 \mod p$[^15],[^51],[^14 - $A = 0$ - $B = 4$ -- $p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab$ +- $p = \mathtt{0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab}$ -Let’s $P \in E(F_q)$ have coordinates (x, y), define **$-P$** as a point on a curve with coordinates (x, -y). +Let $P \in E(F_q)$ have coordinates (x, y), define **$-P$** as a point on a curve with coordinates (x, -y). -**The addition operation for Elliptic Curve** is a function $+\colon E(F_p) \times E(F_p) \rightarrow E(F_p)$ defined with following rules: let’s P and Q $\in E(F_p)$ +**The addition operation for Elliptic Curve** is a function $+\colon E(F_p) \times E(F_p) \rightarrow E(F_p)$ defined with following rules: let P and Q $\in E(F_p)$ - if $P \ne Q$ and $P \ne -Q$ - draw a line passing through P and Q. This line intersects the curve at a third point R - - reflect the point R about the x-axis by changing the sign of the y-coordinate. The resulting point is P+Q. + - reflect the point R across the x-axis by changing the sign of the y-coordinate. The resulting point is P+Q. - if $P=Q$ - draw a tangent line throw P for an elliptic curve. The line will intersect the curve at the second point R. - - reflect the point R about the x-axis the same way to get point 2P + - reflect the point R across the x-axis the same way to get point 2P - $P = -Q$ - - $P + Q = P + (-P) = 0$ — the point on infinity -- Q = 0 - - $P + Q = P + 0 = P$ + - $P + Q = P + (-P) = \mathcal{O}$ — the point on infinity +- $Q = \mathcal{O}$ + - $P + Q = P + \mathcal{O} = P$ With the addition operation, Elliptic Curve forms a **group**. @@ -128,21 +128,21 @@ Group/subgroup **order** is the number of elements in group/subgroup. Notation: |G| or #G, where G represents the group. -For some technical reason (for `pairing` operation which we will define later), -we will operate not with the entire $E(F_p)$, -but only with the two subgroups $G_1$ and $G_2$ +For some technical reason (related to the `pairing` operation which we will define later), +we will not operate over the entire $E(F_p)$, +but only over the two subgroups $G_1$ and $G_2$ having the same **order** $r$. $G_1$ is a subset of $E(F_p)$, while $G_2$ is a subgroup of another group that we will define later. -The value of $r$ should be a prime number, and $G1 \ne G2$ +The value of $r$ should be a prime number and $G_1 \ne G_2$ -For our BLS12-381 Elliptic Curve, **the order r** of $G1$ and $G2$[^15],[^51] is given by: +For the BLS12-381 Elliptic Curve, **the order r** of $G_1$ and $G_2$[^15],[^51] is given by: -- $r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001$ +- $r = \mathtt{0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001}$ #### Field extension -**The field extension $F_{p^k}$** is a set comprising all polynomials with a degree < k and coefficients from $F_p$, along with defined operations of multiplication ($\cdot$) and addition ($+$). +**The field extension $F_{p^k}$ of $F_{p}$** is a set comprising all polynomials of degree < k and coefficients from $F_p$, along with defined operations of multiplication ($\cdot$) and addition ($+$). $$ a_{k - 1}x^{k - 1} + \ldots + a_1x + a_0 = A(x) \in F_{p^k} \vert a_i \in F_p @@ -177,7 +177,7 @@ We'll construct this field not directly as an extension from $F_p$, but rather through a stepwise process. First, we'll build $F_{p^2}$ as a quadratic extension of the field $F_p$. Second, we'll establish $F_{p^6}$ as a cubic extension of $F_{p^2}$. -Finally, we'll create $F_{p^{12}}$, a quadratic extension of the +Finally, we'll create $F_{p^{12}}$ as a quadratic extension of the field $F_{p^6}$. To define these fields, we'll need to set up three irreducible polynomials[^51]: @@ -186,7 +186,7 @@ To define these fields, we'll need to set up three irreducible polynomials[^51]: - $F_{p^6} = F_{p^2}[v] / (v^3 - u - 1)$ - $F_{p^{12}} = F_{p^6}[w] / (w^2 - v)$ -The second subgroup we'll utilize has an order of r and +The second subgroup we'll utilize has order r and resides within the same elliptic curve but with elements from $F_{p^{12}}$. Specifically, $G_2 \subset E(F_{p^{12}})$, where $E: y^2 = x^3 + 4$ @@ -214,14 +214,14 @@ In most cases, we will be working with points from $G_2' \subset E'(F_{p^2})$ an #### Generators -If there exists an element g in the group G such that $\textbraceleft g, 2g, 3g, \ldots, |G|g \textbraceright = G$, the group G is called a ***cyclic group*** and g is termed a ***generator*** +If there exists an element $g$ in the group $G$ such that $\textbraceleft g, 2 \cdot g, 3 \cdot g, \ldots, |G|g \textbraceright = G$, the group $G$ is called a ***cyclic group*** and $g$ is termed a ***generator*** $G_1$ and $G_2$ are cyclic subgroups with the following generators[^15],[^51]: $G_1$: -- $x = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb$ -- $y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1$ +- $x = \mathtt{0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb}$ +- $y = \mathtt{0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1}$ For $(x', y') \in G_2 \subset E'(F_{p^2}):$ $$x' = x_0 + x_1u$$ @@ -230,13 +230,13 @@ $$y' = y_0 + y_1u$$ $G_2$: -- $x_0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8$ -- $x_1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e$ -- $y_0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801$ -- $y_1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be$ +- $x_0 = \mathtt{0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8}$ +- $x_1 = \mathtt{0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e}$ +- $y_0 = \mathtt{0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801}$ +- $y_1 = \mathtt{0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be}$ -**Cofactor** is the ratio of the size of the entire group G to the size of the subgroup H: +**Cofactor** is the ratio of the size of the entire group $G$ to the size of the subgroup $H$: $$ |G|/|H| @@ -244,30 +244,30 @@ $$ Cofactor $G_1\colon h = |E(F_p)|/r$[^51] -$$h = 0x396c8c005555e1568c00aaab0000aaab$$ +$$h = \mathtt{0x396c8c005555e1568c00aaab0000aaab}$$ Cofactor $G_2\colon h' = |E'(F_{p^2})|/r$[^51] -$$h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5$$ +$$h' = \mathtt{0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5}$$ #### Pairing -Pairing is an operation necessary for digital signatures and zkSNARKs verification. It performs the operation $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{p^{12}}$. +Pairing is a necessary operation for the verification of BLS signatures and certain zkSNARKs. It performs the operation $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{p^{12}}$. The main properties of the pairing operation are: - $e(P, Q + R) = e(P, Q) \cdot e(P, R)$ - $e(P + S, R) = e(P, R)\cdot e(S, R)$ -To compute this function, we utilize an algorithm called Miller Loop. -For effective implementation of this algorithm, +To compute this function, we utilize an algorithm called Miller Loop. +For an affective implementation of this algorithm, we require a key parameter for the BLS curve, denoted as $x$: -$$ x = -0xd201000000010000$$ +$$ x = -\mathtt{0xd201000000010000}$$ This parameter can be found in the following sources: -- [^15] section specification, pairing parameters, miller loop scalar +- [^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 @@ -276,7 +276,7 @@ This parameter can be found in the following sources: The parameters for the BLS12-381 curve are as follows: -Base field modulus: $p = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab$ +Base field modulus: $p = \mathtt{0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab}$ $$ E\colon y^2 \equiv x^3 + 4 @@ -286,7 +286,7 @@ $$ E'\colon y^2 \equiv x^3 + 4(u + 1) $$ -Main subgroup order: $r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001$ +Main subgroup order: $r = \mathtt{0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001}$ $$ F_{p^2} = F_p[u] / (u^2 + 1) @@ -300,27 +300,27 @@ $$ F_{p^{12}} = F_{p^6}[w] / (w^2 - v) $$ -Generator for G1: +Generator for $G_1$: -- $x = 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb$ -- $y = 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1$ +- $x = \mathtt{0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb}$ +- $y = \mathtt{0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1}$ -Generator for G2: +Generator for $G_2$: -- $x_0 = 0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8$ -- $x_1 = 0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e$ -- $y_0 = 0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801$ -- $y_1 = 0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be$ +- $x_0 = \mathtt{0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8}$ +- $x_1 = \mathtt{0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e}$ +- $y_0 = \mathtt{0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801}$ +- $y_1 = \mathtt{0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be}$ -Cofactor for G1: -$$h = 0x396c8c005555e1568c00aaab0000aaab$$ +Cofactor for $G_1$: +$$h = \mathtt{0x396c8c005555e1568c00aaab0000aaab}$$ -Cofactor for G2: -$$h' = 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5$$ +Cofactor for $G_2$: +$$h' = \mathtt{0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5}$$ Key BLS12-381 parameter used in Miller Loop: -$$x = -0xd201000000010000$$ +$$x = -\mathtt{0xd201000000010000}$$ All parameters were sourced from [^15], [^51], and [^14], and they remain consistent across these sources. @@ -329,10 +329,10 @@ All parameters were sourced from [^15], [^51], and [^14], and they remain consis This section delineates the functionality of the `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` functions, operating in accordance with the RFC9380 specification "Hashing to Elliptic Curves"[^62]. -These functions map the field elements in $F_p$ or $F_{p^2}$ +These functions map field elements in $F_p$ or $F_{p^2}$ to their corresponding subgroups: $G_1 \subset E(F_p)$ or $G_2 \subset E'(F_{p^2})$. `bls12381_map_fp_to_g1`/`bls12381_map_fp2_to_g2` combine the functionalities -of map_to_curve and clear_cofactor from RFC9380[^63]. +of `map_to_curve` and `clear_cofactor` from RFC9380[^63]. ```text fn bls12381_map_fp_to_g1(u): @@ -340,10 +340,10 @@ fn bls12381_map_fp_to_g1(u): return clear_cofactor(Q); ``` -We choose not to implement the hash_to_field function as a host function due to potential changes in hashing methods. +We choose not to implement the `hash_to_field` function as a host function due to potential changes in hashing methods. Additionally, executing this function within the contract consumes approximately 2 TGas, which is acceptable for our goals. -Specific implementation parameters for bls12381_map_fp_to_g1 and bls12381_map_fp2_to_g2 can be found in RFC9380 +Specific implementation parameters for `bls12381_map_fp_to_g1` and `bls12381_map_fp2_to_g2` can be found in RFC9380 under sections 8.8.1[^64] and 8.8.2[^65], respectively. ### Curve points encoding @@ -532,9 +532,9 @@ This section aims to verify the correctness of summing two valid elements on the Edge cases: - Points not from G1. -- 0 + 0 = 0. -- P + 0 = 0 + P = P. -- P + (-P) = (-P) + P = 0. +- $\mathcal{O} + \mathcal{O} = \mathcal{O}$. +- $P + \mathcal{O} = \mathcal{O} + P = P$. +- $P + (-P) = (-P) + P = \mathcal{O}$. - P + P (tangent to the curve). - The sum of two points P and (-(P + P)) (tangent to the curve at point P). @@ -543,7 +543,7 @@ Edge cases: This section aims to validate the correctness of point inversion: -- Generate random points on the curve and verify P - P = -P + P = 0. +- Generate random points on the curve and verify $P - P = -P + P = \mathcal{O}$. - Generate random points on the curve and verify -(-P) = P. - Generate random points from G1 and ensure that -P also belong to G1. - Utilize an external implementation, generate random points on the curve, and compare results. @@ -551,7 +551,7 @@ This section aims to validate the correctness of point inversion: Edge cases: - Point not from G1 -- -0 +- -$\mathcal{O}$ Tests for incorrect data @@ -926,9 +926,9 @@ For an empty input, the function returns ERROR_CODE = 0. Tests for one pair -- Generate a random point $P \in G_1$: verify $e(P, 0) = 1$ -- Generate a random point $Q \in G_2$: verify $e(0, Q) = 1$ -- Generate random points $P \ne 0 \in G_1$ and $Q \ne 0 \in G_2$: verify $e(P, Q) \ne 1$ +- Generate a random point $P \in G_1$: verify $e(P, \mathcal{O}) = 1$ +- Generate a random point $Q \in G_2$: verify $e(\mathcal{O}, Q) = 1$ +- Generate random points $P \ne \mathcal{O} \in G_1$ and $Q \ne \mathcal{O} \in G_2$: verify $e(P, Q) \ne 1$ Tests for two pairs From c70a134b493f189b32b610206a2051ba0522a05a Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 6 Dec 2023 14:18:20 +0200 Subject: [PATCH 140/163] fix encoding section --- neps/nep-0488.md | 57 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 768b75d66..4b9d80c3e 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -354,25 +354,26 @@ The sign of a point on the elliptic curve is represented as a u8 type in Rust, w #### Scalar -The scalar value is encoded as a little-endian [u8; 32]. All possible byte combinations are allowed. +A scalar value is encoded as little-endian [u8; 32]. All possible byte combinations are allowed. -#### Fields elements Fp +#### Fields elements $F_p$ Values from $F_p$ are encoded as big-endian [u8; 48]. Only values less than p are permitted. If the value is equal to or greater than p, an error should be returned. -#### Extension fields elements Fp2 +#### Extension fields elements $F_{p^2}$ -An element $q \in F_{p^{2}}$ can be expressed as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$. The element from $F_{p^2}$ is encoded in [u8; 96] as a byte concatenation of $c_1$ and $c_0$. The encoding for $c_1$ and $c_0$ follows the rule described in the previous section. +An element $q \in F_{p^{2}}$ can be expressed as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$. +An element from $F_{p^2}$ is encoded in [u8; 96] as the byte concatenation of $c_1$ and $c_0$. The encoding for $c_1$ and $c_0$ follows the rule described in the previous section. The representation of $q \in F_{p^2}$, with $q = c_0 + c_1 v$, is encoded as [u8; 96]: - $c_1 \in F_p$ is represented as `[u8; 48]` - $c_0 \in F_p$ is represented as `[u8; 48]` -#### Uncompressed points on curve E(Fp) +#### Uncompressed points on curve $E(F_p)$ Points on the curve are represented by affine coordinates: $(x: F_p, y: F_p)$. -The elements from $E(F_p)$ are encoded in `[u8; 96]` as a byte concatenation of x and y point coordinates, where $x, y \in F_p$. +Elements from $E(F_p)$ are encoded in `[u8; 96]` as the byte concatenation of the x and y point coordinates, where $x, y \in F_p$. The encoding follows the rules outlined in the section “Fields elements $F_p$”. $E(F_p)$ is encoded as [u8; 96]: @@ -384,14 +385,14 @@ $E(F_p)$ is encoded as [u8; 96]: When this bit is set to 1, it designates an infinity point. In this case, all other bits should be set to 0. -Encoding point on infinity: +Encoding the point at infinity: ```bash let x: [u8; 96] = [0; 96]; x[0] = x[0] | 0x40; ``` -#### Compressed points on curve E(Fp) +#### Compressed points on curve $E(F_p)$ The points on the curve are represented by affine coordinates: $(x: F_p, y: F_p)$. Elements from $E(F_p)$ in compressed form are encoded as `[u8; 48]`, @@ -399,8 +400,8 @@ with big-endian encoded $x \in F_p$. The $y$ coordinate is determined by the formula: $y = \pm \sqrt{x^3 + 4}$. - The highest bit indicates if the point is encoded in compressed form and should be set to 1. -- The second-highest bit marks a point as infinity (if set to 1). - - For infinity points, all bits except the first two should be set to 0; other encodings should be considered as incorrect. +- The second-highest bit marks the point at infinity (if set to 1). + - For the point at infinity, all bits except the first two should be set to 0; other encodings should be considered as incorrect. - To represent the sign of $y$, the third-highest bit in the x encoding is utilized. - If the bit is 0, $y$ is positive; if 1, $y$ is negative. We'll consider the number positive by taking the smallest value between $y$ and $-y$. @@ -414,7 +415,7 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x20; ``` -Encoding the point of infinity: +Encoding the point at infinity: ```rust let x: [u8; 48] = [0; 48]; @@ -422,7 +423,7 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x40; ``` -#### Uncompressed points on twisted curve E'(Fp2) +#### Uncompressed points on the twisted curve $E'(F_{p^2})$ The points on the curve are represented by affine coordinates: $(x: F_{p^2}, y: F_{p^2})$. Elements from $E'(F_{p^2})$ are encoded in [u8; 192] as a concatenation of bytes representing x and y coordinates, where $x, y \in F_{p^2}$. @@ -432,14 +433,14 @@ The encoding for $x$ and $y$ follows the rules detailed in the "Extension Fields When this bit is set to 1, it designates an infinity point. In this case, all other bits should be set to 0. -Encoding the point of infinity: +Encoding the point at infinity: ```bash let x: [u8; 192] = [0; 192]; x[0] = x[0] | 0x40; ``` -#### Compressed points on twisted curve E'(Fp2) +#### Compressed points on twisted curve $E'(F_{p^2})$ The points on the curve are represented by affine coordinates: $(x: F_{p^2}, y: F_{p^2})$. Elements from $E'(F_{p^2})$ in compressed form are encoded as [u8; 96], @@ -447,8 +448,8 @@ with big-endian encoded $x \in F_{p^2}$. The $y$ coordinate is determined using the formula: $y = \pm \sqrt{x^3 + 4(u + 1)}$. - The highest bit indicates if the point is encoded in compressed form and should be set to 1. -- The second-highest bit marks a point as infinity (if set to 1). - - For infinity points, all bits except the first two should be set to 0; other encodings should be considered as incorrect. +- The second-highest bit marks the point at infinity (if set to 1). + - For the point at infinity, all bits except the first two should be set to 0; other encodings should be considered as incorrect. - To represent the sign of $y$, the third-highest bit in the x encoding is utilized. - If the bit is 0, $y$ is positive; if 1, $y$ is negative. We'll consider the number positive by taking the smallest value between $y$ and $-y$: first compare $c_1$, then $c_0$. @@ -462,7 +463,7 @@ x[0] = x[0] | 0x80; x[0] = x[0] | 0x20; ``` -Encoding the point of infinity: +Encoding the point at infinity: ```rust let x: [u8; 96] = [0; 96]; @@ -477,8 +478,8 @@ For instance, verifying if a point belongs to the subgroup is gas-consuming. If an error is returned by the near host function, the entire execution is reverted. To mitigate this, when the input verification is complex, the host function will successfully complete its work but return an ERROR_CODE. -This enables users to handle error cases independently. It's important to note that host functions -might terminate with an error if it's straightforward to avoid (e.g., incorrect input size). +This enables users to handle error cases independently. It's important to note that host functions +might terminate with an error if it's straightforward to avoid it (e.g., incorrect input size). The ERROR_CODE is encoded as a little-endian u64 and can hold the following values: @@ -526,12 +527,12 @@ This section aims to verify the correctness of summing two valid elements on the - Utilize points on the curve with known addition results for comparison, such as tests from EIP-2537[^47],[^48]. - Generate random points on the curve and verify the commutative property: P + Q = Q + P. -- Validate that the sum of random points from G1 remains in G1. +- Validate that the sum of random points from $G_1$ remains in $G_1$. - Generate random points on the curve and use another library to cross-check the results. Edge cases: -- Points not from G1. +- Points not from $G_1$. - $\mathcal{O} + \mathcal{O} = \mathcal{O}$. - $P + \mathcal{O} = \mathcal{O} + P = P$. - $P + (-P) = (-P) + P = \mathcal{O}$. @@ -545,12 +546,12 @@ This section aims to validate the correctness of point inversion: - Generate random points on the curve and verify $P - P = -P + P = \mathcal{O}$. - Generate random points on the curve and verify -(-P) = P. -- Generate random points from G1 and ensure that -P also belong to G1. +- Generate random points from $G_1$ and ensure that -P also belong to $G_1$. - Utilize an external implementation, generate random points on the curve, and compare results. Edge cases: -- Point not from G1 +- Point not from $G_1$ - -$\mathcal{O}$ Tests for incorrect data @@ -850,7 +851,7 @@ The ERROR_CODE is returned. - Validate the results for known answers from EIP-2537[^47],[^48] - Generate a random point $a$ from $F_{p^2}$: - Verify the result with another library. - - Check that result point on curve in G2. + - Check that result point on curve in $G_2$. - Compare results for $a$ and $-a$; they should have the same x-coordinates and opposite y-coordinates. Edge cases: @@ -955,8 +956,8 @@ For an empty input, the function returns ERROR_CODE = 0. Tests for error cases -- The first point is on the curve but not in G1. -- The second point is on the curve but not in G2. +- The first point is on the curve but not in $G_1$. +- The second point is on the curve but not in $G_2$. - The input length is not divisible by 288. - The first point is not on the curve. - The second point is not on the curve. @@ -995,7 +996,7 @@ The ERROR_CODE is returned. Tests for decompressing a single point -- Generate random points on the curve from G1 and not from G1: +- Generate random points on the curve from $G_1$ and not from $G_1$: - Check that the uncompressed point lies on the curve. - Compare the result with another library. - Generate random points with a negative y: @@ -1128,7 +1129,7 @@ BLS12-381 offers more security bits compared to the already existing pairing-fri In nearcore, host functions for another pairing-friendly curve, BN254, have already been implemented[^10]. Some projects[^20] might consider utilizing the supported curve as an alternative. However, recent research indicates that this curve provides less than 100 bits of security and is not recommended for use[^13]. Furthermore, projects involved in cross-chain interactions, like Rainbow Bridge, are mandated to employ the same curve as the target protocol, which, in the case of Ethereum, is currently BLS12-381[^3]. Consequently, there is no viable alternative to employing a different pairing-friendly curve. -An alternative approach involves creating a single straightforward host function in nearcore for BLS signature verification. This was the initially proposed solution[^26]. However, this solution lacks flexibility[^28] for several reasons: (1) projects may utilize different hash functions; (2) some projects might employ the G1 subgroup for public keys, while others use G2; (3) the specifications for Ethereum 2.0 remain in draft, subject to potential changes; (4) instead of a more varied and adaptable set of functions (inspired by EIP-2537's precompiles), we are left with a single large function; (5) there will be no support for zkSNARKs verification. +An alternative approach involves creating a single straightforward host function in nearcore for BLS signature verification. This was the initially proposed solution[^26]. However, this solution lacks flexibility[^28] for several reasons: (1) projects may utilize different hash functions; (2) some projects might employ the $G_1$ subgroup for public keys, while others use $G_2$; (3) the specifications for Ethereum 2.0 remain in draft, subject to potential changes; (4) instead of a more varied and adaptable set of functions (inspired by EIP-2537's precompiles), we are left with a single large function; (5) there will be no support for zkSNARKs verification. Another alternative is to perform BLS12-381 operations off-chain. In this scenario, applications utilizing the BLS curve will no longer maintain trustlessness. From f6402c45d1345f7f5d02e7b757d92e0016ead648 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 6 Dec 2023 14:53:15 +0200 Subject: [PATCH 141/163] fix host functions specidifcations --- neps/nep-0488.md | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 4b9d80c3e..21eeb8ece 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -503,7 +503,7 @@ The function calculates the sum of signed elements on the BLS12-381 curve. It ac The operations, including the $E(F_p)$ curve, points on the curve, multiplication by -1, and the addition operation, are detailed in the BLS12-381 Curve Specification section. -Note: The function accepts points from the entire curve, not restricted to $G_1$. +Note: This function accepts points from the entire curve and is not restricted to points in $G_1$. ***Input:*** @@ -523,7 +523,7 @@ The ERROR_CODE is returned. Tests for the sum of two points -This section aims to verify the correctness of summing two valid elements on the curve: +This section aims to verify the correctness of summing up two valid elements on the curve: - Utilize points on the curve with known addition results for comparison, such as tests from EIP-2537[^47],[^48]. - Generate random points on the curve and verify the commutative property: P + Q = Q + P. @@ -564,16 +564,16 @@ This section aims to validate the handling of incorrect input data: - Erroneous coding of field elements resulting in a correct element on the curve modulo p. - Erroneous coding of field elements with an incorrect extra bit in the decompressed encoding. - Point not on the curve. -- Incorrect encoding of the point on infinity. +- Incorrect encoding of the point at infinity. - Input is beyond memory bounds. Tests for the sum of an arbitrary amount of points This section focuses on validating the summation functionality with an arbitrary number of points: -- Generate random points on the curve and verify that the sum of the random permutation matches. +- Generate random points on the curve and verify that the sum of a random permutation matches. - Generate random points on the curve and utilize another library to validate results. -- Create points and cross-check the outcome with the multiexp function. +- Create points and cross-check the outcome with the `multiexp` function. - Generate random points from $G_1$ and confirm that the sum is also from $G_1$. Edge cases: @@ -599,7 +599,7 @@ The function computes the sum of the signed elements on the BLS12-381 curve. It The $E'(F_{p^2})$ curve, the points on the curve, the multiplication by -1, and the addition operation are all defined in the BLS12-381 Curve Specification section. -Note: The function accepts any points on the curve, not limited to $G_2$. +Note: The function accepts any points on the curve and is not limited to points in $G_2$. ***Input:*** @@ -613,7 +613,7 @@ More details are available in the Curve Points Encoding section. The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). + - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - Points or signs are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. @@ -658,7 +658,7 @@ Please note: The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 96 bytes represent one point $\in E(F_p)$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). + - Output: 96 bytes represent one point $\in E(F_p)$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - Points are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. @@ -741,14 +741,14 @@ Please note: ***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. -Expected `224*k` bytes as an input that is interpreted as byte concatenation of `k` slices, each slice is the concatenation of uncompressed point from $E'(F_{p^2})$ — `192` bytes and scalar — `32` bytes. More details are in the Curve Points Encoding section. +The expected input size is `224*k` bytes, interpreted as the byte concatenation of `k` slices. Each slice is the concatenation of an uncompressed point from $E'(F_{p^2})$ — `192` bytes and a scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). + - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - Points are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. @@ -772,10 +772,10 @@ pub fn bls12381_g2_multiexp( ***Description:*** -The function takes the list of field elements $a_i \in F_p$ and maps them to $G_1 \subset E(F_p)$. +This function takes as input a list of field elements $a_i \in F_p$ and maps them to $G_1 \subset E(F_p)$. You can find the specification of this mapping function in the section titled 'Map to curve specification.' -Importantly, this function does NOT perform the mapping of the byte string into $F_p$. -The implementation of this function may vary and can be effectively executed within the contract. +Importantly, this function does NOT perform the mapping of the byte string into $F_p$. +The implementation of the mapping to $F_p$ may vary and can be effectively executed within the contract. ***Input:*** @@ -832,7 +832,9 @@ pub fn bls12381_map_fp_to_g1( ***Description:*** -The function takes the list of elements $a_i \in F_{p^2}$ and maps them to $G_2 \subset E'(F_{p^2})$. You can find the mapping function's specifications in the "Map to Curve Specification" section. It's important to note that this function does NOT map the byte string into $F_{p^2}$. The implementation of this function may vary and can be effectively executed within the contract. +This function takes as input a list of elements $a_i \in F_{p^2}$ and maps them to $G_2 \subset E'(F_{p^2})$. +You can find the mapping function specification in the "Map to Curve Specification" section. It's important to note that this function does NOT map byte strings into $F_{p^2}$. +The implementation of the mapping to $F_{p^2}$ may vary and can be effectively executed within the contract. ***Input:*** the function takes as input `96*k` bytes — the elements from $F_{p^2}$ (two unsigned integers $< p$). Additional details can be found in the Curve Points Encoding section. @@ -851,7 +853,7 @@ The ERROR_CODE is returned. - Validate the results for known answers from EIP-2537[^47],[^48] - Generate a random point $a$ from $F_{p^2}$: - Verify the result with another library. - - Check that result point on curve in $G_2$. + - Check that the resulting point lies in $G_2$. - Compare results for $a$ and $-a$; they should have the same x-coordinates and opposite y-coordinates. Edge cases: @@ -900,13 +902,13 @@ $e([a]P, [b]Q) = e(P, Q)^{ab} = e([b]P, [a]Q)$ This function is necessary to verify BLS signatures/zkSNARKs. -This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$ and validate: +This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$ and validates: $$ \prod e(p_i, q_i) = 1 $$ -We don’t calculate the pairing function itself: the result will be in the huge field, and in all known applications only this validation check is necessary. +We don’t need to calculate the pairing function itself as the result would lie on a huge field, and in all known applications only this validation check is necessary. ***Input:*** A sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$. Each point is encoded in decompressed form. An expected input size of 288*k bytes is anticipated, interpreted as byte concatenation of k slices. Each slice comprises the concatenation of an uncompressed point from $G_1 \subset E(F_p)$ (occupying 96 bytes) and a point from $G_2 \subset E'(F_{p^2})$ (occupying 192 bytes). Additional details can be found in the Curve Points Encoding section. @@ -962,7 +964,7 @@ For an empty input, the function returns ERROR_CODE = 0. - The first point is not on the curve. - The second point is not on the curve. - Input length exceeds the memory limit. -- Incorrect encoding of the infinity point. +- Incorrect encoding of the point at infinity. - Incorrect encoding of a curve point: - Incorrect decompression bit. - Coordinates greater than or equal to 'p'. @@ -1016,7 +1018,7 @@ The ERROR_CODE is returned. - The input is beyond memory bounds. - Point is not on the curve. - Incorrect decompression bit. -- Incorrectly encoded infinity point. +- Incorrectly encoded point at infinity. - Point with a coordinate larger than 'p'. ***Annotation:*** @@ -1059,7 +1061,7 @@ pub fn bls12381_decompress_g2(&mut self, #### General comments for all functions -In all functions, input is fetched from memory, beginning at `value_ptr` and extending to `value_ptr + value_len`. +In all functions, the input is fetched from memory, beginning at `value_ptr` and extending to `value_ptr + value_len`. If `value_len` is `u64::MAX`, input will come from the register. Execution ends only if there's an incorrect input length, From 32798b21bcd8e466498097b365acc5053eba15bb Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Wed, 6 Dec 2023 15:07:20 +0200 Subject: [PATCH 142/163] fix Future possibilities and Implementation sections --- neps/nep-0488.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 21eeb8ece..d26b85132 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1117,7 +1117,7 @@ In addition, there are implementations in other languages that are less relevant One of the possible libraries to use is the blst library[^30]. This library exhibits good performance[^45] and has undergone several audits[^55]. -You can find the draft implementation in nearcore, which is based on this library, through this link[^54]. +You can find a draft implementation in nearcore, which is based on this library, through this link[^54]. ## Security Implications @@ -1125,7 +1125,7 @@ The implementation's security depends on the chosen library's security, supporti Within this NEP, a constant execution time for all operations isn't mandated. This isn't an issue when employing host functions for BLS signature/zkSNARKs verification. However, refrain from using these host functions if a constant-time algorithm is necessary. -BLS12-381 offers more security bits compared to the already existing pairing-friendly curve BN254. Consequently, the security of projects requiring the pairing-friendly curve will be enhanced. +BLS12-381 offers more security bits compared to the already existing pairing-friendly curve BN254. Consequently, the security of projects requiring a pairing-friendly curve will be enhanced. ## Alternatives @@ -1139,7 +1139,7 @@ Another alternative is to perform BLS12-381 operations off-chain. In this scenar In the future, there might be support for working with various curves beyond just BLS12-381. In Ethereum, prior to EIP-2537[^15], there was a proposal, EIP-1962[^27], to introduce pairing-friendly elliptic curves in a versatile format, accommodating not only BLS curves but numerous others as well. However, this proposal wasn't adopted due to its extensive scope and complexity. Implementing every conceivable curve might not be practical, but it remains a potential extension worth considering. -Another potential extension could involve supporting hash_to_field or hash_to_curve operations[^58]. Enabling their support would optimize gas usage for encoding messages into elements on the curve, which could benefit BLS signatures. However, implementing the hash_to_field operation requires supporting multiple hashing algorithms simultaneously and doesn't demand a significant amount of gas for implementation within the contract. Therefore, these functions exceed the scope of this proposal. +Another potential extension could involve supporting `hash_to_field` or `hash_to_curve` operations[^58]. Enabling their support would optimize gas usage for encoding messages into elements on the curve, which could be beneficial to BLS signatures. However, implementing the hash_to_field operation requires supporting multiple hashing algorithms simultaneously and doesn't demand a significant amount of gas for implementation within the contract. Therefore, these functions exceed the scope of this proposal. Additionally, a potential expansion might encompass supporting not only affine coordinates but also other coordinate systems, such as homogeneous or Jacobian projective coordinates. From 8ea07dabdc798a37296877ede4a4a244559cfd70 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 12 Dec 2023 10:52:50 +0200 Subject: [PATCH 143/163] fix style --- neps/nep-0488.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index d26b85132..b359a68d7 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -87,9 +87,9 @@ $$ y^2 \equiv x^3 + Ax + B \mod p $$ -together with an imaginary point at infinity $\mathcal{O}$, where: $A, B \in F_p$, p is prime > 3, and $4A^3 + 27B^2 \not \equiv 0 \mod p$ +together with an imaginary point at infinity $\mathcal{O}$, where: $A, B \in F_p$, $p$ is a 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],[^51],[^14],[^11] +In the case of BLS12-381 the equation is $y^2 \equiv x^3 + 4 \mod p$[^15],[^51],[^14],[^11] **Parameters for our case:** @@ -97,16 +97,16 @@ In the case of BLS12-381 equation is $y^2 \equiv x^3 + 4 \mod p$[^15],[^51],[^14 - $B = 4$ - $p = \mathtt{0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab}$ -Let $P \in E(F_q)$ have coordinates (x, y), define **$-P$** as a point on a curve with coordinates (x, -y). +Let $P \in E(F_q)$ have coordinates $(x, y)$, define **$-P$** as a point on a curve with coordinates $(x, -y)$. -**The addition operation for Elliptic Curve** is a function $+\colon E(F_p) \times E(F_p) \rightarrow E(F_p)$ defined with following rules: let P and Q $\in E(F_p)$ +**The addition operation for Elliptic Curve** is a function $+\colon E(F_p) \times E(F_p) \rightarrow E(F_p)$ defined with following rules: let $P$ and $Q \in E(F_p)$ - if $P \ne Q$ and $P \ne -Q$ - - draw a line passing through P and Q. This line intersects the curve at a third point R - - reflect the point R across the x-axis by changing the sign of the y-coordinate. The resulting point is P+Q. + - draw a line passing through $P$ and $Q$. This line intersects the curve at a third point $R$. + - reflect the point $R$ across the $x$-axis by changing the sign of the $y$-coordinate. The resulting point is $P+Q$. - if $P=Q$ - - draw a tangent line throw P for an elliptic curve. The line will intersect the curve at the second point R. - - reflect the point R across the x-axis the same way to get point 2P + - draw a tangent line through $P$ for an elliptic curve. The line will intersect the curve at the second point $R$. + - reflect the point $R$ across the $x$-axis the same way to get point $2P$ - $P = -Q$ - $P + Q = P + (-P) = \mathcal{O}$ — the point on infinity - $Q = \mathcal{O}$ @@ -552,7 +552,7 @@ This section aims to validate the correctness of point inversion: Edge cases: - Point not from $G_1$ -- -$\mathcal{O}$ +- $-\mathcal{O}$ Tests for incorrect data From 5401f53bc76f8277149238c5ca5346b2744294e2 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 12 Dec 2023 10:59:57 +0200 Subject: [PATCH 144/163] fix tests list --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b359a68d7..f28b43dbb 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -560,7 +560,7 @@ This section aims to validate the handling of incorrect input data: - Incorrect input length. - Incorrect sign value (not 0 or 1). -- Erroneous coding of field elements, resulting in a correct point on the curve if only the suffix is considered. +- Erroneous coding of field elements: one of the first three bits set up incorrectly. - Erroneous coding of field elements resulting in a correct element on the curve modulo p. - Erroneous coding of field elements with an incorrect extra bit in the decompressed encoding. - Point not on the curve. From b279616b3fe9916fba6c23c3e10b0c1e149b4423 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 12 Dec 2023 11:30:08 +0200 Subject: [PATCH 145/163] fix functions description --- neps/nep-0488.md | 58 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index f28b43dbb..047d0c043 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -36,29 +36,29 @@ we must efficiently verify BLS signatures based on BLS12-381, as these are the s In this NEP, we propose to add the following host functions: -- ***bls12381_g1_sum —*** computes the sum of signed points from $G_1$ on an elliptic curve. This function is useful for aggregating public keys in the BLS signature scheme. It can be employed for simple addition in $G_1$. It is kept separate from the `multiexp` function due to gas cost considerations. -- ***bls12381_g2_sum —*** computes the sum of signed points from $G_2$ on an elliptic curve. This function is useful for aggregating signatures in the BLS signature scheme. -- ***bls12381_g1_multiexp —*** calculates $\sum g_i s_i$ for points $g_i \in G_1$ and scalars $s_i$. This operation can be used to multiply a group element by a scalar. -- ***bls12381_g2_multiexp —*** calculates $\sum g_i s_i$ for points $g_i \in G_2$ and scalars $s_i$. +- ***bls12381_p1_sum —*** computes the sum of signed points from $E(F_p)$ elliptic curve. This function is useful for aggregating public keys in the BLS signature scheme. It can be employed for simple addition in $E(F_p)$. It is kept separate from the `multiexp` function due to gas cost considerations. +- ***bls12381_p2_sum —*** computes the sum of signed points from $E'(F_{p^2})$ elliptic curve. This function is useful for aggregating signatures in the BLS signature scheme. +- ***bls12381_p1_multiexp —*** calculates $\sum g_i s_i$ for points $g_i \in E(F_p)$ and scalars $s_i$. This operation can be used to multiply a group element by a scalar. +- ***bls12381_p2_multiexp —*** calculates $\sum g_i s_i$ for points $g_i \in E'(F_{p^2})$ and scalars $s_i$. - ***bls12381_map_fp_to_g1 —*** maps base field elements into $G_1$ points. It does not perform the mapping of byte strings into field elements. - ***bls12381_map_fp2_to_g2 —*** maps extension field elements into $G_2$ points. This function does not perform the mapping of byte strings into extension field elements, which would be needed to efficiently map a message into a group element. We are not implementing the `hash_to_field`[^60] function because the latter can be executed within a contract and various hashing algorithms can be used within this function. -- ***bls12381_decompress_g1 —*** decompresses points from $G_1$ provided in a compressed form. Certain protocols offer points on the curve in a compressed form (e.g., the light client updates in Ethereum 2.0), and decompression is a time-consuming operation. All the other functions in this NEP only accept decompressed points for simplicity and optimized gas consumption. -- ***bls12381_decompress_g2 —*** decompresses points from $G_2$ provided in a compressed form. +- ***bls12381_p1_decompress —*** decompresses points from $E(F_p)$ provided in a compressed form. Certain protocols offer points on the curve in a compressed form (e.g., the light client updates in Ethereum 2.0), and decompression is a time-consuming operation. All the other functions in this NEP only accept decompressed points for simplicity and optimized gas consumption. +- ***bls12381_p2_decompress —*** decompresses points from $E'(F_{p^2})$ provided in a compressed form. - ***bls12381_pairing_check —*** verifies 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$. This function is used to verify BLS signatures or zkSNARKs. Functions required for verifying BLS signatures[^59]: -- bls12381_g1_sum -- bls12381_g2_sum +- bls12381_p1_sum +- bls12381_p2_sum - bls12381_map_fp2_to_g2 -- bls12381_decompress_g1 -- bls12381_decompress_g2 +- bls12381_p1_decompress +- bls12381_p2_decompress - bls12381_pairing_check Functions required for verifying zkSNARKs: -- bls12381_g1_sum -- bls12381_g1_multiexp +- bls12381_p1_sum +- bls12381_p1_multiexp - bls12381_pairing_check Both zkSNARKs and BLS signatures can be implemented alternatively by swapping $G_1$ and $G_2$. @@ -495,7 +495,7 @@ The encoding rules for curve points and field elements align with the standards ### Host functions -#### bls12381_g1_sum +#### bls12381_p1_sum ***Description:*** @@ -585,13 +585,13 @@ Edge cases: ***Annotation:*** ```rust -pub fn bls12381_g1_sum(&mut self, +pub fn bls12381_p1_sum(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; ``` -#### bls12381_g2_sum +#### bls12381_p2_sum ***Description:*** @@ -620,18 +620,18 @@ The ERROR_CODE is returned. ***Test cases:*** -The test cases are identical to those of `bls12381_g1_sum`, with the only alteration being the substitution of points from $G_1$ and $E(F_p)$ with points from $G_2$ and $E'(F_{p^2})$. +The test cases are identical to those of `bls12381_p1_sum`, with the only alteration being the substitution of points from $G_1$ and $E(F_p)$ with points from $G_2$ and $E'(F_{p^2})$. ***Annotation:*** ```rust -pub fn bls12381_g2_sum(&mut self, +pub fn bls12381_p2_sum(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; ``` -#### ***bls12381_g1_multiexp*** +#### ***bls12381_p1_multiexp*** ***Description:*** @@ -686,7 +686,7 @@ Edge cases: Tests for sum of two points -These are identical test cases to those in the `bls12381_g1_sum` section. +These are identical test cases to those in the `bls12381_p1_sum` section. - Generate random points P and Q, then compare the results with the sum function. @@ -706,12 +706,12 @@ These are identical test cases to those in the `bls12381_g1_sum` section. Tests for error cases -The same test cases as those in the `bls12381_g1_sum` section will be applied. +The same test cases as those in the `bls12381_p1_sum` section will be applied. ***Annotation:*** ```rust -pub fn bls12381_g1_multiexp( +pub fn bls12381_p1_multiexp( &mut self, value_len: u64, value_ptr: u64, @@ -719,7 +719,7 @@ pub fn bls12381_g1_multiexp( ) -> Result; ``` -#### ***bls12381_g2_multiexp*** +#### ***bls12381_p2_multiexp*** ***Description:*** @@ -755,12 +755,12 @@ The ERROR_CODE is returned. ***Test cases:*** -The test cases are identical to those for `bls12381_g1_multiexp`, except that the points from $G_1$ and $E(F_p)$ are replaced with points from $G_2$ and $E'(F_{p^2})$ +The test cases are identical to those for `bls12381_p1_multiexp`, except that the points from $G_1$ and $E(F_p)$ are replaced with points from $G_2$ and $E'(F_{p^2})$ ***Annotation:*** ```rust -pub fn bls12381_g2_multiexp( +pub fn bls12381_p2_multiexp( &mut self, value_len: u64, value_ptr: u64, @@ -978,7 +978,7 @@ pub fn bls12381_pairing_check(&mut self, register_id: u64) -> Result; ``` -#### bls12381_decompress_g1 +#### bls12381_p1_decompress ***Description:*** The function decompresses compressed points from $E(F_p)$. It takes an arbitrary number of points $p_i \in E(F_p)$ in compressed format as input and outputs the same number of points from $E(F_p)$ in decompressed format. Further details about the decompressed and compressed formats are available in the Curve Points Encoding section. @@ -1024,13 +1024,13 @@ The ERROR_CODE is returned. ***Annotation:*** ```rust -pub fn bls12381_decompress_g1(&mut self, +pub fn bls12381_p1_decompress(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; ``` -#### bls12381_decompress_g2 +#### bls12381_p2_decompress ***Description:*** The function decompresses compressed points from $E'(F_{p^2})$. It takes an arbitrary number of points $p_i \in E'(F_{p^2})$ in compressed format as input and outputs the same number of points from $E'(F_{p^2})$ in decompressed format. For more information about the decompressed and compressed formats, refer to the Curve Points Encoding section. @@ -1048,12 +1048,12 @@ The ERROR_CODE is returned. ***Test cases:*** -The same test cases as `bls12381_decompress_g1`, but with points from $G_2$, and the input length should be divisible by 96. +The same test cases as `bls12381_p1_decompress`, but with points from $G_2$, and the input length should be divisible by 96. ***Annotation:*** ```rust -pub fn bls12381_decompress_g2(&mut self, +pub fn bls12381_p2_decompress(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; From b9392075b467469e1b1cd80f21ff173020961aba Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 12 Dec 2023 12:14:07 +0200 Subject: [PATCH 146/163] minor fixes --- neps/nep-0488.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 047d0c043..088e807e7 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -36,10 +36,10 @@ we must efficiently verify BLS signatures based on BLS12-381, as these are the s In this NEP, we propose to add the following host functions: -- ***bls12381_p1_sum —*** computes the sum of signed points from $E(F_p)$ elliptic curve. This function is useful for aggregating public keys in the BLS signature scheme. It can be employed for simple addition in $E(F_p)$. It is kept separate from the `multiexp` function due to gas cost considerations. -- ***bls12381_p2_sum —*** computes the sum of signed points from $E'(F_{p^2})$ elliptic curve. This function is useful for aggregating signatures in the BLS signature scheme. -- ***bls12381_p1_multiexp —*** calculates $\sum g_i s_i$ for points $g_i \in E(F_p)$ and scalars $s_i$. This operation can be used to multiply a group element by a scalar. -- ***bls12381_p2_multiexp —*** calculates $\sum g_i s_i$ for points $g_i \in E'(F_{p^2})$ and scalars $s_i$. +- ***bls12381_p1_sum —*** computes the sum of signed points from $E(F_p)$ elliptic curve. This function is useful for aggregating public keys or signatures in the BLS signature scheme. It can be employed for simple addition in $E(F_p)$. It is kept separate from the `multiexp` function due to gas cost considerations. +- ***bls12381_p2_sum —*** computes the sum of signed points from $E'(F_{p^2})$ elliptic curve. This function is useful for aggregating signatures or public keys in the BLS signature scheme. +- ***bls12381_p1_multiexp —*** calculates $\sum p_i s_i$ for points $p_i \in E(F_p)$ and scalars $s_i$. This operation can be used to multiply a group element by a scalar. +- ***bls12381_p2_multiexp —*** calculates $\sum p_i s_i$ for points $p_i \in E'(F_{p^2})$ and scalars $s_i$. - ***bls12381_map_fp_to_g1 —*** maps base field elements into $G_1$ points. It does not perform the mapping of byte strings into field elements. - ***bls12381_map_fp2_to_g2 —*** maps extension field elements into $G_2$ points. This function does not perform the mapping of byte strings into extension field elements, which would be needed to efficiently map a message into a group element. We are not implementing the `hash_to_field`[^60] function because the latter can be executed within a contract and various hashing algorithms can be used within this function. - ***bls12381_p1_decompress —*** decompresses points from $E(F_p)$ provided in a compressed form. Certain protocols offer points on the curve in a compressed form (e.g., the light client updates in Ethereum 2.0), and decompression is a time-consuming operation. All the other functions in this NEP only accept decompressed points for simplicity and optimized gas consumption. From 8453fed5d464661da199f54339a34765f4986a06 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 12 Dec 2023 12:44:05 +0200 Subject: [PATCH 147/163] fix ERROR_CODE encoding --- neps/nep-0488.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 088e807e7..9d315af6e 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -481,13 +481,14 @@ will successfully complete its work but return an ERROR_CODE. This enables users to handle error cases independently. It's important to note that host functions might terminate with an error if it's straightforward to avoid it (e.g., incorrect input size). -The ERROR_CODE is encoded as a little-endian u64 and can hold the following values: +The ERROR_CODE is an u64 and can hold the following values: -- 0: No error, execution was successful. +- 0: No error, execution was successful. For `bls12381_pairing_check` function, the pairing result equals the multiplicative identity. - 1: Execution finished with error due to: - Incorrect encoding (e.g., incorrectly set compression/decompression bit, coordinate >= p, etc.). - A point not on the curve (where applicable). - A point not in the expected subgroup (where applicable). +- 2: Can be returned only in `bls12381_pairing_check`. No error, execution was successful, but the pairing result doesn't equal the multiplicative identity. #### General comments @@ -916,14 +917,12 @@ We don’t need to calculate the pairing function itself as the result would lie The ERROR_CODE is returned. -- ERROR_CODE = 0: the input is correct - - Output: 1 byte with two possible values: 1 if the pairing result equals the multiplicative identity, and 0 otherwise. +- ERROR_CODE = 0: the input is correct, the pairing result equals the multiplicative identity. - ERROR_CODE = 1: - Points encoded incorrectly (refer to the Curve Points Encoded section). - Point not on the curve. - Point not in $G_1/G_2$. - -For an empty input, the function returns ERROR_CODE = 0. +- ERROR_CODE = 2: the input is correct, the pairing result doesn't equal the multiplicative identity. ***Test cases:*** From 60edc7fceadded08640114fa62ebf9c599ab5763 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 15:34:13 +0200 Subject: [PATCH 148/163] non constant time comments --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 9d315af6e..b9e9b4aba 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1122,7 +1122,7 @@ You can find a draft implementation in nearcore, which is based on this library, The implementation's security depends on the chosen library's security, supporting operations with BLS curves. -Within this NEP, a constant execution time for all operations isn't mandated. This isn't an issue when employing host functions for BLS signature/zkSNARKs verification. However, refrain from using these host functions if a constant-time algorithm is necessary. +Within this NEP, a constant execution time for all operations isn't mandated. All the computations executed by smart contract are entirely public anyway, so there would be no advantage to a constant-time algorithm. BLS12-381 offers more security bits compared to the already existing pairing-friendly curve BN254. Consequently, the security of projects requiring a pairing-friendly curve will be enhanced. From d4655c4f3ed7769cc303ec41d609d866d7aac396 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 15:35:18 +0200 Subject: [PATCH 149/163] Fix the library list Co-authored-by: Ekleog-NEAR <96595974+Ekleog-NEAR@users.noreply.github.com> --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b9e9b4aba..b218f52c4 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1112,7 +1112,7 @@ In addition, there are implementations in other languages that are less relevant 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] +6. C++, ***Matter Labs C++ EIP-1962 implementation***[^42] One of the possible libraries to use is the blst library[^30]. This library exhibits good performance[^45] and has undergone several audits[^55]. From 384395bde4ada74c1f242126add3dea29fccaa5a Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 15:36:46 +0200 Subject: [PATCH 150/163] Specify register id Co-authored-by: Ekleog-NEAR <96595974+Ekleog-NEAR@users.noreply.github.com> --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b218f52c4..44029c085 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1061,7 +1061,7 @@ pub fn bls12381_p2_decompress(&mut self, #### General comments for all functions In all functions, the input is fetched from memory, beginning at `value_ptr` and extending to `value_ptr + value_len`. -If `value_len` is `u64::MAX`, input will come from the register. +If `value_len` is `u64::MAX`, input will come from the register with id `value_ptr`. Execution ends only if there's an incorrect input length, input extends beyond memory bounds, or gas limits are reached. From c9dc82ddcbe457d60708a6a94456f3396b5b7e97 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 15:40:09 +0200 Subject: [PATCH 151/163] Fix encoding bits description Co-authored-by: Ekleog-NEAR <96595974+Ekleog-NEAR@users.noreply.github.com> --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 44029c085..a7491818c 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -399,7 +399,7 @@ Elements from $E(F_p)$ in compressed form are encoded as `[u8; 48]`, with big-endian encoded $x \in F_p$. The $y$ coordinate is determined by the formula: $y = \pm \sqrt{x^3 + 4}$. -- The highest bit indicates if the point is encoded in compressed form and should be set to 1. +- The highest bit indicates that the point is encoded in compressed form and thus must always be set to 1. - The second-highest bit marks the point at infinity (if set to 1). - For the point at infinity, all bits except the first two should be set to 0; other encodings should be considered as incorrect. - To represent the sign of $y$, the third-highest bit in the x encoding is utilized. From ebbf76819108b4cf76daf0fbcd99c3915a249373 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 15:45:56 +0200 Subject: [PATCH 152/163] fix reference --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a7491818c..013f6c893 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1207,7 +1207,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^46]: Bench vectors from EIP2537: [https://eips.ethereum.org/assets/eip-2537/bench_vectors](https://eips.ethereum.org/assets/eip-2537/bench_vectors) [^47]: Metter Labs tests for EIP2537: [https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537](https://github.com/matter-labs/eip1962/tree/master/src/test/test_vectors/eip2537) [^48]: Tests from Go Ethereum implementation: [https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles](https://github.com/ethereum/go-ethereum/tree/master/core/vm/testdata/precompiles) -[^51]: draft-irtf-cfrg-pairing-friendly-curves-11 [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-) *(*[https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/bls.md) → [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04) → this ref*)* +[^51]: draft-irtf-cfrg-pairing-friendly-curves-11 [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-) [^52]: Paper with BLS12-381: [https://eprint.iacr.org/2019/403.pdf](https://eprint.iacr.org/2019/403.pdf) [^53]: Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) [^54]: Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 From 83a17d86b22e9e6a443b42a3b7edea70cbfcd6ab Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 16:18:59 +0200 Subject: [PATCH 153/163] remove redundant description --- neps/nep-0488.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 013f6c893..754179d3a 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -365,10 +365,6 @@ Values from $F_p$ are encoded as big-endian [u8; 48]. Only values less than p ar An element $q \in F_{p^{2}}$ can be expressed as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$. An element from $F_{p^2}$ is encoded in [u8; 96] as the byte concatenation of $c_1$ and $c_0$. The encoding for $c_1$ and $c_0$ follows the rule described in the previous section. -The representation of $q \in F_{p^2}$, with $q = c_0 + c_1 v$, is encoded as [u8; 96]: - -- $c_1 \in F_p$ is represented as `[u8; 48]` -- $c_0 \in F_p$ is represented as `[u8; 48]` #### Uncompressed points on curve $E(F_p)$ @@ -376,11 +372,6 @@ Points on the curve are represented by affine coordinates: $(x: F_p, y: F_p)$. Elements from $E(F_p)$ are encoded in `[u8; 96]` as the byte concatenation of the x and y point coordinates, where $x, y \in F_p$. The encoding follows the rules outlined in the section “Fields elements $F_p$”. -$E(F_p)$ is encoded as [u8; 96]: - -- $x \in F_p$ is represented as [u8; 48] -- $y \in F_p$ is represented as [u8; 48] - *The second-highest bit* within the encoding serves to signify a point at infinity. When this bit is set to 1, it designates an infinity point. In this case, all other bits should be set to 0. From 8ebe96e2bd9f5e9a731dbe701507b4760b5726e5 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 17:05:06 +0200 Subject: [PATCH 154/163] move general comments up --- neps/nep-0488.md | 68 ++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 754179d3a..3e6904a99 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -487,6 +487,39 @@ The encoding rules for curve points and field elements align with the standards ### Host functions +#### General comments for all functions + +In all functions, the input is fetched from memory, beginning at `value_ptr` and extending to `value_ptr + value_len`. +If `value_len` is `u64::MAX`, input will come from the register with id `value_ptr`. + +Execution ends only if there's an incorrect input length, +input extends beyond memory bounds, or gas limits are reached. +Otherwise, execution completes successfully, providing the `ERROR_CODE`. + +If the `ERROR_CODE` equals 0, the output data will be written to +the register with the `register_id` identifier. +Otherwise, nothing will be written to the register. + +***Gas Estimation:*** + +The algorithms described above exhibit linear complexity concerning the number of elements. Gas estimation can be calculated using the following formula: + +```rust +let k = input_bytes/item_size +let gas_consumed = A + B * k +``` + +Here, A and B denote empirically calculated constants unique to each algorithm. + +For gas estimation, the benchmark vectors outlined in EIP-2537[^46] can be used where applicable. + +***Error cases (execution is terminated):*** + +For all functions, execution will terminate in the following cases: + +- The input length is not divisible by `item_size`. +- The input is beyond memory bounds. + #### bls12381_p1_sum ***Description:*** @@ -1049,39 +1082,6 @@ pub fn bls12381_p2_decompress(&mut self, register_id: u64) -> Result; ``` -#### General comments for all functions - -In all functions, the input is fetched from memory, beginning at `value_ptr` and extending to `value_ptr + value_len`. -If `value_len` is `u64::MAX`, input will come from the register with id `value_ptr`. - -Execution ends only if there's an incorrect input length, -input extends beyond memory bounds, or gas limits are reached. -Otherwise, execution completes successfully, providing the `ERROR_CODE`. - -If the `ERROR_CODE` equals 0, the output data will be written to -the register with the `register_id` identifier. -Otherwise, nothing will be written to the register. - -***Gas Estimation:*** - -The algorithms described above exhibit linear complexity concerning the number of elements. Gas estimation can be calculated using the following formula: - -```rust -let k = input_bytes/item_size -let gas_consumed = A + B * k -``` - -Here, A and B denote empirically calculated constants unique to each algorithm. - -For gas estimation, the benchmark vectors outlined in EIP-2537[^46] can be used where applicable. - -***Error cases (execution is terminated):*** - -For all functions, execution will terminate in the following cases: - -- The input length is not divisible by `item_size`. -- The input is beyond memory bounds. - ## Reference Implementation Primarily, concerning integration with nearcore, our interest lies in Rust language libraries. The current implementations of BLS12-381 in Rust are: @@ -1201,7 +1201,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^51]: draft-irtf-cfrg-pairing-friendly-curves-11 [https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-11#name-bls-curves-for-the-128-bit-) [^52]: Paper with BLS12-381: [https://eprint.iacr.org/2019/403.pdf](https://eprint.iacr.org/2019/403.pdf) [^53]: Zkcrypto points encoding: [https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md](https://github.com/zkcrypto/pairing/blob/0.14.0/src/bls12_381/README.md) -[^54]: Draft PR for BLS12-381 operations in nearcore: https://github.com/near/nearcore/pull/9317 +[^54]: Draft PR for BLS12-381 operations in nearcore: [https://github.com/near/nearcore/pull/9317](https://github.com/near/nearcore/pull/9317) [^55]: Audit for BLST library: [https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf](https://research.nccgroup.com/wp-content/uploads/2021/01/NCC_Group_EthereumFoundation_ETHF002_Report_2021-01-20_v1.0.pdf) [^58]: hash_to_curve and hash_to_field function: [https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio](https://datatracker.ietf.org/doc/html/rfc9380#name-hash_to_field-implementatio) [^59]: Implementation of BLS-signature based on these host functions: [https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs](https://github.com/olga24912/bls-signature-verificaion-poc/blob/main/src/lib.rs) From f9343c85ae2d5932d95f5ae4d8ac38f4a28ca8e8 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 17:21:36 +0200 Subject: [PATCH 155/163] remove unused register_id in pairing check function --- neps/nep-0488.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 3e6904a99..335314317 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -997,8 +997,7 @@ The ERROR_CODE is returned. ```rust pub fn bls12381_pairing_check(&mut self, value_len: u64, - value_ptr: u64, - register_id: u64) -> Result; + value_ptr: u64) -> Result; ``` #### bls12381_p1_decompress From d508b6fd3976bde6f5da142a7d097a0921161995 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 17:31:01 +0200 Subject: [PATCH 156/163] negative numbers explanation --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 335314317..d9c6591b0 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -394,7 +394,7 @@ The $y$ coordinate is determined by the formula: $y = \pm \sqrt{x^3 + 4}$. - The second-highest bit marks the point at infinity (if set to 1). - For the point at infinity, all bits except the first two should be set to 0; other encodings should be considered as incorrect. - To represent the sign of $y$, the third-highest bit in the x encoding is utilized. - - If the bit is 0, $y$ is positive; if 1, $y$ is negative. We'll consider the number positive by taking the smallest value between $y$ and $-y$. + - If the bit is 0, $y$ is positive; if 1, $y$ is negative. We'll consider the number positive by taking the smallest value between $y$ and $-y$, after reducing them to $[0, p)$. The encoding for $x \in F_p$ as `[u8; 48]` bytes follows the rules described in the section "Extension fields elements $F_{p}$". From a634505e98b74d6e75dac1a23cf362e049185da4 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 17:36:25 +0200 Subject: [PATCH 157/163] comments about positive values --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index d9c6591b0..77432d671 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -442,7 +442,7 @@ The $y$ coordinate is determined using the formula: $y = \pm \sqrt{x^3 + 4(u + 1 - The second-highest bit marks the point at infinity (if set to 1). - For the point at infinity, all bits except the first two should be set to 0; other encodings should be considered as incorrect. - To represent the sign of $y$, the third-highest bit in the x encoding is utilized. - - If the bit is 0, $y$ is positive; if 1, $y$ is negative. We'll consider the number positive by taking the smallest value between $y$ and $-y$: first compare $c_1$, then $c_0$. + - If the bit is 0, $y$ is positive; if 1, $y$ is negative. We'll consider the number positive by taking the smallest value between $y$ and $-y$: first compare $c_1$, then $c_0$, after reduction to $[0, p)$. The encoding of $x \in F_{p^2}$ as [u8; 96] bytes follows the rules from the section “Extension Fields Elements $F_{p^2}$”. From 6f9d3a45b112ca85f7de439c0dcb14c27f055abe Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 21 Dec 2023 18:10:29 +0200 Subject: [PATCH 158/163] simplify pairing description --- neps/nep-0488.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 77432d671..bb24351b6 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -916,16 +916,8 @@ pub fn bls12381_map_fp2_to_g2( ***Description:*** -The pairing function $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{q^{12}}$, exhibits the following properties: - -- $e(P, Q + R) = e(P, Q) \cdot e(P, R)$ -- $e(P + S, R) = e(P, R)\cdot e(S, R)$ - -Consequently: - -$e([a]P, [b]Q) = e(P, Q)^{ab} = e([b]P, [a]Q)$ - -This function is necessary to verify BLS signatures/zkSNARKs. +The pairing function is a bilinear function $e\colon G_1 \times G_2 \rightarrow G_T$, where $G_T \subset F_{q^{12}}$, +which is used to verify BLS signatures/zkSNARKs. This function takes as input the sequence of pairs $(p_i, q_i)$, where $p_i \in G_1 \subset E(F_{p})$ and $q_i \in G_2 \subset E'(F_{p^2})$ and validates: From 177d508ffac4b055eceb00ba47a28117dab2d1fe Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Thu, 28 Dec 2023 13:37:02 +0200 Subject: [PATCH 159/163] general encoding comments --- neps/nep-0488.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index bb24351b6..b3f27fe29 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -348,6 +348,15 @@ under sections 8.8.1[^64] and 8.8.2[^65], respectively. ### Curve points encoding +#### General comments + +The encoding rules for curve points and field elements align with the standards established in zkcrypto[^53] and +the implementation in the milagro lib[^29]. + +For elements from $F_p$ the first three bits will always be $0$, because the first byte of $p$ equals $1$. As a result, +we can use these bits to encode extra information: the encoding format, the point at infinity, and the points' sign. +Read more in sections: Uncompressed/compressed points on curve $E(F_p)$/$E'(F_{p^2})$. + #### Sign The sign of a point on the elliptic curve is represented as a u8 type in Rust, with two possible values: 0 for a positive sign and 1 for a negative sign. Any other u8 value is considered invalid and should be treated as incorrect. @@ -365,7 +374,6 @@ Values from $F_p$ are encoded as big-endian [u8; 48]. Only values less than p ar An element $q \in F_{p^{2}}$ can be expressed as $q = c_0 + c_1 v$, where $c_0, c_1 \in F_p$. An element from $F_{p^2}$ is encoded in [u8; 96] as the byte concatenation of $c_1$ and $c_0$. The encoding for $c_1$ and $c_0$ follows the rule described in the previous section. - #### Uncompressed points on curve $E(F_p)$ Points on the curve are represented by affine coordinates: $(x: F_p, y: F_p)$. @@ -481,10 +489,6 @@ The ERROR_CODE is an u64 and can hold the following values: - A point not in the expected subgroup (where applicable). - 2: Can be returned only in `bls12381_pairing_check`. No error, execution was successful, but the pairing result doesn't equal the multiplicative identity. -#### General comments - -The encoding rules for curve points and field elements align with the standards established in zkcrypto[^53] and the implementation in the milagro lib[^29]. - ### Host functions #### General comments for all functions From ec3e025f6b3fd43e1665d2340bb551b96fc55959 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 14 May 2024 16:26:53 +0300 Subject: [PATCH 160/163] support multiplication and addition only for subgroup --- neps/nep-0488.md | 98 +++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index b3f27fe29..8fed8bb07 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -36,10 +36,10 @@ we must efficiently verify BLS signatures based on BLS12-381, as these are the s In this NEP, we propose to add the following host functions: -- ***bls12381_p1_sum —*** computes the sum of signed points from $E(F_p)$ elliptic curve. This function is useful for aggregating public keys or signatures in the BLS signature scheme. It can be employed for simple addition in $E(F_p)$. It is kept separate from the `multiexp` function due to gas cost considerations. -- ***bls12381_p2_sum —*** computes the sum of signed points from $E'(F_{p^2})$ elliptic curve. This function is useful for aggregating signatures or public keys in the BLS signature scheme. -- ***bls12381_p1_multiexp —*** calculates $\sum p_i s_i$ for points $p_i \in E(F_p)$ and scalars $s_i$. This operation can be used to multiply a group element by a scalar. -- ***bls12381_p2_multiexp —*** calculates $\sum p_i s_i$ for points $p_i \in E'(F_{p^2})$ and scalars $s_i$. +- ***bls12381_g1_sum —*** computes the sum of signed points from $G_1 \subset E(F_p)$. This function is useful for aggregating public keys or signatures in the BLS signature scheme. It can be employed for simple addition in $E(F_p)$. It is kept separate from the `multiexp` function due to gas cost considerations. +- ***bls12381_g2_sum —*** computes the sum of signed points from $G_2 \subset E'(F_{p^2})$. This function is useful for aggregating signatures or public keys in the BLS signature scheme. +- ***bls12381_g1_multiexp —*** calculates $\sum p_i s_i$ for points $p_i \in G_1 \subset E(F_p)$ and scalars $s_i$. This operation can be used to multiply a group element by a scalar. +- ***bls12381_g2_multiexp —*** calculates $\sum p_i s_i$ for points $p_i \in G_2 \subset E'(F_{p^2})$ and scalars $s_i$. - ***bls12381_map_fp_to_g1 —*** maps base field elements into $G_1$ points. It does not perform the mapping of byte strings into field elements. - ***bls12381_map_fp2_to_g2 —*** maps extension field elements into $G_2$ points. This function does not perform the mapping of byte strings into extension field elements, which would be needed to efficiently map a message into a group element. We are not implementing the `hash_to_field`[^60] function because the latter can be executed within a contract and various hashing algorithms can be used within this function. - ***bls12381_p1_decompress —*** decompresses points from $E(F_p)$ provided in a compressed form. Certain protocols offer points on the curve in a compressed form (e.g., the light client updates in Ethereum 2.0), and decompression is a time-consuming operation. All the other functions in this NEP only accept decompressed points for simplicity and optimized gas consumption. @@ -48,8 +48,8 @@ In this NEP, we propose to add the following host functions: Functions required for verifying BLS signatures[^59]: -- bls12381_p1_sum -- bls12381_p2_sum +- bls12381_g1_sum +- bls12381_g2_sum - bls12381_map_fp2_to_g2 - bls12381_p1_decompress - bls12381_p2_decompress @@ -57,8 +57,8 @@ Functions required for verifying BLS signatures[^59]: Functions required for verifying zkSNARKs: -- bls12381_p1_sum -- bls12381_p1_multiexp +- bls12381_g1_sum +- bls12381_g1_multiexp - bls12381_pairing_check Both zkSNARKs and BLS signatures can be implemented alternatively by swapping $G_1$ and $G_2$. @@ -524,29 +524,30 @@ For all functions, execution will terminate in the following cases: - The input length is not divisible by `item_size`. - The input is beyond memory bounds. -#### bls12381_p1_sum +#### bls12381_g1_sum ***Description:*** -The function calculates the sum of signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ represents a point on the elliptic curve, and $s_i \in {0, 1}$ signifies the point's sign. The output is a single point from $E(F_p)$ equivalent to $\sum (-1)^{s_i}p_i$. +The function calculates the sum of signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in G_1 \subset E(F_p)$ represents a point on the elliptic curve, and $s_i \in {0, 1}$ signifies the point's sign. The output is a single point from $G_1 \subset E(F_p)$ equivalent to $\sum (-1)^{s_i}p_i$. -The operations, including the $E(F_p)$ curve, points on the curve, multiplication by -1, and the addition operation, are detailed in the BLS12-381 Curve Specification section. +The operations, including the $E(F_p)$ curve, $G_1$ subgroup, points on the curve, multiplication by -1, and the addition operation, are detailed in the BLS12-381 Curve Specification section. -Note: This function accepts points from the entire curve and is not restricted to points in $G_1$. +Note: This function accepts only points from $G_1$. ***Input:*** -The sequence of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ represents a point and $s_i \in {0, 1}$ denotes the sign. Each point is encoded in decompressed form as $(x\colon F_p, y\colon F_p)$, and the sign is encoded in one byte, taking only two allowed values: 0 or 1. Expect 97*k bytes as input, which are interpreted as byte concatenation of k slices, with each slice representing the point sign and the uncompressed point from $E(F_p)$. Further details are available in the Curve Points Encoding section. +The sequence of pairs $(s_i, p_i)$, where $p_i \in G_1 \subset E(F_p)$ represents a point and $s_i \in {0, 1}$ denotes the sign. Each point is encoded in decompressed form as $(x\colon F_p, y\colon F_p)$, and the sign is encoded in one byte, taking only two allowed values: 0 or 1. Expect 97*k bytes as input, which are interpreted as byte concatenation of k slices, with each slice representing the point sign and the uncompressed point from $E(F_p)$. Further details are available in the Curve Points Encoding section. ***Output:*** The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 96 bytes represent one point $\in E(F_p)$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). + - Output: 96 bytes represent one point $\in G_1 \subset E(F_p)$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - Points or signs are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. + - Point is not from $G_1$ ***Test cases:*** @@ -555,13 +556,12 @@ The ERROR_CODE is returned. This section aims to verify the correctness of summing up two valid elements on the curve: - Utilize points on the curve with known addition results for comparison, such as tests from EIP-2537[^47],[^48]. -- Generate random points on the curve and verify the commutative property: P + Q = Q + P. +- Generate random points on the curve from $G_1$ and verify the commutative property: P + Q = Q + P. - Validate that the sum of random points from $G_1$ remains in $G_1$. -- Generate random points on the curve and use another library to cross-check the results. +- Generate random points on the curve from $G_1$ and use another library to cross-check the results. Edge cases: -- Points not from $G_1$. - $\mathcal{O} + \mathcal{O} = \mathcal{O}$. - $P + \mathcal{O} = \mathcal{O} + P = P$. - $P + (-P) = (-P) + P = \mathcal{O}$. @@ -580,7 +580,6 @@ This section aims to validate the correctness of point inversion: Edge cases: -- Point not from $G_1$ - $-\mathcal{O}$ Tests for incorrect data @@ -593,6 +592,7 @@ This section aims to validate the handling of incorrect input data: - Erroneous coding of field elements resulting in a correct element on the curve modulo p. - Erroneous coding of field elements with an incorrect extra bit in the decompressed encoding. - Point not on the curve. +- Point not from $G_1$. - Incorrect encoding of the point at infinity. - Input is beyond memory bounds. @@ -614,27 +614,27 @@ Edge cases: ***Annotation:*** ```rust -pub fn bls12381_p1_sum(&mut self, +pub fn bls12381_g1_sum(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; ``` -#### bls12381_p2_sum +#### bls12381_g2_sum ***Description:*** -The function computes the sum of the signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ represents a point on the elliptic curve and $s_i \in {0, 1}$ is the point's sign. The output is a single point from $E'(F_{p^2})$ equal to $\sum (-1)^{s_i}p_i$. +The function computes the sum of the signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in G_2 \subset E'(F_{p^2})$ represents a point on the elliptic curve and $s_i \in {0, 1}$ is the point's sign. The output is a single point from $G_2 \subset E'(F_{p^2})$ equal to $\sum (-1)^{s_i}p_i$. -The $E'(F_{p^2})$ curve, the points on the curve, the multiplication by -1, and the addition operation are all defined in the BLS12-381 Curve Specification section. +The $E'(F_{p^2})$ curve, $G_2$ subgroup, the points on the curve, the multiplication by -1, and the addition operation are all defined in the BLS12-381 Curve Specification section. -Note: The function accepts any points on the curve and is not limited to points in $G_2$. +Note: The function accepts only points from $G_2$. ***Input:*** -The sequence of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ represents a sign. +The sequence of pairs $(s_i, p_i)$, where $p_i \in G_2 \subset E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ represents a sign. Each point is encoded in decompressed form as $(x: F_{p^2}, y: F_{p^2})$, and the sign is encoded in one byte. The expected input size is 193*k bytes, interpreted as a byte concatenation of k slices, -each slice representing the point sign alongside the uncompressed point from $E'(F_{p^2})$. +each slice representing the point sign alongside the uncompressed point from $G_2 \subset E'(F_{p^2})$. More details are available in the Curve Points Encoding section. ***Output:*** @@ -642,29 +642,30 @@ More details are available in the Curve Points Encoding section. The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). + - Output: 192 bytes represent one point $\in G_2 \subset E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - Points or signs are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. + - Point is not from $G_2$. ***Test cases:*** -The test cases are identical to those of `bls12381_p1_sum`, with the only alteration being the substitution of points from $G_1$ and $E(F_p)$ with points from $G_2$ and $E'(F_{p^2})$. +The test cases are identical to those of `bls12381_g1_sum`, with the only alteration being the substitution of points from $G_1$ and $E(F_p)$ with points from $G_2$ and $E'(F_{p^2})$. ***Annotation:*** ```rust -pub fn bls12381_p2_sum(&mut self, +pub fn bls12381_g2_sum(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; ``` -#### ***bls12381_p1_multiexp*** +#### ***bls12381_g1_multiexp*** ***Description:*** -The function accepts a list of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ denotes a scalar. It calculates $\sum s_i \cdot p_i$. +The function accepts a list of pairs $(p_i, s_i)$, where $p_i \in G_1 \subset E(F_p)$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ denotes a scalar. It calculates $\sum s_i \cdot p_i$. The scalar multiplication operation signifies the addition of that point a scalar number of times: @@ -672,25 +673,26 @@ $$ s \cdot p = \underbrace{p + p + \ldots + p}_{s} $$ -The $E(F_p)$ curve, points on the curve, and the addition operation are defined in the BLS12-381 Curve Specification section. +The $E(F_p)$ curve, $G_1$ subgroup, points on the curve, and the addition operation are defined in the BLS12-381 Curve Specification section. Please note: -- The function accepts any points on the curve, not solely from $G_1$. +- The function accepts only points from $G_1$. - The scalar is an arbitrary unsigned integer and can exceed the group order. - To enhance gas efficiency, the Pippenger’s algorithm[^25] can be utilized. -***Input:*** The sequence of pairs $(p_i, s_i)$, where $p_i \in E(F_p)$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ is a scalar. The expected input size is 128*k bytes, interpreted as byte concatenation of k slices. Each slice comprises the concatenation of an uncompressed point from $E(F_p)$— 96 bytes, along with a scalar— 32 bytes. Further details are available in the Curve Points Encoding section. +***Input:*** The sequence of pairs $(p_i, s_i)$, where $p_i \in G_1 \subset E(F_p)$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ is a scalar. The expected input size is 128*k bytes, interpreted as byte concatenation of k slices. Each slice comprises the concatenation of an uncompressed point from $G_1 \subset E(F_p)$— 96 bytes, along with a scalar— 32 bytes. Further details are available in the Curve Points Encoding section. ***Output:*** The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 96 bytes represent one point $\in E(F_p)$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). + - Output: 96 bytes represent one point $\in G_1 \subset E(F_p)$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - Points are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. + - Point is not from $G_1$ ***Test cases:*** @@ -715,7 +717,7 @@ Edge cases: Tests for sum of two points -These are identical test cases to those in the `bls12381_p1_sum` section. +These are identical test cases to those in the `bls12381_g1_sum` section. - Generate random points P and Q, then compare the results with the sum function. @@ -730,17 +732,18 @@ These are identical test cases to those in the `bls12381_p1_sum` section. - Tests with known answers from EIP-2537[^47],[^48] - Random number of points, scalars, and points: - Check with results from another library. - - Check with raw implementation based on the sum function and the double-and-add algorithm.- Empty input + - Check with raw implementation based on the sum function and the double-and-add algorithm. +- Empty input - Maximum number of scalars and points. Tests for error cases -The same test cases as those in the `bls12381_p1_sum` section will be applied. +The same test cases as those in the `bls12381_g1_sum` section will be applied. ***Annotation:*** ```rust -pub fn bls12381_p1_multiexp( +pub fn bls12381_g1_multiexp( &mut self, value_len: u64, value_ptr: u64, @@ -748,11 +751,11 @@ pub fn bls12381_p1_multiexp( ) -> Result; ``` -#### ***bls12381_p2_multiexp*** +#### ***bls12381_g2_multiexp*** ***Description:*** -The function takes a list of pairs $(p_i, s_i)$ as input, where $p_i \in E'(F_{p^2})$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ denotes a scalar. The function computes $\sum s_i \cdot p_i$. +The function takes a list of pairs $(p_i, s_i)$ as input, where $p_i \in G_2 \subset E'(F_{p^2})$ represents a point on the curve, and $s_i \in \mathbb{N}_0$ denotes a scalar. The function computes $\sum s_i \cdot p_i$. This scalar multiplication operation involves adding the point $p$ to itself a specified number of times: @@ -760,36 +763,37 @@ $$ s \cdot p = \underbrace{p + p + \ldots + p}_{s} $$ -The $E'(F_{p^2})$ curve, points on the curve, and the addition operation are defined in the BLS12-381 Curve Specification section. +The $E'(F_{p^2})$ curve, $G_2$ subgroup, points on the curve, and the addition operation are defined in the BLS12-381 Curve Specification section. Please note: -- The function accepts any points on the curve, not solely from $G_2$. +- The function accepts only points from $G_2$. - The scalar is an arbitrary unsigned integer and can exceed the group order. - To enhance gas efficiency, the Pippenger’s algorithm[^25] can be utilized. -***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. +***Input:*** the sequence of pairs $(p_i, s_i)$, where $p_i \in G_2 \subset E'(F_{p^2})$ is a point on the curve and $s_i \in \mathbb{N}_0$ is a scalar. -The expected input size is `224*k` bytes, interpreted as the byte concatenation of `k` slices. Each slice is the concatenation of an uncompressed point from $E'(F_{p^2})$ — `192` bytes and a scalar — `32` bytes. More details are in the Curve Points Encoding section. +The expected input size is `224*k` bytes, interpreted as the byte concatenation of `k` slices. Each slice is the concatenation of an uncompressed point from $G_2 \subset E'(F_{p^2})$ — `192` bytes and a scalar — `32` bytes. More details are in the Curve Points Encoding section. ***Output:*** The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). + - Output: 192 bytes represent one point $\in G_2 \subset E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - Points are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. + - Point is not in $G_2$ subgroup. ***Test cases:*** -The test cases are identical to those for `bls12381_p1_multiexp`, except that the points from $G_1$ and $E(F_p)$ are replaced with points from $G_2$ and $E'(F_{p^2})$ +The test cases are identical to those for `bls12381_g1_multiexp`, except that the points from $G_1$ and $E(F_p)$ are replaced with points from $G_2$ and $E'(F_{p^2})$ ***Annotation:*** ```rust -pub fn bls12381_p2_multiexp( +pub fn bls12381_g2_multiexp( &mut self, value_len: u64, value_ptr: u64, From 59c7f7fb286e5dc8ba35ed41a8bf5a0f77002105 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 20 May 2024 18:18:10 +0300 Subject: [PATCH 161/163] fix reference --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 8fed8bb07..076e9d48b 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -1172,7 +1172,7 @@ The previous NEP for supporting BLS signature based on BLS12-381[^26] [^17]: Article about Rainbow Bridge [https://near.org/blog/eth-near-rainbow-bridge](https://near.org/blog/eth-near-rainbow-bridge) [^19]: Intro into zkSNARKs: [https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b](https://media.consensys.net/introduction-to-zksnarks-with-examples-3283b554fc3b) [^20]: Zeropool project: [https://zeropool.network/](https://zeropool.network/) -[^24]: Precompiles on Aurora: [https://doc.aurora.dev/evm/precompiles/](https://doc.aurora.dev/evm/precompiles/) +[^24]: Precompiles on Aurora: [https://doc.aurora.dev/dev-reference/precompiles/](https://doc.aurora.dev/dev-reference/precompiles/) [^25]: Pippenger Algorithm: [https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf](https://github.com/wborgeaud/python-pippenger/blob/master/pippenger.pdf) [^26]: NEP-446 proposal for BLS-signature verification: [https://github.com/nearprotocol/neps/pull/446](https://github.com/nearprotocol/neps/pull/446) [^27]: EIP-1962 EC arithmetic and pairings with runtime definitions: [https://eips.ethereum.org/EIPS/eip-1962](https://eips.ethereum.org/EIPS/eip-1962) From 52f95599df93c2608e1a7304a5b4bc54de5fcaa5 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Mon, 20 May 2024 18:48:50 +0300 Subject: [PATCH 162/163] fix formula representation --- neps/nep-0488.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index 076e9d48b..a01f6b2fe 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -355,7 +355,7 @@ the implementation in the milagro lib[^29]. For elements from $F_p$ the first three bits will always be $0$, because the first byte of $p$ equals $1$. As a result, we can use these bits to encode extra information: the encoding format, the point at infinity, and the points' sign. -Read more in sections: Uncompressed/compressed points on curve $E(F_p)$/$E'(F_{p^2})$. +Read more in sections: Uncompressed/compressed points on curve $E(F_p)$ / $E'(F_{p^2})$. #### Sign From 60ca0053c46c39efb0960d40c08d62a96b308755 Mon Sep 17 00:00:00 2001 From: Olga Kunyavskaya Date: Tue, 21 May 2024 19:57:04 +0300 Subject: [PATCH 163/163] sum for any point, multiexp only for subgroup --- neps/nep-0488.md | 56 ++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/neps/nep-0488.md b/neps/nep-0488.md index a01f6b2fe..71c079923 100644 --- a/neps/nep-0488.md +++ b/neps/nep-0488.md @@ -36,8 +36,8 @@ we must efficiently verify BLS signatures based on BLS12-381, as these are the s In this NEP, we propose to add the following host functions: -- ***bls12381_g1_sum —*** computes the sum of signed points from $G_1 \subset E(F_p)$. This function is useful for aggregating public keys or signatures in the BLS signature scheme. It can be employed for simple addition in $E(F_p)$. It is kept separate from the `multiexp` function due to gas cost considerations. -- ***bls12381_g2_sum —*** computes the sum of signed points from $G_2 \subset E'(F_{p^2})$. This function is useful for aggregating signatures or public keys in the BLS signature scheme. +- ***bls12381_p1_sum —*** computes the sum of signed points from $E(F_p)$ elliptic curve. This function is useful for aggregating public keys or signatures in the BLS signature scheme. It can be employed for simple addition in $E(F_p)$. It is kept separate from the `multiexp` function due to gas cost considerations. +- ***bls12381_p2_sum —*** computes the sum of signed points from $E'(F_{p^2})$ elliptic curve. This function is useful for aggregating signatures or public keys in the BLS signature scheme. - ***bls12381_g1_multiexp —*** calculates $\sum p_i s_i$ for points $p_i \in G_1 \subset E(F_p)$ and scalars $s_i$. This operation can be used to multiply a group element by a scalar. - ***bls12381_g2_multiexp —*** calculates $\sum p_i s_i$ for points $p_i \in G_2 \subset E'(F_{p^2})$ and scalars $s_i$. - ***bls12381_map_fp_to_g1 —*** maps base field elements into $G_1$ points. It does not perform the mapping of byte strings into field elements. @@ -48,8 +48,8 @@ In this NEP, we propose to add the following host functions: Functions required for verifying BLS signatures[^59]: -- bls12381_g1_sum -- bls12381_g2_sum +- bls12381_p1_sum +- bls12381_p2_sum - bls12381_map_fp2_to_g2 - bls12381_p1_decompress - bls12381_p2_decompress @@ -57,7 +57,7 @@ Functions required for verifying BLS signatures[^59]: Functions required for verifying zkSNARKs: -- bls12381_g1_sum +- bls12381_p1_sum - bls12381_g1_multiexp - bls12381_pairing_check @@ -524,30 +524,29 @@ For all functions, execution will terminate in the following cases: - The input length is not divisible by `item_size`. - The input is beyond memory bounds. -#### bls12381_g1_sum +#### bls12381_p1_sum ***Description:*** -The function calculates the sum of signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in G_1 \subset E(F_p)$ represents a point on the elliptic curve, and $s_i \in {0, 1}$ signifies the point's sign. The output is a single point from $G_1 \subset E(F_p)$ equivalent to $\sum (-1)^{s_i}p_i$. +The function calculates the sum of signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ represents a point on the elliptic curve, and $s_i \in {0, 1}$ signifies the point's sign. The output is a single point from $E(F_p)$ equivalent to $\sum (-1)^{s_i}p_i$. -The operations, including the $E(F_p)$ curve, $G_1$ subgroup, points on the curve, multiplication by -1, and the addition operation, are detailed in the BLS12-381 Curve Specification section. +The operations, including the $E(F_p)$ curve, points on the curve, multiplication by -1, and the addition operation, are detailed in the BLS12-381 Curve Specification section. -Note: This function accepts only points from $G_1$. +Note: This function accepts points from the entire curve and is not restricted to points in $G_1$. ***Input:*** -The sequence of pairs $(s_i, p_i)$, where $p_i \in G_1 \subset E(F_p)$ represents a point and $s_i \in {0, 1}$ denotes the sign. Each point is encoded in decompressed form as $(x\colon F_p, y\colon F_p)$, and the sign is encoded in one byte, taking only two allowed values: 0 or 1. Expect 97*k bytes as input, which are interpreted as byte concatenation of k slices, with each slice representing the point sign and the uncompressed point from $E(F_p)$. Further details are available in the Curve Points Encoding section. +The sequence of pairs $(s_i, p_i)$, where $p_i \in E(F_p)$ represents a point and $s_i \in {0, 1}$ denotes the sign. Each point is encoded in decompressed form as $(x\colon F_p, y\colon F_p)$, and the sign is encoded in one byte, taking only two allowed values: 0 or 1. Expect 97*k bytes as input, which are interpreted as byte concatenation of k slices, with each slice representing the point sign and the uncompressed point from $E(F_p)$. Further details are available in the Curve Points Encoding section. ***Output:*** The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 96 bytes represent one point $\in G_1 \subset E(F_p)$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). + - Output: 96 bytes represent one point $\in E(F_p)$ in its decompressed form. In case of an empty input, it outputs a point on infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - Points or signs are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. - - Point is not from $G_1$ ***Test cases:*** @@ -556,12 +555,13 @@ The ERROR_CODE is returned. This section aims to verify the correctness of summing up two valid elements on the curve: - Utilize points on the curve with known addition results for comparison, such as tests from EIP-2537[^47],[^48]. -- Generate random points on the curve from $G_1$ and verify the commutative property: P + Q = Q + P. +- Generate random points on the curve and verify the commutative property: P + Q = Q + P. - Validate that the sum of random points from $G_1$ remains in $G_1$. -- Generate random points on the curve from $G_1$ and use another library to cross-check the results. +- Generate random points on the curve and use another library to cross-check the results. Edge cases: +- Points not from $G_1$. - $\mathcal{O} + \mathcal{O} = \mathcal{O}$. - $P + \mathcal{O} = \mathcal{O} + P = P$. - $P + (-P) = (-P) + P = \mathcal{O}$. @@ -580,6 +580,7 @@ This section aims to validate the correctness of point inversion: Edge cases: +- Points not from $G_1$. - $-\mathcal{O}$ Tests for incorrect data @@ -592,7 +593,6 @@ This section aims to validate the handling of incorrect input data: - Erroneous coding of field elements resulting in a correct element on the curve modulo p. - Erroneous coding of field elements with an incorrect extra bit in the decompressed encoding. - Point not on the curve. -- Point not from $G_1$. - Incorrect encoding of the point at infinity. - Input is beyond memory bounds. @@ -614,27 +614,27 @@ Edge cases: ***Annotation:*** ```rust -pub fn bls12381_g1_sum(&mut self, +pub fn bls12381_p1_sum(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; ``` -#### bls12381_g2_sum +#### bls12381_p2_sum ***Description:*** -The function computes the sum of the signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in G_2 \subset E'(F_{p^2})$ represents a point on the elliptic curve and $s_i \in {0, 1}$ is the point's sign. The output is a single point from $G_2 \subset E'(F_{p^2})$ equal to $\sum (-1)^{s_i}p_i$. +The function computes the sum of the signed elements on the BLS12-381 curve. It accepts an arbitrary number of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ represents a point on the elliptic curve and $s_i \in {0, 1}$ is the point's sign. The output is a single point from $E'(F_{p^2})$ equal to $\sum (-1)^{s_i}p_i$. -The $E'(F_{p^2})$ curve, $G_2$ subgroup, the points on the curve, the multiplication by -1, and the addition operation are all defined in the BLS12-381 Curve Specification section. +The $E'(F_{p^2})$ curve, the points on the curve, the multiplication by -1, and the addition operation are all defined in the BLS12-381 Curve Specification section. -Note: The function accepts only points from $G_2$. +Note: The function accepts any points on the curve and is not limited to points in $G_2$. ***Input:*** -The sequence of pairs $(s_i, p_i)$, where $p_i \in G_2 \subset E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ represents a sign. +The sequence of pairs $(s_i, p_i)$, where $p_i \in E'(F_{p^2})$ is point and $s_i \in \textbraceleft 0, 1 \textbraceright$ represents a sign. Each point is encoded in decompressed form as $(x: F_{p^2}, y: F_{p^2})$, and the sign is encoded in one byte. The expected input size is 193*k bytes, interpreted as a byte concatenation of k slices, -each slice representing the point sign alongside the uncompressed point from $G_2 \subset E'(F_{p^2})$. +each slice representing the point sign alongside the uncompressed point from $E'(F_{p^2})$. More details are available in the Curve Points Encoding section. ***Output:*** @@ -642,20 +642,19 @@ More details are available in the Curve Points Encoding section. The ERROR_CODE is returned. - ERROR_CODE = 0: the input is correct - - Output: 192 bytes represent one point $\in G_2 \subset E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). + - Output: 192 bytes represent one point $\in E'(F_{p^2})$ in its decompressed form. In case of an empty input, it outputs the point at infinity (refer to the Curve Points Encoding section for more details). - ERROR_CODE = 1: - Points or signs are incorrectly encoded (refer to Curve points encoded section). - Point is not on the curve. - - Point is not from $G_2$. ***Test cases:*** -The test cases are identical to those of `bls12381_g1_sum`, with the only alteration being the substitution of points from $G_1$ and $E(F_p)$ with points from $G_2$ and $E'(F_{p^2})$. +The test cases are identical to those of `bls12381_p1_sum`, with the only alteration being the substitution of points from $G_1$ and $E(F_p)$ with points from $G_2$ and $E'(F_{p^2})$. ***Annotation:*** ```rust -pub fn bls12381_g2_sum(&mut self, +pub fn bls12381_p2_sum(&mut self, value_len: u64, value_ptr: u64, register_id: u64) -> Result; @@ -717,7 +716,7 @@ Edge cases: Tests for sum of two points -These are identical test cases to those in the `bls12381_g1_sum` section. +These are identical test cases to those in the `bls12381_p1_sum` section, but only with points from $G_1$ subgroup. - Generate random points P and Q, then compare the results with the sum function. @@ -738,7 +737,8 @@ These are identical test cases to those in the `bls12381_g1_sum` section. Tests for error cases -The same test cases as those in the `bls12381_g1_sum` section will be applied. +- The same test cases as those in the `bls12381_p1_sum` section. +- Points not from $G_1$. ***Annotation:***