diff --git a/specs/ecc-proof.md b/specs/ecc-proof.md index 83fe10036..b76f1ed68 100644 --- a/specs/ecc-proof.md +++ b/specs/ecc-proof.md @@ -1,52 +1,36 @@ # Ecc Proof -[Elliptic Curve Digital Signature Algorithm]: https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm - -According to the [Elliptic Curve Digital Signature Algorithm] (ECDSA), the signatures `(r,s)` are calculated via ECDSA from `msg_hash` and a `public_key` using the formula - -`(r,s)=ecdsa(msg_hash, public_key)` - -The `public_key` is obtained from `private_key` by mapping the latter to an elliptic curve (EC) point. The `r` is the x-component of an EC point, and the same EC point's y-component will be used to determine the recovery id `v = y%2` (the parity of y). Given the signature `(v, r, s)`, the `public_key` can be recovered from `(v, r, s)` and `msg_hash` using `ecrecover`. - +EccCircuit supports three ECC operations which are addition, multiplication and pairing. This circuit provides the correctness of `EccTable`. ## Circuit behavior -SigTable built inside zkevm-circuits is used to verify signatures. It has the following columns: -- `msg_hash`: Advice Column, the Keccak256 hash of the message that's signed; -- `sig_v`: Advice Column, the recovery id, either 0 or 1, it should be the parity of y; -- `sig_r`: Advice Column, the signature's `r` component; -- `sig_s`: Advice Column, the signature's `s` component; -- `recovered_addr`: Advice Column, the recovered address, i.e. the 20-bytes address that must have signed the message; -- `is_valid`: Advice Column, indicates whether or not the signature is valid or not upon signature verification. +EccTable built inside zkevm-circuits is used to verify ECC operations. It has the following columns: +- `op_type`: Types of ecc operations, `Add`, `Mul` and `Pairing` +- `px`: x-coordinate of point 1 +- `py`: y-coordinate of point 1 +- `qx`: scalar number if `op_type` is `Mul` otherwise it's x-coordinate of point 2 +- `qy`: zero if `op_type` is `Mul` otherwise it's y-coordinate of point 2 +- `outx`: x-coordinate of output +- `outy`: y-coordinate of output +- `is_valid`: Indicates whether the operation is valid or not. Constraints on the shape of the table is like: -| 0 op_type | 1 input_1 | 2 input_2 | 3 output | 4 is_valid | -| --------- | ------------- | ------------- | ------------- | ---------- | -| $tag | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | bool | - -* tag: ADD, MUL and PAIRING +| 0 op_type | 1 px | 2 py | 3 qx | 2 qy | 2 outx | 2 outy | 4 is_valid | +| --------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ---------- | +| $tag | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | bool | -The Sig Circuit aims at proving the correctness of SigTable. This mainly includes the following type of constraints: -- checking that the signature is obtained correctly. This is done by the ECDSA chip, and the correctness of `v` is checked separately; -- checking that `msg_hash` is obtained correctly from Keccak hash function. This is done by lookup to Keccak table; +- tag: `Add`, `Mul` and `Pairing` ## Constraints -`assign_ecdsa` method takes the signature data and uses ECDSA chip to verify its correctness. The verification result `sig_is_valid` will be returned. The recovery id `v` value will be computed and verified. - -`sign_data_decomposition` method takes the signature data and the return values of `assign_ecdsa`, and returns the cells for byte decomposition of the keys and messages in the form of `SignDataDecomposed`. The latter consists of the following contents: -- `SignDataDecomposed` - - `pk_hash_cells`: byte cells for keccak256 hash of public key; - - `msg_hash_cells`: byte cells for `msg_hash`; - - `pk_cells`: byte cells for the EC coordinates of public key; - - `address`: RLC of `pk_hash` last 20 bytes; - - `is_address_zero`: check if address is zero; - - `r_cells`, `s_cells`: byte cells for signatures `r` and `s`. +This mainly includes the following type of constraints: +- Checking `op_type` is one of `Add`, `Mul` or `Pairing`. +- Checking p and q are valid curve points. +- Checking the correctness amon p, q and out. This is done by `ECCVerifyChip`. -The decomposed sign data are sent to `assign_sign_verify` method to compute and verify their RLC values and perform Keccak lookup checks. ## Code -Please refer to `src/zkevm-specs/sig_circuit.py` \ No newline at end of file +Please refer to `src/zkevm-specs/ecc_circuit.py` \ No newline at end of file diff --git a/specs/tables.md b/specs/tables.md index 4109b938e..553420e4e 100644 --- a/specs/tables.md +++ b/specs/tables.md @@ -383,10 +383,10 @@ NOTE: ## Elliptic Curve Table -Proved by the Elliptic Curve circuit. +Proved by the ecc_circuit. The circuit verifies the correctness of ECC operations. -| 0 op_type | 1 input_a | 2 input_b | 3 output | 4 is_valid | -| --------- | ------------- | ------------- | ------------- | ---------- | -| $tag | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | bool | +| 0 op_type | 1 px | 2 py | 3 qx | 2 qy | 2 outx | 2 outy | 4 is_valid | +| --------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ---------- | +| $tag | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | $value{Lo,Hi} | bool | -- **tag**: supports `Add`, `Mul` and `Pairing` +- tag: supports `Add`, `Mul` and `Pairing` diff --git a/src/zkevm_specs/evm_circuit/table.py b/src/zkevm_specs/evm_circuit/table.py index abe3003e3..ee1b39d48 100644 --- a/src/zkevm_specs/evm_circuit/table.py +++ b/src/zkevm_specs/evm_circuit/table.py @@ -555,6 +555,7 @@ class SigTableRow(TableRow): sig_r: Word sig_s: Word recovered_addr: FQ + is_valid: FQ @dataclass(frozen=True) diff --git a/src/zkevm_specs/util/ec.py b/src/zkevm_specs/util/ec.py index be1d93d81..876ee5103 100644 --- a/src/zkevm_specs/util/ec.py +++ b/src/zkevm_specs/util/ec.py @@ -33,10 +33,6 @@ def to_le_bytes(self) -> bytes: def to_be_bytes(self) -> bytes: return self.to_int_value().to_bytes(32, "big") - def add(self, other: WrongFieldInteger) -> int: - # Python will extend the size if it exceeds 32bytes. So, don't need to take care overflow here. - return self.to_int_value() + other.to_int_value() - class Secp256k1BaseField(WrongFieldInteger): """