Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 37 additions & 18 deletions EIPS/eip-2537.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ One should note that base field modulus `p` is equal to `3 mod 4` that allows an

### Fields and Groups

Field Fp is defined as the finite field of size `p` with elements represented as integers between 0 and p-1 (both inclusive).
Field Fp is defined as the finite field of size `p` with elements represented as integers between 0 and p-1 (both inclusive).

Field Fp2 is defined as `Fp[X]/(X^2-nr2)` with elements `el = c0 + c1 * v`, where `v` is the formal square root of `nr2` represented as integer pairs `(c0,c1)`.

Group G1 is defined as a set of Fp pairs (points) `(x,y)` such that either `(x,y)` is `(0,0)` or `x,y` satisfy the curve Fp equation.

Group G2 is defined as a set of Fp2 pairs (points) `(x',y')` such that either `(x,y)` is `(0,0)` or `(x',y')` satisfy the curve Fp2 equation.
Expand Down Expand Up @@ -138,17 +138,22 @@ G1 addition call expects `256` bytes as an input that is interpreted as byte con
Error cases:

- Invalid coordinate encoding
- Either of points not in G1 (i.e. neither on a curve nor the infinity point)
- An input is neither a point on the G1 elliptic curve nor the infinity point
- Input has invalid length

Note:

There is no subgroup check for the G1 addition precompile.

#### ABI for G1 multiplication

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

Error cases:

- Invalid coordinate encoding
- The point not in G1 (i.e. neither on a curve nor the infinity point)
- An input is neither a point on the G1 elliptic curve nor the infinity point
- An input is on the G1 elliptic curve but not in the correct subgroup
- Input has invalid length

#### ABI for G1 MSM
Expand All @@ -158,8 +163,9 @@ G1 MSM call expects `160*k` (`k` being a **positive** integer) bytes as an input
Error cases:

- Invalid coordinate encoding
- Any point not in G1 (i.e. neither on a curve nor the infinity point)
- Input has invalid length
- An input is neither a point on the G1 elliptic curve nor the infinity point
- An input is on the G1 elliptic curve but not in the correct subgroup
- Input has invalid length

#### ABI for G2 addition

Expand All @@ -168,8 +174,12 @@ G2 addition call expects `512` bytes as an input that is interpreted as byte con
Error cases:

- Invalid coordinate encoding
- Either of points not in G2 (i.e. neither on a curve nor the infinity point)
- Input has invalid length
- An input is neither a point on the G2 elliptic curve nor the infinity point
- Input has invalid length

Note:

There is no subgroup check for the G2 addition precompile.

#### ABI for G2 multiplication

Expand All @@ -178,8 +188,9 @@ G2 multiplication call expects `288` bytes as an input that is interpreted as by
Error cases:

- Invalid coordinate encoding
- Either of points not in G1 (i.e. neither on a curve nor the infinity point)
- Input has invalid length
- An input is neither a point on the G2 elliptic curve nor the infinity point
- An input is on the G2 elliptic curve but not in the correct subgroup
- Input has invalid length


#### ABI for G2 MSM
Expand All @@ -189,8 +200,9 @@ G2 MSM call expects `288*k` (`k` being a **positive** integer) bytes as an input
Error cases:

- Invalid coordinate encoding
- Any point not in G2 (i.e. neither on a curve nor the infinity point)
- Input has invalid length
- An input is neither a point on the G2 elliptic curve nor the infinity point
- An input is on the G2 elliptic curve but not in the correct subgroup
- Input has invalid length

#### ABI for pairing

Expand All @@ -206,9 +218,13 @@ Output is a `32` bytes where first `31` bytes are equal to `0x00` and the last b
Error cases:

- Invalid coordinate encoding
- Any of points being not on the respective curve
- Any of points is not in the correct subgroup
- Input has invalid length
- An input is neither a point on its respective elliptic curve nor the infinity point
- An input is on its respective elliptic curve but not in the correct subgroup
- Input has invalid length

