@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
package/main/main.zkasm
ADDED
@@ -0,0 +1,237 @@
|
|
1
|
+
INCLUDE "constants.zkasm"
|
2
|
+
INCLUDE "vars.zkasm"
|
3
|
+
|
4
|
+
; Blocks zkROM
|
5
|
+
; A - Load initial registers into memory: oldStateRoot (B), oldAccInputHash (C), oldNumBatch (SP) & chainID (GAS)
|
6
|
+
; B - Compute keccaks needed to finish the batch
|
7
|
+
; C - Loop parsing RLP transactions
|
8
|
+
; D - Load blockNum variable & Loop processing transactions
|
9
|
+
; E - Batch computations: get newLocalExitRoot, assert transactions size, compute batchHashData & compute newAccInputHash
|
10
|
+
; F - Finalize execution
|
11
|
+
|
12
|
+
start: ; main zkROM entry point
|
13
|
+
;;;;;;;;;;;;;;;;;;
|
14
|
+
;; A - Load input variables
|
15
|
+
;;;;;;;;;;;;;;;;;;
|
16
|
+
STEP => A
|
17
|
+
0 :ASSERT ; Ensure it is the beginning of the execution
|
18
|
+
|
19
|
+
CTX :MSTORE(forkID)
|
20
|
+
CTX - %FORK_ID :JMPNZ(failAssert)
|
21
|
+
|
22
|
+
B => A :MSTORE(oldStateRoot)
|
23
|
+
|
24
|
+
; safety check that the input root is indeed inside the range limit of 4 goldilocks fields elements
|
25
|
+
%FOUR_GOLDILOCKS => B
|
26
|
+
1 :LT4
|
27
|
+
|
28
|
+
C :MSTORE(oldAccInputHash)
|
29
|
+
SP :MSTORE(oldNumBatch)
|
30
|
+
GAS :MSTORE(chainID) ; assumed to be less than 32 bits
|
31
|
+
|
32
|
+
${getL1InfoRoot()} :MSTORE(l1InfoRoot)
|
33
|
+
${getSequencerAddr()} :MSTORE(sequencerAddr)
|
34
|
+
${getTimestampLimit()} :MSTORE(timestampLimit)
|
35
|
+
${getTxsLen()} :MSTORE(batchL2DataLength) ; less than 120000 bytes. Enforced by the smart contract
|
36
|
+
${getForcedBlockHashL1()} => A :MSTORE(forcedBlockHashL1)
|
37
|
+
|
38
|
+
;set initial state root
|
39
|
+
$ => SR :MLOAD(oldStateRoot)
|
40
|
+
SR :MSTORE(batchSR)
|
41
|
+
; Increase batch number
|
42
|
+
SP + 1 :MSTORE(newNumBatch)
|
43
|
+
; compute isForced flag
|
44
|
+
0 => B
|
45
|
+
$ :EQ, JMPC(computeKeccaks)
|
46
|
+
1 :MSTORE(isForced)
|
47
|
+
|
48
|
+
;;;;;;;;;;;;;;;;;;
|
49
|
+
;; B - Compute keccaks needed to finish the batch
|
50
|
+
;;;;;;;;;;;;;;;;;;
|
51
|
+
computeKeccaks:
|
52
|
+
$${eventLog(onStartBatch, C)}
|
53
|
+
|
54
|
+
; Compute necessary keccak counters to finish batch
|
55
|
+
$ => A :MLOAD(batchL2DataLength)
|
56
|
+
; Divide the total data length + 1 by 136 to obtain the keccak counter increment.
|
57
|
+
; 136 is the value used by the prover to increment keccak counters
|
58
|
+
A + 1 :MSTORE(arithA)
|
59
|
+
136 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB]
|
60
|
+
$ => B :MLOAD(arithRes1)
|
61
|
+
; Compute minimum necessary keccaks to finish the batch
|
62
|
+
B + 1 + %MIN_CNT_KECCAK_BATCH => B :MSTORE(cntKeccakPreProcess)
|
63
|
+
%MAX_CNT_KECCAK_F - CNT_KECCAK_F - B :JMPN(outOfCountersKeccak)
|
64
|
+
|
65
|
+
;;;;;;;;;;;;;;;;;;
|
66
|
+
;; C - Loop parsing RLP transactions
|
67
|
+
;; - Load transaction RLP data and ensure it has correct RLP encoding
|
68
|
+
;; - If an error is found in any transaction, the batch will not process any transaction
|
69
|
+
;;;;;;;;;;;;;;;;;;
|
70
|
+
|
71
|
+
1 => E :MSTORE(lastHashKIdUsed)
|
72
|
+
0 :MSTORE(batchHashPos)
|
73
|
+
E :MSTORE(batchHashDataId)
|
74
|
+
$ => A :MLOAD(lastCtxUsed)
|
75
|
+
A + %CALLDATA_RESERVED_CTX => A :MSTORE(ctxTxToUse) ; Points at first context to be used when processing transactions. We reserve ctx = 1 for calldata
|
76
|
+
A :MSTORE(lastCtxUsed)
|
77
|
+
$${var p = 0}
|
78
|
+
; set flag isLoadingRLP to 1
|
79
|
+
1 :MSTORE(isLoadingRLP)
|
80
|
+
|
81
|
+
txLoopRLP:
|
82
|
+
$ => A :MLOAD(lastCtxUsed)
|
83
|
+
A+1 => CTX :MSTORE(lastCtxUsed)
|
84
|
+
; If batchL2DataLength is zero, we finalize batch
|
85
|
+
$ => A :MLOAD(batchL2DataLength), JMPZ(finalizeBatch)
|
86
|
+
$ => C :MLOAD(batchL2DataParsed)
|
87
|
+
C - A :JMPN(loadTx_rlp, endCheckRLP)
|
88
|
+
|
89
|
+
endCheckRLP:
|
90
|
+
; set flag isLoadingRLP to 0
|
91
|
+
0 :MSTORE(isLoadingRLP)
|
92
|
+
|
93
|
+
;;;;;;;;;;;;;;;;;;
|
94
|
+
;; D - Load blockNum variable
|
95
|
+
;; - Loop processing transactions
|
96
|
+
;; - Load transaction data and interpret it
|
97
|
+
;;;;;;;;;;;;;;;;;;
|
98
|
+
|
99
|
+
setBlockNum:
|
100
|
+
%LAST_BLOCK_STORAGE_POS => C
|
101
|
+
%ADDRESS_SYSTEM => A
|
102
|
+
%SMT_KEY_SC_STORAGE => B
|
103
|
+
$ :SLOAD,MSTORE(blockNum)
|
104
|
+
; If forced batch ==> process a forced changeL2BlockTx
|
105
|
+
$ :MLOAD(isForced), JMPZ(txLoop, handleForcedBatch)
|
106
|
+
|
107
|
+
handleForcedBatch:
|
108
|
+
1 :MSTORE(currentTx), JMP(processChangeL2Block)
|
109
|
+
|
110
|
+
txLoop:
|
111
|
+
$ => A :MLOAD(pendingTxs)
|
112
|
+
A - 1 :MSTORE(pendingTxs), JMPN(processTxsEnd)
|
113
|
+
$ => A :MLOAD(currentTx)
|
114
|
+
A + 1 :MSTORE(currentTx)
|
115
|
+
$ => A :MLOAD(ctxTxToUse) ; Load first context used by transaction
|
116
|
+
A + 1 => CTX :MSTORE(ctxTxToUse)
|
117
|
+
; Detect if transaction is a change L2 block tx
|
118
|
+
; Store initial state at the beginning of the transaction
|
119
|
+
SR :MSTORE(originSR)
|
120
|
+
$ => A :MLOAD(isChangeL2BlockTx)
|
121
|
+
A - 1 :JMPZ(processChangeL2Block, processTx)
|
122
|
+
|
123
|
+
processTxFinished:
|
124
|
+
%MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary)
|
125
|
+
; Increase cumulativeGasUsed
|
126
|
+
$ => A :MLOAD(txGasLimit)
|
127
|
+
A - GAS => A
|
128
|
+
$ => B :MLOAD(cumulativeGasUsed)
|
129
|
+
$ :ADD, MSTORE(cumulativeGasUsed), CALL(fillBlockInfoTreeWithTxReceipt)
|
130
|
+
; Increase txIndex
|
131
|
+
$ => A :MLOAD(txIndex)
|
132
|
+
A + 1 :MSTORE(txIndex)
|
133
|
+
processIntrinsicTxFinished:
|
134
|
+
$${eventLog(onFinishTx)} :JMP(txLoop)
|
135
|
+
|
136
|
+
processTxsEnd:
|
137
|
+
; Write values at storage at the end of block processing
|
138
|
+
:CALL(consolidateBlock)
|
139
|
+
finalizeBatch:
|
140
|
+
|
141
|
+
;;;;;;;;;;;;;;;;;;
|
142
|
+
;; E - Batch asserts & computations:
|
143
|
+
;; - get newLocalExitRoot
|
144
|
+
;; - assert transactions size
|
145
|
+
;; - compute batchHashData
|
146
|
+
;; - compute newAccInputHash
|
147
|
+
;;;;;;;;;;;;;;;;;;
|
148
|
+
|
149
|
+
;; Batch must be always end correctly
|
150
|
+
;; Meaning that enough zk-counters should be available to finalize it
|
151
|
+
;; - 'keccaks' are reserved at the very beginning of the batch in order to be able to perform the final 'accInputHash' hash
|
152
|
+
;; - the rest of counters will not overflow since it is added a %SAFE_RANGE bandwith
|
153
|
+
|
154
|
+
;; Get local exit root
|
155
|
+
; Read 'localExitRoot' variable from GLOBAL_EXIT_ROOT_MANAGER_L2 and store
|
156
|
+
; it to the 'newLocalExitRoot' input
|
157
|
+
%ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 => A
|
158
|
+
%SMT_KEY_SC_STORAGE => B
|
159
|
+
%LOCAL_EXIT_ROOT_STORAGE_POS => C
|
160
|
+
$ => A :SLOAD
|
161
|
+
A :MSTORE(newLocalExitRoot)
|
162
|
+
|
163
|
+
;; Transactions size verification
|
164
|
+
; Ensure bytes added to compute the 'batchHashData' matches the number of bytes loaded from input
|
165
|
+
$ => A :MLOAD(batchHashPos)
|
166
|
+
$ :MLOAD(batchL2DataLength), ASSERT
|
167
|
+
|
168
|
+
;; Compute 'batchHashData'
|
169
|
+
A => HASHPOS
|
170
|
+
$ => E :MLOAD(batchHashDataId)
|
171
|
+
|
172
|
+
HASHPOS :HASHKLEN(E)
|
173
|
+
$ => A :HASHKDIGEST(E)
|
174
|
+
|
175
|
+
A :MSTORE(batchHashData)
|
176
|
+
|
177
|
+
;; Compute 'newAccInputHash'
|
178
|
+
0 => HASHPOS
|
179
|
+
|
180
|
+
32 => D
|
181
|
+
$ => A :MLOAD(oldAccInputHash)
|
182
|
+
A :HASHK(0)
|
183
|
+
|
184
|
+
$ => A :MLOAD(batchHashData)
|
185
|
+
A :HASHK(0)
|
186
|
+
|
187
|
+
$ => A :MLOAD(l1InfoRoot)
|
188
|
+
A :HASHK(0)
|
189
|
+
|
190
|
+
8 => D
|
191
|
+
$ => A :MLOAD(timestampLimit)
|
192
|
+
A :HASHK(0)
|
193
|
+
|
194
|
+
20 => D
|
195
|
+
$ => A :MLOAD(sequencerAddr)
|
196
|
+
A :HASHK(0)
|
197
|
+
|
198
|
+
32 => D
|
199
|
+
$ => A :MLOAD(forcedBlockHashL1)
|
200
|
+
A :HASHK(0)
|
201
|
+
|
202
|
+
; finish accInputHash
|
203
|
+
HASHPOS :HASHKLEN(0)
|
204
|
+
|
205
|
+
$ => C :HASHKDIGEST(0)
|
206
|
+
C :MSTORE(newAccInputHash)
|
207
|
+
$${eventLog(onFinishBatch)}
|
208
|
+
|
209
|
+
;;;;;;;;;;;;;;;;;;
|
210
|
+
;; F - Finalize execution
|
211
|
+
;;;;;;;;;;;;;;;;;;
|
212
|
+
; safety check that the output root is indeed inside the range limit of 4 goldilocks fields elements
|
213
|
+
SR => A
|
214
|
+
%FOUR_GOLDILOCKS => B
|
215
|
+
1 :LT4
|
216
|
+
|
217
|
+
; Set output registers
|
218
|
+
$ => D :MLOAD(newAccInputHash)
|
219
|
+
$ => E :MLOAD(newLocalExitRoot)
|
220
|
+
$ => PC :MLOAD(newNumBatch)
|
221
|
+
|
222
|
+
; Set registers to its initials values
|
223
|
+
$ => CTX :MLOAD(forkID)
|
224
|
+
$ => B :MLOAD(oldStateRoot)
|
225
|
+
$ => C :MLOAD(oldAccInputHash)
|
226
|
+
$ => SP :MLOAD(oldNumBatch)
|
227
|
+
$ => GAS :MLOAD(chainID)
|
228
|
+
finalizeExecution:
|
229
|
+
:JMP(finalWait)
|
230
|
+
|
231
|
+
INCLUDE "end.zkasm"
|
232
|
+
INCLUDE "load-tx-rlp.zkasm"
|
233
|
+
INCLUDE "process-tx.zkasm"
|
234
|
+
INCLUDE "process-change-l2-block.zkasm"
|
235
|
+
INCLUDE "utils.zkasm"
|
236
|
+
INCLUDE "block-info.zkasm"
|
237
|
+
|
@@ -0,0 +1,274 @@
|
|
1
|
+
INCLUDE "opcodes/arithmetic.zkasm"
|
2
|
+
INCLUDE "opcodes/block.zkasm"
|
3
|
+
INCLUDE "opcodes/comparison.zkasm"
|
4
|
+
INCLUDE "opcodes/context-information.zkasm"
|
5
|
+
INCLUDE "opcodes/create-terminate-context.zkasm"
|
6
|
+
INCLUDE "opcodes/crypto.zkasm"
|
7
|
+
INCLUDE "opcodes/flow-control.zkasm"
|
8
|
+
INCLUDE "opcodes/logs.zkasm"
|
9
|
+
INCLUDE "opcodes/stack-operations.zkasm"
|
10
|
+
INCLUDE "opcodes/storage-memory.zkasm"
|
11
|
+
INCLUDE "opcodes/calldata-returndata-code.zkasm"
|
12
|
+
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Map all Ethereum opcodes to its rom address
|
16
|
+
* empty opcodes are set to INVALID opcode
|
17
|
+
*/
|
18
|
+
mapping_opcodes:
|
19
|
+
:JMP(opSTOP) ; 0x00
|
20
|
+
:JMP(opADD) ; 0x01
|
21
|
+
:JMP(opMUL) ; 0x02
|
22
|
+
:JMP(opSUB) ; 0x03
|
23
|
+
:JMP(opDIV) ; 0x04
|
24
|
+
:JMP(opSDIV) ; 0x05
|
25
|
+
:JMP(opMOD) ; 0x06
|
26
|
+
:JMP(opSMOD) ; 0x07
|
27
|
+
:JMP(opADDMOD) ; 0x08
|
28
|
+
:JMP(opMULMOD) ; 0x09
|
29
|
+
:JMP(opEXP) ; 0x0a
|
30
|
+
:JMP(opSIGNEXTEND) ; 0x0b
|
31
|
+
:JMP(opINVALID) ; 0x0c
|
32
|
+
:JMP(opINVALID) ; 0x0d
|
33
|
+
:JMP(opINVALID) ; 0x0e
|
34
|
+
:JMP(opINVALID) ; 0x0f
|
35
|
+
:JMP(opLT) ; 0x10
|
36
|
+
:JMP(opGT) ; 0x11
|
37
|
+
:JMP(opSLT) ; 0x12
|
38
|
+
:JMP(opSGT) ; 0x13
|
39
|
+
:JMP(opEQ) ; 0x14
|
40
|
+
:JMP(opISZERO) ; 0x15
|
41
|
+
:JMP(opAND) ; 0x16
|
42
|
+
:JMP(opOR) ; 0x17
|
43
|
+
:JMP(opXOR) ; 0x18
|
44
|
+
:JMP(opNOT) ; 0x19
|
45
|
+
:JMP(opBYTE) ; 0x1a
|
46
|
+
:JMP(opSHL) ; 0x1b
|
47
|
+
:JMP(opSHR) ; 0x1c
|
48
|
+
:JMP(opSAR) ; 0x1d
|
49
|
+
:JMP(opINVALID) ; 0x1e
|
50
|
+
:JMP(opINVALID) ; 0x1f
|
51
|
+
:JMP(opSHA3) ; 0x20
|
52
|
+
:JMP(opINVALID) ; 0x21
|
53
|
+
:JMP(opINVALID) ; 0x22
|
54
|
+
:JMP(opINVALID) ; 0x23
|
55
|
+
:JMP(opINVALID) ; 0x24
|
56
|
+
:JMP(opINVALID) ; 0x25
|
57
|
+
:JMP(opINVALID) ; 0x26
|
58
|
+
:JMP(opINVALID) ; 0x27
|
59
|
+
:JMP(opINVALID) ; 0x28
|
60
|
+
:JMP(opINVALID) ; 0x29
|
61
|
+
:JMP(opINVALID) ; 0x2a
|
62
|
+
:JMP(opINVALID) ; 0x2b
|
63
|
+
:JMP(opINVALID) ; 0x2c
|
64
|
+
:JMP(opINVALID) ; 0x2d
|
65
|
+
:JMP(opINVALID) ; 0x2e
|
66
|
+
:JMP(opINVALID) ; 0x2f
|
67
|
+
:JMP(opADDRESS) ; 0x30
|
68
|
+
:JMP(opBALANCE) ; 0x31
|
69
|
+
:JMP(opORIGIN) ; 0x32
|
70
|
+
:JMP(opCALLER) ; 0x33
|
71
|
+
:JMP(opCALLVALUE) ; 0x34
|
72
|
+
:JMP(opCALLDATALOAD) ; 0x35
|
73
|
+
:JMP(opCALLDATASIZE) ; 0x36
|
74
|
+
:JMP(opCALLDATACOPY) ; 0x37
|
75
|
+
:JMP(opCODESIZE) ; 0x38
|
76
|
+
:JMP(opCODECOPY) ; 0x39
|
77
|
+
:JMP(opGASPRICE) ; 0x3a
|
78
|
+
:JMP(opEXTCODESIZE) ; 0x3b
|
79
|
+
:JMP(opEXTCODECOPY) ; 0x3c
|
80
|
+
:JMP(opRETURNDATASIZE) ; 0x3d
|
81
|
+
:JMP(opRETURNDATACOPY) ; 0x3e
|
82
|
+
:JMP(opEXTCODEHASH) ; 0x3f
|
83
|
+
:JMP(opBLOCKHASH) ; 0x40
|
84
|
+
:JMP(opCOINBASE) ; 0x41
|
85
|
+
:JMP(opTIMESTAMP) ; 0x42
|
86
|
+
:JMP(opNUMBER) ; 0x43
|
87
|
+
:JMP(opDIFFICULTY) ; 0x44
|
88
|
+
:JMP(opGASLIMIT) ; 0x45
|
89
|
+
:JMP(opCHAINID) ; 0x46
|
90
|
+
:JMP(opSELFBALANCE) ; 0x47
|
91
|
+
:JMP(opINVALID) ; 0x48
|
92
|
+
:JMP(opINVALID) ; 0x49
|
93
|
+
:JMP(opINVALID) ; 0x4A
|
94
|
+
:JMP(opINVALID) ; 0x4B
|
95
|
+
:JMP(opINVALID) ; 0x4C
|
96
|
+
:JMP(opINVALID) ; 0x4D
|
97
|
+
:JMP(opINVALID) ; 0x4E
|
98
|
+
:JMP(opINVALID) ; 0x4F
|
99
|
+
:JMP(opPOP) ; 0x50
|
100
|
+
:JMP(opMLOAD) ; 0x51
|
101
|
+
:JMP(opMSTORE) ; 0x52
|
102
|
+
:JMP(opMSTORE8) ; 0x53
|
103
|
+
:JMP(opSLOAD) ; 0x54
|
104
|
+
:JMP(opSSTORE) ; 0x55
|
105
|
+
:JMP(opJUMP) ; 0x56
|
106
|
+
:JMP(opJUMPI) ; 0x57
|
107
|
+
:JMP(opPC) ; 0x58
|
108
|
+
:JMP(opMSIZE) ; 0x59
|
109
|
+
:JMP(opGAS) ; 0x5a
|
110
|
+
:JMP(opJUMPDEST) ; 0x5b
|
111
|
+
:JMP(opINVALID) ; 0x5C
|
112
|
+
:JMP(opINVALID) ; 0x5D
|
113
|
+
:JMP(opINVALID) ; 0x5E
|
114
|
+
:JMP(opPUSH0) ; 0x5F
|
115
|
+
1 => D :JMP(opPUSH1) ; 0x60
|
116
|
+
2 => D :JMP(opPUSH2) ; 0x61
|
117
|
+
3 => D :JMP(opPUSH3) ; 0x62
|
118
|
+
4 => D :JMP(opPUSH4) ; 0x63
|
119
|
+
5 => D :JMP(opPUSH5) ; 0x64
|
120
|
+
6 => D :JMP(opPUSH6) ; 0x65
|
121
|
+
7 => D :JMP(opPUSH7) ; 0x66
|
122
|
+
8 => D :JMP(opPUSH8) ; 0x67
|
123
|
+
9 => D :JMP(opPUSH9) ; 0x68
|
124
|
+
10 => D :JMP(opPUSH10) ; 0x69
|
125
|
+
11 => D :JMP(opPUSH11) ; 0x6a
|
126
|
+
12 => D :JMP(opPUSH12) ; 0x6b
|
127
|
+
13 => D :JMP(opPUSH13) ; 0x6c
|
128
|
+
14 => D :JMP(opPUSH14) ; 0x6d
|
129
|
+
15 => D :JMP(opPUSH15) ; 0x6e
|
130
|
+
16 => D :JMP(opPUSH16) ; 0x6f
|
131
|
+
17 => D :JMP(opPUSH17) ; 0x70
|
132
|
+
18 => D :JMP(opPUSH18) ; 0x71
|
133
|
+
19 => D :JMP(opPUSH19) ; 0x72
|
134
|
+
20 => D :JMP(opPUSH20) ; 0x73
|
135
|
+
21 => D :JMP(opPUSH21) ; 0x74
|
136
|
+
22 => D :JMP(opPUSH22) ; 0x75
|
137
|
+
23 => D :JMP(opPUSH23) ; 0x76
|
138
|
+
24 => D :JMP(opPUSH24) ; 0x77
|
139
|
+
25 => D :JMP(opPUSH25) ; 0x78
|
140
|
+
26 => D :JMP(opPUSH26) ; 0x79
|
141
|
+
27 => D :JMP(opPUSH27) ; 0x7a
|
142
|
+
28 => D :JMP(opPUSH28) ; 0x7b
|
143
|
+
29 => D :JMP(opPUSH29) ; 0x7c
|
144
|
+
30 => D :JMP(opPUSH30) ; 0x7d
|
145
|
+
31 => D :JMP(opPUSH31) ; 0x7e
|
146
|
+
32 => D :JMP(opPUSH32) ; 0x7f
|
147
|
+
:JMP(opDUP1) ; 0x80
|
148
|
+
:JMP(opDUP2) ; 0x81
|
149
|
+
:JMP(opDUP3) ; 0x82
|
150
|
+
:JMP(opDUP4) ; 0x83
|
151
|
+
:JMP(opDUP5) ; 0x84
|
152
|
+
:JMP(opDUP6) ; 0x85
|
153
|
+
:JMP(opDUP7) ; 0x86
|
154
|
+
:JMP(opDUP8) ; 0x87
|
155
|
+
:JMP(opDUP9) ; 0x88
|
156
|
+
:JMP(opDUP10) ; 0x89
|
157
|
+
:JMP(opDUP11) ; 0x8a
|
158
|
+
:JMP(opDUP12) ; 0x8b
|
159
|
+
:JMP(opDUP13) ; 0x8c
|
160
|
+
:JMP(opDUP14) ; 0x8d
|
161
|
+
:JMP(opDUP15) ; 0x8e
|
162
|
+
:JMP(opDUP16) ; 0x8f
|
163
|
+
:JMP(opSWAP1) ; 0x90
|
164
|
+
:JMP(opSWAP2) ; 0x91
|
165
|
+
:JMP(opSWAP3) ; 0x92
|
166
|
+
:JMP(opSWAP4) ; 0x93
|
167
|
+
:JMP(opSWAP5) ; 0x94
|
168
|
+
:JMP(opSWAP6) ; 0x95
|
169
|
+
:JMP(opSWAP7) ; 0x96
|
170
|
+
:JMP(opSWAP8) ; 0x97
|
171
|
+
:JMP(opSWAP9) ; 0x98
|
172
|
+
:JMP(opSWAP10) ; 0x99
|
173
|
+
:JMP(opSWAP11) ; 0x9a
|
174
|
+
:JMP(opSWAP12) ; 0x9b
|
175
|
+
:JMP(opSWAP13) ; 0x9c
|
176
|
+
:JMP(opSWAP14) ; 0x9d
|
177
|
+
:JMP(opSWAP15) ; 0x9e
|
178
|
+
:JMP(opSWAP16) ; 0x9f
|
179
|
+
:JMP(opLOG0) ; 0xa0
|
180
|
+
:JMP(opLOG1) ; 0xa1
|
181
|
+
:JMP(opLOG2) ; 0xa2
|
182
|
+
:JMP(opLOG3) ; 0xa3
|
183
|
+
:JMP(opLOG4) ; 0xa4
|
184
|
+
:JMP(opINVALID) ; 0xA5
|
185
|
+
:JMP(opINVALID) ; 0xA6
|
186
|
+
:JMP(opINVALID) ; 0xA7
|
187
|
+
:JMP(opINVALID) ; 0xA8
|
188
|
+
:JMP(opINVALID) ; 0xA9
|
189
|
+
:JMP(opINVALID) ; 0xAA
|
190
|
+
:JMP(opINVALID) ; 0xAB
|
191
|
+
:JMP(opINVALID) ; 0xAC
|
192
|
+
:JMP(opINVALID) ; 0xAD
|
193
|
+
:JMP(opINVALID) ; 0xAE
|
194
|
+
:JMP(opINVALID) ; 0xAF
|
195
|
+
:JMP(opINVALID) ; 0xB0
|
196
|
+
:JMP(opINVALID) ; 0xB1
|
197
|
+
:JMP(opINVALID) ; 0xB2
|
198
|
+
:JMP(opINVALID) ; 0xB3
|
199
|
+
:JMP(opINVALID) ; 0xB4
|
200
|
+
:JMP(opINVALID) ; 0xB5
|
201
|
+
:JMP(opINVALID) ; 0xB6
|
202
|
+
:JMP(opINVALID) ; 0xB7
|
203
|
+
:JMP(opINVALID) ; 0xB8
|
204
|
+
:JMP(opINVALID) ; 0xB9
|
205
|
+
:JMP(opINVALID) ; 0xBA
|
206
|
+
:JMP(opINVALID) ; 0xBB
|
207
|
+
:JMP(opINVALID) ; 0xBC
|
208
|
+
:JMP(opINVALID) ; 0xBD
|
209
|
+
:JMP(opINVALID) ; 0xBE
|
210
|
+
:JMP(opINVALID) ; 0xBF
|
211
|
+
:JMP(opINVALID) ; 0xC0
|
212
|
+
:JMP(opINVALID) ; 0xC1
|
213
|
+
:JMP(opINVALID) ; 0xC2
|
214
|
+
:JMP(opINVALID) ; 0xC3
|
215
|
+
:JMP(opINVALID) ; 0xC4
|
216
|
+
:JMP(opINVALID) ; 0xC5
|
217
|
+
:JMP(opINVALID) ; 0xC6
|
218
|
+
:JMP(opINVALID) ; 0xC7
|
219
|
+
:JMP(opINVALID) ; 0xC8
|
220
|
+
:JMP(opINVALID) ; 0xC9
|
221
|
+
:JMP(opINVALID) ; 0xCA
|
222
|
+
:JMP(opINVALID) ; 0xCB
|
223
|
+
:JMP(opINVALID) ; 0xCC
|
224
|
+
:JMP(opINVALID) ; 0xCD
|
225
|
+
:JMP(opINVALID) ; 0xCE
|
226
|
+
:JMP(opINVALID) ; 0xCF
|
227
|
+
:JMP(opINVALID) ; 0xD0
|
228
|
+
:JMP(opINVALID) ; 0xD1
|
229
|
+
:JMP(opINVALID) ; 0xD2
|
230
|
+
:JMP(opINVALID) ; 0xD3
|
231
|
+
:JMP(opINVALID) ; 0xD4
|
232
|
+
:JMP(opINVALID) ; 0xD5
|
233
|
+
:JMP(opINVALID) ; 0xD6
|
234
|
+
:JMP(opINVALID) ; 0xD7
|
235
|
+
:JMP(opINVALID) ; 0xD8
|
236
|
+
:JMP(opINVALID) ; 0xD9
|
237
|
+
:JMP(opINVALID) ; 0xDA
|
238
|
+
:JMP(opINVALID) ; 0xDB
|
239
|
+
:JMP(opINVALID) ; 0xDC
|
240
|
+
:JMP(opINVALID) ; 0xDD
|
241
|
+
:JMP(opINVALID) ; 0xDE
|
242
|
+
:JMP(opINVALID) ; 0xDF
|
243
|
+
:JMP(opINVALID) ; 0xE0
|
244
|
+
:JMP(opINVALID) ; 0xE1
|
245
|
+
:JMP(opINVALID) ; 0xE2
|
246
|
+
:JMP(opINVALID) ; 0xE3
|
247
|
+
:JMP(opINVALID) ; 0xE4
|
248
|
+
:JMP(opINVALID) ; 0xE5
|
249
|
+
:JMP(opINVALID) ; 0xE6
|
250
|
+
:JMP(opINVALID) ; 0xE7
|
251
|
+
:JMP(opINVALID) ; 0xE8
|
252
|
+
:JMP(opINVALID) ; 0xE9
|
253
|
+
:JMP(opINVALID) ; 0xEA
|
254
|
+
:JMP(opINVALID) ; 0xEB
|
255
|
+
:JMP(opINVALID) ; 0xEC
|
256
|
+
:JMP(opINVALID) ; 0xED
|
257
|
+
:JMP(opINVALID) ; 0xEE
|
258
|
+
:JMP(opINVALID) ; 0xEF
|
259
|
+
:JMP(opCREATE) ; 0xf0
|
260
|
+
:JMP(opCALL) ; 0xf1
|
261
|
+
:JMP(opCALLCODE) ; 0xf2
|
262
|
+
:JMP(opRETURN) ; 0xf3
|
263
|
+
:JMP(opDELEGATECALL) ; 0xf4
|
264
|
+
:JMP(opCREATE2) ; 0xf5
|
265
|
+
:JMP(opINVALID) ; 0xf6
|
266
|
+
:JMP(opINVALID) ; 0xf7
|
267
|
+
:JMP(opINVALID) ; 0xf8
|
268
|
+
:JMP(opINVALID) ; 0xf9
|
269
|
+
:JMP(opSTATICCALL) ; 0xfa
|
270
|
+
:JMP(opINVALID) ; 0xfb
|
271
|
+
:JMP(opINVALID) ; 0xfc
|
272
|
+
:JMP(opREVERT) ; 0xfd
|
273
|
+
:JMP(opINVALID) ; 0xfe
|
274
|
+
:JMP(opSENDALL) ; 0xff
|
@@ -0,0 +1,123 @@
|
|
1
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
2
|
+
;; PRE: len(inA) >= len(inB)
|
3
|
+
;;
|
4
|
+
;;
|
5
|
+
;; array_add_AGTB:
|
6
|
+
;; in:
|
7
|
+
;; · C ∈ [1, 32], the len of inA
|
8
|
+
;; · D ∈ [1, 32], the len of inB
|
9
|
+
;; · inA ∈ [0, 2²⁵⁶ - 1]^C, the first input array
|
10
|
+
;; · inB ∈ [0, 2²⁵⁶ - 1]^D, the second input array
|
11
|
+
;;
|
12
|
+
;; output:
|
13
|
+
;; · out = inA + inB, with len(out) <= C + 1
|
14
|
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
15
|
+
|
16
|
+
; function array_add_AGTB(a: bigint[], b: bigint[], base: bigint): bigint[] {
|
17
|
+
; const alen = a.length;
|
18
|
+
; const blen = b.length;
|
19
|
+
; let result = new Array<bigint>(alen);
|
20
|
+
; let sum = 0n;
|
21
|
+
; let carry = 0n;
|
22
|
+
; for (let i = 0; i < blen; i++) {
|
23
|
+
; sum = a[i] + b[i] + carry;
|
24
|
+
; carry = sum >= base ? 1n : 0n;
|
25
|
+
; out[i] = sum - carry * base;
|
26
|
+
; }
|
27
|
+
; for (let i = blen; i < alen; i++) {
|
28
|
+
; sum = a[i] + carry;
|
29
|
+
; carry = sum == base ? 1n : 0n; // the past carry is at most 1n
|
30
|
+
; out[i] = sum - carry * base;
|
31
|
+
; }
|
32
|
+
|
33
|
+
; if (carry === 1n) {
|
34
|
+
; result.push(carry);
|
35
|
+
; }
|
36
|
+
; return result;
|
37
|
+
; }
|
38
|
+
|
39
|
+
; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead.
|
40
|
+
|
41
|
+
VAR GLOBAL array_add_AGTB_inA[%ARRAY_MAX_LEN]
|
42
|
+
VAR GLOBAL array_add_AGTB_inB[%ARRAY_MAX_LEN]
|
43
|
+
VAR GLOBAL array_add_AGTB_out[%ARRAY_MAX_LEN_PLUS_ONE]
|
44
|
+
VAR GLOBAL array_add_AGTB_len_inA
|
45
|
+
VAR GLOBAL array_add_AGTB_len_inB
|
46
|
+
VAR GLOBAL array_add_AGTB_len_out
|
47
|
+
|
48
|
+
VAR GLOBAL array_add_AGTB_carry
|
49
|
+
|
50
|
+
VAR GLOBAL array_add_AGTB_RR
|
51
|
+
|
52
|
+
array_add_AGTB:
|
53
|
+
%MAX_CNT_BINARY - CNT_BINARY - 2*D - C+ D :JMPN(outOfCountersBinary)
|
54
|
+
%MAX_CNT_STEPS - STEP - 5 - 14*D - 3 - 9*C+9*D - 8 :JMPN(outOfCountersStep)
|
55
|
+
|
56
|
+
RR :MSTORE(array_add_AGTB_RR)
|
57
|
+
|
58
|
+
C :MSTORE(array_add_AGTB_len_inA)
|
59
|
+
D :MSTORE(array_add_AGTB_len_inB)
|
60
|
+
|
61
|
+
0 => E ; index in loops
|
62
|
+
0 :MSTORE(array_add_AGTB_carry)
|
63
|
+
|
64
|
+
array_add_AGTB_loopZero2inB:
|
65
|
+
; The result will be stored as D·base + C
|
66
|
+
|
67
|
+
0 => D ; reset the carry chunk
|
68
|
+
|
69
|
+
; a[i] + b[i], where a[i],b[i] ∈ [0,base-1]: This number cannot be GT base + (base - 2), two chunks
|
70
|
+
$ => A :MLOAD(array_add_AGTB_inA + E)
|
71
|
+
$ => B :MLOAD(array_add_AGTB_inB + E)
|
72
|
+
$ => C :ADD, JMPNC(__array_add_AGTB_continue_1)
|
73
|
+
1 => D
|
74
|
+
__array_add_AGTB_continue_1:
|
75
|
+
|
76
|
+
; sum = (a[i] + b[i]) + carry: This number cannot be GT base + (base - 1), two chunks
|
77
|
+
$ => A :MLOAD(array_add_AGTB_carry)
|
78
|
+
C => B
|
79
|
+
$ => C :ADD, JMPNC(__array_add_AGTB_continue_2)
|
80
|
+
1 => D
|
81
|
+
__array_add_AGTB_continue_2:
|
82
|
+
|
83
|
+
C :MSTORE(array_add_AGTB_out + E)
|
84
|
+
D :MSTORE(array_add_AGTB_carry)
|
85
|
+
|
86
|
+
E + 1 => E,A
|
87
|
+
$ => B :MLOAD(array_add_AGTB_len_inB)
|
88
|
+
B - A :JMPZ(array_add_AGTB_loop_index_check, array_add_AGTB_loopZero2inB)
|
89
|
+
|
90
|
+
array_add_AGTB_loop_index_check:
|
91
|
+
$ => B :MLOAD(array_add_AGTB_len_inA)
|
92
|
+
B - A :JMPZ(array_add_AGTB_check_carry)
|
93
|
+
|
94
|
+
array_add_AGTB_loopInB2InA:
|
95
|
+
0 => D ; reset the carry chunk
|
96
|
+
|
97
|
+
; sum = a[i] + carry: This number cannot be GT base, two chunks
|
98
|
+
$ => A :MLOAD(array_add_AGTB_inA + E)
|
99
|
+
$ => B :MLOAD(array_add_AGTB_carry)
|
100
|
+
$ => C :ADD, JMPNC(__array_add_AGTB_continue_3)
|
101
|
+
1 => D
|
102
|
+
__array_add_AGTB_continue_3:
|
103
|
+
|
104
|
+
C :MSTORE(array_add_AGTB_out + E)
|
105
|
+
D :MSTORE(array_add_AGTB_carry)
|
106
|
+
|
107
|
+
E + 1 => E,A
|
108
|
+
$ => B :MLOAD(array_add_AGTB_len_inA)
|
109
|
+
B - A :JMPZ(array_add_AGTB_check_carry, array_add_AGTB_loopInB2InA)
|
110
|
+
|
111
|
+
array_add_AGTB_check_carry:
|
112
|
+
D => A
|
113
|
+
A :JMPZ(__array_add_AGTB_continue_4)
|
114
|
+
; In this case, the carry = 1 and we should append it to the result
|
115
|
+
1 :MSTORE(array_add_AGTB_out + E)
|
116
|
+
E + 1 :MSTORE(array_add_AGTB_len_out)
|
117
|
+
:JMP(array_add_AGTB_end)
|
118
|
+
__array_add_AGTB_continue_4:
|
119
|
+
E :MSTORE(array_add_AGTB_len_out)
|
120
|
+
|
121
|
+
array_add_AGTB_end:
|
122
|
+
$ => RR :MLOAD(array_add_AGTB_RR)
|
123
|
+
:RETURN
|