Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

Commit

Permalink
doc: ecc_circuit md spec
Browse files Browse the repository at this point in the history
  • Loading branch information
KimiWu123 committed Oct 31, 2023
1 parent 416b5c7 commit 578fdf1
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 44 deletions.
54 changes: 19 additions & 35 deletions specs/ecc-proof.md
Original file line number Diff line number Diff line change
@@ -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`
Please refer to `src/zkevm-specs/ecc_circuit.py`
10 changes: 5 additions & 5 deletions specs/tables.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
1 change: 1 addition & 0 deletions src/zkevm_specs/evm_circuit/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ class SigTableRow(TableRow):
sig_r: Word
sig_s: Word
recovered_addr: FQ
is_valid: FQ


@dataclass(frozen=True)
Expand Down
4 changes: 0 additions & 4 deletions src/zkevm_specs/util/ec.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down

0 comments on commit 578fdf1

Please sign in to comment.