You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/specs/ISA.md
+7-5Lines changed: 7 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -672,8 +672,7 @@ The elliptic curve extension supports arithmetic over elliptic curves `C` in the
672
672
673
673
We note that
674
674
the definitions of the curve arithmetic operations for short Weierstrass curves do not depend on `C::B`. The VM configuration will specify a list of supported curves. For
675
-
each curve `C` (of either form) there will be associated configuration parameters `C::COORD_SIZE` and `C::BLOCK_SIZE` (
676
-
defined below). The extension operates on address spaces `1` and `2`, meaning all memory cells are constrained to be
675
+
each curve `C` (of either form) there will be associated configuration parameters `C::COORD_SIZE` and `C::BLOCK_SIZE` (defined below). The extension operates on address spaces `1` and `2`, meaning all memory cells are constrained to be
677
676
bytes.
678
677
679
678
An affine curve point `EcPoint(x, y)` is a pair of `x,y` where each element is an array of `C::COORD_SIZE` elements each
@@ -691,6 +690,8 @@ r32_ec_point(a) -> EcPoint {
691
690
}
692
691
```
693
692
693
+
The instructions that have prefix `SW_` perform short Weierstrass curve operations, and those with prefix `TE_` perform twisted Edwards curve operations.
| SW_ADD_NE\<C\>|`a,b,c,1,2`| Set `r32_ec_point(a) = r32_ec_point(b) + r32_ec_point(c)` (curve addition). Assumes that `r32_ec_point(b), r32_ec_point(c)` both lie on the curve and are not the identity point. Further assumes that `r32_ec_point(b).x, r32_ec_point(c).x` are not equal in the coordinate field. |
@@ -706,9 +707,10 @@ The elliptic curve extension defines the following phantom sub-instructions.
| SwHintDecompress | 0x40 |`a,b,c_upper`| Uses `c_upper = C::IDX` to determine the index of the curve `C`, from the list of enabled curves. Assumes the `C::IDX`th curve is a short Weierstrass curve. Read from memory `x = [r32{0}(a): C::COORD_SIZE]_2` for an element in the coordinate field of `C`. Let `rec_id = [r32{0}(b)]_2` be a byte in memory for the recovery id, where the lowest bit is 1 if and only if the `y` coordinate of the corresponding point is odd. If there exists a unique `y` such that `(x, y)` is a point on `C` and `y` has the same parity as `rec_id`, then the sub-instruction resets the hint stream to `[1, 0, 0, 0]` followed by `y: [_; C::COORD_SIZE]`. Otherwise, it resets the hint stream to `[0, 0, 0, 0]` followed by `sqrt: [_; C::COORD_SIZE]` where `sqrt * sqrt == (x^3 + ax + b) * non_qr` (`non_qr` is a quadratic nonresidue of `C::Fp`). |
710
-
| TeHintDecompress | 0x40 |`a,b,c_upper`| Uses `c_upper = C::IDX` to determine the index of the curve `C`, from the list of enabled curves. Assumes the `C::IDX`th curve is a twisted Edwards curve. Read from memory `y = [r32{0}(a): C::COORD_SIZE]_2` for an element in the coordinate field of `C`. Let `rec_id = [r32{0}(b)]_2` be a byte in memory for the recovery id, where the lowest bit is 1 if and only if the `x` coordinate of the corresponding point is odd. If there exists a unique `x` such that `(x, y)` is a point on `C` and `x` has the same parity as `rec_id`, then the sub-instruction resets the hint stream to `[1, 0, 0, 0]` followed by `x: [_; C::COORD_SIZE]`. Otherwise, TODO |
711
-
| HintNonQr | 0x41 |`_,_,c_upper`| Reset the hint stream to equal `non_qr: [_; C::COORD_SIZE]` where `non_qr` is a quadratic nonresidue of `C::Fp`. |
710
+
| SwHintDecompress | 0x40 |`a,b,c_upper`| Use `c_upper = C::IDX` to determine the index of the curve `C`, from the list of enabled short Weierstrass curves. Read from memory `x = [r32{0}(a): C::COORD_SIZE]_2` for an element in the coordinate field of `C`. Let `rec_id = [r32{0}(b)]_2` be a byte in memory for the recovery id, where the lowest bit is 1 if and only if the `y` coordinate of the corresponding point is odd. If there exists a unique `y` such that `(x, y)` is a point on `C` and `y` has the same parity as `rec_id`, then the sub-instruction resets the hint stream to `[1, 0, 0, 0]` followed by `y: [_; C::COORD_SIZE]`. Otherwise, it resets the hint stream to `[0, 0, 0, 0]` followed by `sqrt: [_; C::COORD_SIZE]` where `sqrt * sqrt == (x^3 + ax + b) * non_qr` where `non_qr` is a quadratic nonresidue of `C::Fp` that is fixed for the curve. |
711
+
| SwHintNonQr | 0x41 |`_,_,c_upper`| Reset the hint stream to equal `non_qr: [_; C::COORD_SIZE]` where `non_qr` is a quadratic nonresidue of `C::Fp`. This element is fixed for the curve during VM instantiation so multiple calls to this instruction will always return the same hint. |
712
+
| TeHintDecompress | 0x42 |`a,b,c_upper`| Use `c_upper = C::IDX` to determine the index of the curve `C`, from the list of enabled twisted Edwards curves. Read from memory `y = [r32{0}(a): C::COORD_SIZE]_2` for an element in the coordinate field of `C`. Let `rec_id = [r32{0}(b)]_2` be a byte in memory for the recovery id, where the lowest bit is 1 if and only if the `x` coordinate of the corresponding point is odd. If there exists a unique `x` such that `(x, y)` is a point on `C` and `x` has the same parity as `rec_id`, then the sub-instruction resets the hint stream to `[1, 0, 0, 0]` followed by `x: [_; C::COORD_SIZE]`. Otherwise, it resets the hint stream to `[0, 0, 0, 0]` followed by `sqrt: [_; C::COORD_SIZE]` where `sqrt * sqrt = (y^2 - 1) / (C::D * y^2 - C::A) * non_qr` where `non_qr` is a quadratic nonresidue of `C::Fp` that is fixed for the curve. |
713
+
| TeHintNonQr | 0x43 |`_,_,c_upper`| Reset the hint stream to equal `non_qr: [_; C::COORD_SIZE]` where `non_qr` is a quadratic nonresidue of `C::Fp`. This element is fixed for the curve during VM instantiation so multiple calls to this instruction will always return the same hint. |
Copy file name to clipboardExpand all lines: docs/specs/RISCV.md
+6-5Lines changed: 6 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -163,18 +163,19 @@ Complex extension field arithmetic over `Fp2` depends on `Fp` where `-1` is not
163
163
164
164
## Elliptic Curve Extension
165
165
166
-
The elliptic curve extension supports arithmetic over short Weierstrass curves and twisted Edwards curves, which requires specification of the elliptic curve `C`. The extension must be configured to support a fixed ordered list of supported curves. There is one list for each type of curves (short Weierstrass and twisted Edwards). We use `config.curve_idx(C)` to denote the index of `C` in the appropriate list. In the list below, `idx` denotes `config.curve_idx(C)`.
166
+
The elliptic curve extension supports arithmetic over short Weierstrass curves and twisted Edwards curves, which requires specification of the elliptic curve `C`. The extension must be configured to support two fixed ordered lists of supported curves: one list of short Weierstrass curves and one list of twisted Edwards curves. Instructions prefixed with `sw_` are for short Weierstrass curves and instructions prefixed with `te_` are for twisted Edwards curves. We use `config.curve_idx(C)` to denote the index of `C` in the appropriate list. In the list below, `idx` denotes `config.curve_idx(C)`.
| sw_add_ne\<C\>| R | 0101011 | 001 |`idx*8`|`EcPoint([rd:2*C::COORD_SIZE]_2) = EcPoint([rs1:2*C::COORD_SIZE]_2) + EcPoint([rs2:2*C::COORD_SIZE]_2)`. Assumes that input affine points are not identity and do not have same x-coordinate. |
171
171
| sw_double\<C\>| R | 0101011 | 001 |`idx*8+1`|`EcPoint([rd:2*C::COORD_SIZE]_2) = 2 * EcPoint([rs1:2*C::COORD_SIZE]_2)`. Assumes that input affine point is not identity. `rs2` is unused and must be set to `x0`. |
172
172
| sw_setup\<C\>| R | 0101011 | 001 |`idx*8+2`|`assert([rs1: 2*C::COORD_SIZE]_2 == [C::MODULUS, CURVE_A])` in the chip defined by the register index of `rs2`. For the sake of implementation convenience it also writes an unconstrained value into `[rd: 2*C::COORD_SIZE]_2`. If `ind(rs2) != 0`, then this instruction is setup for `sw_add_ne`. Otherwise it is setup for `sw_double`. When `ind(rs2) != 0` (add_ne), it is required for proper functionality that `[rs2: C::COORD_SIZE]_2 != [rs1: C::COORD_SIZE]_2`; otherwise (double), it is required that `[rs1 + C::COORD_SIZE: C::COORD_SIZE]_2 != C::Fp::ZERO`|
173
-
| sw_hint_decompress | R | 0101011 | 001 |`idx*8+3`| Read `x: C::Fp` from `[rs1: C::COORD_SIZE]_2` and `rec_id: u8` from `[rs2]_2`. If there exists a unique `y: C::Fp` such that `(x, y)` is a point on `C` and `y` has the same parity as `rec_id`, then reset the hint stream to `[1u8, 0u8, 0u8, 0u8]` concatenated with the limbs representing `y` in little-endian order; otherwise, reset it to `[0u8; 4]` concatenated the limbs representing `sqrt` where `sqrt * sqrt == (x^3 + ax + b) * non_qr` (`non_qr` is a quadratic nonresidue of `C::Fp`). `rd` should be `x0`. |
173
+
| sw_hint_decompress\<C\>| R | 0101011 | 001 |`idx*8+3`| Read `x: C::Fp` from `[rs1: C::COORD_SIZE]_2` and `rec_id: u8` from `[rs2]_2`. If there exists a unique `y: C::Fp` such that `(x, y)` is a point on `C` and `y` has the same parity as `rec_id`, then reset the hint stream to `[1u8, 0u8, 0u8, 0u8]` concatenated with the limbs representing `y` in little-endian order; otherwise, reset it to `[0u8; 4]` concatenated the limbs representing `sqrt` where `sqrt * sqrt == (x^3 + ax + b) * non_qr` where `non_qr` is a quadratic nonresidue of `C::Fp` that is fixed for the curve. `rd` should be `x0`. |
174
+
| sw_hint_non_qr\<C\>| R | 0101011 | 001 |`idx*8+4`| Reset the hint stream to equal `non_qr` where `non_qr` is a quadratic nonresidue of `C::Fp`. This element is fixed for the curve during VM instantiation so multiple calls to this instruction will always return the same hint. `rd`, `rs1`, and `rs2` should be `x0`. |
| te_setup\<C\>| R | 0101011 | 100 |`idx*8+2`|`assert([rs1: 2*C::COORD_SIZE]_2 == [C::MODULUS, C::CURVE_A] && [rs2: C::COORD_SIZE]_2 == C::CURVE_D])`. For the sake of implementation convenience it also writes an unconstrained value into `[rd: 2*C::COORD_SIZE]_2`. |
176
-
| te_hint_decompress | R | 0101011 | 100 |`idx*8+3`| Read `y: C::Fp` from `[rs1: C::COORD_SIZE]_2` and `rec_id: u8` from `[rs2]_2`. Reset the hint stream to equal the unique `x: C::Fp` such that `(x, y)` is a point on `C` and `x` has the same parity as `rec_id`, if it exists. Otherwise reset hint stream to arbitrary `C::Fp`. `rd` should be `x0`. |
177
-
|hint_non_qr| R | 0101011 |001|`idx*8+4`| Reset the hint stream to equal `non_qr` where `non_qr` is a quadratic nonresidue of `C::Fp`. `rd`, `rs1`, and `rs2` should be `x0`. |
176
+
| te_setup\<C\>| R | 0101011 | 100 |`idx*8+1`|`assert([rs1: 2*C::COORD_SIZE]_2 == [C::MODULUS, C::CURVE_A] && [rs2: C::COORD_SIZE]_2 == C::CURVE_D])`. For the sake of implementation convenience it also writes an unconstrained value into `[rd: 2*C::COORD_SIZE]_2`. |
177
+
| te_hint_decompress\<C\>| R | 0101011 | 100 |`idx*8+2`| Read `y: C::Fp` from `[rs1: C::COORD_SIZE]_2` and `rec_id: u8` from `[rs2]_2`. If there exists a unique `x: C::Fp` such that `(x, y)` is a point on `C` and `x` has the same parity as `rec_id`, then reset the hint stream to `[1u8, 0u8, 0u8, 0u8]` concatenated with the limbs representing `x` in little-endian order; otherwise, reset it to `[0u8; 4]` concatenated the limbs representing `sqrt` where `sqrt * sqrt == (y^2 - 1) / (C::D * y^2 - C::A) * non_qr` where `non_qr` is a quadratic nonresidue of `C::Fp` that is fixed for the curve. `rd` should be `x0`.|
178
+
|te_hint_non_qr\<C\>| R | 0101011 |100|`idx*8+3`| Reset the hint stream to equal `non_qr` where `non_qr` is a quadratic nonresidue of `C::Fp`. This element is fixed for the curve during VM instantiation so multiple calls to this instruction will always return the same hint. `rd`, `rs1`, and `rs2` should be `x0`. |
178
179
179
180
180
181
Since `funct7` is 7-bits, up to 16 curves can be supported simultaneously. We use `idx*8` to leave some room for future expansion.
0 commit comments