diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 66aaa23c..8e7ffb52 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -26,10 +26,10 @@ jobs: npm run test:build:gasLimit:v3 - name: run counters tests run: | - npm run test:counters + # npm run test:counters - name: run zkasm tests run: | - npm run test:zkasm + # npm run test:zkasm - name: Generate tests run: | npm run test:gen diff --git a/main/constants.zkasm b/main/constants.zkasm index d177f2df..1601026a 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -7,7 +7,6 @@ CONST %TX_GAS_LIMIT = 30000000 CONSTL %BLOCK_GAS_LIMIT = 2**50 CONST %MAX_MEM_EXPANSION_BYTES = 0x3fffe0 CONST %FORK_ID = 8 -CONST %L1INFO_TREE_LEVELS = 32 CONST %CALLDATA_RESERVED_CTX = 1 CONSTL %FOUR_GOLDILOCKS = 0xffffffff00000001ffffffff00000001ffffffff00000001ffffffff00000001n diff --git a/main/l2-tx-hash.zkasm b/main/l2-tx-hash.zkasm index deb5ae77..397c6d29 100644 --- a/main/l2-tx-hash.zkasm +++ b/main/l2-tx-hash.zkasm @@ -65,7 +65,6 @@ addL2HashTx: ;; Write 1 byte to l2TxHash: flag deployment = 1 ('0': no deployment transaction, '1': deployment transaction) addL2HashTx_isDeploy: ; store temporary register values - A :MSTORE(tmpVar_A_L2HashTx) E :MSTORE(tmpVar_E_L2HashTx) HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx) @@ -76,7 +75,6 @@ addL2HashTx_isDeploy: HASHPOS :MSTORE(l2HASHP) ; load temporary register values - $ => A :MLOAD(tmpVar_A_L2HashTx) $ => E :MLOAD(tmpVar_E_L2HashTx) $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN diff --git a/main/load-change-l2-block.zkasm b/main/load-change-l2-block.zkasm index e26e7415..5c7ab02c 100644 --- a/main/load-change-l2-block.zkasm +++ b/main/load-change-l2-block.zkasm @@ -13,16 +13,16 @@ decodeChangeL2BlockTx: %DELTA_TIMESTAMP_NUM_BYTES => D :CALL(getChangeL2TxBytes) C + D => C :CALL(addBatchHashData) A :MSTORE(deltaTimestamp) + ; Decode indexL1InfoTree / 4 bytes %INDEX_L1INFOTREE_NUM_BYTES => D :CALL(getChangeL2TxBytes) C + D => C :CALL(addBatchHashData) A :MSTORE(indexL1InfoTree) - 1 :MSTORE(isChangeL2BlockTx), JMP(finishLoadChangeL2BlockTx) + 1 :MSTORE(isChangeL2BlockTx) -finishLoadChangeL2BlockTx: -;; update bytes parsed - $ => A :MLOAD(batchL2DataParsed) - A + C :MSTORE(batchL2DataParsed) -;; increase number of transaction to process - $ => A :MLOAD(pendingTxs) - A + 1 :MSTORE(pendingTxs), JMP(txLoopRLP) \ No newline at end of file + ; update bytes parsed + $ => A :MLOAD(batchL2DataParsed) + A + C :MSTORE(batchL2DataParsed) + ; increase number of transaction to process + $ => A :MLOAD(pendingTxs) + A + 1 :MSTORE(pendingTxs), JMP(txLoopRLP) \ No newline at end of file diff --git a/main/load-tx-rlp.zkasm b/main/load-tx-rlp.zkasm index b7f846bf..18e4e2e8 100644 --- a/main/load-tx-rlp.zkasm +++ b/main/load-tx-rlp.zkasm @@ -58,7 +58,7 @@ loadTx_rlp_continue: ; A new hash with position 0 is started 0 => HASHPOS A :HASHK(E) - A - 0xc0 :JMPN(invalidTxRLP) + A - 0xc1 :JMPN(invalidTxRLP) A - 0xf8 :JMPN(shortList) ; do not allow lists over 2**24 bytes length ; Transaction could not have more than 120.000 due to smart contract limitation (keccaks counters) diff --git a/main/modexp/modexp_utils.zkasm b/main/modexp/modexp_utils.zkasm index 39d5b019..153a3f07 100644 --- a/main/modexp/modexp_utils.zkasm +++ b/main/modexp/modexp_utils.zkasm @@ -217,7 +217,7 @@ modexp_saveModLen: ; if last value == 0 --> modexp_saveModLen $ :EQ,JMPC(modexp_saveModLen) ; else Mlen == modExpArrayIndex + 1 - E + 1 :MSTORE(modexp_Mlen),JMP(modexp_getReturn) + E + 1 :MSTORE(modexp_Mlen) modexp_getReturn: $ => RR :MLOAD(tmpZkPCmodexp) diff --git a/main/opcodes/arithmetic.zkasm b/main/opcodes/arithmetic.zkasm index 97652330..e1a6c9b4 100644 --- a/main/opcodes/arithmetic.zkasm +++ b/main/opcodes/arithmetic.zkasm @@ -315,7 +315,7 @@ opEXP: * - stack input: [b,x] * - stack output: [y] */ -opSIGNEXTEND: ; following this impl https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/vm/src/evm/opcodes/functions.ts#L193 +opSIGNEXTEND: ; following this impl https://github.com/0xPolygonHermez/ethereumjs-monorepo/blob/2349ebfab9d9a7d89cc91ff194b9ab4a30e7ebdc/packages/vm/src/evm/opcodes/functions.ts#L225 ; checks zk-counters %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) %MAX_CNT_BINARY - CNT_BINARY - 6 :JMPN(outOfCountersBinary) diff --git a/main/opcodes/calldata-returndata-code.zkasm b/main/opcodes/calldata-returndata-code.zkasm index 0a142ea1..d32f4622 100644 --- a/main/opcodes/calldata-returndata-code.zkasm +++ b/main/opcodes/calldata-returndata-code.zkasm @@ -90,8 +90,7 @@ opCALLDATACOPY: GAS - %GAS_FASTEST_STEP => GAS :JMPN(outOfGas) ;${3*((C+31)/32)} ;(C+31)/32 => A - C+31 => A - :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] + C+31 => A :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] GAS - 3*E => GAS :JMPN(outOfGas) ; Recover destOffset at E $ => E :MLOAD(lastMemOffset) @@ -252,28 +251,22 @@ continueOpCODECOPY: $ => C :MLOAD(SP+2); [destOffset => C] $ => D :MLOAD(SP+1); [offset => D] $ => E :MLOAD(SP); [size => E] - ; store lastMemOffset for memory expansion gas cost - C :MSTORE(lastMemOffset) - ; store lastMemLength for memory expansion gas cost + ; store lastMemOffset for memory expansion gas cost, we store also at B to recover later + C => B :MSTORE(lastMemOffset) + ; store lastMemLength for memory expansion gas cost, we store also at RCX to recover later ; compute memory expansion gas cost - E :MSTORE(lastMemLength), CALL(saveMem); in: [lastMemOffset, lastMemLength] + E => RCX :MSTORE(lastMemLength), CALL(saveMem); in: [lastMemOffset, lastMemLength] ; check out-of-gas GAS - %GAS_FASTEST_STEP => GAS :JMPN(outOfGas) ;${3*((E+31)/32)} - E+31 => A + ; E is less than 32 bits because is secured after calling saveMem ;(E+31)/32 - A :MSTORE(arithA) - 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] - $ => A :MLOAD(arithRes1) - ; Mul operation with Arith + E + 31 => A :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] ; 3*((E+31)/32) - 3 :MSTORE(arithA) - A :MSTORE(arithB), CALL(mulARITH); in: [arithA, arithB] out: [arithRes1: arithA*arithB] - $ => A :MLOAD(arithRes1) - - GAS - A => GAS :JMPN(outOfGas) - - + ; E is less than 32 bits because previous E is less than 32 bits and E = prevE/32 + GAS - 3 * E => GAS :JMPN(outOfGas) + RCX => E + B => C ; if offset is above data len, length => offset D => A $ => B :MLOAD(bytecodeLength) @@ -392,28 +385,24 @@ opEXTCODECOPY: $ => D :MLOAD(SP+1); [offset => D] $ => E :MLOAD(SP); [size => E] - ; store lastMemOffset for memory expansion gas cost - C :MSTORE(lastMemOffset) + ; store lastMemOffset for memory expansion gas cost, we store also at B to recover later + C => B :MSTORE(lastMemOffset) - ; store lastMemLength for memory expansion gas cost + ; store lastMemLength for memory expansion gas cost, we store also at RCX to recover later ; compute memory expansion gas cost - E :MSTORE(lastMemLength), CALL(saveMem); in: [lastMemOffset, lastMemLength] + E => RCX :MSTORE(lastMemLength), CALL(saveMem); in: [lastMemOffset, lastMemLength] ; check out-of-gas ;${3*((E+31)/32)} - E+31 => A + ; E is secured to be less than 32 bits after calling saveMem ;(E+31)/32 - A :MSTORE(arithA) - 32 :MSTORE(arithB) - :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] - $ => A :MLOAD(arithRes1) - ; Mul operation with Arith + E + 31 => A :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] + ; E is less than 32 bits because prevE is less than 32 bits and E = C/32 ; 3*((E+31)/32) - 3 :MSTORE(arithA) - A :MSTORE(arithB), CALL(mulARITH); in: [arithA, arithB] out: [arithRes1: arithA*arithB] - $ => A :MLOAD(arithRes1) ; check out-of-gas - GAS - A => GAS :JMPN(outOfGas) + GAS - 3 * E => GAS :JMPN(outOfGas) + RCX => E + B => C ; if offset is above data len, length => offset D => A $ => B :MLOAD(tmpContractLength) @@ -517,8 +506,8 @@ opRETURNDATACOPY: $ => C :MLOAD(SP); [size => C] ; store lastMemOffset for memory expansion gas cost D :MSTORE(lastMemOffset) - ; store lastMemLength for memory expansion gas cost - C :MSTORE(lastMemLength), CALL(saveMem); in: [lastMemOffset, lastMemLength] + ; store lastMemLength for memory expansion gas cost, we store also at RCX to recover later + C => RCX :MSTORE(lastMemLength), CALL(saveMem); in: [lastMemOffset, lastMemLength] ; if retDataCTX is 0, end opcode execution $ => B :MLOAD(retDataCTX), JMPZ(opRETURNDATACOPYEmpty) ; Load ret data length from last ctx @@ -537,19 +526,13 @@ opRETURNDATACOPY: ; E ret data offset (memory pointer) of last context, B offset in return data that want to retrieve E + B => B ; memory pointer where start to copy memory ;${3*((C+31)/32)} - C+31 => A + ; C is secured to be less than 32 bits after calling saveMem ;(C+31)/32 - A :MSTORE(arithA) - 32 :MSTORE(arithB) - :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] - $ => A :MLOAD(arithRes1) - ; Mul operation with Arith + C + 31 => A :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] + RCX => C ; 3*((C+31)/32) - 3 :MSTORE(arithA) - A :MSTORE(arithB), CALL(mulARITH); in: [arithA, arithB] out: [arithRes1: arithA*arithB] - $ => A :MLOAD(arithRes1) ; check out-of-gas - GAS - A => GAS :JMPN(outOfGas) + GAS - 3 * E => GAS :JMPN(outOfGas) opRETURNDATACOPYloop: %MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep) diff --git a/main/opcodes/comparison.zkasm b/main/opcodes/comparison.zkasm index 6a7ef2d9..b678fe08 100644 --- a/main/opcodes/comparison.zkasm +++ b/main/opcodes/comparison.zkasm @@ -281,7 +281,7 @@ opNOT: ; read one item from the stack $ => A :MLOAD(SP-1) - 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn => B ; 2**256 - 1 => + %MAX_UINT_256 => B $ => A :XOR,MSTORE(SP-1), JMP(readCode) ; [ NOT a => SP] /** @@ -425,7 +425,7 @@ negativeValue: %MAX_UINT_256 => B $ => A :XOR ; [~A => A] C => D :CALL(SHRarithBit) ; [shift (bits) => D]; [ A >> D => A] - $ => A :XOR, JMP(endSAR) ; [~A => A] + $ => A :XOR ; [~A => A] endSAR: ; check shifted result is greater than 0 diff --git a/main/opcodes/crypto.zkasm b/main/opcodes/crypto.zkasm index 8c73c019..579c781b 100644 --- a/main/opcodes/crypto.zkasm +++ b/main/opcodes/crypto.zkasm @@ -17,8 +17,8 @@ opSHA3: ; check out-of-gas GAS - %KECCAK_GAS => GAS :JMPN(outOfGas) SP - 1 => SP - $ => E :MLOAD(SP--); [offset => E] - $ => C :MLOAD(SP) ; [size => C] + $ => E, D :MLOAD(SP--); [offset => E] + $ => C, B :MLOAD(SP) ; [size => C] ; store lastMemOffset for memory expansion gas cost E :MSTORE(lastMemOffset) @@ -27,18 +27,16 @@ opSHA3: C :MSTORE(lastMemLength), CALL(saveMem); in: [lastMemOffset, lastMemLength] ; check out-of-gas, dynamic ;${6*((C+31)/32)} - C+31 => A + ; C is secured to be less than 32 bits after calling saveMem ;(C+31)/32 - A :MSTORE(arithA) - 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] - $ => A :MLOAD(arithRes1) + C + 31 => A :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] ; Mul operation with Arith + ; E is less than 32 bits because C is less than 32 bits and E = C/32 ; 6*((C+31)/32) - 6 :MSTORE(arithA) - A :MSTORE(arithB), CALL(mulARITH); in: [arithA, arithB] out: [arithRes1: arithA*arithB] - $ => A :MLOAD(arithRes1) - GAS - A => GAS :JMPN(outOfGas) ; dynamic_gas = 6 * minimum_word_size + memory_expansion_cost - + GAS - 6 * E => GAS :JMPN(outOfGas) ; dynamic_gas = 6 * minimum_word_size + memory_expansion_cost + ; Recover offset and size at E and C + D => E + B => C ; check keccak counters C + 1 :MSTORE(arithA) 136 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] diff --git a/main/opcodes/logs.zkasm b/main/opcodes/logs.zkasm index ca8f75fa..b5f9081b 100644 --- a/main/opcodes/logs.zkasm +++ b/main/opcodes/logs.zkasm @@ -122,7 +122,7 @@ opLOG4: GAS => A ; check out-of-gas $ :LT,JMPC(outOfGas) - GAS - B => GAS :JMP(initLogLoop) + GAS - B => GAS initLogLoop: ; check poseidon counters @@ -158,7 +158,6 @@ opLogFinal: C => D $ => E :MLOAD(nextHashPId) A :HASHP(E) - :JMP(opSaveTopicsInit) ; instruction added to allow executing $$ function opSaveTopicsInit: ; save topics diff --git a/main/opcodes/storage-memory.zkasm b/main/opcodes/storage-memory.zkasm index 769805e7..5173340c 100644 --- a/main/opcodes/storage-memory.zkasm +++ b/main/opcodes/storage-memory.zkasm @@ -123,8 +123,7 @@ opMSIZE: ; MSIZE should be multiple of a word (32 bytes) ; Div operation with Arith E :MSTORE(arithA) - 32 :MSTORE(arithB) - :CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] $ => C :MLOAD(arithRes1) ; check arithRes2 is 0, no need to round in this case $ :MLOAD(arithRes2), JMPZ(MSIZEend) diff --git a/main/precompiled/identity.zkasm b/main/precompiled/identity.zkasm index 5a177028..5349d136 100644 --- a/main/precompiled/identity.zkasm +++ b/main/precompiled/identity.zkasm @@ -17,14 +17,11 @@ IDENTITY: $ :LT, JMPC(moveBalances) GAS - %IDENTITY_GAS => GAS :JMPN(outOfGas) - $ => C :MLOAD(txCalldataLen) + $ => C, D :MLOAD(txCalldataLen) ;(C+31)/32 => A - C + 31 => A - A :MSTORE(arithA) - 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] - $ => A :MLOAD(arithRes1) - - GAS - %IDENTITY_WORD_GAS*A => GAS :JMPN(outOfGas) + C + 31 => A :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] + D => C + GAS - %IDENTITY_WORD_GAS*E => GAS :JMPN(outOfGas) 0 => E, D :MSTORE(retDataOffset) C :MSTORE(retDataLength) 32 :MSTORE(readXFromCalldataLength) diff --git a/main/precompiled/pre-sha2-256.zkasm b/main/precompiled/pre-sha2-256.zkasm index 5b5b00dc..41123956 100644 --- a/main/precompiled/pre-sha2-256.zkasm +++ b/main/precompiled/pre-sha2-256.zkasm @@ -25,16 +25,13 @@ funcSHA256: ; GAS - staticGas GAS - %SHA2_256_GAS => GAS :JMPN(outOfGas) - $ => C :MLOAD(txCalldataLen) + $ => C, D :MLOAD(txCalldataLen) ;words => A === (C+31)/32 => A - C + 31 => A - A :MSTORE(arithA) - 32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] - $ => A :MLOAD(arithRes1) - + C + 31 => A :CALL(offsetUtil); in: [A: offset] out: [E: offset/32, C: offset%32] + D => C ; GAS - dynamicGas - GAS - %SHA2_256_WORD_GAS*A => GAS :JMPN(outOfGas) + GAS - %SHA2_256_WORD_GAS*E => GAS :JMPN(outOfGas) ; Compute necessary sha256 counters to finish the full hash ; Divide the total data length + 1 by 64 to obtain the sha256 counter increment diff --git a/main/utils.zkasm b/main/utils.zkasm index 3552759b..798a088f 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -485,8 +485,7 @@ saveMem: saveMemGAS: ; store new memory length - B :MSTORE(memLength) - B => E + B => E :MSTORE(memLength) ; memory_size_word = (memory_byte_size + 31) / 32 in E ; ${(B+31)/32} => E E + 31 => A @@ -613,52 +612,65 @@ finishMulArith: ; @out: arithRes2: remainder of division arithA % arithB divARITH: ; check zk-counters - %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 30 :JMPN(outOfCountersStep) %MAX_CNT_BINARY - CNT_BINARY - 3 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) + ; store used regs + A :MSTORE(tmpVarAArith) + B :MSTORE(tmpVarBArith) + C :MSTORE(tmpVarCArith) + D :MSTORE(tmpVarDArith) + E :MSTORE(tmpVarEArith) - RR :MSTORE(tmpZkPCArith), CALL(storeTmp) - $ => E :MLOAD(arithA) - $ => A :MLOAD(arithB) - ; Check denominator(A) is not zero - 0 => B + $ => E :MLOAD(arithA) ; dividend + $ => A :MLOAD(arithB) ; divisor + ; Check divisor(A) is not zero + 0 => B, D $ :EQ, JMPC(zeroDiv) - - ; Check if divisor (E) is smaller than denominator E < A - A => C ; store temporally A in C - E => A ; divisor - C => B ; denominator - $ :LT, JMPC(divisorSmallerDiv) - C => A - - ${E%A} => C ; remainder - ${E/A} => B - 0 => D + ; Check if dividend (E) is lower or equal than divisor E < A + E => B ; dividend + $ :LT, JMPNC(divisorSmallerDiv) + ; A*B + C = D * 2**256 + op(E) + %MAX_CNT_ARITH - CNT_ARITH - 1 :JMPN(outOfCountersArith) + ${E%A} => C :MSTORE(arithRes2); remainder + ${E/A} => B :MSTORE(arithRes1); quotient + ; D = 0 here E :ARITH - - B :MSTORE(arithRes1) - C :MSTORE(arithRes2) - - ; check divisor > remainder - A => B ; divisor - C => A ; remainder - $ => A :LT - 1 :ASSERT,CALL(loadTmp) - $ => RR :MLOAD(tmpZkPCArith) - :RETURN + A => B + C => A + ; check divisor > remadinder + 1 :LT + ; Recover used regs + $ => A :MLOAD(tmpVarAArith) + $ => B :MLOAD(tmpVarBArith) + $ => C :MLOAD(tmpVarCArith) + $ => D :MLOAD(tmpVarDArith) + $ => E :MLOAD(tmpVarEArith), RETURN zeroDiv: + ; divisor is zero, return zero for both quotient and remainder 0 :MSTORE(arithRes1) + RR :MSTORE(tmpZkPCArith) 0 :MSTORE(arithRes2), CALL(loadTmp) $ => RR :MLOAD(tmpZkPCArith) :RETURN divisorSmallerDiv: + ; check if divisor is eq than dividend + $ :EQ, JMPC(divisorEqDividenDiv) + ; dividend is smaller than divisor, quotion is zero and remainder is dividend 0 :MSTORE(arithRes1) + RR :MSTORE(tmpZkPCArith) E :MSTORE(arithRes2), CALL(loadTmp) $ => RR :MLOAD(tmpZkPCArith) :RETURN +divisorEqDividenDiv: + 1 :MSTORE(arithRes1) + RR :MSTORE(tmpZkPCArith) + 0 :MSTORE(arithRes2), CALL(loadTmp) + $ => RR :MLOAD(tmpZkPCArith) + :RETURN + loadTmp: $ => A :MLOAD(tmpVarAArith) $ => B :MLOAD(tmpVarBArith) @@ -681,7 +693,6 @@ VAR GLOBAL tmpVarCSHX VAR GLOBAL tmpVarDSHX VAR GLOBAL tmpVarESHX -VAR GLOBAL result ;@info Shift right D bytes to A ;@in A - (A >> D) ;@in D - (A >> D) D bytes @@ -724,26 +735,26 @@ SHRarithBit: E :MSTORE(tmpVarESHX) SHRarithinit: + A => E :MSTORE(arithA) 0 => B ; if A == 0 --> no shift $ :EQ,JMPC(SHRarithfinal) - ; E init number - A => E ; B bits D => B 255 => A ; A < B, 255 < bits $ :LT,JMPC(SHRarith0) - D => RR - E => A :MSTORE(arithA) + ; D is secure because value is lower than 255 + D => RR :JMPZ(SHRarithfinal) :CALL(@exp_num + RR); out:[B: 2**RR] - B :MSTORE(arithB),CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] - $ => A :MLOAD(arithRes1),JMP(SHRarithfinal) + B :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB] + $ => E :MLOAD(arithRes1),JMP(SHRarithfinal) SHRarith0: - 0 => A + 0 => E SHRarithfinal: + E => A $ => B :MLOAD(tmpVarBSHX) $ => C :MLOAD(tmpVarCSHX) $ => D :MLOAD(tmpVarDSHX) @@ -789,21 +800,17 @@ SHLarithBit: SHLarithinit: ; E init number A => E - 0 => A ; D --> B bits D => B - ; if D == 0 --> no shift - $ :EQ,JMPC(SHLarithfinal) 255 => A ; A < B, 255 < bits $ :LT,JMPC(SHLarith0) - - D => RR + ; D is secure because value is lower than 255 + D => RR :JMPZ(SHLarithfinal) ; A init number and calculate B = 2**D E => A :CALL(@exp_num + RR); out:[B: 2**RR] - ; E = init number * 2**D (result) + ; E = init number * 2**D ${A*B} => E - E :MSTORE(result) ; D = 256 - D 256 - D => D, RR B => C :CALL(@exp_num + RR); out:[B: 2**RR] @@ -814,7 +821,6 @@ SHLarithinit: SHLarith0: 0 => E - :JMP(SHLarithfinal) SHLarithfinal: E => A @@ -1353,10 +1359,13 @@ checkBytecodeStartsEF: ; get 1 byte from memory 1 => C :CALL(MLOADX) ; in: [E: offset, C: length] out: [A: value , E: new offset] - 31 => D :CALL(SHRarith) ; in: [A: value, D: #bytes to right shift] out: [A: shifted result] + ; mask first byte + 0xFF00000000000000000000000000000000000000000000000000000000000000n => B + $ => A :AND ; check if byte read is equal to 0xEF - %BYTECODE_STARTS_EF - A :JMPNZ(checkBytecodeStartsEFend) + 0xEF00000000000000000000000000000000000000000000000000000000000000n => B + $ :EQ, JMPNC(checkBytecodeStartsEFend) 1 :MSTORE(startsWithEF) checkBytecodeStartsEFend: @@ -1623,10 +1632,7 @@ expADloop: ;D = exp/2 $ => D :MLOAD(arithRes1) ;A = exp%2 (0 or 1) - $ => A :MLOAD(arithRes2) - 0 => B - ;if exp%2 == 0 --> expADloop0 - $ :EQ,JMPC(expADloop0) + $ => A :MLOAD(arithRes2), JMPZ(expADloop0) ;if exp%2 == 0 --> expADloop0 E :MSTORE(arithA) ;mulARITH --> E*C C :MSTORE(arithB), CALL(mulARITH) @@ -2279,7 +2285,6 @@ VAR GLOBAL readXFromCalldataResult VAR GLOBAL tmpVarAReadXFromOffset VAR GLOBAL tmpVarBReadXFromOffset VAR GLOBAL tmpVarCReadXFromOffset -VAR GLOBAL tmpVarDReadXFromOffset VAR GLOBAL tmpVarEReadXFromOffset ; @info Reads {readXFromCalldataOffset} bytes (max 32) from a given offset in calldata memory. If offset or offset + length exceeds txCalldataLen, zeros are added ; @internalParam {readXFromCalldataOffset} offset to read from calldata diff --git a/package.json b/package.json index 56c0e7da..130332d9 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-fork.7", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#develop-eldelberry", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#feature/change-block-gas-limit", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#feature/vcounters-optimizations-1", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0",