Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/incaberry #310

Merged
merged 22 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5802be4
changes ecrecover to use extra arithmetic features and fix some bugs
zkronos73 Oct 9, 2023
6f4fb20
add some comments and improvements
zkronos73 Oct 9, 2023
6ef49e2
update comments and fix
zkronos73 Oct 9, 2023
69f40c5
updating counters information
zkronos73 Oct 10, 2023
685ecd8
fix typo on checkSqrtFpEc
zkronos73 Oct 10, 2023
d23ded4
update counters stimation ecrecover
zkronos73 Oct 10, 2023
8bdf9c9
gha add ssh key
krlosMata Oct 13, 2023
1c4193f
Merge pull request #35 from 0xPolygonHermez/feature/gha-internal
zkronos73 Oct 13, 2023
8fd2908
add more specific tests
zkronos73 Oct 13, 2023
bf318fb
fix a bug and add more tests
zkronos73 Oct 13, 2023
a6fa3f1
fix bug tests on package.json
zkronos73 Oct 13, 2023
73df4d5
fix typos and adjusts binary counters
zkronos73 Oct 13, 2023
8ceca9a
Merge pull request #36 from 0xPolygonHermez/fix/ecrecover-alias-diffe…
krlosMata Oct 13, 2023
2e4dbe4
update fork id constant
zkronos73 Oct 14, 2023
2d02d2b
update package.json with testvector updated
zkronos73 Oct 16, 2023
70fece7
Merge pull request #39 from 0xPolygonHermez/fix/update-fork-id
krlosMata Oct 16, 2023
e132ff2
add management of point at infinity
zkronos73 Oct 16, 2023
8b43d3e
error on point-at-infinity + comments + fix dual path
zkronos73 Oct 16, 2023
ccb6141
add comments and extra test
zkronos73 Oct 16, 2023
e78c976
add more tests
zkronos73 Oct 20, 2023
994aa21
Merge pull request #42 from 0xPolygonHermez/fix/ecrecover-point-at-in…
krlosMata Oct 31, 2023
f3b6d78
update packages to fork.6
krlosMata Nov 20, 2023
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
2 changes: 1 addition & 1 deletion main/constants.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ CONST %LOCAL_EXIT_ROOT_STORAGE_POS = 1
CONST %LAST_TX_STORAGE_POS = 0
CONST %STATE_ROOT_STORAGE_POS = 1
CONST %MAX_MEM_EXPANSION_BYTES = 0x3fffe0
CONST %FORK_ID = 5
CONST %FORK_ID = 6
CONST %CALLDATA_RESERVED_CTX = 1

; RLP
Expand Down
9 changes: 7 additions & 2 deletions main/ecrecover/addFpEc.zkasm
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; addFpEc C = (A + C) % FpEc
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRE: A,C no alias-free
;; POST: C no alias-free (on MAP)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; RESOURCES:
; 2 ariths + 7 steps

addFpEc:
1 => B
Expand Down
15 changes: 14 additions & 1 deletion main/ecrecover/checkSqrtFpEc.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,21 @@
;; BLOCK: 1 2 3 4 5 6 7
;; (*) 222 + initial initialization
;;
;; return 1 => no sqrts 0 => has solutions
;; PRE: C no alias-free
;; POST: A in [0,1]
;; return A: A = 1 ==> C = -1 ==> hasn't root
;; A = 0 ==> C != -1 ==> has root or MAP, proof fails.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

VAR GLOBAL checkSqrtFpEc_base
VAR GLOBAL checkSqrtFpEc_RR

checkSqrtFpEc:
; RESOURCES:
; 248 x (3 steps + 2 arith + 8 steps + 2 arith + 7 steps) = 992 ariths + 4464 steps
; 6 x (1 step + 2 arith + 8 steps) = 12 ariths + 54 steps
; 6 steps + 1 binary
; TOTAL = 1004 ariths + 1 binary + 4524 steps

RR :MSTORE(checkSqrtFpEc_RR)
C :MSTORE(checkSqrtFpEc_base)
Expand Down Expand Up @@ -1539,7 +1547,12 @@ checkSqrtFpEc:
C => B :CALL(mulFpEc)


; FPEC_MINUS_ONE hasn't alias of 256 bits
C => B
%FPEC_MINUS_ONE => A
$ => RR :MLOAD(checkSqrtFpEc_RR)

; A = 1 ==> C = -1 ==> hasn't root
; A = 0 ==> C != -1 ==> has root or MAP, proof fails.

$ => A :EQ,RETURN
124 changes: 79 additions & 45 deletions main/ecrecover/ecrecover.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ INCLUDE "constEc.zkasm"
; 6 - not exists sqrt of y
; 100 - fail sqrt, but has solution (!!!)

; MAP: MAlicious Prover
;
; RESOURCES:
; PATH without root: 1014 arith + 10 binaries + 4527 steps
; PATH with root: 528 arith + 523 binaries + 6294 steps - 1 keccak
; PATH fail checks: 2 arith + 8 binaries + 45 steps

ecrecover_precompiled:
%FNEC_MINUS_ONE :MSTORE(ecrecover_s_upperlimit),JMP(ecrecover_store_args)