Note:

If any input is the infinity point, pairing result will be 1. Protocols may want to check and reject infinity points prior to calling the precompile.

#### ABI for mapping Fp element to G1 point

Expand All @@ -217,7 +233,7 @@ Field-to-curve call expects `64` bytes as an input that is interpreted as an ele
Error cases:

- Input has invalid length
- Input is not correctly encoded
- Input is not correctly encoded

#### ABI for mapping Fp2 element to G2 point

Expand All @@ -226,7 +242,7 @@ Field-to-curve call expects `128` bytes as an input that is interpreted as a an
Error cases:

- Input has invalid length
- Input is not correctly encoded
- Input is not correctly encoded


### Gas burning on error
Expand Down Expand Up @@ -338,9 +354,12 @@ There are no backward compatibility questions.

### Subgroup checks

A subgroup check **is mandatory** during the pairing call. Implementations *should* use fast subgroup checks: at the time of writing, multiplication gas cost is based on the `double-and-add` multiplication method that has a clear "worst case" (all bits are equal to one). For pairing operations, it is expected that implementations use faster subgroup checks, e.g. by using the wNAF multiplication method for elliptic curves that is ~ `40%` cheaper with windows size equal to 4. (Tested empirically. Savings are due to lower hamming weight of the group order and even lower hamming weight for wNAF. Concretely, subgroup check for both G1 and G2 points in a pair are around `35000` combined).
Scalar multiplications, MSMs and pairings MUST perform a subgroup check.
Implementations SHOULD use the optimized subgroup check method detailed in a dedicated [document](../assets/eip-2537/fast_subgroup_checks.md).

On any input that fail the subgroup check, the precompile MUST return an error.

As endomorphism acceleration requires input on the correct subgroup, implementers MAY use endomorphism acceleration.

### Field to curve mapping

Expand Down
51 changes: 51 additions & 0 deletions assets/eip-2537/fast_subgroup_checks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Fast subgroup checks used by EIP-2537

### Fields and Groups

Field Fp is defined as the finite field of size `p` with elements represented as integers between 0 and p-1 (both inclusive).

Field Fp2 is defined as `Fp[X]/(X^2-nr2)` with elements `el = c0 + c1 * v`, where `v` is the formal square root of `nr2` represented as integer pairs `(c0,c1)`.

Group G1 is defined as a set of Fp pairs (points) `(x,y)` such that either `(x,y)` is `(0,0)` or `x,y` satisfy the curve Fp equation.

Group G2 is defined as a set of Fp2 pairs (points) `(x',y')` such that either `(x,y)` is `(0,0)` or `(x',y')` satisfy the curve Fp2 equation.

## Curve parameters

The set of parameters used by fast subgroup checks:

```
|x| (seed) = 15132376222941642752
x is negative = true
Cube root of unity modulo p - Beta = 793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350
r = 4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437 * v
s = 2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530 + 1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257 * v
```

## Helper function to compute the conjugate over Fp2 - `conjugate`

`conjugate(c0 + c1 * v) := c0 - c1 * v`

## G1 endomorphism - `phi`

The endomorphism `phi` transform the point from `(x,y)` to `(Beta*x,y)` where `Beta` is a precomputed cube root of unity modulo `p` given above in parameters sections:

`phi((x,y)) := (Beta*x,y)`

## G2 endomorphism - `psi`

`psi((x,y)) := (conjugate(x)*r,conjugate(y)*s)`

# The G1 case

Before accepting a point `P` as input that purports to be a member of G1 subject the input to the following endomorphism test: `phi(P) + x^2*P = 0`


# The G2 case

Before accepting a point `P` as input that purports to be a member of G2 subject the input to the following endomorphism test: `psi(P) + x*P = 0`

# Resources

* https://eprint.iacr.org/2021/1130.pdf, sec.4
* https://eprint.iacr.org/2022/352.pdf, sec. 4.2