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.
- package/.eslintrc.js +33 -0
- package/.github/CODEOWNERS +14 -0
- package/.github/ISSUE_TEMPLATE/bug.yml +38 -0
- package/.github/ISSUE_TEMPLATE/feature.yml +26 -0
- package/.github/ISSUE_TEMPLATE/question.yml +26 -0
- package/.github/workflows/main.yaml +40 -0
- package/LICENSE +636 -0
- package/README.md +23 -5
- package/audits/Hexens_Polygon_zkEVM_PUBLIC_27.02.23.pdf +0 -0
- package/audits/Polygon-zkEVM-Public-v1.1-verichains-19-03-2024.pdf +0 -0
- package/audits/zkEVM-ROM-upgrade-1-Spearbit-30-May.pdf +0 -0
- package/audits/zkEVM-ROM-upgrade-2-Spearbit-21-August.pdf +0 -0
- package/audits/zkEVM-engagement-1-Spearbit-27-March.pdf +0 -0
- package/audits/zkEVM-engagement-2-Spearbit-27-March.pdf +0 -0
- package/audits/zkEVM-engagement-3-Spearbit-6-April.pdf +0 -0
- package/counters/README.md +45 -0
- package/counters/counters-executor.js +80 -0
- package/counters/countersConstants.zkasm +370 -0
- package/counters/endIncludes.zkasm +18 -0
- package/counters/initIncludes.zkasm +2 -0
- package/counters/tests/MLOAD32.zkasm +27 -0
- package/counters/tests/MLOADX.zkasm +30 -0
- package/counters/tests/MSTORE32.zkasm +32 -0
- package/counters/tests/MSTOREX.zkasm +36 -0
- package/counters/tests/SHLarith.zkasm +28 -0
- package/counters/tests/SHLarithBit.zkasm +28 -0
- package/counters/tests/SHRarith.zkasm +28 -0
- package/counters/tests/SHRarithBit.zkasm +28 -0
- package/counters/tests/abs.zkasm +29 -0
- package/counters/tests/addBatchHashByteByByte.zkasm +31 -0
- package/counters/tests/computeGasSendCall.zkasm +30 -0
- package/counters/tests/divArith.zkasm +27 -0
- package/counters/tests/expAD.zkasm +30 -0
- package/counters/tests/getLenBits.zkasm +30 -0
- package/counters/tests/getLenBytes.zkasm +32 -0
- package/counters/tests/isEmptyAccount.zkasm +30 -0
- package/counters/tests/mulARITH.zkasm +28 -0
- package/counters/tests/offsetUtil.zkasm +29 -0
- package/counters/tests/opADDMOD.zkasm +28 -0
- package/counters/tests/opAdd.zkasm +27 -0
- package/counters/tests/opBLOCKHASH.zkasm +28 -0
- package/counters/tests/opCALL.zkasm +41 -0
- package/counters/tests/opCALLCODE.zkasm +41 -0
- package/counters/tests/opCALLDATACOPY.zkasm +28 -0
- package/counters/tests/opCALLDATALOAD.zkasm +27 -0
- package/counters/tests/opCODECOPY.zkasm +28 -0
- package/counters/tests/opCREATE.zkasm +35 -0
- package/counters/tests/opCREATE2.zkasm +35 -0
- package/counters/tests/opDELEGATECALL.zkasm +35 -0
- package/counters/tests/opDIV.zkasm +27 -0
- package/counters/tests/opEXP.zkasm +29 -0
- package/counters/tests/opEXTCODECOPY.zkasm +29 -0
- package/counters/tests/opMOD.zkasm +27 -0
- package/counters/tests/opMUL.zkasm +27 -0
- package/counters/tests/opMULMOD.zkasm +28 -0
- package/counters/tests/opRETURN.zkasm +32 -0
- package/counters/tests/opRETURNDATACOPY.zkasm +29 -0
- package/counters/tests/opREVERT.zkasm +32 -0
- package/counters/tests/opSDIV.zkasm +28 -0
- package/counters/tests/opSHA3.zkasm +28 -0
- package/counters/tests/opSIGNEXTEND.zkasm +27 -0
- package/counters/tests/opSMOD.zkasm +28 -0
- package/counters/tests/opSTATICCALL.zkasm +35 -0
- package/counters/tests/opSUB.zkasm +27 -0
- package/counters/tests/saveMem.zkasm +31 -0
- package/docs/opcode-cost-zk-counters.md +315 -0
- package/docs/usage-ecrecover.md +51 -0
- package/index.js +43 -0
- package/main/block-info.zkasm +204 -0
- package/main/constants.zkasm +145 -0
- package/main/ecrecover/addFpEc.zkasm +31 -0
- package/main/ecrecover/checkSqrtFpEc.zkasm +1558 -0
- package/main/ecrecover/constEc.zkasm +13 -0
- package/main/ecrecover/ecrecover.zkasm +280 -0
- package/main/ecrecover/invFnEc.zkasm +44 -0
- package/main/ecrecover/invFpEc.zkasm +45 -0
- package/main/ecrecover/mulFnEc.zkasm +36 -0
- package/main/ecrecover/mulFpEc.zkasm +36 -0
- package/main/ecrecover/mulPointEc.zkasm +311 -0
- package/main/ecrecover/sqFpEc.zkasm +38 -0
- package/main/ecrecover/sqrtFpEc.zkasm +70 -0
- package/main/end.zkasm +4 -0
- package/main/l2-tx-hash.zkasm +159 -0
- package/main/load-change-l2-block-utils.zkasm +11 -0
- package/main/load-change-l2-block.zkasm +28 -0
- package/main/load-tx-rlp-utils.zkasm +72 -0
- package/main/load-tx-rlp.zkasm +431 -0
- package/main/main.zkasm +237 -0
- package/main/map-opcodes.zkasm +274 -0
- package/main/modexp/array_lib/array_add_AGTB.zkasm +123 -0
- package/main/modexp/array_lib/array_add_short.zkasm +85 -0
- package/main/modexp/array_lib/array_div.zkasm +215 -0
- package/main/modexp/array_lib/array_div_long.zkasm +284 -0
- package/main/modexp/array_lib/array_div_short.zkasm +222 -0
- package/main/modexp/array_lib/array_mul.zkasm +97 -0
- package/main/modexp/array_lib/array_mul_long.zkasm +156 -0
- package/main/modexp/array_lib/array_mul_short.zkasm +127 -0
- package/main/modexp/array_lib/array_square.zkasm +246 -0
- package/main/modexp/array_lib/unused/array_add.zkasm +100 -0
- package/main/modexp/array_lib/unused/array_is_odd.zkasm +23 -0
- package/main/modexp/array_lib/unused/array_is_one.zkasm +33 -0
- package/main/modexp/array_lib/unused/array_is_zero.zkasm +34 -0
- package/main/modexp/array_lib/unused/array_sub_AGTB.zkasm +111 -0
- package/main/modexp/array_lib/unused/array_unshift.zkasm +37 -0
- package/main/modexp/array_lib/utils/array_compare.zkasm +82 -0
- package/main/modexp/array_lib/utils/array_trim.zkasm +49 -0
- package/main/modexp/constants.zkasm +5 -0
- package/main/modexp/modexp.zkasm +296 -0
- package/main/modexp/modexp_utils.zkasm +230 -0
- package/main/opcodes/arithmetic.zkasm +357 -0
- package/main/opcodes/block.zkasm +163 -0
- package/main/opcodes/calldata-returndata-code.zkasm +619 -0
- package/main/opcodes/comparison.zkasm +446 -0
- package/main/opcodes/context-information.zkasm +169 -0
- package/main/opcodes/create-terminate-context.zkasm +1011 -0
- package/main/opcodes/crypto.zkasm +96 -0
- package/main/opcodes/flow-control.zkasm +126 -0
- package/main/opcodes/logs.zkasm +193 -0
- package/main/opcodes/stack-operations.zkasm +658 -0
- package/main/opcodes/storage-memory.zkasm +313 -0
- package/main/pairings/BN254/addPointBN254.zkasm +245 -0
- package/main/pairings/BN254/ecAdd.zkasm +312 -0
- package/main/pairings/BN254/ecMul.zkasm +159 -0
- package/main/pairings/BN254/escalarMulBN254.zkasm +155 -0
- package/main/pairings/BN254/lineDiffPointsBN254.zkasm +83 -0
- package/main/pairings/BN254/lineSamePointsBN254.zkasm +96 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm +49 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +236 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm +444 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm +212 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm +228 -0
- package/main/pairings/FP12BN254/CYCLOFP12BN254/xBinDecompBN254.zkasm +64 -0
- package/main/pairings/FP12BN254/frob2Fp12BN254.zkasm +80 -0
- package/main/pairings/FP12BN254/frob3Fp12BN254.zkasm +96 -0
- package/main/pairings/FP12BN254/frobFp12BN254.zkasm +96 -0
- package/main/pairings/FP12BN254/inverseFp12BN254.zkasm +289 -0
- package/main/pairings/FP12BN254/mulFp12BN254.zkasm +408 -0
- package/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm +296 -0
- package/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm +291 -0
- package/main/pairings/FP12BN254/squareFp12BN254.zkasm +376 -0
- package/main/pairings/FP2BN254/addFp2BN254.zkasm +19 -0
- package/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm +20 -0
- package/main/pairings/FP2BN254/invFp2BN254.zkasm +66 -0
- package/main/pairings/FP2BN254/mulFp2BN254.zkasm +19 -0
- package/main/pairings/FP2BN254/squareFp2BN254.zkasm +21 -0
- package/main/pairings/FP2BN254/subFp2BN254.zkasm +19 -0
- package/main/pairings/FP4BN254/squareFp4BN254.zkasm +76 -0
- package/main/pairings/FP6BN254/addFp6BN254.zkasm +59 -0
- package/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm +51 -0
- package/main/pairings/FP6BN254/inverseFp6BN254.zkasm +208 -0
- package/main/pairings/FP6BN254/mulFp6BN254.zkasm +201 -0
- package/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm +65 -0
- package/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm +134 -0
- package/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm +128 -0
- package/main/pairings/FP6BN254/squareFp6BN254.zkasm +147 -0
- package/main/pairings/FP6BN254/subFp6BN254.zkasm +59 -0
- package/main/pairings/FPBN254/addFpBN254.zkasm +29 -0
- package/main/pairings/FPBN254/invFpBN254.zkasm +55 -0
- package/main/pairings/FPBN254/mulFpBN254.zkasm +29 -0
- package/main/pairings/FPBN254/reduceFpBN254.zkasm +25 -0
- package/main/pairings/FPBN254/squareFpBN254.zkasm +31 -0
- package/main/pairings/FPBN254/subFpBN254.zkasm +36 -0
- package/main/pairings/FRBN254/reduceFrBN254.zkasm +25 -0
- package/main/pairings/constants.zkasm +62 -0
- package/main/pairings/ecPairing.zkasm +244 -0
- package/main/pairings/finalExpBN254.zkasm +2095 -0
- package/main/pairings/halfPairingBN254.zkasm +428 -0
- package/main/pairings/loopLengthBN254.zkasm +75 -0
- package/main/pairings/millerLoopBN254.zkasm +741 -0
- package/main/pairings/pairingBN254.zkasm +481 -0
- package/main/pairings/unused/addFp12BN254.zkasm +130 -0
- package/main/pairings/unused/expByXCycloFp12BN254.zkasm +411 -0
- package/main/pairings/unused/expFp12BN254.zkasm +333 -0
- package/main/pairings/unused/subFp12BN254.zkasm +130 -0
- package/main/pairings/unused/xPseudoBinDecompBN254.zkasm +68 -0
- package/main/pairings/utilsTests/expCycloFp12BN254.zkasm +334 -0
- package/main/precompiled/end.zkasm +42 -0
- package/main/precompiled/identity.zkasm +99 -0
- package/main/precompiled/pre-ecAdd.zkasm +84 -0
- package/main/precompiled/pre-ecMul.zkasm +82 -0
- package/main/precompiled/pre-ecPairing.zkasm +72 -0
- package/main/precompiled/pre-ecrecover.zkasm +71 -0
- package/main/precompiled/pre-modexp.zkasm +367 -0
- package/main/precompiled/pre-sha2-256.zkasm +125 -0
- package/main/precompiled/revert-precompiled.zkasm +25 -0
- package/main/precompiled/selector.zkasm +77 -0
- package/main/process-change-l2-block.zkasm +147 -0
- package/main/process-tx.zkasm +587 -0
- package/main/tables/2-exp.zkasm +260 -0
- package/main/touched.zkasm +118 -0
- package/main/utils.zkasm +2335 -0
- package/main/vars.zkasm +117 -0
- package/package.json +62 -3
- package/test/bytes-length.zkasm +39 -0
- package/test/ecrecover.zkasm +538 -0
- package/test/lt4-test.zkasm +38 -0
- package/test/mstorex.zkasm +191 -0
- package/test/opcalldatacopy.ignore.zkasm +331 -0
- package/test/performance/read-push.zkasm +71 -0
- package/test/read-push.zkasm +304 -0
- package/test/testArrayArith.zkasm +1099 -0
- package/test/testArrayUtils.zkasm +335 -0
- package/test/testCycloFp12ArithBN254.zkasm +548 -0
- package/test/testEcAdd.zkasm +252 -0
- package/test/testEcMul.zkasm +231 -0
- package/test/testEcPairing.zkasm +436 -0
- package/test/testFinalExpBn254.zkasm +139 -0
- package/test/testFp12ArithBN254.zkasm +692 -0
- package/test/testFp2ArithBN254.zkasm +185 -0
- package/test/testFp4ArithBN254.zkasm +128 -0
- package/test/testFp6ArithBN254.zkasm +260 -0
- package/test/testFpArithBN254.zkasm +159 -0
- package/test/testFrArithBN254.zkasm +113 -0
- package/test/testHalfPairingBN254.zkasm +285 -0
- package/test/testModExp.zkasm +586 -0
- package/test/testModExpReturn.zkasm +81 -0
- package/test/testPairingBN254.zkasm +463 -0
- package/test/testPointArithBN254.zkasm +270 -0
- package/test/testSHA256.zkasm +27 -0
- package/test/touched-assert.zkasm +59 -0
- package/test/utils-expAD.zkasm +48 -0
- package/test/utils-getLenBytes.zkasm +36 -0
- package/tools/audit-tools/registry-op-checker.js +71 -0
- package/tools/get-not-used-labels.js +31 -0
- package/tools/helpers/helpers.js +47 -0
- package/tools/modexp-utils/README.md +5 -0
- package/tools/modexp-utils/modexp-test-gen.js +168 -0
- package/tools/modexp-utils/modexp-test-int.sage +37 -0
- package/tools/parallel-testing/checker.sh +6 -0
- package/tools/parallel-testing/gen-parallel-tests.js +78 -0
- package/tools/parallel-testing/parallel-tests-sample/sample.test.js +136 -0
- package/tools/run-tests-zkasm.js +83 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
/**
|
2
|
+
* @link [https://www.evm.codes/precompiled#0x08?fork=berlin]
|
3
|
+
* @zk-counters
|
4
|
+
* - dynamic steps: 200000 * nInputs + 175000
|
5
|
+
* - dynamic arith: 15000 * nInputs + 17500
|
6
|
+
* - dynamic binary: 4100 * nInputs + 750
|
7
|
+
* @process-precompiled
|
8
|
+
* - stack input: [x1, y1, x2, y2, ..., xk, yk]
|
9
|
+
* - stack output: [success]
|
10
|
+
* @note For implementation details, see: https://hackmd.io/kcEJAWISQ56eE6YpBnurgw?view
|
11
|
+
*/
|
12
|
+
|
13
|
+
funcEcPairing:
|
14
|
+
; Move balances if value > 0 just before executing the contract CALL
|
15
|
+
$ => B :MLOAD(txValue)
|
16
|
+
0 => A
|
17
|
+
zkPC+2 => RR
|
18
|
+
$ :LT, JMPC(moveBalances)
|
19
|
+
|
20
|
+
GAS - %ECPAIRING_GAS => GAS :JMPN(outOfGas) ; gas static = 45000
|
21
|
+
|
22
|
+
1 => C
|
23
|
+
$ => B :MLOAD(txCalldataLen),JMPZ(continueInput0)
|
24
|
+
B :MSTORE(arithA)
|
25
|
+
192 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB]
|
26
|
+
$ => A :MLOAD(arithRes2), JMPNZ(preEndFail)
|
27
|
+
$ => A :MLOAD(arithRes1)
|
28
|
+
A :MSTORE(ecPairing_ninputs)
|
29
|
+
|
30
|
+
GAS - 34000*A => GAS :JMPN(outOfGas) ; gas = 34000 * inputsLength
|
31
|
+
|
32
|
+
%MAX_CNT_BINARY - CNT_BINARY - 750 - 4100*A :JMPN(outOfCountersBinary)
|
33
|
+
%MAX_CNT_ARITH - CNT_ARITH - 17500 - 15000*A :JMPN(outOfCountersArith)
|
34
|
+
%MAX_CNT_STEPS - STEP - 175000 - 200000*A :JMPN(outOfCountersStep)
|
35
|
+
|
36
|
+
-32 :MSTORE(readXFromCalldataOffset),CALL(ecPairing)
|
37
|
+
B :JMPNZ(preEndFail)
|
38
|
+
$ => C :MLOAD(ecPairing_result)
|
39
|
+
|
40
|
+
continueInput0:
|
41
|
+
|
42
|
+
; write ecAdd data into memory
|
43
|
+
0 => E
|
44
|
+
C :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset]
|
45
|
+
|
46
|
+
; prepare return data
|
47
|
+
0 :MSTORE(retDataOffset)
|
48
|
+
32 :MSTORE(retDataLength)
|
49
|
+
$ => A :MLOAD(originCTX), JMPZ(handleGas)
|
50
|
+
; set retDataCTX
|
51
|
+
$ => B :MLOAD(currentCTX)
|
52
|
+
A => CTX
|
53
|
+
B :MSTORE(retDataCTX)
|
54
|
+
B => CTX
|
55
|
+
|
56
|
+
; write result ecpairing into previous context memory
|
57
|
+
$ => C :MLOAD(retCallLength)
|
58
|
+
$ => E :MLOAD(retCallOffset)
|
59
|
+
|
60
|
+
; ecpairing result is in bytesToStore
|
61
|
+
C - 32 :JMPN(continueECPAIRING)
|
62
|
+
32 => C
|
63
|
+
|
64
|
+
continueECPAIRING:
|
65
|
+
$ => CTX :MLOAD(originCTX), CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset]
|
66
|
+
:JMP(endECPAIRING)
|
67
|
+
|
68
|
+
preEndECPAIRING:
|
69
|
+
$ => CTX :MLOAD(originCTX)
|
70
|
+
|
71
|
+
endECPAIRING:
|
72
|
+
CTX :MSTORE(currentCTX), JMP(preEnd)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
/**
|
2
|
+
* @link [https://www.evm.codes/precompiled#0x01?fork=berlin]
|
3
|
+
* @zk-counters
|
4
|
+
* - dynamic steps:
|
5
|
+
* - dynamic arith:
|
6
|
+
* - dynamic binary:
|
7
|
+
* @process-precompiled
|
8
|
+
* - stack input: [hash, v, r, s]
|
9
|
+
* - stack output: [publicAddress]
|
10
|
+
*/
|
11
|
+
funcECRECOVER:
|
12
|
+
; Move balances if value > 0 just before executing the contract CALL
|
13
|
+
$ => B :MLOAD(txValue)
|
14
|
+
0 => A
|
15
|
+
zkPC+2 => RR
|
16
|
+
$ :LT, JMPC(moveBalances)
|
17
|
+
|
18
|
+
GAS - %ECRECOVER_GAS => GAS :JMPN(outOfGas) ; gas static = 3000
|
19
|
+
; read data stored in calldata
|
20
|
+
; read hash [32 bytes]
|
21
|
+
32 :MSTORE(readXFromCalldataLength)
|
22
|
+
0 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
23
|
+
$ => A :MLOAD(readXFromCalldataResult)
|
24
|
+
; read v [32 bytes]
|
25
|
+
E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
26
|
+
$ => D :MLOAD(readXFromCalldataResult)
|
27
|
+
; read r [32 bytes]
|
28
|
+
E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
29
|
+
$ => B :MLOAD(readXFromCalldataResult)
|
30
|
+
; read s [32 bytes]
|
31
|
+
E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
32
|
+
$ => C :MLOAD(readXFromCalldataResult),CALL(ecrecover_precompiled) ; in: [A: hash, B: r, C: s, D: v], out: [A: result_ecrecover, B: result_code]
|
33
|
+
B :JMPNZ(endECRECOVERFail)
|
34
|
+
|
35
|
+
; write ecrecover data into memory
|
36
|
+
0 => E
|
37
|
+
A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset]
|
38
|
+
|
39
|
+
; prepare return data
|
40
|
+
0 :MSTORE(retDataOffset)
|
41
|
+
32 :MSTORE(retDataLength)
|
42
|
+
$ => A :MLOAD(originCTX), JMPZ(handleGas)
|
43
|
+
; set retDataCTX
|
44
|
+
$ => B :MLOAD(currentCTX)
|
45
|
+
A => CTX
|
46
|
+
B :MSTORE(retDataCTX)
|
47
|
+
B => CTX
|
48
|
+
|
49
|
+
; write result ecrecover into previous context memory
|
50
|
+
$ => C :MLOAD(retCallLength), JMPZ(preEndECRECOVER)
|
51
|
+
$ => E :MLOAD(retCallOffset)
|
52
|
+
|
53
|
+
; ecrecover result is in bytesToStore
|
54
|
+
C - 32 :JMPN(continueEcrecover)
|
55
|
+
32 => C
|
56
|
+
|
57
|
+
continueEcrecover:
|
58
|
+
$ => CTX :MLOAD(originCTX), CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset]
|
59
|
+
:JMP(endECRECOVER)
|
60
|
+
|
61
|
+
endECRECOVERFail:
|
62
|
+
$ => A :MLOAD(originCTX), JMPZ(handleGas)
|
63
|
+
A => CTX
|
64
|
+
0 :MSTORE(retDataCTX)
|
65
|
+
CTX :MSTORE(currentCTX), JMP(preEnd)
|
66
|
+
|
67
|
+
preEndECRECOVER:
|
68
|
+
$ => CTX :MLOAD(originCTX)
|
69
|
+
|
70
|
+
endECRECOVER:
|
71
|
+
CTX :MSTORE(currentCTX), JMP(preEnd)
|
@@ -0,0 +1,367 @@
|
|
1
|
+
/**
|
2
|
+
* @link [https://www.evm.codes/precompiled#0x05?fork=berlin]
|
3
|
+
* @zk-counters
|
4
|
+
* - dynamic steps:
|
5
|
+
* - dynamic arith:
|
6
|
+
* - dynamic binary:
|
7
|
+
* @process-precompiled
|
8
|
+
* - stack input: [x1, y1, x2, y2]
|
9
|
+
* - stack output: [x, y]
|
10
|
+
* @note We work with unbounded and unsigned integers represented in (little-endian) chunks of 256 bits.
|
11
|
+
* @note After a few discussions, we decided to set the maximum input length of the base, modulus and exponent to 32.
|
12
|
+
* See [https://github.com/0xPolygonHermez/zkevm-rom-internal/issues/43] for more details.
|
13
|
+
*/
|
14
|
+
INCLUDE "../modexp/constants.zkasm"
|
15
|
+
|
16
|
+
INCLUDE "../modexp/modexp.zkasm"
|
17
|
+
INCLUDE "../modexp/modexp_utils.zkasm"
|
18
|
+
|
19
|
+
INCLUDE "../modexp/array_lib/utils/array_trim.zkasm"
|
20
|
+
INCLUDE "../modexp/array_lib/utils/array_compare.zkasm"
|
21
|
+
|
22
|
+
INCLUDE "../modexp/array_lib/array_add_AGTB.zkasm"
|
23
|
+
INCLUDE "../modexp/array_lib/array_add_short.zkasm"
|
24
|
+
INCLUDE "../modexp/array_lib/array_mul_long.zkasm"
|
25
|
+
INCLUDE "../modexp/array_lib/array_mul_short.zkasm"
|
26
|
+
INCLUDE "../modexp/array_lib/array_mul.zkasm"
|
27
|
+
INCLUDE "../modexp/array_lib/array_square.zkasm"
|
28
|
+
INCLUDE "../modexp/array_lib/array_div_short.zkasm"
|
29
|
+
INCLUDE "../modexp/array_lib/array_div_long.zkasm"
|
30
|
+
INCLUDE "../modexp/array_lib/array_div.zkasm"
|
31
|
+
|
32
|
+
VAR GLOBAL multiplication_complexity
|
33
|
+
|
34
|
+
VAR GLOBAL modexp_Bsize
|
35
|
+
VAR GLOBAL modexp_Esize
|
36
|
+
VAR GLOBAL modexp_Msize
|
37
|
+
VAR GLOBAL modexp_Mend
|
38
|
+
VAR GLOBAL modexp_offset
|
39
|
+
VAR GLOBAL modexp_returnIndex
|
40
|
+
VAR GLOBAL modexp_returnFirstIndex
|
41
|
+
VAR GLOBAL modexp_returnIndexRem
|
42
|
+
VAR GLOBAL expLenBits
|
43
|
+
VAR GLOBAL retCopyLen
|
44
|
+
|
45
|
+
funcModexp:
|
46
|
+
|
47
|
+
%MAX_CNT_BINARY - CNT_BINARY - 20 :JMPN(outOfCountersBinary)
|
48
|
+
%MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith)
|
49
|
+
%MAX_CNT_STEPS - STEP - 400 :JMPN(outOfCountersStep)
|
50
|
+
|
51
|
+
; Move balances if value > 0 just before executing the contract CALL
|
52
|
+
$ => B :MLOAD(txValue)
|
53
|
+
0 => A
|
54
|
+
zkPC + 2 => RR
|
55
|
+
$ :LT, JMPC(moveBalances)
|
56
|
+
|
57
|
+
; read data stored in calldata
|
58
|
+
; Bsize [32 bytes], Esize [32 bytes], Msize [32 bytes]
|
59
|
+
; Bsize [32 bytes]
|
60
|
+
32 :MSTORE(readXFromCalldataLength)
|
61
|
+
0 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
62
|
+
$ => A :MLOAD(readXFromCalldataResult)
|
63
|
+
A :MSTORE(modexp_Bsize) ;Bsize = base size
|
64
|
+
; Esize [32 bytes]
|
65
|
+
E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
66
|
+
$ => A :MLOAD(readXFromCalldataResult)
|
67
|
+
A :MSTORE(modexp_Esize) ;Esize = exp size
|
68
|
+
; Msize [32 bytes]
|
69
|
+
E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
70
|
+
$ => A :MLOAD(readXFromCalldataResult)
|
71
|
+
A :MSTORE(modexp_Msize) ;Msize = mod size
|
72
|
+
; store offset modexp num values
|
73
|
+
E + 32 => E
|
74
|
+
E :MSTORE(modexp_offset)
|
75
|
+
; get exp offset = 96 bytes (Bsize | Esize | Msize) + Bsize
|
76
|
+
$ => A :MLOAD(modexp_Bsize)
|
77
|
+
96 => B
|
78
|
+
$ => A :ADD
|
79
|
+
$ => B :MLOAD(txCalldataLen)
|
80
|
+
; expLenBits = bit length of first 32 bytes of exp
|
81
|
+
0 :MSTORE(expLenBits)
|
82
|
+
; if 96 + Bsize (exp offset) < txCalldataLen --> setExpBits, else --> expLenBits = 0
|
83
|
+
$ :LT, JMPC(setExpBits, setMaxLen)
|
84
|
+
|
85
|
+
setExpBits:
|
86
|
+
; E exp offset
|
87
|
+
A => E
|
88
|
+
$ => A,C :MLOAD(modexp_Esize)
|
89
|
+
33 => B
|
90
|
+
; A, C = Esize
|
91
|
+
; if Esize <= 32 --> setExpBitsContinue
|
92
|
+
$ => B :LT, JMPC(setExpBitsContinue)
|
93
|
+
32 => C
|
94
|
+
|
95
|
+
setExpBitsContinue:
|
96
|
+
; read a length of bytes (C) from exp offset (E)
|
97
|
+
C :MSTORE(readXFromCalldataLength)
|
98
|
+
E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
99
|
+
$ => A :MLOAD(readXFromCalldataResult)
|
100
|
+
; A = first 32 bytes of exp
|
101
|
+
32 - C => D :CALL(SHRarith)
|
102
|
+
A => B :CALL(getLenBits); A bits length first 32 bytes
|
103
|
+
; A = bit length of first 32 bytes of exp
|
104
|
+
A :JMPZ(setMaxLen)
|
105
|
+
A - 1 :MSTORE(expLenBits)
|
106
|
+
|
107
|
+
setMaxLen:
|
108
|
+
; set B with max length (max(Blen, Mlen))
|
109
|
+
$ => B :MLOAD(modexp_Msize)
|
110
|
+
$ => A :MLOAD(modexp_Bsize)
|
111
|
+
$ :LT, JMPC(calculateGas)
|
112
|
+
A => B
|
113
|
+
|
114
|
+
; B: max_length = max(Blen, Mlen)
|
115
|
+
calculateGas:
|
116
|
+
|
117
|
+
%MAX_CNT_BINARY - CNT_BINARY - 10 :JMPN(outOfCountersBinary)
|
118
|
+
%MAX_CNT_ARITH - CNT_ARITH - 2 :JMPN(outOfCountersArith)
|
119
|
+
%MAX_CNT_STEPS - STEP - 120 :JMPN(outOfCountersStep)
|
120
|
+
|
121
|
+
B :MSTORE(arithA)
|
122
|
+
7 :MSTORE(arithB), CALL(addARITH)
|
123
|
+
; check arith overflow
|
124
|
+
$ :MLOAD(addArithOverflow), JMPNZ(outOfGas)
|
125
|
+
$ => B :MLOAD(arithRes1)
|
126
|
+
B :MSTORE(arithA)
|
127
|
+
8 :MSTORE(arithB), CALL(divARITH)
|
128
|
+
; B: words = (max_length + 7) / 8
|
129
|
+
$ => B :MLOAD(arithRes1)
|
130
|
+
%MAX_GAS_WORD_MODEXP => A
|
131
|
+
$ :LT, JMPC(outOfGas)
|
132
|
+
; A: multiplication_complexity = words**2
|
133
|
+
B :MSTORE(arithA)
|
134
|
+
B :MSTORE(arithB), CALL(mulARITH)
|
135
|
+
$ => A :MLOAD(arithRes1)
|
136
|
+
A :MSTORE(multiplication_complexity), JMPZ(dynamicGas)
|
137
|
+
|
138
|
+
$ => A :MLOAD(modexp_Esize)
|
139
|
+
33 => B
|
140
|
+
; if Esize <= 32 --> modexp_expLT32
|
141
|
+
$ => B :LT, JMPC(modexp_expLT32)
|
142
|
+
;elif Esize > 32: iteration_count = (8 * (Esize - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1)
|
143
|
+
A :MSTORE(arithA)
|
144
|
+
32 :MSTORE(arithB), CALL(subARITH)
|
145
|
+
$ => A :MLOAD(arithRes1)
|
146
|
+
A :MSTORE(arithA)
|
147
|
+
8 :MSTORE(arithB), CALL(mulARITH)
|
148
|
+
; check arith overflow
|
149
|
+
$ :MLOAD(mulArithOverflowFlag), JMPNZ(outOfGas)
|
150
|
+
; A = 8 * (Esize - 32)
|
151
|
+
$ => A :MLOAD(arithRes1)
|
152
|
+
$ => B :MLOAD(expLenBits)
|
153
|
+
; iteration_count = (8 * (Esize - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1)
|
154
|
+
A :MSTORE(arithA)
|
155
|
+
B :MSTORE(arithB), CALL(addARITH)
|
156
|
+
; check arith overflow
|
157
|
+
$ :MLOAD(addArithOverflow), JMPNZ(outOfGas)
|
158
|
+
$ => E :MLOAD(arithRes1), JMP(finalGas)
|
159
|
+
; E = iteration_count
|
160
|
+
|
161
|
+
modexp_expLT32:
|
162
|
+
$ => E :MLOAD(expLenBits)
|
163
|
+
|
164
|
+
finalGas:
|
165
|
+
E => B
|
166
|
+
%MAX_GAS_IT_MODEXP => A
|
167
|
+
$ :LT, JMPC(outOfGas)
|
168
|
+
1 => A
|
169
|
+
$ :LT, JMPC(dynamicGas)
|
170
|
+
1 => E
|
171
|
+
|
172
|
+
dynamicGas:
|
173
|
+
|
174
|
+
%MAX_CNT_BINARY - CNT_BINARY - 9 :JMPN(outOfCountersBinary)
|
175
|
+
%MAX_CNT_ARITH - CNT_ARITH - 3 :JMPN(outOfCountersArith)
|
176
|
+
%MAX_CNT_STEPS - STEP - 55 :JMPN(outOfCountersStep)
|
177
|
+
|
178
|
+
; E = calculate_iteration_count = max(iteration_count, 1)
|
179
|
+
$ => A :MLOAD(multiplication_complexity)
|
180
|
+
A :MSTORE(arithA)
|
181
|
+
E :MSTORE(arithB), CALL(mulARITH)
|
182
|
+
; check arith overflow
|
183
|
+
$ :MLOAD(mulArithOverflowFlag), JMPNZ(outOfGas)
|
184
|
+
; A = multiplication_complexity * iteration_count
|
185
|
+
$ => A :MLOAD(arithRes1)
|
186
|
+
A :MSTORE(arithA)
|
187
|
+
3 :MSTORE(arithB), CALL(divARITH)
|
188
|
+
; A = multiplication_complexity * iteration_count / 3
|
189
|
+
$ => A :MLOAD(arithRes1)
|
190
|
+
%TX_GAS_LIMIT => B
|
191
|
+
$ :LT, JMPNC(outOfGas)
|
192
|
+
200 => B
|
193
|
+
$ :LT, JMPC(lastChecks)
|
194
|
+
A => B
|
195
|
+
|
196
|
+
lastChecks:
|
197
|
+
B :MSTORE(preGAS)
|
198
|
+
; B = max(200, multiplication_complexity * iteration_count / 3)
|
199
|
+
GAS - B => GAS :JMPN(outOfGas)
|
200
|
+
; check first modulo size and base size to match ethereum specification
|
201
|
+
0 => A
|
202
|
+
$ => B :MLOAD(modexp_Msize)
|
203
|
+
$ :EQ, JMPC(save0outMod0) ; if Msize = 0 --> save0outMod0
|
204
|
+
; Msize > 0 from here
|
205
|
+
$ => B :MLOAD(modexp_Bsize)
|
206
|
+
$ :EQ, JMPC(save0out) ; if Bsize = 0 --> save0out
|
207
|
+
; Bsize > 0 from here
|
208
|
+
|
209
|
+
; Check maximum length allowed in the zkEVM reagrding the modExp
|
210
|
+
; If parameters (length > %MAX_SIZE_MODEXP) --> zkEVM does a revert returning all the gas consumed
|
211
|
+
%MAX_SIZE_MODEXP => A
|
212
|
+
$ => B :MLOAD(modexp_Bsize)
|
213
|
+
$ :LT, JMPC(preFailModExpLength) ; if Bsize > MAX_SIZE_MODEXP --> preFailModExpLength
|
214
|
+
$ => B :MLOAD(modexp_Esize)
|
215
|
+
$ :LT, JMPC(preFailModExpLength) ; if Esize > MAX_SIZE_MODEXP --> preFailModExpLength
|
216
|
+
$ => B :MLOAD(modexp_Msize)
|
217
|
+
$ :LT, JMPC(preFailModExpLength) ; if Msize > MAX_SIZE_MODEXP --> preFailModExpLength
|
218
|
+
; get base value
|
219
|
+
$ => E :MLOAD(modexp_offset) ; This is used in modexp_getBase, modexp_getExp and modexp_getMod
|
220
|
+
$ => C :MLOAD(modexp_Bsize)
|
221
|
+
:CALL(modexp_getBase)
|
222
|
+
; get exp value
|
223
|
+
$ => C :MLOAD(modexp_Esize)
|
224
|
+
:CALL(modexp_getExp)
|
225
|
+
; get mod value
|
226
|
+
$ => C :MLOAD(modexp_Msize)
|
227
|
+
:CALL(modexp_getMod)
|
228
|
+
1 => B
|
229
|
+
; if mod == 0 --> return 0
|
230
|
+
$ => A :MLOAD(modexp_Mlen), JMPZ(save0out)
|
231
|
+
; if Mlen != 1 --> checkExpLen
|
232
|
+
$ :EQ, JMPNC(checkExpLen)
|
233
|
+
; if Mlen == 1 && mod == 1 --> return 0
|
234
|
+
$ => A :MLOAD(modexp_M)
|
235
|
+
$ :EQ, JMPC(save0out)
|
236
|
+
|
237
|
+
checkExpLen:
|
238
|
+
; if exp == 0 --> return 1
|
239
|
+
$ => A :MLOAD(modexp_Elen), JMPZ(save1out)
|
240
|
+
|
241
|
+
checkBaseLen:
|
242
|
+
; if base == 0 --> return 0
|
243
|
+
$ => A :MLOAD(modexp_Blen), JMPZ(save0out)
|
244
|
+
; if Blen != 1 --> callMODEXP
|
245
|
+
$ :EQ, JMPNC(callMODEXP)
|
246
|
+
; if Blen == 1 && base == 1 --> return 1
|
247
|
+
$ => A :MLOAD(modexp_B)
|
248
|
+
$ :EQ, JMPC(save1out)
|
249
|
+
|
250
|
+
callMODEXP:
|
251
|
+
:CALL(modexp)
|
252
|
+
:JMP(finalMODEXP)
|
253
|
+
|
254
|
+
save1out:
|
255
|
+
1 :MSTORE(modexp_out), JMP(finalMODEXP)
|
256
|
+
|
257
|
+
save0out:
|
258
|
+
$ => B :MLOAD(modexp_Msize)
|
259
|
+
%MAX_SIZE_MODEXP => A
|
260
|
+
$ :LT,JMPC(preFailModExpLength)
|
261
|
+
0 :MSTORE(modexp_out), JMP(finalMODEXP)
|
262
|
+
|
263
|
+
save0outMod0:
|
264
|
+
0 :MSTORE(modexp_out), JMP(preEndMODEXP)
|
265
|
+
|
266
|
+
finalMODEXP:
|
267
|
+
%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep)
|
268
|
+
|
269
|
+
; Get lower between retCallLength and modexp_Msize
|
270
|
+
$ => A :MLOAD(modexp_Msize)
|
271
|
+
$ => B :MLOAD(retCallLength)
|
272
|
+
A - B :JMPN(finalMODEXPreturn)
|
273
|
+
B => A
|
274
|
+
|
275
|
+
finalMODEXPreturn:
|
276
|
+
; write data into memory
|
277
|
+
A :MSTORE(retCopyLen)
|
278
|
+
0 => B
|
279
|
+
$ => C :MLOAD(modexp_Msize)
|
280
|
+
C :MSTORE(arithA)
|
281
|
+
32 :MSTORE(arithB), CALL(divARITH)
|
282
|
+
$ => E :MLOAD(arithRes1)
|
283
|
+
E :MSTORE(modexp_returnFirstIndex)
|
284
|
+
$ => A :MLOAD(arithRes2)
|
285
|
+
A :MSTORE(modexp_returnIndexRem), JMPZ(memoryLoop)
|
286
|
+
; if Msize % 32 > 0, copy last bytes, else --> memoryLoop
|
287
|
+
A => C
|
288
|
+
$ => A :MLOAD(modexp_out+E)
|
289
|
+
32 - C => D :CALL(SHLarith)
|
290
|
+
A :MSTORE(bytesToStore)
|
291
|
+
B => E
|
292
|
+
:CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset]
|
293
|
+
E => B
|
294
|
+
$ => A :MLOAD(modexp_Msize)
|
295
|
+
A - C => C :JMPZ(modexpReturn)
|
296
|
+
$ => E :MLOAD(modexp_returnFirstIndex)
|
297
|
+
|
298
|
+
memoryLoop:
|
299
|
+
|
300
|
+
%MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary)
|
301
|
+
%MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep)
|
302
|
+
|
303
|
+
E - 1 => E :MSTORE(modexp_returnIndex)
|
304
|
+
$ => A :MLOAD(modexp_out+E)
|
305
|
+
A :MSTORE(bytesToStore)
|
306
|
+
B => E
|
307
|
+
:CALL(MSTORE32) ; in: [bytesToStore, E: offset] out: [E: new offset]
|
308
|
+
E => B
|
309
|
+
$ => E :MLOAD(modexp_returnIndex)
|
310
|
+
C - 32 => C :JMPNZ(memoryLoop)
|
311
|
+
|
312
|
+
modexpReturn:
|
313
|
+
%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep)
|
314
|
+
|
315
|
+
; prepare return data
|
316
|
+
0 :MSTORE(retDataOffset)
|
317
|
+
$ => C :MLOAD(modexp_Msize)
|
318
|
+
C :MSTORE(retDataLength)
|
319
|
+
$ => B :MLOAD(retCallOffset)
|
320
|
+
$ => A :MLOAD(originCTX), JMPZ(handleGas)
|
321
|
+
; set retDataCTX
|
322
|
+
$ => E :MLOAD(currentCTX)
|
323
|
+
A => CTX
|
324
|
+
E :MSTORE(retDataCTX)
|
325
|
+
|
326
|
+
$ => C :MLOAD(retCopyLen)
|
327
|
+
$ => E :MLOAD(modexp_returnFirstIndex)
|
328
|
+
$ => A :MLOAD(modexp_returnIndexRem), JMPZ(returnLoop)
|
329
|
+
A => C
|
330
|
+
$ => A :MLOAD(modexp_out+E)
|
331
|
+
32 - C => D :CALL(SHLarith)
|
332
|
+
A :MSTORE(bytesToStore)
|
333
|
+
B => E
|
334
|
+
:CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset]
|
335
|
+
E => B
|
336
|
+
$ => A :MLOAD(retCopyLen)
|
337
|
+
A - C => C :JMPZ(endMODEXP)
|
338
|
+
$ => E :MLOAD(modexp_returnFirstIndex)
|
339
|
+
|
340
|
+
returnLoop:
|
341
|
+
%MAX_CNT_BINARY - CNT_BINARY - 2 :JMPN(outOfCountersBinary)
|
342
|
+
%MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep)
|
343
|
+
|
344
|
+
E - 1 => E :MSTORE(modexp_returnIndex)
|
345
|
+
C - 32 :JMPN(returnLoopFinal)
|
346
|
+
$ => A :MLOAD(modexp_out+E)
|
347
|
+
A :MSTORE(bytesToStore)
|
348
|
+
B => E
|
349
|
+
:CALL(MSTORE32) ; in: [bytesToStore, E: offset] out: [E: new offset]
|
350
|
+
E => B
|
351
|
+
$ => E :MLOAD(modexp_returnIndex)
|
352
|
+
C - 32 => C :JMPZ(endMODEXP, returnLoop)
|
353
|
+
|
354
|
+
returnLoopFinal:
|
355
|
+
$ => A :MLOAD(modexp_out+E)
|
356
|
+
32 - C => D :CALL(SHLarith)
|
357
|
+
A :MSTORE(bytesToStore)
|
358
|
+
B => E
|
359
|
+
:CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset]
|
360
|
+
:JMP(endMODEXP)
|
361
|
+
|
362
|
+
preEndMODEXP:
|
363
|
+
$ => A :MLOAD(originCTX), JMPZ(handleGas)
|
364
|
+
A => CTX
|
365
|
+
|
366
|
+
endMODEXP:
|
367
|
+
CTX :MSTORE(currentCTX), JMP(preEnd)
|
@@ -0,0 +1,125 @@
|
|
1
|
+
/**
|
2
|
+
* @link [https://www.evm.codes/precompiled#0x02?fork=berlin]
|
3
|
+
* @zk-counters
|
4
|
+
* - dynamic steps:
|
5
|
+
* - dynamic binary:
|
6
|
+
* @process-precompiled
|
7
|
+
* - stack input: [data]
|
8
|
+
* - stack output: [hash]
|
9
|
+
*/
|
10
|
+
VAR GLOBAL sha256DataOffset
|
11
|
+
VAR GLOBAL sha256DataId
|
12
|
+
VAR GLOBAL sha256Hash
|
13
|
+
VAR GLOBAL tmpZkSHA256
|
14
|
+
|
15
|
+
funcSHA256:
|
16
|
+
%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep)
|
17
|
+
%MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary)
|
18
|
+
|
19
|
+
; Move balances if value > 0 just before executing the contract CALL
|
20
|
+
$ => B :MLOAD(txValue)
|
21
|
+
0 => A
|
22
|
+
zkPC+2 => RR
|
23
|
+
$ :LT, JMPC(moveBalances)
|
24
|
+
|
25
|
+
; GAS - staticGas
|
26
|
+
GAS - %SHA2_256_GAS => GAS :JMPN(outOfGas)
|
27
|
+
|
28
|
+
$ => C :MLOAD(txCalldataLen)
|
29
|
+
|
30
|
+
;words => A === (C+31)/32 => A
|
31
|
+
C + 31 => A
|
32
|
+
A :MSTORE(arithA)
|
33
|
+
32 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB]
|
34
|
+
$ => A :MLOAD(arithRes1)
|
35
|
+
|
36
|
+
; GAS - dynamicGas
|
37
|
+
GAS - %SHA2_256_WORD_GAS*A => GAS :JMPN(outOfGas)
|
38
|
+
|
39
|
+
; Compute necessary sha256 counters to finish the full hash
|
40
|
+
; Divide the total data length + 1 by 64 to obtain the sha256 counter increment
|
41
|
+
; 64 is the value used by the prover to increment sha256 counters
|
42
|
+
C + 1 :MSTORE(arithA)
|
43
|
+
64 :MSTORE(arithB), CALL(divARITH); in: [arithA, arithB] out: [arithRes1: arithA/arithB, arithRes2: arithA%arithB]
|
44
|
+
$ => A :MLOAD(arithRes1)
|
45
|
+
|
46
|
+
; check enough sha256 counters left
|
47
|
+
%MAX_CNT_SHA256_F - CNT_SHA256_F - A :JMPN(outOfCountersSha256)
|
48
|
+
|
49
|
+
; prepare retData
|
50
|
+
0 :MSTORE(retDataOffset)
|
51
|
+
32 :MSTORE(retDataLength)
|
52
|
+
32 :MSTORE(readXFromCalldataLength)
|
53
|
+
0 => HASHPOS
|
54
|
+
:CALL(SHA256data)
|
55
|
+
; get & update sha256Data ID
|
56
|
+
$ => E :MLOAD(sha256DataId)
|
57
|
+
E + 1 :MSTORE(sha256DataId)
|
58
|
+
|
59
|
+
; copy sha256 to memory (hash 32 bytes)
|
60
|
+
0 => E
|
61
|
+
A :MSTORE(bytesToStore), CALL(MSTORE32); in: [bytesToStore, E: offset] out: [E: new offset]
|
62
|
+
|
63
|
+
SHA256dataReturn:
|
64
|
+
; handle CTX
|
65
|
+
$ => A :MLOAD(originCTX), JMPZ(handleGas)
|
66
|
+
; set retDataCTX
|
67
|
+
$ => B :MLOAD(currentCTX)
|
68
|
+
A => CTX
|
69
|
+
B :MSTORE(retDataCTX)
|
70
|
+
B => CTX
|
71
|
+
; copy sha256 to retData (hash 32 bytes)
|
72
|
+
$ => C :MLOAD(retCallLength)
|
73
|
+
$ => E :MLOAD(retCallOffset)
|
74
|
+
$ => CTX :MLOAD(originCTX)
|
75
|
+
C - 32 :JMPN(continueSHA256dataReturn)
|
76
|
+
32 => C
|
77
|
+
|
78
|
+
continueSHA256dataReturn:
|
79
|
+
$ => A :MLOAD(sha256Hash)
|
80
|
+
; MSTORE memory origin CTX
|
81
|
+
A :MSTORE(bytesToStore), CALL(MSTOREX) ; in: [bytesToStore, E: offset, C: length] out: [E: new offset]
|
82
|
+
; set currentCTX
|
83
|
+
CTX :MSTORE(currentCTX), JMP(preEnd)
|
84
|
+
|
85
|
+
SHA256data:
|
86
|
+
RR :MSTORE(tmpZkSHA256)
|
87
|
+
0 => E :MSTORE(sha256DataOffset)
|
88
|
+
|
89
|
+
SHA256dataLoop:
|
90
|
+
%MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep)
|
91
|
+
|
92
|
+
; Copy from calldata to hashS
|
93
|
+
C :JMPZ(computeSHA256)
|
94
|
+
C - 32 :JMPN(SHA256dataFinal)
|
95
|
+
$ => E :MLOAD(sha256DataOffset)
|
96
|
+
E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
97
|
+
$ => A :MLOAD(readXFromCalldataResult)
|
98
|
+
E + 32 => E :MSTORE(sha256DataOffset)
|
99
|
+
|
100
|
+
$ => E :MLOAD(sha256DataId)
|
101
|
+
32 => D
|
102
|
+
A :HASHS(E)
|
103
|
+
C - 32 => C :JMP(SHA256dataLoop)
|
104
|
+
|
105
|
+
SHA256dataFinal:
|
106
|
+
%MAX_CNT_STEPS - STEP - 300 :JMPN(outOfCountersStep)
|
107
|
+
|
108
|
+
$ => E :MLOAD(sha256DataOffset)
|
109
|
+
C :MSTORE(readXFromCalldataLength)
|
110
|
+
E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value]
|
111
|
+
$ => A :MLOAD(readXFromCalldataResult)
|
112
|
+
32 - C => D :CALL(SHRarith)
|
113
|
+
$ => E :MLOAD(sha256DataId)
|
114
|
+
C => D
|
115
|
+
A :HASHS(E)
|
116
|
+
|
117
|
+
computeSHA256:
|
118
|
+
%MAX_CNT_STEPS - STEP - 20 :JMPN(outOfCountersStep)
|
119
|
+
|
120
|
+
$ => E :MLOAD(sha256DataId)
|
121
|
+
HASHPOS :HASHSLEN(E)
|
122
|
+
$ => A :HASHSDIGEST(E)
|
123
|
+
A :MSTORE(sha256Hash)
|
124
|
+
$ => RR :MLOAD(tmpZkSHA256)
|
125
|
+
:RETURN
|
@@ -0,0 +1,25 @@
|
|
1
|
+
revertPrecompiled:
|
2
|
+
%MAX_CNT_STEPS - STEP - 100 :JMPN(outOfCountersStep)
|
3
|
+
|
4
|
+
; load initSR to revert all state changes
|
5
|
+
; revert touched accounts
|
6
|
+
$ => SR :MLOAD(initSR), CALL(revertTouched)
|
7
|
+
$${eventLog(onError, revert)}
|
8
|
+
:CALL(revertBlockInfoTree)
|
9
|
+
; check if it is the first context
|
10
|
+
$ => A :MLOAD(originCTX), JMPZ(handleGasFromError) ; first context
|
11
|
+
A => CTX :MSTORE(currentCTX)
|
12
|
+
|
13
|
+
; clear retDataCTX, no return data in revert precompiled
|
14
|
+
0 :MSTORE(retDataCTX)
|
15
|
+
|
16
|
+
; return gas not used to previous context
|
17
|
+
$ => B :MLOAD(gasCTX)
|
18
|
+
GAS + B => GAS
|
19
|
+
|
20
|
+
; restore SP and PC
|
21
|
+
$ => SP :MLOAD(lastSP)
|
22
|
+
$ => PC :MLOAD(lastPC)
|
23
|
+
|
24
|
+
; write 0 in previous context stack
|
25
|
+
0 :MSTORE(SP++), JMP(readCode)
|