@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.

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,311 @@
1
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
+ ;;
3
+ ;; mulPointEc (p1_x,p1_y,p2_x,p2_y,k1,k2) = (p3_x, p3_y, HASHPOS)
4
+ ;;
5
+ ;; PRE: p1_x, p1_y, p2_x, p2_y, k1, k2 are alias-free
6
+ ;; POST: p3_x, p3_y is alias-free HASHPOS = [0,1]
7
+ ;;
8
+ ;; HASHPOS = 0 ==> p3 is the point at infinity
9
+ ;; HASHPOS = 1 ==> p3 is not the point at infinity
10
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11
+
12
+ VAR GLOBAL mulPointEc_p1_x
13
+ VAR GLOBAL mulPointEc_p1_y
14
+ VAR GLOBAL mulPointEc_p2_x
15
+ VAR GLOBAL mulPointEc_p2_y
16
+ VAR GLOBAL mulPointEc_k1
17
+ VAR GLOBAL mulPointEc_k2
18
+
19
+ ; p3 output point
20
+ VAR GLOBAL mulPointEc_p3_x
21
+ VAR GLOBAL mulPointEc_p3_y
22
+
23
+ ; point p12 = p1 + p2
24
+ VAR GLOBAL mulPointEc_p12_x
25
+ VAR GLOBAL mulPointEc_p12_y
26
+
27
+ ; mulPointEc_p12_empty = 1 ==> p12 is the point at infinity
28
+ ; mulPointEc_p12_empty = 0 ==> p12 isn't the point at infinity
29
+ VAR GLOBAL mulPointEc_p12_empty
30
+
31
+ ; backups
32
+ VAR GLOBAL mulPointEc_RR
33
+ VAR GLOBAL mulPointEc_RCX
34
+
35
+ ; PRECONDITION: p1,p2 are points of curve
36
+ ; PRECONDITION: p1,p2 are alias-free
37
+
38
+ ; RESOURCES (k1,k2):
39
+ ; 1 arith + 18 steps // setup, calculation p12
40
+ ; + 2 binaries * 256 // get bits of k1,k2 (steps evaluated inside loop)
41
+ ; + number_of_bits_1(k1|k2) * arith // additions
42
+ ; + (256 - left_bits_zero(k1|k2) * arith // squares
43
+ ; + 24 * 256 steps // get bits k1,k2 + additions + squares (steps, regular)
44
+ ; - (24 - 8) * left_bits_zero(k1|k2) * steps // get bits k1,k2 + additions + squares (steps first bits = 0)
45
+ ; - (24 - 12) * number_of_bits_1(k1|k2) * steps // get bits k1,k2 + additions + squares (k1,k2 bits = 0)
46
+ ; + (3 - 5) steps // last part - last part square no done
47
+ ; - 1 arith // first assignation
48
+ ;
49
+ ;
50
+ ; RESOURCES (worst case): 512 arith + 512 binaries + 6160 steps // 18 + 256 * 24 - 2 = 6160
51
+
52
+ mulPointEc:
53
+ RR :MSTORE(mulPointEc_RR)
54
+ RCX :MSTORE(mulPointEc_RCX)
55
+
56
+ 256 => RCX
57
+
58
+ ; HASHPOS used to mulPointEc_p3_no_infinity
59
+ ; HASHPOS = 0 ==> p3 is the point at infinity
60
+ ; HASHPOS = 1 ==> p3 is not the point at infinity
61
+
62
+ 0n => HASHPOS :MSTORE(mulPointEc_p3_x)
63
+
64
+ 0n :MSTORE(mulPointEc_p3_y)
65
+
66
+ $ => A :MLOAD(mulPointEc_p1_x)
67
+ $ => B :MLOAD(mulPointEc_p1_y)
68
+ $ => C :MLOAD(mulPointEc_p2_x)
69
+ $ => D :MLOAD(mulPointEc_p2_y)
70
+
71
+ ; check p1.x == p2.x
72
+ ; [steps: 11]
73
+ ${A == C} :JMPZ(mulPointDiffInitialPoints)
74
+
75
+ ; verify path p1.x == p2.x
76
+ C :ASSERT
77
+
78
+ ; check p1.y (B) == p2.y (D)
79
+ ; [steps: 13]
80
+ ${B == D} :JMPNZ(mulPointSameInitialPoints)
81
+
82
+ ; verify path p1.y != p2.y ==> p1.y = -p2.y
83
+ ; use arith because in this path save a lot of arith,
84
+ ; because when add p12 do nothing.
85
+
86
+ ; y + (-y) = y + P - y = P
87
+ ; y != 0, because cubic root of -7 not exists (y^2 = x^3 + 7)
88
+
89
+ B => A ; A = p1_y
90
+ D => C ; C = p2_y
91
+ 1 => B
92
+ 0 => D ; check p1_y * 1 + p2_y = 0 * 2^256 * 0 + FPEC
93
+ %FPEC :ARITH
94
+
95
+ ; p2 == -p1
96
+ ; mulPointEc_p12_empty = 1: no add p12 because it was origin point p = O + p = p
97
+ ; [steps: 18]
98
+ 1n :MSTORE(mulPointEc_p12_empty),JMP(mulPointEc_loop)
99
+
100
+
101
+ mulPointSameInitialPoints:
102
+ ; [steps.before: 13]
103
+ ; verify path p1.y (B) == p2.y (D)
104
+ ; as an ASSERT(B == mulPointEc_p2_y)
105
+ B :MLOAD(mulPointEc_p2_y)
106
+
107
+ ; p2 == p1
108
+ 0n :MSTORE(mulPointEc_p12_empty)
109
+ ; A == p1_x
110
+ ; B == p1_y
111
+ ; (A,B) * 2 = (E, op)
112
+ ${xDblPointEc(A,B)} => E :MSTORE(mulPointEc_p12_x)
113
+
114
+ ; [steps: 17]
115
+ ${yDblPointEc(A,B)} :ARITH_ECADD_SAME, MSTORE(mulPointEc_p12_y),JMP(mulPointEc_loop)
116
+
117
+ mulPointDiffInitialPoints:
118
+ ; [steps.before: 11]
119
+ ; verify path p1.x != p2.x
120
+ ; p2.x != p1.x ==> p2 != p1
121
+ ; [MAP] if p1 == p2 => arith fails because p1 = p2
122
+
123
+ 0n :MSTORE(mulPointEc_p12_empty)
124
+ ; (A, B) + (C, D) = (E, op)
125
+ ${xAddPointEc(A,B,C,D)} => E :MSTORE(mulPointEc_p12_x)
126
+ ; [steps: 14]
127
+ ${yAddPointEc(A,B,C,D)} :ARITH_ECADD_DIFFERENT, MSTORE(mulPointEc_p12_y)
128
+
129
+
130
+ ; Goes forward in different branches of code depending on the values of the
131
+ ; most significant bits of k1 and k2.
132
+ ; First branch was determined by k1 most significant bit.
133
+
134
+ ;
135
+ ; Most Significant bit was calculated ki + ki,
136
+ ;
137
+ ; A b255 b254 b253 ... b1 b0
138
+ ; A b255 b254 b253 ... b1 b0
139
+ ; ---------------------------
140
+ ; E b254 b253 b252 ... b0 0
141
+ ;
142
+ ; if b255 == 1 then carry = 1
143
+ ; if b255 == 0 then carry = 0
144
+ ;
145
+ ; E = A << 1 (equivalent A + A)
146
+ ;
147
+ ; store E to be used in next round
148
+ ;
149
+ ; [steps.before (worst case): 18]
150
+ ;
151
+ ; [steps.byloop (p3initialempty.nolast): 8]
152
+ ; [steps.byloop (bit.k1|bit.k2 == 0): 12]
153
+ ; [steps.byloop (worst case): 7 + 17 = 24]
154
+
155
+ mulPointEc_loop:
156
+ $ => A,B :MLOAD(mulPointEc_k1)
157
+ ; E = A*2 [carry] => bit 255 = 1
158
+ $ => E :ADD,MSTORE(mulPointEc_k1),JMPC(mulPointEc_k11)
159
+
160
+ ; high_bit(k1) == 0 high_bit(k2) == ??
161
+ mulPointEc_k10:
162
+ ; store E on multipointEc_k1, E was A*2 equivalent SHL and 255 bit on carry.
163
+ $ => A,B :MLOAD(mulPointEc_k2)
164
+ ; E = A*2 [carry] => bit 255 = 1
165
+ $ => E :ADD,MSTORE(mulPointEc_k2),JMPC(mulPointEc_k10_k21)
166
+
167
+ ; high_bit(k1) == 0 high_bit(k2) == 0
168
+ mulPointEc_k10_k20:
169
+ $ => A :MLOAD(mulPointEc_p3_x)
170
+ $ => B :MLOAD(mulPointEc_p3_y), JMP(mulPointEc_square)
171
+
172
+ ; high_bit(k1) == 1 high_bit(k2) == ??
173
+ mulPointEc_k11:
174
+ $ => A,B :MLOAD(mulPointEc_k2)
175
+ $ => E :ADD,MSTORE(mulPointEc_k2),JMPC(mulPointEc_k11_k21)
176
+
177
+ ; high_bit(k1) == 1 high_bit(k2) == 0
178
+ mulPointEc_k11_k20:
179
+ $ => C :MLOAD(mulPointEc_p1_x)
180
+ $ => D :MLOAD(mulPointEc_p1_y), JMP(mulPointEc_p2_loaded)
181
+
182
+ ; high_bit(k1) == 1 high_bit(k2) == 1
183
+ mulPointEc_k11_k21:
184
+ ; if (mulPointEc_p12_empty) k11_k21 same as k10_k20
185
+ $ :MLOAD(mulPointEc_p12_empty),JMPNZ(mulPointEc_k10_k20)
186
+
187
+ $ => C :MLOAD(mulPointEc_p12_x)
188
+ $ => D :MLOAD(mulPointEc_p12_y), JMP(mulPointEc_p2_loaded)
189
+
190
+ ; high_bit(k1) == 0 high_bit(k2) == 1
191
+ mulPointEc_k10_k21:
192
+ $ => C :MLOAD(mulPointEc_p2_x)
193
+ $ => D :MLOAD(mulPointEc_p2_y), JMP(mulPointEc_p2_loaded)
194
+
195
+ ; [steps.loadp2 (worst case): 7 (regular case 6)
196
+
197
+ ; in this point C,D have point to be add
198
+ mulPointEc_p2_loaded:
199
+ ; [steps.p3empty.nolast: 10]
200
+ ; [steps.p3empty.last: 5]
201
+ ; [steps.xeq.yeq: 10 + steps.square = 16]
202
+ ; [steps.xeq.yneq: 11 + steps.square = 17]
203
+ ; [steps.xneq.nolast: 7 + steps.square = 13]
204
+ ; [steps.xneq.last: 7 + steps.square = 13]
205
+ ; [steps.block: 17]
206
+
207
+ ; check if p3 has a value, isn't point at infinity (Origin point)
208
+ HASHPOS :JMPZ(mulPointEc_p3_assignment)
209
+
210
+
211
+ ; check C == p3.x
212
+ ${ C == mem.mulPointEc_p3_x } :JMPNZ(mulPointEc_x_equals_before_add)
213
+
214
+ ; [MAP] if C == mem.mulPointEc_p3_x ==> fails arithmetic because check
215
+ ; points are different
216
+
217
+ ; p3 = (A,B)
218
+ $ => A :MLOAD(mulPointEc_p3_x)
219
+ $ => B :MLOAD(mulPointEc_p3_y)
220
+
221
+ ; p3 = p3 + (C,D)
222
+ ; (C, D) is point to add (p1 or p2 or p12)
223
+ ; (A, B) + (C, D) = (E, op)
224
+
225
+ ${xAddPointEc(A,B,C,D)} => E :MSTORE(mulPointEc_p3_x)
226
+ ${yAddPointEc(A,B,C,D)} => B :ARITH_ECADD_DIFFERENT, MSTORE(mulPointEc_p3_y)
227
+
228
+ mulPointEc_after_add:
229
+
230
+ E => A :JMP(mulPointEc_square)
231
+
232
+ mulPointEc_p3_assignment:
233
+
234
+ ; p3 = (C,D)
235
+ 1 => HASHPOS ; flag, mulPointEc_p3 has a value, no-empty
236
+ C => A :MSTORE(mulPointEc_p3_x)
237
+ D => B :MSTORE(mulPointEc_p3_y)
238
+
239
+ mulPointEc_square:
240
+ ; [steps.last: 1]
241
+ ; [steps.nolast.p3empty: 2]
242
+ ; [steps.nolast.p3: 6]
243
+ ; [steps.block: 6]
244
+
245
+ ; E,A = p3_x B = p3_y
246
+ RCX - 1 => RCX :JMPZ(mulPointEc_end_loop)
247
+
248
+ ; if p3 was empty, no square, because O = O + O
249
+ HASHPOS :JMPZ(mulPointEc_loop)
250
+
251
+ $ => A :MLOAD(mulPointEc_p3_x)
252
+ $ => B :MLOAD(mulPointEc_p3_y)
253
+
254
+ ; (A, B) * 2 = (E, op)
255
+ ${xDblPointEc(A,B)} => E :MSTORE(mulPointEc_p3_x)
256
+ ${yDblPointEc(A,B)} :ARITH_ECADD_SAME, MSTORE(mulPointEc_p3_y), JMP(mulPointEc_loop)
257
+
258
+ mulPointEc_x_equals_before_add:
259
+ ; [MAP] if C != mem.mulPointEc_p3_x ==> fails, MLOAD fails because read something different
260
+ ; for memory. It verifies C and mulPointEc_p3_x are same value, as an ASSERT.
261
+ C :MLOAD(mulPointEc_p3_x)
262
+
263
+ ; points to add: point1 (p3) + point2 (C,D)
264
+
265
+ ; C: point2.x
266
+ ; D: point2.y
267
+
268
+ ; p3_x == C, check if points are same or a point was opposite point
269
+
270
+ ${ D == mem.mulPointEc_p3_y } :JMPNZ(mulPointEc_same_point_to_add)
271
+
272
+ ; In this path must be verified that D != mulPointEc_p3_y to
273
+ ; how p2_y and p3_y are different for same x, it implies that
274
+ ; p2_y == -p3_y. In this case next operation with p3 doesn't
275
+ ; spend arithmetics, for this reason is used an arithmetic
276
+ ; instead of binary to use similar resources on different paths.
277
+
278
+ ; if p2_y == -p3_y, and them are alias free ==> p2_y + p3_y === FPEC
279
+
280
+ 1 => B
281
+ D => A
282
+ 0 => D
283
+ $ => C :MLOAD(mulPointEc_p3_y)
284
+
285
+ ; p2_y * 1 + p3_y = 2^256 * 0 + FPEC
286
+ %FPEC :ARITH
287
+
288
+ ; NOTE: all points are free of alias because arithmetic guaranties it
289
+
290
+ ; HASHPOS flag = 0, mulPointEc_p3 was empty, need addition must be an assignation
291
+ 0n => HASHPOS :MSTORE(mulPointEc_p3_x)
292
+ 0n :MSTORE(mulPointEc_p3_y), JMP(mulPointEc_square)
293
+
294
+ mulPointEc_same_point_to_add:
295
+ ; [steps.block: 5]
296
+ ; must check really are equals, use MLOAD as ASSERT
297
+ ; ASSERT(D == mulPointEc_p3_y)
298
+
299
+ D :MLOAD(mulPointEc_p3_y)
300
+ C => A
301
+ D => B
302
+
303
+ ; (A,B) * 2 = (E, op)
304
+ ${xDblPointEc(A,B)} => E :MSTORE(mulPointEc_p3_x)
305
+ ${yDblPointEc(A,B)} => B :ARITH_ECADD_SAME, MSTORE(mulPointEc_p3_y), JMP(mulPointEc_after_add)
306
+
307
+ mulPointEc_end_loop:
308
+ ; [steps.block: 3]
309
+
310
+ $ => RR :MLOAD(mulPointEc_RR)
311
+ $ => RCX :MLOAD(mulPointEc_RCX), RETURN
@@ -0,0 +1,38 @@
1
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
+ ;;
3
+ ;; sqFpEc (C = C * C)
4
+ ;;
5
+ ;; PRE: C no alias-free
6
+ ;; POST: C no alias-free (on MAP)
7
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8
+
9
+
10
+ ; RESOURCES:
11
+ ; 2 arith + 8 steps
12
+
13
+ sqFpEc:
14
+ C => A,B
15
+ 0n => C
16
+
17
+ ; A * A + 0 = [D] * 2 ** 256 + [E]
18
+
19
+ $${var _sqFpEc_AA = A * A}
20
+
21
+ ${_sqFpEc_AA >> 256} => D
22
+
23
+ ;;
24
+ ;; result of command was only 256 bits, not need mask
25
+ ;; ${_sqFpEc_AA & ((1 << 256) - 1)} == ${_sqFpEc_AA}
26
+
27
+ ${_sqFpEc_AA} => E :ARITH
28
+
29
+ ;
30
+ ; with committed E,D
31
+ ; FpEc * [k] + [C] = D * 2 ** 256 + E
32
+ ;
33
+
34
+ ${_sqFpEc_AA % const.FPEC} => C
35
+ ${_sqFpEc_AA / const.FPEC} => B
36
+ %FPEC => A
37
+
38
+ E :ARITH,RETURN
@@ -0,0 +1,70 @@
1
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
+ ;;
3
+ ;; sqrtFpEc (C = sqrt(C,A))
4
+ ;;
5
+ ;; PRE: A = [0,1], C no alias-free
6
+ ;; POST: C is alias-free
7
+ ;; NOTE: if C has sqrt B = 1 if not B = 0
8
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9
+
10
+ ; RESOURCES:
11
+ ; with root: 2 arith + 1 binary + 14 steps
12
+ ; without root: 1 binary + 5 steps
13
+ ; TOTAL (worst case): 2 arith + 1 binary + 14 steps
14
+
15
+ VAR GLOBAL sqrtFpC_tmp
16
+ VAR GLOBAL sqrtFpC_res
17
+
18
+ sqrtFpEc:
19
+
20
+ ; PATH: hasn't sqrt => 1 binary
21
+ ; PATH: has sqrt => 1 binary + 2 arith
22
+ ; TOTAL resources: 1 binary + 2 arith
23
+
24
+ C :MSTORE(sqrtFpC_tmp)
25
+
26
+ ; [A] * [A] + 0 = [D] * 2 ** 256 + [E]
27
+
28
+ ; set C because if jmp to sqrtFpEc C must have return value (FPEC_NON_SQRT)
29
+ ${var _sqrtFpEc_sqrt = sqrtFpEcParity(C,A) } => A,C :MSTORE(sqrtFpC_res)
30
+
31
+ ; In this point we check if C is LT than FPEC because if not:
32
+ ; a) A = FPEC_NON_SQRT, check hasn't sqrt.
33
+ ; b) A is an alias, it's a MAP, we check hasn't sqrt, but has => no proof generated
34
+
35
+ ; A and C has same value
36
+
37
+ %FPEC => B
38
+
39
+ ; A
40
+ $ => B :LT,JMPNC(sqrtFpEc_End)
41
+
42
+ ; A,C < FPEC (alias free)
43
+ A => B
44
+ 0 => C
45
+
46
+ ; A = B => A * A + 0 =?
47
+
48
+ $${var _sqrtFpEc_sq = _sqrtFpEc_sqrt * _sqrtFpEc_sqrt }
49
+
50
+ ${_sqrtFpEc_sq >> 256} => D
51
+ ${_sqrtFpEc_sq} => E :ARITH
52
+
53
+ ;
54
+ ; with committed E,D
55
+ ; FpEc * [k] + C = D * 2 ** 256 + E
56
+ ;
57
+
58
+ $ => C :MLOAD(sqrtFpC_tmp)
59
+ ${_sqrtFpEc_sq / const.FPEC} => B
60
+ %FPEC => A
61
+ E :ARITH
62
+
63
+ ; sqrtFpC_res hasn't alias because in this path sqrtFpC_res < FPEC
64
+
65
+ 1 => B
66
+ $ => C :MLOAD(sqrtFpC_res),RETURN
67
+
68
+ sqrtFpEc_End:
69
+ ; B is 0, because C >= FPEC
70
+ :RETURN
package/main/end.zkasm ADDED
@@ -0,0 +1,4 @@
1
+ finalWait:
2
+ ${beforeLast()} :JMPN(finalWait)
3
+ ; Set all registers to 0 except inputs: B (oldStateRoot), C (oldAccInputHash), SP (oldNumBatch), GAS (chainID) & CTX (forkID)
4
+ 0 => A, D, E, PC, SR, HASHPOS, RR, RCX :JMP(start)
@@ -0,0 +1,159 @@
1
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
+ ;; Compute l2TxHash for legacy and preEIP155 transactions
3
+ ;;
4
+ ;; - preEIP155 (message to sign in Ethereum: rlp[nonce, gasprice, gaslimit, to, value, data])
5
+ ;; [ 1 bytes ] txType = 0
6
+ ;; [ 8 bytes ] nonce
7
+ ;; [ 32 bytes ] gasPrice
8
+ ;; [ 8 bytes ] gasLimit
9
+ ;; [ 1 bytes ] deployment ('0': no deloyment, '1': deployment)
10
+ ;; [ 20 bytes ] to (0 bytes if it is a deployment)
11
+ ;; [ 32 bytes ] value
12
+ ;; [ 3 bytes ] dataLength
13
+ ;; [ XX bytes ] data
14
+ ;; [ 20 bytes ] from
15
+ ;;
16
+ ;;
17
+ ;; - Legacy (message to sign in Ethereum: rlp[nonce, gasprice, gaslimit, to, value, data, chainId, 0, 0])
18
+ ;; [ 1 bytes ] txType = 1
19
+ ;; [ 8 bytes ] nonce
20
+ ;; [ 32 bytes ] gasPrice
21
+ ;; [ 8 bytes ] gasLimit
22
+ ;; [ 1 bytes ] deployment ('0': no deloyment, '1': deployment)
23
+ ;; [ 20 bytes ] to (0 bytes if it is a deployment)
24
+ ;; [ 32 bytes ] value
25
+ ;; [ 3 bytes ] dataLength
26
+ ;; [ XX bytes ] data
27
+ ;; [ 8 bytes ] chainId
28
+ ;; [ 20 bytes ] from
29
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30
+
31
+
32
+ VAR CTX l2TxHashPointer ; Pointer to l2TxHash hash address
33
+ VAR CTX l2HASHP ; pointer to the l2TxHash to store the bytes
34
+ VAR GLOBAL tmpVar_HASHPOS_L2HashTx ; temporary variable register HASHPOS
35
+ VAR GLOBAL tmpVar_A_L2HashTx ; temporary variable register A
36
+ VAR GLOBAL tmpVar_D_L2HashTx ; temporary variable register D
37
+ VAR GLOBAL tmpVar_E_L2HashTx ; temporary variable register E
38
+
39
+ ;; Check counters to do the hashp and initialize HASHPOS of the l2TxHash
40
+ initL2HashTx:
41
+ ; check one binary available to perform correctly the HASHPDIGEST
42
+ %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary)
43
+ ; reserve one byte for the txType in the l2HashTx
44
+ ; txType will be known at the end of the RLP parsing
45
+ 1 :MSTORE(l2HASHP), RETURN
46
+
47
+ ;; Write generic bytes to the l2TxHash
48
+ ; @in A => value to write
49
+ ; @in D => bytes size to write
50
+ addL2HashTx:
51
+ ; store temporary register values
52
+ E :MSTORE(tmpVar_E_L2HashTx)
53
+ HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx)
54
+
55
+ ; load pointer l2HashTx and write bytes
56
+ $ => E :MLOAD(l2TxHashPointer)
57
+ $ => HASHPOS :MLOAD(l2HASHP)
58
+ A :HASHP(E)
59
+ HASHPOS :MSTORE(l2HASHP)
60
+
61
+ ; load temporary register values
62
+ $ => E :MLOAD(tmpVar_E_L2HashTx)
63
+ $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN
64
+
65
+ ;; Write 1 byte to l2TxHash: flag deployment = 1 ('0': no deployment transaction, '1': deployment transaction)
66
+ addL2HashTx_isDeploy:
67
+ ; store temporary register values
68
+ A :MSTORE(tmpVar_A_L2HashTx)
69
+ E :MSTORE(tmpVar_E_L2HashTx)
70
+ HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx)
71
+
72
+ ; load pointer l2HashTx and write deployment flag
73
+ $ => E :MLOAD(l2TxHashPointer)
74
+ $ => HASHPOS :MLOAD(l2HASHP)
75
+ 1 :HASHP1(E)
76
+ HASHPOS :MSTORE(l2HASHP)
77
+
78
+ ; load temporary register values
79
+ $ => A :MLOAD(tmpVar_A_L2HashTx)
80
+ $ => E :MLOAD(tmpVar_E_L2HashTx)
81
+ $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN
82
+
83
+ ;; Write 1 byte to l2TxHash: flag deployment = 0 ('0': no deployment transaction, '1': deployment transaction)
84
+ addL2HashTx_isNotDeploy:
85
+ ; store temporary register values
86
+ E :MSTORE(tmpVar_E_L2HashTx)
87
+ HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx)
88
+
89
+ ; load pointer l2HashTx and write deployment flag
90
+ $ => E :MLOAD(l2TxHashPointer)
91
+ $ => HASHPOS :MLOAD(l2HASHP)
92
+ 0 :HASHP1(E)
93
+ HASHPOS :MSTORE(l2HASHP)
94
+
95
+ ; load temporary register values
96
+ $ => E :MLOAD(tmpVar_E_L2HashTx)
97
+ $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN
98
+
99
+ ;; Write 3 bytes to l2TxHash: data length
100
+ addL2HashTx_dataLength:
101
+ ; store temporary register values
102
+ A :MSTORE(tmpVar_A_L2HashTx)
103
+ D :MSTORE(tmpVar_D_L2HashTx)
104
+ E :MSTORE(tmpVar_E_L2HashTx)
105
+ HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx)
106
+
107
+ ; load pointer l2HashTx and write data length
108
+ $ => E :MLOAD(l2TxHashPointer)
109
+ $ => HASHPOS :MLOAD(l2HASHP)
110
+ 3 => D
111
+ $ => A :MLOAD(txCalldataLen)
112
+ A :HASHP(E)
113
+ HASHPOS :MSTORE(l2HASHP)
114
+
115
+ ; load temporary register values
116
+ $ => A :MLOAD(tmpVar_A_L2HashTx)
117
+ $ => D :MLOAD(tmpVar_D_L2HashTx)
118
+ $ => E :MLOAD(tmpVar_E_L2HashTx)
119
+ $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN
120
+
121
+ ;; Write 1 byte to l2TxHash: txType
122
+ ; note: HASHPOS is not reovered and the outcome register is the l2TxHash length
123
+ addL2HashTx_txType:
124
+ ; store temporary register values
125
+ A :MSTORE(tmpVar_A_L2HashTx)
126
+ E :MSTORE(tmpVar_E_L2HashTx)
127
+ HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx)
128
+
129
+ ; load pointer l2HashTx and write txType
130
+ $ => E :MLOAD(l2TxHashPointer)
131
+ ; write txType in the first byte of the l2TxHash
132
+ 0 => HASHPOS
133
+ $ => A :MLOAD(isPreEIP155), JMPZ(addL2HashTx_txType_write_1)
134
+ 0 :HASHP1(E), JMP(addL2HashTx_txType_finish)
135
+ addL2HashTx_txType_write_1:
136
+ 1 :HASHP1(E)
137
+ addL2HashTx_txType_finish:
138
+ ; load temporary register values
139
+ $ => A :MLOAD(tmpVar_A_L2HashTx)
140
+ $ => E :MLOAD(tmpVar_E_L2HashTx)
141
+ $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN
142
+
143
+ ;; Closes l2TxHash and store the result
144
+ closeL2TxHash:
145
+ ; store temporary register values
146
+ E :MSTORE(tmpVar_E_L2HashTx)
147
+ HASHPOS :MSTORE(tmpVar_HASHPOS_L2HashTx)
148
+
149
+ ; load HASHPOS l2TxHash
150
+ $ => HASHPOS :MLOAD(l2HASHP)
151
+ $ => E :MLOAD(l2TxHashPointer)
152
+ HASHPOS :HASHPLEN(E)
153
+ ; digest l2TxHash
154
+ $ => E :HASHPDIGEST(E)
155
+ E :MSTORE(l2TxHash)
156
+
157
+ ; load temporary register values
158
+ $ => E :MLOAD(tmpVar_E_L2HashTx)
159
+ $ => HASHPOS :MLOAD(tmpVar_HASHPOS_L2HashTx), RETURN
@@ -0,0 +1,11 @@
1
+ ;; get D bytes from transaction bytes
2
+ ;@in D: number of bytes to get
3
+ ;@in C: current data parsed pointer
4
+ ;@out A: D bytes from batch data at offset C
5
+ getChangeL2TxBytes:
6
+ $ => A :MLOAD(batchL2DataLength)
7
+ $ => B :MLOAD(batchL2DataParsed)
8
+ A - B - C - D :JMPN(invalidDecodeChangeL2Block)
9
+ ${getTxs(p,D)} => A
10
+ $${p = p + D}
11
+ :RETURN
@@ -0,0 +1,28 @@
1
+ INCLUDE "load-change-l2-block-utils.zkasm"
2
+ ;;;;;;;;;;;;;;;;;;
3
+ ;; ChangeL2BlockTx:
4
+ ;; - fields: [type | deltaTimestamp | indexL1InfoTree ]
5
+ ;; - bytes: [ 1 | 4 | 4 ]
6
+ ;;;;;;;;;;;;;;;;;;
7
+
8
+ decodeChangeL2BlockTx:
9
+ ; No changeL2BlockTx allowed at forced batches
10
+ $ :MLOAD(isForced), JMPNZ(invalidDecodeChangeL2Block)
11
+
12
+ ; Decode deltaTimestamp / 4 bytes
13
+ %DELTA_TIMESTAMP_NUM_BYTES => D :CALL(getChangeL2TxBytes)
14
+ C + D => C :CALL(addBatchHashData)
15
+ A :MSTORE(deltaTimestamp)
16
+ ; Decode indexL1InfoTree / 4 bytes
17
+ %INDEX_L1INFOTREE_NUM_BYTES => D :CALL(getChangeL2TxBytes)
18
+ C + D => C :CALL(addBatchHashData)
19
+ A :MSTORE(indexL1InfoTree)
20
+ 1 :MSTORE(isChangeL2BlockTx), JMP(finishLoadChangeL2BlockTx)
21
+
22
+ finishLoadChangeL2BlockTx:
23
+ ;; update bytes parsed
24
+ $ => A :MLOAD(batchL2DataParsed)
25
+ A + C :MSTORE(batchL2DataParsed)
26
+ ;; increase number of transaction to process
27
+ $ => A :MLOAD(pendingTxs)
28
+ A + 1 :MSTORE(pendingTxs), JMP(txLoopRLP)