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 zkevm-rom might be problematic. Click here for more details.

Files changed (232) hide show
  1. package/.eslintrc.js +33 -0
  2. package/.github/CODEOWNERS +14 -0
  3. package/.github/ISSUE_TEMPLATE/bug.yml +38 -0
  4. package/.github/ISSUE_TEMPLATE/feature.yml +26 -0
  5. package/.github/ISSUE_TEMPLATE/question.yml +26 -0
  6. package/.github/workflows/main.yaml +40 -0
  7. package/LICENSE +636 -0
  8. package/README.md +23 -5
  9. package/audits/Hexens_Polygon_zkEVM_PUBLIC_27.02.23.pdf +0 -0
  10. package/audits/Polygon-zkEVM-Public-v1.1-verichains-19-03-2024.pdf +0 -0
  11. package/audits/zkEVM-ROM-upgrade-1-Spearbit-30-May.pdf +0 -0
  12. package/audits/zkEVM-ROM-upgrade-2-Spearbit-21-August.pdf +0 -0
  13. package/audits/zkEVM-engagement-1-Spearbit-27-March.pdf +0 -0
  14. package/audits/zkEVM-engagement-2-Spearbit-27-March.pdf +0 -0
  15. package/audits/zkEVM-engagement-3-Spearbit-6-April.pdf +0 -0
  16. package/counters/README.md +45 -0
  17. package/counters/counters-executor.js +80 -0
  18. package/counters/countersConstants.zkasm +370 -0
  19. package/counters/endIncludes.zkasm +18 -0
  20. package/counters/initIncludes.zkasm +2 -0
  21. package/counters/tests/MLOAD32.zkasm +27 -0
  22. package/counters/tests/MLOADX.zkasm +30 -0
  23. package/counters/tests/MSTORE32.zkasm +32 -0
  24. package/counters/tests/MSTOREX.zkasm +36 -0
  25. package/counters/tests/SHLarith.zkasm +28 -0
  26. package/counters/tests/SHLarithBit.zkasm +28 -0
  27. package/counters/tests/SHRarith.zkasm +28 -0
  28. package/counters/tests/SHRarithBit.zkasm +28 -0
  29. package/counters/tests/abs.zkasm +29 -0
  30. package/counters/tests/addBatchHashByteByByte.zkasm +31 -0
  31. package/counters/tests/computeGasSendCall.zkasm +30 -0
  32. package/counters/tests/divArith.zkasm +27 -0
  33. package/counters/tests/expAD.zkasm +30 -0
  34. package/counters/tests/getLenBits.zkasm +30 -0
  35. package/counters/tests/getLenBytes.zkasm +32 -0
  36. package/counters/tests/isEmptyAccount.zkasm +30 -0
  37. package/counters/tests/mulARITH.zkasm +28 -0
  38. package/counters/tests/offsetUtil.zkasm +29 -0
  39. package/counters/tests/opADDMOD.zkasm +28 -0
  40. package/counters/tests/opAdd.zkasm +27 -0
  41. package/counters/tests/opBLOCKHASH.zkasm +28 -0
  42. package/counters/tests/opCALL.zkasm +41 -0
  43. package/counters/tests/opCALLCODE.zkasm +41 -0
  44. package/counters/tests/opCALLDATACOPY.zkasm +28 -0
  45. package/counters/tests/opCALLDATALOAD.zkasm +27 -0
  46. package/counters/tests/opCODECOPY.zkasm +28 -0
  47. package/counters/tests/opCREATE.zkasm +35 -0
  48. package/counters/tests/opCREATE2.zkasm +35 -0
  49. package/counters/tests/opDELEGATECALL.zkasm +35 -0
  50. package/counters/tests/opDIV.zkasm +27 -0
  51. package/counters/tests/opEXP.zkasm +29 -0
  52. package/counters/tests/opEXTCODECOPY.zkasm +29 -0
  53. package/counters/tests/opMOD.zkasm +27 -0
  54. package/counters/tests/opMUL.zkasm +27 -0
  55. package/counters/tests/opMULMOD.zkasm +28 -0
  56. package/counters/tests/opRETURN.zkasm +32 -0
  57. package/counters/tests/opRETURNDATACOPY.zkasm +29 -0
  58. package/counters/tests/opREVERT.zkasm +32 -0
  59. package/counters/tests/opSDIV.zkasm +28 -0
  60. package/counters/tests/opSHA3.zkasm +28 -0
  61. package/counters/tests/opSIGNEXTEND.zkasm +27 -0
  62. package/counters/tests/opSMOD.zkasm +28 -0
  63. package/counters/tests/opSTATICCALL.zkasm +35 -0
  64. package/counters/tests/opSUB.zkasm +27 -0
  65. package/counters/tests/saveMem.zkasm +31 -0
  66. package/docs/opcode-cost-zk-counters.md +315 -0
  67. package/docs/usage-ecrecover.md +51 -0
  68. package/index.js +43 -0
  69. package/main/block-info.zkasm +204 -0
  70. package/main/constants.zkasm +145 -0
  71. package/main/ecrecover/addFpEc.zkasm +31 -0
  72. package/main/ecrecover/checkSqrtFpEc.zkasm +1558 -0
  73. package/main/ecrecover/constEc.zkasm +13 -0
  74. package/main/ecrecover/ecrecover.zkasm +280 -0
  75. package/main/ecrecover/invFnEc.zkasm +44 -0
  76. package/main/ecrecover/invFpEc.zkasm +45 -0
  77. package/main/ecrecover/mulFnEc.zkasm +36 -0
  78. package/main/ecrecover/mulFpEc.zkasm +36 -0
  79. package/main/ecrecover/mulPointEc.zkasm +311 -0
  80. package/main/ecrecover/sqFpEc.zkasm +38 -0
  81. package/main/ecrecover/sqrtFpEc.zkasm +70 -0
  82. package/main/end.zkasm +4 -0
  83. package/main/l2-tx-hash.zkasm +159 -0
  84. package/main/load-change-l2-block-utils.zkasm +11 -0
  85. package/main/load-change-l2-block.zkasm +28 -0
  86. package/main/load-tx-rlp-utils.zkasm +72 -0
  87. package/main/load-tx-rlp.zkasm +431 -0
  88. package/main/main.zkasm +237 -0
  89. package/main/map-opcodes.zkasm +274 -0
  90. package/main/modexp/array_lib/array_add_AGTB.zkasm +123 -0
  91. package/main/modexp/array_lib/array_add_short.zkasm +85 -0
  92. package/main/modexp/array_lib/array_div.zkasm +215 -0
  93. package/main/modexp/array_lib/array_div_long.zkasm +284 -0
  94. package/main/modexp/array_lib/array_div_short.zkasm +222 -0
  95. package/main/modexp/array_lib/array_mul.zkasm +97 -0
  96. package/main/modexp/array_lib/array_mul_long.zkasm +156 -0
  97. package/main/modexp/array_lib/array_mul_short.zkasm +127 -0
  98. package/main/modexp/array_lib/array_square.zkasm +246 -0
  99. package/main/modexp/array_lib/unused/array_add.zkasm +100 -0
  100. package/main/modexp/array_lib/unused/array_is_odd.zkasm +23 -0
  101. package/main/modexp/array_lib/unused/array_is_one.zkasm +33 -0
  102. package/main/modexp/array_lib/unused/array_is_zero.zkasm +34 -0
  103. package/main/modexp/array_lib/unused/array_sub_AGTB.zkasm +111 -0
  104. package/main/modexp/array_lib/unused/array_unshift.zkasm +37 -0
  105. package/main/modexp/array_lib/utils/array_compare.zkasm +82 -0
  106. package/main/modexp/array_lib/utils/array_trim.zkasm +49 -0
  107. package/main/modexp/constants.zkasm +5 -0
  108. package/main/modexp/modexp.zkasm +296 -0
  109. package/main/modexp/modexp_utils.zkasm +230 -0
  110. package/main/opcodes/arithmetic.zkasm +357 -0
  111. package/main/opcodes/block.zkasm +163 -0
  112. package/main/opcodes/calldata-returndata-code.zkasm +619 -0
  113. package/main/opcodes/comparison.zkasm +446 -0
  114. package/main/opcodes/context-information.zkasm +169 -0
  115. package/main/opcodes/create-terminate-context.zkasm +1011 -0
  116. package/main/opcodes/crypto.zkasm +96 -0
  117. package/main/opcodes/flow-control.zkasm +126 -0
  118. package/main/opcodes/logs.zkasm +193 -0
  119. package/main/opcodes/stack-operations.zkasm +658 -0
  120. package/main/opcodes/storage-memory.zkasm +313 -0
  121. package/main/pairings/BN254/addPointBN254.zkasm +245 -0
  122. package/main/pairings/BN254/ecAdd.zkasm +312 -0
  123. package/main/pairings/BN254/ecMul.zkasm +159 -0
  124. package/main/pairings/BN254/escalarMulBN254.zkasm +155 -0
  125. package/main/pairings/BN254/lineDiffPointsBN254.zkasm +83 -0
  126. package/main/pairings/BN254/lineSamePointsBN254.zkasm +96 -0
  127. package/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm +49 -0
  128. package/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +236 -0
  129. package/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm +444 -0
  130. package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm +212 -0
  131. package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm +228 -0
  132. package/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm +64 -0
  133. package/main/pairings/FP12BN254/frob2Fp12BN254.zkasm +80 -0
  134. package/main/pairings/FP12BN254/frob3Fp12BN254.zkasm +96 -0
  135. package/main/pairings/FP12BN254/frobFp12BN254.zkasm +96 -0
  136. package/main/pairings/FP12BN254/inverseFp12BN254.zkasm +289 -0
  137. package/main/pairings/FP12BN254/mulFp12BN254.zkasm +408 -0
  138. package/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm +296 -0
  139. package/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm +291 -0
  140. package/main/pairings/FP12BN254/squareFp12BN254.zkasm +376 -0
  141. package/main/pairings/FP2BN254/addFp2BN254.zkasm +19 -0
  142. package/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm +20 -0
  143. package/main/pairings/FP2BN254/invFp2BN254.zkasm +66 -0
  144. package/main/pairings/FP2BN254/mulFp2BN254.zkasm +19 -0
  145. package/main/pairings/FP2BN254/squareFp2BN254.zkasm +21 -0
  146. package/main/pairings/FP2BN254/subFp2BN254.zkasm +19 -0
  147. package/main/pairings/FP4BN254/squareFp4BN254.zkasm +76 -0
  148. package/main/pairings/FP6BN254/addFp6BN254.zkasm +59 -0
  149. package/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm +51 -0
  150. package/main/pairings/FP6BN254/inverseFp6BN254.zkasm +208 -0
  151. package/main/pairings/FP6BN254/mulFp6BN254.zkasm +201 -0
  152. package/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm +65 -0
  153. package/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm +134 -0
  154. package/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm +128 -0
  155. package/main/pairings/FP6BN254/squareFp6BN254.zkasm +147 -0
  156. package/main/pairings/FP6BN254/subFp6BN254.zkasm +59 -0
  157. package/main/pairings/FPBN254/addFpBN254.zkasm +29 -0
  158. package/main/pairings/FPBN254/invFpBN254.zkasm +55 -0
  159. package/main/pairings/FPBN254/mulFpBN254.zkasm +29 -0
  160. package/main/pairings/FPBN254/reduceFpBN254.zkasm +25 -0
  161. package/main/pairings/FPBN254/squareFpBN254.zkasm +31 -0
  162. package/main/pairings/FPBN254/subFpBN254.zkasm +36 -0
  163. package/main/pairings/FRBN254/reduceFrBN254.zkasm +25 -0
  164. package/main/pairings/constants.zkasm +62 -0
  165. package/main/pairings/ecPairing.zkasm +244 -0
  166. package/main/pairings/finalExpBN254.zkasm +2095 -0
  167. package/main/pairings/halfPairingBN254.zkasm +428 -0
  168. package/main/pairings/loopLengthBN254.zkasm +75 -0
  169. package/main/pairings/millerLoopBN254.zkasm +741 -0
  170. package/main/pairings/pairingBN254.zkasm +481 -0
  171. package/main/pairings/unused/addFp12BN254.zkasm +130 -0
  172. package/main/pairings/unused/expByXCycloFp12BN254.zkasm +411 -0
  173. package/main/pairings/unused/expFp12BN254.zkasm +333 -0
  174. package/main/pairings/unused/subFp12BN254.zkasm +130 -0
  175. package/main/pairings/unused/xPseudoBinDecompBN254.zkasm +68 -0
  176. package/main/pairings/utilsTests/expCycloFp12BN254.zkasm +334 -0
  177. package/main/precompiled/end.zkasm +42 -0
  178. package/main/precompiled/identity.zkasm +99 -0
  179. package/main/precompiled/pre-ecAdd.zkasm +84 -0
  180. package/main/precompiled/pre-ecMul.zkasm +82 -0
  181. package/main/precompiled/pre-ecPairing.zkasm +72 -0
  182. package/main/precompiled/pre-ecrecover.zkasm +71 -0
  183. package/main/precompiled/pre-modexp.zkasm +367 -0
  184. package/main/precompiled/pre-sha2-256.zkasm +125 -0
  185. package/main/precompiled/revert-precompiled.zkasm +25 -0
  186. package/main/precompiled/selector.zkasm +77 -0
  187. package/main/process-change-l2-block.zkasm +147 -0
  188. package/main/process-tx.zkasm +587 -0
  189. package/main/tables/2-exp.zkasm +260 -0
  190. package/main/touched.zkasm +118 -0
  191. package/main/utils.zkasm +2335 -0
  192. package/main/vars.zkasm +117 -0
  193. package/package.json +62 -3
  194. package/test/bytes-length.zkasm +39 -0
  195. package/test/ecrecover.zkasm +538 -0
  196. package/test/lt4-test.zkasm +38 -0
  197. package/test/mstorex.zkasm +191 -0
  198. package/test/opcalldatacopy.ignore.zkasm +331 -0
  199. package/test/performance/read-push.zkasm +71 -0
  200. package/test/read-push.zkasm +304 -0
  201. package/test/testArrayArith.zkasm +1099 -0
  202. package/test/testArrayUtils.zkasm +335 -0
  203. package/test/testCycloFp12ArithBN254.zkasm +548 -0
  204. package/test/testEcAdd.zkasm +252 -0
  205. package/test/testEcMul.zkasm +231 -0
  206. package/test/testEcPairing.zkasm +436 -0
  207. package/test/testFinalExpBn254.zkasm +139 -0
  208. package/test/testFp12ArithBN254.zkasm +692 -0
  209. package/test/testFp2ArithBN254.zkasm +185 -0
  210. package/test/testFp4ArithBN254.zkasm +128 -0
  211. package/test/testFp6ArithBN254.zkasm +260 -0
  212. package/test/testFpArithBN254.zkasm +159 -0
  213. package/test/testFrArithBN254.zkasm +113 -0
  214. package/test/testHalfPairingBN254.zkasm +285 -0
  215. package/test/testModExp.zkasm +586 -0
  216. package/test/testModExpReturn.zkasm +81 -0
  217. package/test/testPairingBN254.zkasm +463 -0
  218. package/test/testPointArithBN254.zkasm +270 -0
  219. package/test/testSHA256.zkasm +27 -0
  220. package/test/touched-assert.zkasm +59 -0
  221. package/test/utils-expAD.zkasm +48 -0
  222. package/test/utils-getLenBytes.zkasm +36 -0
  223. package/tools/audit-tools/registry-op-checker.js +71 -0
  224. package/tools/get-not-used-labels.js +31 -0
  225. package/tools/helpers/helpers.js +47 -0
  226. package/tools/modexp-utils/README.md +5 -0
  227. package/tools/modexp-utils/modexp-test-gen.js +168 -0
  228. package/tools/modexp-utils/modexp-test-int.sage +37 -0
  229. package/tools/parallel-testing/checker.sh +6 -0
  230. package/tools/parallel-testing/gen-parallel-tests.js +78 -0
  231. package/tools/parallel-testing/parallel-tests-sample/sample.test.js +136 -0
  232. package/tools/run-tests-zkasm.js +83 -0
@@ -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