@zkasm/zkevm-rom 0.0.1-security → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @zkasm/zkevm-rom might be problematic. Click here for more details.
- package/.eslintrc.js +33 -0
- package/.github/CODEOWNERS +14 -0
- package/.github/ISSUE_TEMPLATE/bug.yml +38 -0
- package/.github/ISSUE_TEMPLATE/feature.yml +26 -0
- package/.github/ISSUE_TEMPLATE/question.yml +26 -0
- package/.github/workflows/main.yaml +40 -0
- package/LICENSE +636 -0
- package/README.md +23 -5
- package/audits/Hexens_Polygon_zkEVM_PUBLIC_27.02.23.pdf +0 -0
- package/audits/Polygon-zkEVM-Public-v1.1-verichains-19-03-2024.pdf +0 -0
- package/audits/zkEVM-ROM-upgrade-1-Spearbit-30-May.pdf +0 -0
- package/audits/zkEVM-ROM-upgrade-2-Spearbit-21-August.pdf +0 -0
- package/audits/zkEVM-engagement-1-Spearbit-27-March.pdf +0 -0
- package/audits/zkEVM-engagement-2-Spearbit-27-March.pdf +0 -0
- package/audits/zkEVM-engagement-3-Spearbit-6-April.pdf +0 -0
- package/counters/README.md +45 -0
- package/counters/counters-executor.js +80 -0
- package/counters/countersConstants.zkasm +370 -0
- package/counters/endIncludes.zkasm +18 -0
- package/counters/initIncludes.zkasm +2 -0
- package/counters/tests/MLOAD32.zkasm +27 -0
- package/counters/tests/MLOADX.zkasm +30 -0
- package/counters/tests/MSTORE32.zkasm +32 -0
- package/counters/tests/MSTOREX.zkasm +36 -0
- package/counters/tests/SHLarith.zkasm +28 -0
- package/counters/tests/SHLarithBit.zkasm +28 -0
- package/counters/tests/SHRarith.zkasm +28 -0
- package/counters/tests/SHRarithBit.zkasm +28 -0
- package/counters/tests/abs.zkasm +29 -0
- package/counters/tests/addBatchHashByteByByte.zkasm +31 -0
- package/counters/tests/computeGasSendCall.zkasm +30 -0
- package/counters/tests/divArith.zkasm +27 -0
- package/counters/tests/expAD.zkasm +30 -0
- package/counters/tests/getLenBits.zkasm +30 -0
- package/counters/tests/getLenBytes.zkasm +32 -0
- package/counters/tests/isEmptyAccount.zkasm +30 -0
- package/counters/tests/mulARITH.zkasm +28 -0
- package/counters/tests/offsetUtil.zkasm +29 -0
- package/counters/tests/opADDMOD.zkasm +28 -0
- package/counters/tests/opAdd.zkasm +27 -0
- package/counters/tests/opBLOCKHASH.zkasm +28 -0
- package/counters/tests/opCALL.zkasm +41 -0
- package/counters/tests/opCALLCODE.zkasm +41 -0
- package/counters/tests/opCALLDATACOPY.zkasm +28 -0
- package/counters/tests/opCALLDATALOAD.zkasm +27 -0
- package/counters/tests/opCODECOPY.zkasm +28 -0
- package/counters/tests/opCREATE.zkasm +35 -0
- package/counters/tests/opCREATE2.zkasm +35 -0
- package/counters/tests/opDELEGATECALL.zkasm +35 -0
- package/counters/tests/opDIV.zkasm +27 -0
- package/counters/tests/opEXP.zkasm +29 -0
- package/counters/tests/opEXTCODECOPY.zkasm +29 -0
- package/counters/tests/opMOD.zkasm +27 -0
- package/counters/tests/opMUL.zkasm +27 -0
- package/counters/tests/opMULMOD.zkasm +28 -0
- package/counters/tests/opRETURN.zkasm +32 -0
- package/counters/tests/opRETURNDATACOPY.zkasm +29 -0
- package/counters/tests/opREVERT.zkasm +32 -0
- package/counters/tests/opSDIV.zkasm +28 -0
- package/counters/tests/opSHA3.zkasm +28 -0
- package/counters/tests/opSIGNEXTEND.zkasm +27 -0
- package/counters/tests/opSMOD.zkasm +28 -0
- package/counters/tests/opSTATICCALL.zkasm +35 -0
- package/counters/tests/opSUB.zkasm +27 -0
- package/counters/tests/saveMem.zkasm +31 -0
- package/docs/opcode-cost-zk-counters.md +315 -0
- package/docs/usage-ecrecover.md +51 -0
- package/index.js +43 -0
- package/main/block-info.zkasm +204 -0
- package/main/constants.zkasm +145 -0
- package/main/ecrecover/addFpEc.zkasm +31 -0
- package/main/ecrecover/checkSqrtFpEc.zkasm +1558 -0
- package/main/ecrecover/constEc.zkasm +13 -0
- package/main/ecrecover/ecrecover.zkasm +280 -0
- package/main/ecrecover/invFnEc.zkasm +44 -0
- package/main/ecrecover/invFpEc.zkasm +45 -0
- package/main/ecrecover/mulFnEc.zkasm +36 -0
- package/main/ecrecover/mulFpEc.zkasm +36 -0
- package/main/ecrecover/mulPointEc.zkasm +311 -0
- package/main/ecrecover/sqFpEc.zkasm +38 -0
- package/main/ecrecover/sqrtFpEc.zkasm +70 -0
- package/main/end.zkasm +4 -0
- package/main/l2-tx-hash.zkasm +159 -0
- package/main/load-change-l2-block-utils.zkasm +11 -0
- package/main/load-change-l2-block.zkasm +28 -0
- package/main/load-tx-rlp-utils.zkasm +72 -0
- package/main/load-tx-rlp.zkasm +431 -0
- package/main/main.zkasm +237 -0
- package/main/map-opcodes.zkasm +274 -0
- package/main/modexp/array_lib/array_add_AGTB.zkasm +123 -0
- package/main/modexp/array_lib/array_add_short.zkasm +85 -0
- package/main/modexp/array_lib/array_div.zkasm +215 -0
- package/main/modexp/array_lib/array_div_long.zkasm +284 -0
- package/main/modexp/array_lib/array_div_short.zkasm +222 -0
- package/main/modexp/array_lib/array_mul.zkasm +97 -0
- package/main/modexp/array_lib/array_mul_long.zkasm +156 -0
- package/main/modexp/array_lib/array_mul_short.zkasm +127 -0
- package/main/modexp/array_lib/array_square.zkasm +246 -0
- package/main/modexp/array_lib/unused/array_add.zkasm +100 -0
- package/main/modexp/array_lib/unused/array_is_odd.zkasm +23 -0
- package/main/modexp/array_lib/unused/array_is_one.zkasm +33 -0
- package/main/modexp/array_lib/unused/array_is_zero.zkasm +34 -0
- package/main/modexp/array_lib/unused/array_sub_AGTB.zkasm +111 -0
- package/main/modexp/array_lib/unused/array_unshift.zkasm +37 -0
- package/main/modexp/array_lib/utils/array_compare.zkasm +82 -0
- package/main/modexp/array_lib/utils/array_trim.zkasm +49 -0
- package/main/modexp/constants.zkasm +5 -0
- package/main/modexp/modexp.zkasm +296 -0
- package/main/modexp/modexp_utils.zkasm +230 -0
- package/main/opcodes/arithmetic.zkasm +357 -0
- package/main/opcodes/block.zkasm +163 -0
- package/main/opcodes/calldata-returndata-code.zkasm +619 -0
- package/main/opcodes/comparison.zkasm +446 -0
- package/main/opcodes/context-information.zkasm +169 -0
- package/main/opcodes/create-terminate-context.zkasm +1011 -0
- package/main/opcodes/crypto.zkasm +96 -0
- package/main/opcodes/flow-control.zkasm +126 -0
- package/main/opcodes/logs.zkasm +193 -0
- package/main/opcodes/stack-operations.zkasm +658 -0
- package/main/opcodes/storage-memory.zkasm +313 -0
- package/main/pairings/BN254/addPointBN254.zkasm +245 -0
- package/main/pairings/BN254/ecAdd.zkasm +312 -0
- package/main/pairings/BN254/ecMul.zkasm +159 -0
- package/main/pairings/BN254/escalarMulBN254.zkasm +155 -0
- package/main/pairings/BN254/lineDiffPointsBN254.zkasm +83 -0
- package/main/pairings/BN254/lineSamePointsBN254.zkasm +96 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm +49 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +236 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm +444 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm +212 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm +228 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm +64 -0
- package/main/pairings/FP12BN254/frob2Fp12BN254.zkasm +80 -0
- package/main/pairings/FP12BN254/frob3Fp12BN254.zkasm +96 -0
- package/main/pairings/FP12BN254/frobFp12BN254.zkasm +96 -0
- package/main/pairings/FP12BN254/inverseFp12BN254.zkasm +289 -0
- package/main/pairings/FP12BN254/mulFp12BN254.zkasm +408 -0
- package/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm +296 -0
- package/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm +291 -0
- package/main/pairings/FP12BN254/squareFp12BN254.zkasm +376 -0
- package/main/pairings/FP2BN254/addFp2BN254.zkasm +19 -0
- package/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm +20 -0
- package/main/pairings/FP2BN254/invFp2BN254.zkasm +66 -0
- package/main/pairings/FP2BN254/mulFp2BN254.zkasm +19 -0
- package/main/pairings/FP2BN254/squareFp2BN254.zkasm +21 -0
- package/main/pairings/FP2BN254/subFp2BN254.zkasm +19 -0
- package/main/pairings/FP4BN254/squareFp4BN254.zkasm +76 -0
- package/main/pairings/FP6BN254/addFp6BN254.zkasm +59 -0
- package/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm +51 -0
- package/main/pairings/FP6BN254/inverseFp6BN254.zkasm +208 -0
- package/main/pairings/FP6BN254/mulFp6BN254.zkasm +201 -0
- package/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm +65 -0
- package/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm +134 -0
- package/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm +128 -0
- package/main/pairings/FP6BN254/squareFp6BN254.zkasm +147 -0
- package/main/pairings/FP6BN254/subFp6BN254.zkasm +59 -0
- package/main/pairings/FPBN254/addFpBN254.zkasm +29 -0
- package/main/pairings/FPBN254/invFpBN254.zkasm +55 -0
- package/main/pairings/FPBN254/mulFpBN254.zkasm +29 -0
- package/main/pairings/FPBN254/reduceFpBN254.zkasm +25 -0
- package/main/pairings/FPBN254/squareFpBN254.zkasm +31 -0
- package/main/pairings/FPBN254/subFpBN254.zkasm +36 -0
- package/main/pairings/FRBN254/reduceFrBN254.zkasm +25 -0
- package/main/pairings/constants.zkasm +62 -0
- package/main/pairings/ecPairing.zkasm +244 -0
- package/main/pairings/finalExpBN254.zkasm +2095 -0
- package/main/pairings/halfPairingBN254.zkasm +428 -0
- package/main/pairings/loopLengthBN254.zkasm +75 -0
- package/main/pairings/millerLoopBN254.zkasm +741 -0
- package/main/pairings/pairingBN254.zkasm +481 -0
- package/main/pairings/unused/addFp12BN254.zkasm +130 -0
- package/main/pairings/unused/expByXCycloFp12BN254.zkasm +411 -0
- package/main/pairings/unused/expFp12BN254.zkasm +333 -0
- package/main/pairings/unused/subFp12BN254.zkasm +130 -0
- package/main/pairings/unused/xPseudoBinDecompBN254.zkasm +68 -0
- package/main/pairings/utilsTests/expCycloFp12BN254.zkasm +334 -0
- package/main/precompiled/end.zkasm +42 -0
- package/main/precompiled/identity.zkasm +99 -0
- package/main/precompiled/pre-ecAdd.zkasm +84 -0
- package/main/precompiled/pre-ecMul.zkasm +82 -0
- package/main/precompiled/pre-ecPairing.zkasm +72 -0
- package/main/precompiled/pre-ecrecover.zkasm +71 -0
- package/main/precompiled/pre-modexp.zkasm +367 -0
- package/main/precompiled/pre-sha2-256.zkasm +125 -0
- package/main/precompiled/revert-precompiled.zkasm +25 -0
- package/main/precompiled/selector.zkasm +77 -0
- package/main/process-change-l2-block.zkasm +147 -0
- package/main/process-tx.zkasm +587 -0
- package/main/tables/2-exp.zkasm +260 -0
- package/main/touched.zkasm +118 -0
- package/main/utils.zkasm +2335 -0
- package/main/vars.zkasm +117 -0
- package/package.json +62 -3
- package/test/bytes-length.zkasm +39 -0
- package/test/ecrecover.zkasm +538 -0
- package/test/lt4-test.zkasm +38 -0
- package/test/mstorex.zkasm +191 -0
- package/test/opcalldatacopy.ignore.zkasm +331 -0
- package/test/performance/read-push.zkasm +71 -0
- package/test/read-push.zkasm +304 -0
- package/test/testArrayArith.zkasm +1099 -0
- package/test/testArrayUtils.zkasm +335 -0
- package/test/testCycloFp12ArithBN254.zkasm +548 -0
- package/test/testEcAdd.zkasm +252 -0
- package/test/testEcMul.zkasm +231 -0
- package/test/testEcPairing.zkasm +436 -0
- package/test/testFinalExpBn254.zkasm +139 -0
- package/test/testFp12ArithBN254.zkasm +692 -0
- package/test/testFp2ArithBN254.zkasm +185 -0
- package/test/testFp4ArithBN254.zkasm +128 -0
- package/test/testFp6ArithBN254.zkasm +260 -0
- package/test/testFpArithBN254.zkasm +159 -0
- package/test/testFrArithBN254.zkasm +113 -0
- package/test/testHalfPairingBN254.zkasm +285 -0
- package/test/testModExp.zkasm +586 -0
- package/test/testModExpReturn.zkasm +81 -0
- package/test/testPairingBN254.zkasm +463 -0
- package/test/testPointArithBN254.zkasm +270 -0
- package/test/testSHA256.zkasm +27 -0
- package/test/touched-assert.zkasm +59 -0
- package/test/utils-expAD.zkasm +48 -0
- package/test/utils-getLenBytes.zkasm +36 -0
- package/tools/audit-tools/registry-op-checker.js +71 -0
- package/tools/get-not-used-labels.js +31 -0
- package/tools/helpers/helpers.js +47 -0
- package/tools/modexp-utils/README.md +5 -0
- package/tools/modexp-utils/modexp-test-gen.js +168 -0
- package/tools/modexp-utils/modexp-test-int.sage +37 -0
- package/tools/parallel-testing/checker.sh +6 -0
- package/tools/parallel-testing/gen-parallel-tests.js +78 -0
- package/tools/parallel-testing/parallel-tests-sample/sample.test.js +136 -0
- package/tools/run-tests-zkasm.js +83 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
;@info: Add 'data' bytes to batchHashData. batchHashData = H_keccak( transactions )
|
2
|
+
;@in: D: length of the hash
|
3
|
+
addBatchHashData:
|
4
|
+
$ => HASHPOS :MLOAD(batchHashPos)
|
5
|
+
$ => E :MLOAD(batchHashDataId)
|
6
|
+
A :HASHK(E)
|
7
|
+
HASHPOS :MSTORE(batchHashPos)
|
8
|
+
C => HASHPOS
|
9
|
+
$ => E :MLOAD(lastHashKIdUsed), RETURN
|
10
|
+
|
11
|
+
;; get D bytes from transaction bytes
|
12
|
+
;@in D: number of bytes to get
|
13
|
+
;@in C: current data parsed pointer
|
14
|
+
;@out A: D bytes from batch data at offset C
|
15
|
+
getTxBytes:
|
16
|
+
$ => A :MLOAD(batchL2DataLength)
|
17
|
+
$ => B :MLOAD(batchL2DataParsed)
|
18
|
+
A - B - C - D :JMPN(invalidTxRLP)
|
19
|
+
${getTxs(p,D)} => A
|
20
|
+
$${p = p + D}
|
21
|
+
:RETURN
|
22
|
+
|
23
|
+
;; Add bytes to generate ethereum signed message
|
24
|
+
;; - legacy transaction: signedMessage = H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0))
|
25
|
+
;; - pre EIP-155: signedMessage = H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data))
|
26
|
+
addHashTx:
|
27
|
+
$ => A :MLOAD(txRLPLength)
|
28
|
+
A - HASHPOS - D :JMPN(invalidTxRLP)
|
29
|
+
addHashTxBegin:
|
30
|
+
$ => A :MLOAD(batchL2DataLength)
|
31
|
+
$ => B :MLOAD(batchL2DataParsed)
|
32
|
+
A - B - C - D :JMPN(invalidTxRLP)
|
33
|
+
${getTxs(p,D)} => A
|
34
|
+
$${p = p + D}
|
35
|
+
A :HASHK(E)
|
36
|
+
C + D => C :RETURN
|
37
|
+
|
38
|
+
|
39
|
+
;; Check short value is over 127. Error RLP: single byte < 0x80 are not prefixed
|
40
|
+
checkShortRLP:
|
41
|
+
D - 1 :JMPNZ(skipCheckShort)
|
42
|
+
A - %MIN_VALUE_SHORT :JMPN(invalidTxRLP)
|
43
|
+
|
44
|
+
skipCheckShort:
|
45
|
+
:RETURN
|
46
|
+
|
47
|
+
;; Check long list/value is over 55 bytes long. Error RLP: encoded list too short
|
48
|
+
checkLongRLP:
|
49
|
+
A - %MIN_BYTES_LONG :JMPN(invalidTxRLP)
|
50
|
+
:RETURN
|
51
|
+
|
52
|
+
;; Check short value is over 127. Error RLP: single byte < 0x80 are not prefixed
|
53
|
+
checkShortDataRLP:
|
54
|
+
$ => B :MLOAD(txCalldataLen)
|
55
|
+
B - 1 :JMPNZ(skipCheckShortData)
|
56
|
+
A - %MIN_VALUE_SHORT :JMPN(invalidTxRLP)
|
57
|
+
|
58
|
+
skipCheckShortData:
|
59
|
+
:RETURN
|
60
|
+
|
61
|
+
;; Check non-negative integer RLP representation has no leading zeros and it is encoded in its shortest form
|
62
|
+
VAR GLOBAL tmpVarAcheckNonLeadingZeros
|
63
|
+
VAR GLOBAL tmpVarZkPCcheckNonLeadingZeros
|
64
|
+
checkNonLeadingZeros:
|
65
|
+
RR :MSTORE(tmpVarZkPCcheckNonLeadingZeros)
|
66
|
+
A :MSTORE(tmpVarAcheckNonLeadingZeros)
|
67
|
+
; set value to B and get its
|
68
|
+
A => B :CALL(getLenBytes) ; in: [B: number] out: [A: byte length of B]
|
69
|
+
; check (bytes length - encoded length) are not equal
|
70
|
+
D - A :JMPNZ(invalidTxRLP)
|
71
|
+
$ => RR :MLOAD(tmpVarZkPCcheckNonLeadingZeros)
|
72
|
+
$ => A :MLOAD(tmpVarAcheckNonLeadingZeros), RETURN
|
@@ -0,0 +1,431 @@
|
|
1
|
+
INCLUDE "load-tx-rlp-utils.zkasm"
|
2
|
+
INCLUDE "load-change-l2-block.zkasm"
|
3
|
+
INCLUDE "l2-tx-hash.zkasm"
|
4
|
+
|
5
|
+
; Blocks RLP parsing
|
6
|
+
; A - Initialization
|
7
|
+
; B - Read and check RLP fields. Fill 'batchHashData' and Ethereum signed transaction bytes
|
8
|
+
; C - Read signature. Fill 'batchHashData' bytes
|
9
|
+
; D - Finish RLP parsing
|
10
|
+
; E - Handler error RLP fields
|
11
|
+
|
12
|
+
;;;;;;;;;;;;;;;;;;
|
13
|
+
;; A - Initialization
|
14
|
+
;; - Data to parse
|
15
|
+
;; - legacy transaction: [rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0)|r|s|v|effectivePercentage]
|
16
|
+
;; - pre EIP-155 transaction (https://eips.ethereum.org/EIPS/eip-155): [rlp(nonce, gasprice, gaslimit, to, value, data)|r|s|v|effectivePercentage]
|
17
|
+
;; - internal transaction changeL2Block: [txType, deltaTimestamp, indexL1InfoTree]
|
18
|
+
;; - Signed Ethereum transaction
|
19
|
+
;; - legacy transaction: H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0))
|
20
|
+
;; - pre EIP-155 transaction: H_keccak(rlp(nonce, gasprice, gaslimit, to, value, data))
|
21
|
+
;; - RLP encoding information: https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp
|
22
|
+
;; - Entire batch is discarded (no transaction is processed) if any error is found
|
23
|
+
;;;;;;;;;;;;;;;;;;
|
24
|
+
|
25
|
+
loadTx_rlp:
|
26
|
+
; check one keccak is available to begin processing the RLP
|
27
|
+
$ => D :MLOAD(cntKeccakPreProcess)
|
28
|
+
%MAX_CNT_KECCAK_F - CNT_KECCAK_F - 1 - D :JMPN(outOfCountersKeccak)
|
29
|
+
|
30
|
+
; Pointer to next RLP bytes to read
|
31
|
+
0 => C
|
32
|
+
; Check it is a change L2 block transaction
|
33
|
+
%TX_TYPE_NUM_BYTES => D
|
34
|
+
; batchL2DataLength is not zero (at least 1 byte), checked at main
|
35
|
+
${getTxs(p,D)} => A
|
36
|
+
$${p = p + D}
|
37
|
+
C + D => C :CALL(addBatchHashData)
|
38
|
+
A - %CHANGE_L2_BLOCK_TX_TYPE :JMPZ(decodeChangeL2BlockTx)
|
39
|
+
checkFirstTxType:
|
40
|
+
; First transaction must be a change L2 block transaction if it is NOT a forced batch
|
41
|
+
$ :MLOAD(pendingTxs), JMPNZ(loadTx_rlp_continue)
|
42
|
+
; If it is not forced and it is not a change L2 block transaction, we discard the entire batch
|
43
|
+
$ :MLOAD(isForced), JMPZ(invalidNotFirstTxChangeL2Block)
|
44
|
+
|
45
|
+
loadTx_rlp_continue:
|
46
|
+
; We get a new hashId
|
47
|
+
$ => E :MLOAD(nextHashPId)
|
48
|
+
E :MSTORE(l2TxHashPointer)
|
49
|
+
E + 1 :MSTORE(nextHashPId)
|
50
|
+
$ => E :MLOAD(lastHashKIdUsed)
|
51
|
+
E + 1 => E :MSTORE(lastHashKIdUsed)
|
52
|
+
;;;;;;;;;;;;;;;;;;
|
53
|
+
;; B - Read and check RLP fields. Fill 'batchHashData' and Ethereum signed transaction bytes
|
54
|
+
;;;;;;;;;;;;;;;;;;
|
55
|
+
|
56
|
+
;; Read RLP list length
|
57
|
+
; Add first byte to tx hash and batch hash
|
58
|
+
; A new hash with position 0 is started
|
59
|
+
0 => HASHPOS
|
60
|
+
A :HASHK(E)
|
61
|
+
A - 0xc1 :JMPN(invalidTxRLP)
|
62
|
+
A - 0xf8 :JMPN(shortList)
|
63
|
+
; do not allow lists over 2**24 bytes length
|
64
|
+
; Transaction could not have more than 120.000 due to smart contract limitation (keccaks counters)
|
65
|
+
; meaning that the RLP encoding is wrong
|
66
|
+
A - 0xfb :JMPN(longList, invalidTxRLP)
|
67
|
+
|
68
|
+
longList:
|
69
|
+
A - 0xf7 => D :CALL(addHashTxBegin)
|
70
|
+
:CALL(addBatchHashData)
|
71
|
+
:CALL(checkLongRLP)
|
72
|
+
:CALL(checkNonLeadingZeros)
|
73
|
+
:JMP(endList)
|
74
|
+
shortList:
|
75
|
+
A - 0xc0 => A
|
76
|
+
|
77
|
+
endList:
|
78
|
+
A + C => B :MSTORE(txRLPLength)
|
79
|
+
; Check enough keccak zk counters to digest tx hash
|
80
|
+
; We don't check poseidon counters spent for l2 tx hash computing because the number of poseidon counters available is x100 the number of keccak available
|
81
|
+
; so while rlp parsing, keccaks will always be the bottleneck
|
82
|
+
B + 1 :MSTORE(arithA)
|
83
|
+
136 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB]
|
84
|
+
$ => B :MLOAD(arithRes1)
|
85
|
+
$ => D :MLOAD(cntKeccakPreProcess)
|
86
|
+
%MAX_CNT_KECCAK_F - CNT_KECCAK_F - B - D - 1 :JMPN(outOfCountersKeccak)
|
87
|
+
:CALL (initL2HashTx)
|
88
|
+
|
89
|
+
;; Read RLP 'nonce'
|
90
|
+
; 64 bits max
|
91
|
+
nonceREAD:
|
92
|
+
1 => D :CALL(addHashTx)
|
93
|
+
:CALL(addBatchHashData)
|
94
|
+
A - 0x80 :JMPN(endNonce)
|
95
|
+
A - 0x81 :JMPN(nonce0)
|
96
|
+
A - 0x89 :JMPN(shortNonce, invalidTxRLP)
|
97
|
+
|
98
|
+
nonce0:
|
99
|
+
0 => A :MSTORE(lengthNonce), JMP(endNonce)
|
100
|
+
|
101
|
+
shortNonce:
|
102
|
+
A - 0x80 => D
|
103
|
+
D :MSTORE(lengthNonce),CALL(addHashTx)
|
104
|
+
:CALL(addBatchHashData)
|
105
|
+
:CALL(checkShortRLP)
|
106
|
+
:CALL(checkNonLeadingZeros)
|
107
|
+
|
108
|
+
endNonce:
|
109
|
+
8 => D
|
110
|
+
A :MSTORE(txNonce), CALL(addL2HashTx)
|
111
|
+
|
112
|
+
;; Read RLP 'gas price'
|
113
|
+
; 256 bits max
|
114
|
+
gasPriceREAD:
|
115
|
+
1 => D :CALL(addHashTx)
|
116
|
+
:CALL(addBatchHashData)
|
117
|
+
A - 0x80 :JMPN(endGasPrice)
|
118
|
+
A - 0x81 :JMPN(gasPrice0)
|
119
|
+
A - 0xa1 :JMPN(shortGasPrice, invalidTxRLP)
|
120
|
+
|
121
|
+
gasPrice0:
|
122
|
+
0 => A :JMP(endGasPrice)
|
123
|
+
|
124
|
+
shortGasPrice:
|
125
|
+
A - 0x80 => D :CALL(addHashTx)
|
126
|
+
:CALL(addBatchHashData)
|
127
|
+
:CALL(checkShortRLP)
|
128
|
+
:CALL(checkNonLeadingZeros)
|
129
|
+
|
130
|
+
endGasPrice:
|
131
|
+
32 => D
|
132
|
+
A :MSTORE(txGasPriceRLP), CALL(addL2HashTx)
|
133
|
+
|
134
|
+
|
135
|
+
;; Read RLP 'gas limit'
|
136
|
+
; 64 bits max
|
137
|
+
gasLimitREAD:
|
138
|
+
1 => D :CALL(addHashTx)
|
139
|
+
:CALL(addBatchHashData)
|
140
|
+
A - 0x80 :JMPN(endGasLimit)
|
141
|
+
A - 0x81 :JMPN(gasLimit0)
|
142
|
+
A - 0x89 :JMPN(shortGasLimit, invalidTxRLP)
|
143
|
+
|
144
|
+
gasLimit0:
|
145
|
+
0 => A :JMP(endGasLimit)
|
146
|
+
|
147
|
+
shortGasLimit:
|
148
|
+
A - 0x80 => D :CALL(addHashTx)
|
149
|
+
:CALL(addBatchHashData)
|
150
|
+
:CALL(checkShortRLP)
|
151
|
+
:CALL(checkNonLeadingZeros)
|
152
|
+
|
153
|
+
endGasLimit:
|
154
|
+
8 => D
|
155
|
+
A :MSTORE(txGasLimit), CALL(addL2HashTx)
|
156
|
+
|
157
|
+
;; Read RLP 'to'
|
158
|
+
; 160 bits or empty
|
159
|
+
toREAD:
|
160
|
+
1 => D :CALL(addHashTx)
|
161
|
+
:CALL(addBatchHashData)
|
162
|
+
A - 0x80 :JMPN(invalidTxRLP)
|
163
|
+
A - 0x81 :JMPN(noTo)
|
164
|
+
A - 0x94 :JMPN(invalidTxRLP)
|
165
|
+
A - 0x95 :JMPN(shortTo, invalidTxRLP)
|
166
|
+
|
167
|
+
noTo:
|
168
|
+
1 :MSTORE(isCreateContract), CALL(addL2HashTx_isDeploy)
|
169
|
+
:JMP(endTo)
|
170
|
+
|
171
|
+
shortTo:
|
172
|
+
A - 0x80 => D :CALL(addHashTx)
|
173
|
+
:CALL(addL2HashTx_isNotDeploy)
|
174
|
+
:CALL(addL2HashTx)
|
175
|
+
:CALL(addBatchHashData)
|
176
|
+
A :MSTORE(txDestAddr)
|
177
|
+
A :MSTORE(storageAddr)
|
178
|
+
|
179
|
+
endTo:
|
180
|
+
|
181
|
+
;; Read RLP 'value'
|
182
|
+
; 256 bits max
|
183
|
+
valueREAD:
|
184
|
+
1 => D :CALL(addHashTx)
|
185
|
+
:CALL(addBatchHashData)
|
186
|
+
A - 0x80 :JMPN(endValue)
|
187
|
+
A - 0x81 :JMPN(value0)
|
188
|
+
A - 0xa1 :JMPN(shortValue, invalidTxRLP)
|
189
|
+
|
190
|
+
value0:
|
191
|
+
0 => A :JMP(endValue)
|
192
|
+
|
193
|
+
shortValue:
|
194
|
+
A - 0x80 => D :CALL(addHashTx)
|
195
|
+
:CALL(addBatchHashData)
|
196
|
+
:CALL(checkShortRLP)
|
197
|
+
:CALL(checkNonLeadingZeros)
|
198
|
+
|
199
|
+
endValue:
|
200
|
+
32 => D
|
201
|
+
A :MSTORE(txValue), CALL(addL2HashTx)
|
202
|
+
|
203
|
+
;; Read RLP 'data'
|
204
|
+
; should not be a list
|
205
|
+
dataREAD:
|
206
|
+
; Set calldata offset and CTX
|
207
|
+
$ => D :MLOAD(globalCalldataMemoryOffset)
|
208
|
+
%CALLDATA_RESERVED_CTX :MSTORE(calldataCTX)
|
209
|
+
D * 32 :MSTORE(calldataOffset)
|
210
|
+
$ => D :MLOAD(batchHashPos)
|
211
|
+
D :MSTORE(dataStarts)
|
212
|
+
1 => D :CALL(addHashTx)
|
213
|
+
:CALL(addBatchHashData)
|
214
|
+
A - 0x80 :JMPN(veryShortData)
|
215
|
+
A - 0x81 :JMPN(zeroBytesData)
|
216
|
+
A - 0xb8 :JMPN(shortData)
|
217
|
+
; do not allow string over 2**24 bytes length
|
218
|
+
; Transaction could not have more than 120.000 due to smart contract limitation (keccaks counters)
|
219
|
+
; meaning that the RLP encoding is wrong
|
220
|
+
A - 0xbb :JMPN(longData, invalidTxRLP)
|
221
|
+
|
222
|
+
veryShortData:
|
223
|
+
1 :MSTORE(txCalldataLen), CALL(addL2HashTx_dataLength)
|
224
|
+
:CALL(addL2HashTx)
|
225
|
+
31 => D :CALL(SHLarith) ; in: [A: value, D: #bytes to left shift] out: [A: shifted result]
|
226
|
+
; Store current CTX
|
227
|
+
CTX => B
|
228
|
+
; Store calldata to calldata CTX's memory
|
229
|
+
%CALLDATA_RESERVED_CTX => CTX
|
230
|
+
$ => E :MLOAD(globalCalldataMemoryOffset)
|
231
|
+
A :MSTORE(MEM:E)
|
232
|
+
E + 1 :MSTORE(globalCalldataMemoryOffset)
|
233
|
+
$ => E :MLOAD(lastHashKIdUsed)
|
234
|
+
; Restore current CTX
|
235
|
+
B => CTX :JMP(endData)
|
236
|
+
|
237
|
+
shortData:
|
238
|
+
$ => D :MLOAD(batchHashPos)
|
239
|
+
D :MSTORE(dataStarts)
|
240
|
+
A - 0x80 => B :MSTORE(txCalldataLen), CALL(addL2HashTx_dataLength)
|
241
|
+
:JMP(readData)
|
242
|
+
|
243
|
+
longData:
|
244
|
+
A - 0xb7 => D :CALL(addHashTx)
|
245
|
+
:CALL(addBatchHashData)
|
246
|
+
:CALL(checkLongRLP)
|
247
|
+
:CALL(checkNonLeadingZeros)
|
248
|
+
$ => D :MLOAD(batchHashPos)
|
249
|
+
D :MSTORE(dataStarts)
|
250
|
+
A => B :MSTORE(txCalldataLen), CALL(addL2HashTx_dataLength)
|
251
|
+
|
252
|
+
readData:
|
253
|
+
32 => D
|
254
|
+
B - D :JMPN(readDataFinal)
|
255
|
+
B - D :MSTORE(txDataRead), CALL(addHashTx)
|
256
|
+
$ => E :MLOAD(globalCalldataMemoryOffset), CALL(addL2HashTx)
|
257
|
+
; Store current CTX
|
258
|
+
CTX => B
|
259
|
+
; Store calldata to calldata CTX's memory
|
260
|
+
%CALLDATA_RESERVED_CTX => CTX
|
261
|
+
A :MSTORE(MEM:E)
|
262
|
+
; Restore current CTX
|
263
|
+
B => CTX
|
264
|
+
E + 1 :MSTORE(globalCalldataMemoryOffset), CALL(addBatchHashByteByByte) ; in: [A: bytes to add, D: bytes length] out: [E: lastHashKIdUsed, A: shifted bytes to add]
|
265
|
+
$ => B :MLOAD(txDataRead), JMP(readData)
|
266
|
+
|
267
|
+
readDataFinal:
|
268
|
+
B - 1 :JMPN(endData)
|
269
|
+
B => D :CALL(addHashTx)
|
270
|
+
:CALL(addL2HashTx)
|
271
|
+
32 - D => D :CALL(SHLarith); in: [A: value, D: #bytes to left shift] out: [A: shifted result]
|
272
|
+
$ => E :MLOAD(globalCalldataMemoryOffset)
|
273
|
+
; Store current CTX
|
274
|
+
CTX => B
|
275
|
+
; Store calldata to calldata CTX's memory
|
276
|
+
%CALLDATA_RESERVED_CTX => CTX
|
277
|
+
A :MSTORE(MEM:E)
|
278
|
+
; Restore current CTX
|
279
|
+
B => CTX
|
280
|
+
E + 1 :MSTORE(globalCalldataMemoryOffset)
|
281
|
+
32 - D => D :CALL(addBatchHashByteByByte); in: [A: bytes to add, D: bytes length] out: [E: lastHashKIdUsed, A: shifted bytes to add]
|
282
|
+
:CALL(checkShortDataRLP)
|
283
|
+
:JMP(endData)
|
284
|
+
|
285
|
+
zeroBytesData:
|
286
|
+
:CALL(addL2HashTx_dataLength)
|
287
|
+
|
288
|
+
endData:
|
289
|
+
; Check all bytes read to detect pre EIP-155 tx, if bytes read are the same as txLength, we reached the end, so it's a pre EIP-155 tx
|
290
|
+
; txRLPLength and C is at most 120.000 bytes, no need to use a binary for comparison
|
291
|
+
$ => B :MLOAD(txRLPLength)
|
292
|
+
C - B :JMPZ(setPreEIP155Flag)
|
293
|
+
|
294
|
+
;; Read RLP 'chainId'
|
295
|
+
; 64 bits max
|
296
|
+
chainREAD:
|
297
|
+
1 => D :CALL(addHashTx)
|
298
|
+
:CALL(addBatchHashData)
|
299
|
+
A - 0x80 :JMPN(endChainId)
|
300
|
+
A - 0x81 :JMPN(chainId0)
|
301
|
+
A - 0x89 :JMPN(shortChainId, invalidTxRLP)
|
302
|
+
|
303
|
+
chainId0:
|
304
|
+
0 => A :JMP(endChainId)
|
305
|
+
|
306
|
+
|
307
|
+
shortChainId:
|
308
|
+
A - 0x80 => D :CALL(addHashTx)
|
309
|
+
:CALL(addBatchHashData)
|
310
|
+
:CALL(checkShortRLP)
|
311
|
+
:CALL(checkNonLeadingZeros)
|
312
|
+
|
313
|
+
endChainId:
|
314
|
+
8 => D
|
315
|
+
A :MSTORE(txChainId), CALL(addL2HashTx)
|
316
|
+
|
317
|
+
;; Read RLP last two values (0, 0)
|
318
|
+
2 => D :CALL(addHashTx)
|
319
|
+
:CALL(addBatchHashData)
|
320
|
+
; We compare the last two bytes of the RLP with 0x8080, no need to use a binary
|
321
|
+
A - 0x8080 :JMPZ(sizeVerification, invalidTxRLP)
|
322
|
+
|
323
|
+
setPreEIP155Flag:
|
324
|
+
1 :MSTORE(isPreEIP155)
|
325
|
+
;; size verification
|
326
|
+
; checks RLP length read at the RLP header with bytes read during RLP parsing
|
327
|
+
sizeVerification:
|
328
|
+
; txRLPLength and C is at most 120.000 bytes, no need to use a binary for comparison
|
329
|
+
$ => B :MLOAD(txRLPLength)
|
330
|
+
C - B :JMPZ(sizeVerificationSuccess, invalidTxRLP)
|
331
|
+
sizeVerificationSuccess:
|
332
|
+
HASHPOS :HASHKLEN(E)
|
333
|
+
|
334
|
+
;;;;;;;;;;;;;;;;;;
|
335
|
+
;; C - Read signature. Fill 'batchHashData' bytes
|
336
|
+
;;;;;;;;;;;;;;;;;;
|
337
|
+
|
338
|
+
;; read ecdsa 'r'
|
339
|
+
rREADTx:
|
340
|
+
32 => D :CALL(getTxBytes)
|
341
|
+
A :MSTORE(txR)
|
342
|
+
C + D => C :CALL(addBatchHashData)
|
343
|
+
|
344
|
+
;; read ecdsa 's'
|
345
|
+
sREADTx:
|
346
|
+
32 => D :CALL(getTxBytes)
|
347
|
+
A :MSTORE(txS)
|
348
|
+
C + D => C :CALL(addBatchHashData)
|
349
|
+
|
350
|
+
;; read ecdsa 'v'
|
351
|
+
vREADTx:
|
352
|
+
1 => D :CALL(getTxBytes)
|
353
|
+
A :MSTORE(txV)
|
354
|
+
C + D => C :CALL(addBatchHashData)
|
355
|
+
|
356
|
+
;; read effective percentage
|
357
|
+
effectivePercentageTx:
|
358
|
+
1 => D :CALL(getTxBytes)
|
359
|
+
A :MSTORE(effectivePercentageRLP)
|
360
|
+
C + D => C :CALL(addBatchHashData)
|
361
|
+
|
362
|
+
;;;;;;;;;
|
363
|
+
;; D - Finish RLP parsing
|
364
|
+
;;;;;;;;;
|
365
|
+
finishLoadRLP:
|
366
|
+
;; update bytes parsed
|
367
|
+
$ => A :MLOAD(batchL2DataParsed)
|
368
|
+
A + C :MSTORE(batchL2DataParsed)
|
369
|
+
;; increase number of transaction to process
|
370
|
+
$ => A :MLOAD(pendingTxs)
|
371
|
+
A + 1 :MSTORE(pendingTxs)
|
372
|
+
;; compute signature
|
373
|
+
$ => A :HASHKDIGEST(E)
|
374
|
+
A :MSTORE(txHash)
|
375
|
+
|
376
|
+
;; Compute L2txHash
|
377
|
+
;; Get source address from tx signature
|
378
|
+
$ => B :MLOAD(txR)
|
379
|
+
$ => C :MLOAD(txS)
|
380
|
+
$ => D :MLOAD(txV), CALL(ecrecover_tx)
|
381
|
+
checkAndSaveFrom:
|
382
|
+
; warning: we need to insert one transition step between label `checkAndSafeFrom` and `MSTORE(txSrcAddr)` to allow unsigned transactions from executor
|
383
|
+
20 => D
|
384
|
+
; save ecrecover error code
|
385
|
+
B :MSTORE(ecrecoverErrorCode)
|
386
|
+
; save 'from' to l2TxHash
|
387
|
+
A :MSTORE(txSrcAddr), CALL(addL2HashTx)
|
388
|
+
; save 'txType' to l2TxHash
|
389
|
+
:CALL(addL2HashTx_txType)
|
390
|
+
; close l2 tx hash
|
391
|
+
:CALL(closeL2TxHash)
|
392
|
+
:JMP(txLoopRLP)
|
393
|
+
|
394
|
+
;;;;;;;;;
|
395
|
+
;; E - Handler error RLP fields
|
396
|
+
;;;;;;;;;
|
397
|
+
invalidTxRLP:
|
398
|
+
$${eventLog(onError, invalidRLP)} :JMP(appendTxsInit)
|
399
|
+
|
400
|
+
invalidDecodeChangeL2Block:
|
401
|
+
$${eventLog(onError, invalidDecodeChangeL2Block)} :JMP(appendTxsInit)
|
402
|
+
|
403
|
+
invalidNotFirstTxChangeL2Block:
|
404
|
+
$${eventLog(onError, invalidNotFirstTxChangeL2Block)} :JMP(appendTxsInit)
|
405
|
+
|
406
|
+
appendTxsInit:
|
407
|
+
;; Append all missing 'batchL2Data' to 'batchDataHash' bytes
|
408
|
+
$ => B :MLOAD(batchL2DataLength)
|
409
|
+
$ => C :MLOAD(batchHashPos)
|
410
|
+
$${p = C}
|
411
|
+
$ => HASHPOS :MLOAD(batchHashPos)
|
412
|
+
$ => E :MLOAD(batchHashDataId)
|
413
|
+
|
414
|
+
appendTxs:
|
415
|
+
B - C - 32 :JMPN(finalAppendTxs)
|
416
|
+
32 => D
|
417
|
+
${getTxs(p,D)} => A
|
418
|
+
$${p = p + D}
|
419
|
+
A :HASHK(E)
|
420
|
+
C + D => C :JMP(appendTxs)
|
421
|
+
|
422
|
+
finalAppendTxs:
|
423
|
+
B - C => D
|
424
|
+
D - 1 :JMPN(endAppendTxs)
|
425
|
+
${getTxs(p,D)} => A
|
426
|
+
$${p = p + D}
|
427
|
+
A :HASHK(E)
|
428
|
+
C + D => C
|
429
|
+
|
430
|
+
endAppendTxs:
|
431
|
+
HASHPOS :MSTORE(batchHashPos),JMP(finalizeBatch)
|