From f7a72b72c1cd144922c6b79a07a3d5d7aea18b65 Mon Sep 17 00:00:00 2001 From: Ignasirv Date: Thu, 24 Nov 2022 18:06:36 +0100 Subject: [PATCH 1/5] Update all hasp, most hask and fix memory length check --- main/ecrecover/ecrecover.zkasm | 7 ++-- main/main.zkasm | 1 - main/opcodes/block.zkasm | 1 - main/opcodes/calldata-returndata-code.zkasm | 18 ++++----- main/opcodes/crypto.zkasm | 24 ++++++------ main/opcodes/storage-memory.zkasm | 5 +-- main/process-tx.zkasm | 43 ++++++++++++--------- main/utils.zkasm | 19 +++++++-- 8 files changed, 64 insertions(+), 54 deletions(-) diff --git a/main/ecrecover/ecrecover.zkasm b/main/ecrecover/ecrecover.zkasm index e2ee4037..0dc1d9f9 100644 --- a/main/ecrecover/ecrecover.zkasm +++ b/main/ecrecover/ecrecover.zkasm @@ -170,7 +170,10 @@ ecrecover_v_y2_same_parity: E + 1 => E :MSTORE(lastHashKIdUsed) 0 => HASHPOS 32 => D - + ; check keccak counters + $ => A :MLOAD(cntKeccakPreProcess) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 :JMPN(outOfCountersKeccak) + $ => A :MLOAD(mulPointEc_p3_x) A :HASHK(E) @@ -180,8 +183,6 @@ ecrecover_v_y2_same_parity: A :HASHK(E) 64 :HASHKLEN(E) - $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 :JMPN(outOfCountersKeccak) $ => A :HASHKDIGEST(E) ; for address take only last 20 bytes diff --git a/main/main.zkasm b/main/main.zkasm index 54e47eb5..a084dac3 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -154,7 +154,6 @@ processTxsEnd: $ :MLOAD(batchL2DataLength), ASSERT ;; Compute 'batchHashData' - ; Compute 'batchHashData' A => HASHPOS $ => E :MLOAD(batchHashDataId) diff --git a/main/opcodes/block.zkasm b/main/opcodes/block.zkasm index 73bf945a..5e4e2b6e 100644 --- a/main/opcodes/block.zkasm +++ b/main/opcodes/block.zkasm @@ -24,7 +24,6 @@ opBLOCKHASH: %STATE_ROOT_STORAGE_POS :HASHK(E) HASHPOS :HASHKLEN(E) $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1:JMPN(outOfCountersKeccak) $ => C :HASHKDIGEST(E) %ADDRESS_SYSTEM => A %SMT_KEY_SC_STORAGE => B diff --git a/main/opcodes/calldata-returndata-code.zkasm b/main/opcodes/calldata-returndata-code.zkasm index 815ec9be..59b7d0d9 100644 --- a/main/opcodes/calldata-returndata-code.zkasm +++ b/main/opcodes/calldata-returndata-code.zkasm @@ -232,10 +232,6 @@ opCODECOPY: GAS - 3 => GAS :JMPN(outOfGas) GAS - ${3*((E+31)/32)} => GAS :JMPN(outOfGas) :CALL(saveMem) - ; check memory limits - 0x200000 => A - C + E => B - $ :LT,JMPC(errorMLOADMSTORE) ; Check if offset is above data len D => A $ => B :MLOAD(bytecodeLength) @@ -348,11 +344,6 @@ opEXTCODECOPY: GAS - ${3*((E+31)/32)} => GAS :JMPN(outOfGas) :CALL(saveMem) - ; check memory limits - 0x200000 => A - C + E => B - $ :LT,JMPC(errorMLOADMSTORE) - ; Check if offset is above data len D => A $ => B :MLOAD(tmpContractLength) @@ -380,6 +371,15 @@ opEXTCODECOPYCheckHash: 0 => A D => B $ :EQ, JMPC(opEXTCODECOPYCheckHashEnd) + ; check poseidon counters + ; 56 is the value used by the prover to increment poseidon counters depending on the hash length + B :MSTORE(arithA) + 56 :MSTORE(arithB) + :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => B :MLOAD(arithRes1) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 1 => A + $ :LT, JMPC(outOfCountersPoseidon) + E => A ; get hash contract %SMT_KEY_SC_CODE => B diff --git a/main/opcodes/crypto.zkasm b/main/opcodes/crypto.zkasm index b0a9cb4c..af31ec75 100644 --- a/main/opcodes/crypto.zkasm +++ b/main/opcodes/crypto.zkasm @@ -16,8 +16,6 @@ opSHA3: %MAX_CNT_ARITH - CNT_ARITH - 192 :JMPN(outOfCountersArith) %MAX_CNT_BINARY - CNT_BINARY - 193 :JMPN(outOfCountersBinary) %MAX_CNT_MEM_ALIGN - CNT_MEM_ALIGN - 2 :JMPN(outOfCountersMemalign) - $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 :JMPN(outOfCountersKeccak) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 10 :JMPN(outOfCountersPoseidon) %MAX_CNT_STEPS - STEP - 200 :JMPN(outOfCountersStep) @@ -29,6 +27,16 @@ opSHA3: SP - 1 => SP $ => E :MLOAD(SP--); [offset => E] $ => C :MLOAD(SP) ; [size => C] + ; check keccak counters + C :MSTORE(arithA) + 136 :MSTORE(arithB) + :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => B :MLOAD(arithRes1) + $ => A :MLOAD(cntKeccakPreProcess) + ; checks keccak counters + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 => A + $ :LT, JMPC(outOfCountersKeccak) + ; store lastMemOffset for memory expansion gas cost E :MSTORE(lastMemOffset) ; store lastMemLength for memory expansion gas cost @@ -94,17 +102,7 @@ opSHA3End: ; get current hash pointer $ => E :MLOAD(lastHashKIdUsed) ; append A to hash pointer E - HASHPOS :HASHKLEN(E) - - ; Check keccak counters - HASHPOS :MSTORE(arithA) - 136 :MSTORE(arithB) - :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] - $ => B :MLOAD(arithRes1) - $ => A :MLOAD(cntKeccakPreProcess) - ; checks keccak counters - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 => A - $ :LT, JMPC(outOfCountersKeccak) + HASHPOS :HASHKLEN(E) ; compute hash $ => A :HASHKDIGEST(E) ; store hash diff --git a/main/opcodes/storage-memory.zkasm b/main/opcodes/storage-memory.zkasm index 2a607809..b13337e5 100644 --- a/main/opcodes/storage-memory.zkasm +++ b/main/opcodes/storage-memory.zkasm @@ -110,9 +110,7 @@ opMSTORE8: B :MSTORE(lastMemOffset) ; store lastMemLength for memory expansion gas cost. In case of MSTORE8, always 1 byte 1 :MSTORE(lastMemLength) - ; check offset is below memory limit - 0x200000 => A - $ :LT,JMPC(errorMLOADMSTORE) + :CALL(saveMem); in: [lastMemOffset, lastMemLength] B => A :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] $ => B :MLOAD(SP); [value => B] @@ -122,7 +120,6 @@ opMSTORE8: B :MEM_ALIGN_WR8 ; only use LSB of B, rest of bytes could be non zero. ; write at memory position E D :MSTORE(MEM:E) - :CALL(saveMem); in: [lastMemOffset, lastMemLength] :JMP(readCode) /** diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index cd53eca1..657ecab4 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -49,7 +49,6 @@ processTx: E+1 => E :MSTORE(lastTxHashId) ; Check the signature - $ => A :HASHKDIGEST(E) $ => B :MLOAD(txR) $ => C :MLOAD(txS) @@ -241,6 +240,9 @@ getContractAddress: ; Check if create is with CREATE2 opcode $ => A :MLOAD(isCreate2) 0 - A :JMPN(create2) + ; Check keccak counters + $ => A :MLOAD(cntKeccakPreProcess) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1:JMPN(outOfCountersKeccak) $ => A :MLOAD(txNonce) 0x80 => B $ :LT,JMPC(nonce1byte) @@ -278,10 +280,21 @@ nonceIs0: ;; compute new contract address as CREATE2 spec: keccak256(0xff ++ address ++ salt ++ keccak256(init_code))[12:] (https://eips.ethereum.org/EIPS/eip-1014) create2: $ => C :MLOAD(txCalldataLen) + ; Check keccak counters + C :MSTORE(arithA) + 136 :MSTORE(arithB) + :CALL(divARITH) + $ => B :MLOAD(arithRes1) + $ => A :MLOAD(cntKeccakPreProcess) + ; -2 because we will use one more keccack for generating contract address + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 2 => A + $ :LT, JMPC(outOfCountersKeccak) + $ => CTX :MLOAD(originCTX) $ => B :MLOAD(argsOffsetCall) loopCreate2: + ; check zk-counters %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) %MAX_CNT_BINARY - CNT_BINARY - 4 :JMPN(outOfCountersBinary) @@ -308,15 +321,8 @@ endloopCreate2: create2end: $ => CTX :MLOAD(currentCTX) HASHPOS :HASHKLEN(E) - ; Check keccak counters - HASHPOS :MSTORE(arithA) - 136 :MSTORE(arithB) - :CALL(divARITH) - $ => B :MLOAD(arithRes1) - $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 => A - $ :LT, JMPC(outOfCountersKeccak) $ => C :HASHKDIGEST(E) + ; new hash with position 0 is started 0 => HASHPOS $ => E :MLOAD(lastHashKIdUsed) @@ -334,16 +340,6 @@ create2end: endContractAddress: HASHPOS :HASHKLEN(E) - - ; Check keccak counters - HASHPOS :MSTORE(arithA) - 136 :MSTORE(arithB) - :CALL(divARITH) - $ => B :MLOAD(arithRes1) - $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 => A - $ :LT, JMPC(outOfCountersKeccak) - $ => A :HASHKDIGEST(E) :CALL(maskAddress) ; Mask address to 20 bytes A :MSTORE(createContractAddress) @@ -449,6 +445,15 @@ callContract: 0 => A $ :EQ, JMPC(defaultOpCode) ;no bytecode + ; check poseidon counters + ; 56 is the value used by the prover to increment poseidon counters depending on the hash length + B :MSTORE(arithA) + 56 :MSTORE(arithB) + :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => B :MLOAD(arithRes1) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 1 => A + $ :LT, JMPC(outOfCountersPoseidon) + $ => A :MLOAD(txDestAddr) ; get hash contract %SMT_KEY_SC_CODE => B diff --git a/main/utils.zkasm b/main/utils.zkasm index 57679776..56cd9eaa 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -159,7 +159,7 @@ MSTORE32: D :MSTORE(tmpVarD) E :MSTORE(tmpVarE) E => A - 0x200000 => B + 0x400000 => B $ :LT,JMPC(initMSTORE) :JMP(errorMLOADMSTORE) @@ -267,7 +267,7 @@ MLOAD32: C :MSTORE(tmpVarC) D :MSTORE(tmpVarD) E => A - 0x200000 => B + 0x400000 => B $ :LT,JMPC(initMLOAD) :JMP(errorMLOADMSTORE) @@ -989,6 +989,15 @@ hashPoseidonLinearFromMemory: $ => C :MLOAD(memSizeLinearPoseidon) 0 => D C - 1 :JMPN(hashPoseidonReturn) + ; check poseidon counters + ; 56 is the value used by the prover to increment poseidon counters depending on the hash length + C :MSTORE(arithA) + 56 :MSTORE(arithB) + :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => B :MLOAD(arithRes1) + %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 1 => A + $ :LT, JMPC(outOfCountersPoseidon) + ; get a new hashPId $ => B :MLOAD(nextHashPId) B :MSTORE(tmpContractHashId) @@ -1044,6 +1053,10 @@ maskAddress: :RETURN updateSystemData: + ; check keccak counters + $ => A :MLOAD(cntKeccakPreProcess) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1:JMPN(outOfCountersKeccak) + ; Get last tx count %LAST_TX_STORAGE_POS => C %ADDRESS_SYSTEM => A @@ -1062,8 +1075,6 @@ updateSystemData: A :HASHK(E) %STATE_ROOT_STORAGE_POS :HASHK(E) HASHPOS :HASHKLEN(E) - $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1:JMPN(outOfCountersKeccak) $ => C :HASHKDIGEST(E) %ADDRESS_SYSTEM => A SR => D From f8e91414e01ffa24f3e741a9affe17b6094b639a Mon Sep 17 00:00:00 2001 From: Ignasirv Date: Mon, 28 Nov 2022 15:42:14 +0100 Subject: [PATCH 2/5] Check hask keccacks at rlp parsing --- main/load-tx-rlp.zkasm | 11 ++++++++++- main/opcodes/crypto.zkasm | 2 +- main/process-tx.zkasm | 11 +---------- main/vars.zkasm | 1 + 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 2f8d9d77..a70f5cbe 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -45,7 +45,16 @@ shortList: A - 0xc0 => A endList: - A + C :MSTORE(txRLPLength) + A + C => B :MSTORE(txRLPLength) + ; Check enough zk counters to digest tx hash + B + 1 :MSTORE(arithA) + 136 :MSTORE(arithB) + :CALL(divARITH) + $ => B :MLOAD(arithRes1) + $ => D :MLOAD(txHashAccKeccacks) + D + B + 1 => B :MSTORE(txHashAccKeccacks) + $ => D :MLOAD(cntKeccakPreProcess) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D :JMPN(outOfCountersKeccak) ;; Read RLP 'nonce' ; 64 bits max diff --git a/main/opcodes/crypto.zkasm b/main/opcodes/crypto.zkasm index af31ec75..c2b06f4b 100644 --- a/main/opcodes/crypto.zkasm +++ b/main/opcodes/crypto.zkasm @@ -28,7 +28,7 @@ opSHA3: $ => E :MLOAD(SP--); [offset => E] $ => C :MLOAD(SP) ; [size => C] ; check keccak counters - C :MSTORE(arithA) + C + 1 :MSTORE(arithA) 136 :MSTORE(arithB) :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => B :MLOAD(arithRes1) diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index 657ecab4..d53ee504 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -35,15 +35,6 @@ processTx: ; Get sigDataSize $ => HASHPOS :MLOAD(sigDataSize) - ; Check keccak counters - HASHPOS :MSTORE(arithA) - 136 :MSTORE(arithB) - :CALL(divARITH) - $ => B :MLOAD(arithRes1) - $ => A :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 => A - $ :LT, JMPC(outOfCountersKeccak) - ; Get hash address previously stored in RLP parsing $ => E :MLOAD(lastTxHashId) E+1 => E :MSTORE(lastTxHashId) @@ -281,7 +272,7 @@ nonceIs0: create2: $ => C :MLOAD(txCalldataLen) ; Check keccak counters - C :MSTORE(arithA) + C + 1 :MSTORE(arithA) 136 :MSTORE(arithB) :CALL(divARITH) $ => B :MLOAD(arithRes1) diff --git a/main/vars.zkasm b/main/vars.zkasm index 98ce6fdd..27760eb1 100644 --- a/main/vars.zkasm +++ b/main/vars.zkasm @@ -49,6 +49,7 @@ VAR GLOBAL hashContractTxDestAddr ; state-tree hash bytecode leaf value of the ' VAR GLOBAL auxSR ; auxiliaty variable. Temporary state root VAR GLOBAL txRLPLength ; transaction RLP list length VAR GLOBAL txDataRead ; aux varible to check transaction 'data' left that needs to be read +VAR GLOBAL txHashAccKeccacks ; aux var to accumulate the blocked keccacks for tx hashing at rlp parsing VAR CTX txGasLimit ; transaction parameter: 'gas limit' VAR CTX txDestAddr ; transaction parameter: 'to' From 6d8d1a5f780bc2341051e1527f31f96a97158a9a Mon Sep 17 00:00:00 2001 From: Ignasirv Date: Mon, 28 Nov 2022 17:38:02 +0100 Subject: [PATCH 3/5] Fix checking counters after gas at sha3 --- main/opcodes/block.zkasm | 1 - main/opcodes/calldata-returndata-code.zkasm | 6 ++++-- main/opcodes/crypto.zkasm | 20 +++++++++++--------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/main/opcodes/block.zkasm b/main/opcodes/block.zkasm index 5e4e2b6e..9603aabb 100644 --- a/main/opcodes/block.zkasm +++ b/main/opcodes/block.zkasm @@ -23,7 +23,6 @@ opBLOCKHASH: A :HASHK(E) %STATE_ROOT_STORAGE_POS :HASHK(E) HASHPOS :HASHKLEN(E) - $ => A :MLOAD(cntKeccakPreProcess) $ => C :HASHKDIGEST(E) %ADDRESS_SYSTEM => A %SMT_KEY_SC_STORAGE => B diff --git a/main/opcodes/calldata-returndata-code.zkasm b/main/opcodes/calldata-returndata-code.zkasm index 6f58ad2a..ddc30ec9 100644 --- a/main/opcodes/calldata-returndata-code.zkasm +++ b/main/opcodes/calldata-returndata-code.zkasm @@ -382,9 +382,11 @@ opEXTCODECOPYCheckHash: $ :EQ, JMPC(opEXTCODECOPYCheckHashEnd) ; check poseidon counters ; 56 is the value used by the prover to increment poseidon counters depending on the hash length - B :MSTORE(arithA) + RR :MSTORE(tmpZkPC) + B + 1 :MSTORE(arithA) 56 :MSTORE(arithB) :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => RR :MLOAD(tmpZkPC) $ => B :MLOAD(arithRes1) %MAX_CNT_POSEIDON_G - CNT_POSEIDON_G - 1 => A $ :LT, JMPC(outOfCountersPoseidon) @@ -408,7 +410,7 @@ opEXTCODECOPYCheckHash: ; TODO: it could be improved by computing how many 32 bytes slots are needed opEXTCODECOPYCheckHashLoop: - %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep) B - 1 :JMPN(opEXTCODECOPYCheckHashLoopEnd) ; finish reading bytecode 1 => D diff --git a/main/opcodes/crypto.zkasm b/main/opcodes/crypto.zkasm index c2b06f4b..0048b94d 100644 --- a/main/opcodes/crypto.zkasm +++ b/main/opcodes/crypto.zkasm @@ -27,15 +27,6 @@ opSHA3: SP - 1 => SP $ => E :MLOAD(SP--); [offset => E] $ => C :MLOAD(SP) ; [size => C] - ; check keccak counters - C + 1 :MSTORE(arithA) - 136 :MSTORE(arithB) - :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] - $ => B :MLOAD(arithRes1) - $ => A :MLOAD(cntKeccakPreProcess) - ; checks keccak counters - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 => A - $ :LT, JMPC(outOfCountersKeccak) ; store lastMemOffset for memory expansion gas cost E :MSTORE(lastMemOffset) @@ -58,6 +49,17 @@ opSHA3: :CALL(mulARITH) $ => A :MLOAD(arithRes1) GAS - A => GAS :JMPN(outOfGas) ; dynamic_gas = 6 * minimum_word_size + memory_expansion_cost + + ; check keccak counters + C + 1 :MSTORE(arithA) + 136 :MSTORE(arithB) + :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => B :MLOAD(arithRes1) + $ => A :MLOAD(cntKeccakPreProcess) + ; checks keccak counters + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 => A + $ :LT, JMPC(outOfCountersKeccak) + ; new hash id $ => B :MLOAD(lastHashKIdUsed) B + 1 => B :MSTORE(lastHashKIdUsed) From 3eac6cb0c55cb88c56dbc8c3eb23bd0b7eda30f2 Mon Sep 17 00:00:00 2001 From: Ignasirv Date: Tue, 29 Nov 2022 15:58:25 +0100 Subject: [PATCH 4/5] signature haskdigest at rlp parsing --- main/load-tx-rlp.zkasm | 12 ++++++++---- main/main.zkasm | 1 - main/process-tx.zkasm | 19 ++----------------- main/vars.zkasm | 3 --- 4 files changed, 10 insertions(+), 25 deletions(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index a70f5cbe..1a34172b 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -51,10 +51,8 @@ endList: 136 :MSTORE(arithB) :CALL(divARITH) $ => B :MLOAD(arithRes1) - $ => D :MLOAD(txHashAccKeccacks) - D + B + 1 => B :MSTORE(txHashAccKeccacks) $ => D :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D :JMPN(outOfCountersKeccak) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D - 1:JMPN(outOfCountersKeccak) ;; Read RLP 'nonce' ; 64 bits max @@ -324,7 +322,13 @@ vREADTx: ;; increase number of transaction to process $ => A :MLOAD(pendingTxs) A + 1 => A :MSTORE(pendingTxs) - HASHPOS :MSTORE(sigDataSize) ; save bytes length added to ethereum transaction hash +;; check signature + $ => A :HASHKDIGEST(E) + $ => B :MLOAD(txR) + $ => C :MLOAD(txS) + $ => D :MLOAD(txV) + :CALL(ecrecover) + A :MSTORE(txSrcAddr) :JMP(txLoopRLP) ;;;;;;;;; diff --git a/main/main.zkasm b/main/main.zkasm index a084dac3..e8f6dc08 100644 --- a/main/main.zkasm +++ b/main/main.zkasm @@ -90,7 +90,6 @@ skipSetGlobalExitRoot: E+1 => E :MSTORE(lastHashKIdUsed) 0 :MSTORE(batchHashPos) E :MSTORE(batchHashDataId) - E :MSTORE(lastTxHashId) ; Points at first hash address to be used when processing transactions $ => A :MLOAD(lastCtxUsed) A :MSTORE(ctxTxToUse) ; Points at first context to be used when processing transactions diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index aa2859a7..ffb45e29 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -32,24 +32,9 @@ processTx: ; Minimum of 100000 steps left to process a tx %MAX_CNT_STEPS - STEP - 100000 :JMPN(outOfCountersStep) - - ; Get sigDataSize - $ => HASHPOS :MLOAD(sigDataSize) - - ; Get hash address previously stored in RLP parsing - $ => E :MLOAD(lastTxHashId) - E+1 => E :MSTORE(lastTxHashId) - - ; Check the signature - $ => A :HASHKDIGEST(E) - $ => B :MLOAD(txR) - $ => C :MLOAD(txS) - $ => D :MLOAD(txV) - :CALL(ecrecover) - ; Check result is non-zero -checkAndSaveFrom: + ; check from address 0 => B - A :MSTORE(txSrcAddr) + $ => A :MLOAD(txSrcAddr) A :MSTORE(txSrcOriginAddr) $ :EQ,JMPC(invalidIntrinsicTxSignature) diff --git a/main/vars.zkasm b/main/vars.zkasm index 27760eb1..b3b78dee 100644 --- a/main/vars.zkasm +++ b/main/vars.zkasm @@ -17,7 +17,6 @@ VAR GLOBAL batchL2DataParsed ; Number of bytes read when decoding RLP transactio VAR GLOBAL pendingTxs ; Number of transactions decoded in RLP block VAR GLOBAL lastCtxUsed ; Last context that has been used VAR GLOBAL ctxTxToUse ; First context to be used when processing transactions -VAR GLOBAL lastTxHashId ; First hash address to be used when processing transactions VAR GLOBAL lastHashKIdUsed ; Last hash address used VAR GLOBAL nextHashPId ; Next posidon hash address available @@ -49,7 +48,6 @@ VAR GLOBAL hashContractTxDestAddr ; state-tree hash bytecode leaf value of the ' VAR GLOBAL auxSR ; auxiliaty variable. Temporary state root VAR GLOBAL txRLPLength ; transaction RLP list length VAR GLOBAL txDataRead ; aux varible to check transaction 'data' left that needs to be read -VAR GLOBAL txHashAccKeccacks ; aux var to accumulate the blocked keccacks for tx hashing at rlp parsing VAR CTX txGasLimit ; transaction parameter: 'gas limit' VAR CTX txDestAddr ; transaction parameter: 'to' @@ -88,7 +86,6 @@ VAR CTX isDelegateCall ; flag to determine if a new context comes from a DELEGAT VAR CTX isCreate2 ; flag to determine if a new context comes from a CREATE2 opcode VAR CTX salt ; CREATE2 parameter 'salt' used to compute new contract address VAR CTX gasCTX ; remaining gas in the origin CTX when a new context is created -VAR CTX sigDataSize ; hash position for the ethereum transaction hash VAR CTX dataStarts; hash position where de transaction 'data' starts in the batchHashData VAR CTX isPreEIP155 ; flag to check if the current tx is legacy, previous to Spurious Dragon (EIP-155) VAR CTX initTouchedSR ; touched root once a new context begins \ No newline at end of file From 4e5f9c5cab1de8202b8ce166025111829ae4009d Mon Sep 17 00:00:00 2001 From: Ignasirv Date: Tue, 29 Nov 2022 17:15:18 +0100 Subject: [PATCH 5/5] ecrecover at process tx --- main/load-tx-rlp.zkasm | 13 ++++++------- main/process-tx.zkasm | 11 +++++++++-- main/vars.zkasm | 1 + 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index 1a34172b..a7056bd7 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -52,7 +52,7 @@ endList: :CALL(divARITH) $ => B :MLOAD(arithRes1) $ => D :MLOAD(cntKeccakPreProcess) - %MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D - 1:JMPN(outOfCountersKeccak) + %MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D - 1:JMPN(handleOOCatRLP) ;; Read RLP 'nonce' ; 64 bits max @@ -322,18 +322,17 @@ vREADTx: ;; increase number of transaction to process $ => A :MLOAD(pendingTxs) A + 1 => A :MSTORE(pendingTxs) -;; check signature +;; compute signature $ => A :HASHKDIGEST(E) - $ => B :MLOAD(txR) - $ => C :MLOAD(txS) - $ => D :MLOAD(txV) - :CALL(ecrecover) - A :MSTORE(txSrcAddr) + A :MSTORE(txHash) :JMP(txLoopRLP) ;;;;;;;;; ;; E - Handler error RLP fields ;;;;;;;;; +handleOOCatRLP: + ${eventLog(onError, OOCK)} + $ => SR :MLOAD(batchSR) invalidTxRLP: ;; Append all missing 'batchL2Data' to 'batchDataHash' bytes diff --git a/main/process-tx.zkasm b/main/process-tx.zkasm index ffb45e29..373f8022 100644 --- a/main/process-tx.zkasm +++ b/main/process-tx.zkasm @@ -32,9 +32,16 @@ processTx: ; Minimum of 100000 steps left to process a tx %MAX_CNT_STEPS - STEP - 100000 :JMPN(outOfCountersStep) - ; check from address + $ => A :MLOAD(txHash) + ; Check the signature + $ => B :MLOAD(txR) + $ => C :MLOAD(txS) + $ => D :MLOAD(txV) + :CALL(ecrecover) + ; Check result is non-zero +checkAndSaveFrom: 0 => B - $ => A :MLOAD(txSrcAddr) + A :MSTORE(txSrcAddr) A :MSTORE(txSrcOriginAddr) $ :EQ,JMPC(invalidIntrinsicTxSignature) diff --git a/main/vars.zkasm b/main/vars.zkasm index b3b78dee..919e8a24 100644 --- a/main/vars.zkasm +++ b/main/vars.zkasm @@ -60,6 +60,7 @@ VAR CTX txS ; transaction parameter: ecdsa signature S VAR CTX txR ; transaction parameter: ecdsa signature R VAR CTX txV ; transaction parameter: ecdsa signature V VAR CTX txSrcAddr ; address that sends a transaction 'message.sender' +VAR CTX txHash ; signed tx hash VAR CTX txCalldataLen ; calldata length VAR CTX isCreateContract ; flag to determine if a transaction will create a new contract VAR CTX createContractAddress ; address computed of a new contract