Expand All @@ -45,9 +52,9 @@ ecrecover_store_args:
C :MSTORE(ecrecover_s)
D :MSTORE(ecrecover_v)

; check counters

%MAX_CNT_BINARY - CNT_BINARY - 1600 :JMPN(outOfCountersBinary)

%MAX_CNT_BINARY - CNT_BINARY - 550 :JMPN(outOfCountersBinary)
%MAX_CNT_ARITH - CNT_ARITH - 1100 :JMPN(outOfCountersArith)
%MAX_CNT_STEPS - STEP - 6400 :JMPN(outOfCountersStep)

Expand All @@ -73,9 +80,11 @@ ecrecover_store_args:
$ :EQ,JMPC(ecrecover_s_is_zero)

; compute r inverse
; [steps: 23, bin: 4]
$ => A :MLOAD(ecrecover_r),CALL(invFnEc)
B :MSTORE(ecrecover_r_inv)

; [steps: 37, bin: 6, arith: 2]
0x1Bn => B
$ => A :MLOAD(ecrecover_v)
$ => E :EQ,JMPNC(ecrecover_v_not_eq_1b)
Expand All @@ -85,6 +94,7 @@ ecrecover_store_args:

ecrecover_v_not_eq_1b:
0x1Cn => B
; [steps: 42, bin: 8, arith: 2]
$ => E :EQ,JMPNC(ecrecover_v_not_eq_1b1c)

; ecrecover_v_eq_1c:
Expand All @@ -95,81 +105,100 @@ ecrecover_v_ok:
; y^2 = x^3 + 7
;
; A*B*A + 7 = calculate y from x
;
; [steps: 44, bin: 8, arith: 2]
$ => A,B :MLOAD(ecrecover_r),CALL(mulFpEc)

C => A
$ => B :MLOAD(ecrecover_r),CALL(mulFpEc)

7 => A :CALL(addFpEc)


; load on A parity expected
; [steps: 69, bin: 8, arith: 8]
$ => A :MLOAD(ecrecover_v_parity)
C :MSTORE(ecrecover_y2),CALL(sqrtFpEc)

;; If has root y ** (p-1)/2 = 1, if -1 => no root, not valid signature
; If has root B = 1 else B = 0
; If B = 1 => C is alias-free (see sqrtFpEc)

%FPEC_NON_SQRT => A
C => B
$ => E :EQ,JMPNC(ecrecover_has_sqrt)
; [steps: 85, bin: 9, arith: 10]
B :JMPNZ(ecrecover_has_sqrt)

; hasn't sqrt, now verify

$ => C :MLOAD(ecrecover_y2),CALL(checkSqrtFpEc)
; check must return on A register 1, because the root has no solution

; [steps: 4524, bin: 10, arith: 1014]
1 :ASSERT,JMP(ecrecover_not_exists_sqrt_of_y)

ecrecover_has_sqrt:
; (v == 1b) ecrecover_y_parity = 0x00
; (v == 1c) ecrecover_y_parity = 0x01

; C,B: y = sqrt(y^2)
; check B isn't an alias (B must be in [0, FPEC-1])

%FPEC_MINUS_ONE => A
0 :LT ; assert to validate that B (y) isn't n alias.

; C,B: y = sqrtFpEc(y^2)
; C: y = sqrt(y^2) [it's alias free, verified in previous lines]

0x01n => A
C => B

; A = parity(y)
$ => A :AND
$ => B :MLOAD(ecrecover_v_parity)

; ecrevover_y xor ecrecover_y_parity => 0 same parity, 1 different parity
; ecrecover_y2 v parity
; parity (A) (B) A+B-1
; 0 0 -1 same parity
; 0 1 0 different parity
; 1 0 0 different parity
; 1 1 1 same parity
; how solution y = 0 not exists because -7 not has a cubic root,
; always parity of A must be equal to v_parity

A + B - 1 :JMPNZ(ecrecover_v_y2_same_parity)
; ASSERT (A == ecrecover_v_parity), if it fails => MAP
A :MLOAD(ecrecover_v_parity)

; calculate neg(ecrecover_y) C = (A:FPEC) - (B:ecrecovery_y)
C :MSTORE(ecrecover_y)

%FPEC => A
C => B
$ => C :SUB
; calculate C as (hash * inv_r) % FNEC
$ => A :MLOAD(ecrecover_hash)
; [steps: 92, bin: 10, arith: 10]
$ => B :MLOAD(ecrecover_r_inv),CALL(mulFnEc)

ecrecover_v_y2_same_parity:
; calculate k1 as (FNEC - hash * inv_r) % FNEC
; C = (hash * inv_r) % FNEC no alias free (MAP)
C => A
0 => B
; C is zero, special case
$ :EQ,JMPNC(k1_c_is_not_zero)

C :MSTORE(ecrecover_y)
; [steps: 100, bin: 9, arith: 12]

; C = (hash * inv_r) % n
k1_c_is_zero:
; k1 = 0 is alias-free
0 :MSTORE(mulPointEc_k1), JMP(k1_calculated)

$ => A :MLOAD(ecrecover_hash)
$ => B :MLOAD(ecrecover_r_inv),CALL(mulFnEc)

; C = n - (hash * inv_r) % n
k1_c_is_not_zero:
; A,C = (hash * inv_r) % FNEC
; check A is alias-free, if not MAP ==> proof fails
%FNEC => B
1 :LT ; ASSERT A < FNEC

; FNEC - A = FNEC - (hash * inv_r) % FNEC
A => B
%FNEC => A
; B != 0 ==> multPointEc_k1 = FNEC - B
; k1 is alias-free
$ :SUB, MSTORE(mulPointEc_k1)

${const.FNEC - C} => A :MSTORE(mulPointEc_k1)
1 => B
0 => D
%FNEC :ARITH
k1_calculated:

$ => A :MLOAD(ecrecover_s)

; [steps: 105, bin: 9, arith: 13]
$ => B :MLOAD(ecrecover_r_inv),CALL(mulFnEc)

; C = (s * inv_r) % n
C :MSTORE(mulPointEc_k2)
; C = (s * inv_r) % FNEC => k2
; [steps: 113, bin: 9, arith: 15]
C => A :MSTORE(mulPointEc_k2)
%FNEC => B

; ASSERT(k2 is alias free)
1 :LT

%ECGX :MSTORE(mulPointEc_p1_x)
%ECGY :MSTORE(mulPointEc_p1_y)
Expand All @@ -181,24 +210,23 @@ ecrecover_v_y2_same_parity:
; y isn't an alias because was checked before
; (r,y) is a point of curve because it satisfacts the curve equation
$ => A :MLOAD(ecrecover_y)
; [steps: 120, bin: 10, arith: 15]
A :MSTORE(mulPointEc_p2_y),CALL(mulPointEc)

; check if result of mulPointEc is point at infinity
HASHPOS :JMPZ(ecrecover_p3_point_at_infinity)

; [steps: 6280, bin: 522, arith: 527]
; generate keccak of public key to obtain ethereum address
$ => E :MLOAD(lastHashKIdUsed)
E + 1 => E :MSTORE(lastHashKIdUsed)
0 => HASHPOS
32 => D

%FPEC => B
; p3_x, p3_y are alias free because arithmetic guarantees it
$ => A :MLOAD(mulPointEc_p3_x)
1 :LT ; alias assert, mulPointEc_p3_x must be in [0, FPEC - 1]

A :HASHK(E)

$ => A :MLOAD(mulPointEc_p3_y)
1 :LT ; alias assert, mulPointEc_p3_y must be in [0, FPEC - 1]

A :HASHK(E)

64 :HASHKLEN(E)
Expand All @@ -207,6 +235,7 @@ ecrecover_v_y2_same_parity:
; for address take only last 20 bytes
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFn => B
$ => A :AND
; AtEnd [steps: 6294, bin: 523, keccak: 1, arith: 528]
0 => B :JMP(ecrecover_end)

; ERRORS
Expand All @@ -223,11 +252,16 @@ ecrecover_s_is_too_big:
4 => B :JMP(ecrecover_error)

ecrecover_v_not_eq_1b1c:
; AtEnd [steps: 45, bin: 8, arith: 2]
5 => B :JMP(ecrecover_error)

ecrecover_not_exists_sqrt_of_y:
; AtEnd [steps: 4527, bin: 10, arith: 1014]
6 => B :JMP(ecrecover_error)

ecrecover_p3_point_at_infinity:
7 => B :JMP(ecrecover_error)

ecrecover_error:
0 => A

Expand Down
11 changes: 9 additions & 2 deletions main/ecrecover/invFnEc.zkasm
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; invFnEc B = inv(A)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRE: A no alias-free
;; POST: B no alias-free (on MAP)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; RESOURCES:
; non-normalized: 2 ariths + 2 binaries + 12 steps
; normalized: 2 ariths + 1 binaries + 11 steps
; TOTAL (worst case): 2 ariths + 2 binaries + 12 steps

VAR GLOBAL invFnEc_tmp

Expand Down
11 changes: 9 additions & 2 deletions main/ecrecover/invFpEc.zkasm
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; invFpEc B = inv(A)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRE: A no alias-free
;; POST: B no alias-free (on MAP)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; RESOURCES:
; non-normalized: 2 ariths + 2 binaries + 12 steps
; normalized: 2 ariths + 1 binaries + 11 steps
; TOTAL (worst case): 2 ariths + 2 binaries + 12 steps

VAR GLOBAL invFpEc_tmp

Expand Down
9 changes: 7 additions & 2 deletions main/ecrecover/mulFnEc.zkasm
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; mulFnEc (C = A * B)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRE: A,B no alias-free
;; POST: C no alias-free (on MAP)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; RESOURCES:
; 2 arith + 7 steps

mulFnEc:
0 => C
Expand Down
9 changes: 7 additions & 2 deletions main/ecrecover/mulFpEc.zkasm
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; mulFpEc (C = A * B)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PRE: A,B no alias-free
;; POST: C no alias-free (on MAP)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; RESOURCES:
; 2 arith + 7 steps

mulFpEc:
0 => C
Expand Down
Loading